Auto merge of #106235 - compiler-errors:rework-bounds-collection, r=davidtwco
Rework `Bounds` collection I think it's weird for the `Bounds` struct in astconv to store its predicates *almost* converted into real predicates... so we do this eagerly, instead of lazily.
This commit is contained in:
commit
fa51fc01ca
5 changed files with 127 additions and 107 deletions
|
@ -682,7 +682,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
ty::Binder::bind_with_vars(tcx.mk_trait_ref(trait_def_id, substs), bound_vars);
|
ty::Binder::bind_with_vars(tcx.mk_trait_ref(trait_def_id, substs), bound_vars);
|
||||||
|
|
||||||
debug!(?poly_trait_ref, ?assoc_bindings);
|
debug!(?poly_trait_ref, ?assoc_bindings);
|
||||||
bounds.trait_bounds.push((poly_trait_ref, span, constness));
|
bounds.push_trait_bound(tcx, poly_trait_ref, span, constness);
|
||||||
|
|
||||||
let mut dup_bindings = FxHashMap::default();
|
let mut dup_bindings = FxHashMap::default();
|
||||||
for binding in &assoc_bindings {
|
for binding in &assoc_bindings {
|
||||||
|
@ -853,18 +853,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets `implicitly_sized` to true on `Bounds` if necessary
|
/// Sets `implicitly_sized` to true on `Bounds` if necessary
|
||||||
pub(crate) fn add_implicitly_sized<'hir>(
|
pub(crate) fn add_implicitly_sized(
|
||||||
&self,
|
&self,
|
||||||
bounds: &mut Bounds<'hir>,
|
bounds: &mut Bounds<'tcx>,
|
||||||
ast_bounds: &'hir [hir::GenericBound<'hir>],
|
self_ty: Ty<'tcx>,
|
||||||
self_ty_where_predicates: Option<(LocalDefId, &'hir [hir::WherePredicate<'hir>])>,
|
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
|
||||||
|
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) {
|
) {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
// Try to find an unbound in bounds.
|
// Try to find an unbound in bounds.
|
||||||
let mut unbound = None;
|
let mut unbound = None;
|
||||||
let mut search_bounds = |ast_bounds: &'hir [hir::GenericBound<'hir>]| {
|
let mut search_bounds = |ast_bounds: &'tcx [hir::GenericBound<'tcx>]| {
|
||||||
for ab in ast_bounds {
|
for ab in ast_bounds {
|
||||||
if let hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = ab {
|
if let hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = ab {
|
||||||
if unbound.is_none() {
|
if unbound.is_none() {
|
||||||
|
@ -912,7 +913,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
// No lang item for `Sized`, so we can't add it as a bound.
|
// No lang item for `Sized`, so we can't add it as a bound.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bounds.implicitly_sized = Some(span);
|
bounds.push_sized(tcx, self_ty, span);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This helper takes a *converted* parameter type (`param_ty`)
|
/// This helper takes a *converted* parameter type (`param_ty`)
|
||||||
|
@ -963,10 +964,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
}
|
}
|
||||||
hir::GenericBound::Outlives(lifetime) => {
|
hir::GenericBound::Outlives(lifetime) => {
|
||||||
let region = self.ast_region_to_region(lifetime, None);
|
let region = self.ast_region_to_region(lifetime, None);
|
||||||
bounds.region_bounds.push((
|
bounds.push_region_bound(
|
||||||
ty::Binder::bind_with_vars(region, bound_vars),
|
self.tcx(),
|
||||||
|
ty::Binder::bind_with_vars(
|
||||||
|
ty::OutlivesPredicate(param_ty, region),
|
||||||
|
bound_vars,
|
||||||
|
),
|
||||||
lifetime.ident.span,
|
lifetime.ident.span,
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1234,13 +1239,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bounds.projection_bounds.push((
|
bounds.push_projection_bound(
|
||||||
projection_ty.map_bound(|projection_ty| ty::ProjectionPredicate {
|
tcx,
|
||||||
projection_ty,
|
projection_ty
|
||||||
term: term,
|
.map_bound(|projection_ty| ty::ProjectionPredicate { projection_ty, term }),
|
||||||
}),
|
|
||||||
binding.span,
|
binding.span,
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
ConvertedBindingKind::Constraint(ast_bounds) => {
|
ConvertedBindingKind::Constraint(ast_bounds) => {
|
||||||
// "Desugar" a constraint like `T: Iterator<Item: Debug>` to
|
// "Desugar" a constraint like `T: Iterator<Item: Debug>` to
|
||||||
|
@ -1269,7 +1273,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
fn conv_object_ty_poly_trait_ref(
|
fn conv_object_ty_poly_trait_ref(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
trait_bounds: &[hir::PolyTraitRef<'_>],
|
hir_trait_bounds: &[hir::PolyTraitRef<'_>],
|
||||||
lifetime: &hir::Lifetime,
|
lifetime: &hir::Lifetime,
|
||||||
borrowed: bool,
|
borrowed: bool,
|
||||||
representation: DynKind,
|
representation: DynKind,
|
||||||
|
@ -1279,7 +1283,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
let mut bounds = Bounds::default();
|
let mut bounds = Bounds::default();
|
||||||
let mut potential_assoc_types = Vec::new();
|
let mut potential_assoc_types = Vec::new();
|
||||||
let dummy_self = self.tcx().types.trait_object_dummy_self;
|
let dummy_self = self.tcx().types.trait_object_dummy_self;
|
||||||
for trait_bound in trait_bounds.iter().rev() {
|
for trait_bound in hir_trait_bounds.iter().rev() {
|
||||||
if let GenericArgCountResult {
|
if let GenericArgCountResult {
|
||||||
correct:
|
correct:
|
||||||
Err(GenericArgCountMismatch { invalid_args: cur_potential_assoc_types, .. }),
|
Err(GenericArgCountMismatch { invalid_args: cur_potential_assoc_types, .. }),
|
||||||
|
@ -1296,10 +1300,45 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut trait_bounds = vec![];
|
||||||
|
let mut projection_bounds = vec![];
|
||||||
|
for (pred, span) in bounds.predicates() {
|
||||||
|
let bound_pred = pred.kind();
|
||||||
|
match bound_pred.skip_binder() {
|
||||||
|
ty::PredicateKind::Clause(clause) => match clause {
|
||||||
|
ty::Clause::Trait(trait_pred) => {
|
||||||
|
assert_eq!(trait_pred.polarity, ty::ImplPolarity::Positive);
|
||||||
|
trait_bounds.push((
|
||||||
|
bound_pred.rebind(trait_pred.trait_ref),
|
||||||
|
span,
|
||||||
|
trait_pred.constness,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
ty::Clause::Projection(proj) => {
|
||||||
|
projection_bounds.push((bound_pred.rebind(proj), span));
|
||||||
|
}
|
||||||
|
ty::Clause::TypeOutlives(_) => {
|
||||||
|
// Do nothing, we deal with regions separately
|
||||||
|
}
|
||||||
|
ty::Clause::RegionOutlives(_) => bug!(),
|
||||||
|
},
|
||||||
|
ty::PredicateKind::WellFormed(_)
|
||||||
|
| ty::PredicateKind::ObjectSafe(_)
|
||||||
|
| ty::PredicateKind::ClosureKind(_, _, _)
|
||||||
|
| ty::PredicateKind::Subtype(_)
|
||||||
|
| ty::PredicateKind::Coerce(_)
|
||||||
|
| ty::PredicateKind::ConstEvaluatable(_)
|
||||||
|
| ty::PredicateKind::ConstEquate(_, _)
|
||||||
|
| ty::PredicateKind::TypeWellFormedFromEnv(_)
|
||||||
|
| ty::PredicateKind::Ambiguous => bug!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Expand trait aliases recursively and check that only one regular (non-auto) trait
|
// Expand trait aliases recursively and check that only one regular (non-auto) trait
|
||||||
// is used and no 'maybe' bounds are used.
|
// is used and no 'maybe' bounds are used.
|
||||||
let expanded_traits =
|
let expanded_traits =
|
||||||
traits::expand_trait_aliases(tcx, bounds.trait_bounds.iter().map(|&(a, b, _)| (a, b)));
|
traits::expand_trait_aliases(tcx, trait_bounds.iter().map(|&(a, b, _)| (a, b)));
|
||||||
|
|
||||||
let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) = expanded_traits
|
let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) = expanded_traits
|
||||||
.filter(|i| i.trait_ref().self_ty().skip_binder() == dummy_self)
|
.filter(|i| i.trait_ref().self_ty().skip_binder() == dummy_self)
|
||||||
.partition(|i| tcx.trait_is_auto(i.trait_ref().def_id()));
|
.partition(|i| tcx.trait_is_auto(i.trait_ref().def_id()));
|
||||||
|
@ -1336,8 +1375,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
}
|
}
|
||||||
|
|
||||||
if regular_traits.is_empty() && auto_traits.is_empty() {
|
if regular_traits.is_empty() && auto_traits.is_empty() {
|
||||||
let trait_alias_span = bounds
|
let trait_alias_span = trait_bounds
|
||||||
.trait_bounds
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&(trait_ref, _, _)| trait_ref.def_id())
|
.map(|&(trait_ref, _, _)| trait_ref.def_id())
|
||||||
.find(|&trait_ref| tcx.is_trait_alias(trait_ref))
|
.find(|&trait_ref| tcx.is_trait_alias(trait_ref))
|
||||||
|
@ -1368,8 +1406,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
// Use a `BTreeSet` to keep output in a more consistent order.
|
// Use a `BTreeSet` to keep output in a more consistent order.
|
||||||
let mut associated_types: FxHashMap<Span, BTreeSet<DefId>> = FxHashMap::default();
|
let mut associated_types: FxHashMap<Span, BTreeSet<DefId>> = FxHashMap::default();
|
||||||
|
|
||||||
let regular_traits_refs_spans = bounds
|
let regular_traits_refs_spans = trait_bounds
|
||||||
.trait_bounds
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|(trait_ref, _, _)| !tcx.trait_is_auto(trait_ref.def_id()));
|
.filter(|(trait_ref, _, _)| !tcx.trait_is_auto(trait_ref.def_id()));
|
||||||
|
|
||||||
|
@ -1423,7 +1460,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
// the discussion in #56288 for alternatives.
|
// the discussion in #56288 for alternatives.
|
||||||
if !references_self {
|
if !references_self {
|
||||||
// Include projections defined on supertraits.
|
// Include projections defined on supertraits.
|
||||||
bounds.projection_bounds.push((pred, span));
|
projection_bounds.push((pred, span));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
|
@ -1431,7 +1468,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (projection_bound, _) in &bounds.projection_bounds {
|
for (projection_bound, _) in &projection_bounds {
|
||||||
for def_ids in associated_types.values_mut() {
|
for def_ids in associated_types.values_mut() {
|
||||||
def_ids.remove(&projection_bound.projection_def_id());
|
def_ids.remove(&projection_bound.projection_def_id());
|
||||||
}
|
}
|
||||||
|
@ -1440,7 +1477,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
self.complain_about_missing_associated_types(
|
self.complain_about_missing_associated_types(
|
||||||
associated_types,
|
associated_types,
|
||||||
potential_assoc_types,
|
potential_assoc_types,
|
||||||
trait_bounds,
|
hir_trait_bounds,
|
||||||
);
|
);
|
||||||
|
|
||||||
// De-duplicate auto traits so that, e.g., `dyn Trait + Send + Send` is the same as
|
// De-duplicate auto traits so that, e.g., `dyn Trait + Send + Send` is the same as
|
||||||
|
@ -1482,7 +1519,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
let substs = tcx.intern_substs(&substs[..]);
|
let substs = tcx.intern_substs(&substs[..]);
|
||||||
|
|
||||||
let span = i.bottom().1;
|
let span = i.bottom().1;
|
||||||
let empty_generic_args = trait_bounds.iter().any(|hir_bound| {
|
let empty_generic_args = hir_trait_bounds.iter().any(|hir_bound| {
|
||||||
hir_bound.trait_ref.path.res == Res::Def(DefKind::Trait, trait_ref.def_id)
|
hir_bound.trait_ref.path.res == Res::Def(DefKind::Trait, trait_ref.def_id)
|
||||||
&& hir_bound.span.contains(span)
|
&& hir_bound.span.contains(span)
|
||||||
});
|
});
|
||||||
|
@ -1514,7 +1551,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
let existential_projections = bounds.projection_bounds.iter().map(|(bound, _)| {
|
let existential_projections = projection_bounds.iter().map(|(bound, _)| {
|
||||||
bound.map_bound(|mut b| {
|
bound.map_bound(|mut b| {
|
||||||
assert_eq!(b.projection_ty.self_ty(), dummy_self);
|
assert_eq!(b.projection_ty.self_ty(), dummy_self);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! Bounds are restrictions applied to some types after they've been converted into the
|
//! Bounds are restrictions applied to some types after they've been converted into the
|
||||||
//! `ty` form from the HIR.
|
//! `ty` form from the HIR.
|
||||||
|
|
||||||
|
use rustc_hir::LangItem;
|
||||||
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
|
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
|
@ -15,73 +16,53 @@ use rustc_span::Span;
|
||||||
/// ^^^^^^^^^ bounding the type parameter `T`
|
/// ^^^^^^^^^ bounding the type parameter `T`
|
||||||
///
|
///
|
||||||
/// impl dyn Bar + Baz
|
/// impl dyn Bar + Baz
|
||||||
/// ^^^^^^^^^ bounding the forgotten dynamic type
|
/// ^^^^^^^^^ bounding the type-erased dynamic type
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Our representation is a bit mixed here -- in some cases, we
|
/// Our representation is a bit mixed here -- in some cases, we
|
||||||
/// include the self type (e.g., `trait_bounds`) but in others we do not
|
/// include the self type (e.g., `trait_bounds`) but in others we do not
|
||||||
#[derive(Default, PartialEq, Eq, Clone, Debug)]
|
#[derive(Default, PartialEq, Eq, Clone, Debug)]
|
||||||
pub struct Bounds<'tcx> {
|
pub struct Bounds<'tcx> {
|
||||||
/// A list of region bounds on the (implicit) self type. So if you
|
pub predicates: Vec<(ty::Predicate<'tcx>, Span)>,
|
||||||
/// had `T: 'a + 'b` this might would be a list `['a, 'b]` (but
|
|
||||||
/// the `T` is not explicitly included).
|
|
||||||
pub region_bounds: Vec<(ty::Binder<'tcx, ty::Region<'tcx>>, Span)>,
|
|
||||||
|
|
||||||
/// A list of trait bounds. So if you had `T: Debug` this would be
|
|
||||||
/// `T: Debug`. Note that the self-type is explicit here.
|
|
||||||
pub trait_bounds: Vec<(ty::PolyTraitRef<'tcx>, Span, ty::BoundConstness)>,
|
|
||||||
|
|
||||||
/// A list of projection equality bounds. So if you had `T:
|
|
||||||
/// Iterator<Item = u32>` this would include `<T as
|
|
||||||
/// Iterator>::Item => u32`. Note that the self-type is explicit
|
|
||||||
/// here.
|
|
||||||
pub projection_bounds: Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>,
|
|
||||||
|
|
||||||
/// `Some` if there is *no* `?Sized` predicate. The `span`
|
|
||||||
/// is the location in the source of the `T` declaration which can
|
|
||||||
/// be cited as the source of the `T: Sized` requirement.
|
|
||||||
pub implicitly_sized: Option<Span>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Bounds<'tcx> {
|
impl<'tcx> Bounds<'tcx> {
|
||||||
/// Converts a bounds list into a flat set of predicates (like
|
pub fn push_region_bound(
|
||||||
/// where-clauses). Because some of our bounds listings (e.g.,
|
&mut self,
|
||||||
/// regions) don't include the self-type, you must supply the
|
|
||||||
/// self-type here (the `param_ty` parameter).
|
|
||||||
pub fn predicates<'out, 's>(
|
|
||||||
&'s self,
|
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_ty: Ty<'tcx>,
|
region: ty::PolyTypeOutlivesPredicate<'tcx>,
|
||||||
// the output must live shorter than the duration of the borrow of self and 'tcx.
|
span: Span,
|
||||||
) -> impl Iterator<Item = (ty::Predicate<'tcx>, Span)> + 'out
|
) {
|
||||||
where
|
self.predicates.push((region.to_predicate(tcx), span));
|
||||||
'tcx: 'out,
|
}
|
||||||
's: 'out,
|
|
||||||
{
|
|
||||||
// If it could be sized, and is, add the `Sized` predicate.
|
|
||||||
let sized_predicate = self.implicitly_sized.and_then(|span| {
|
|
||||||
// FIXME: use tcx.at(span).mk_trait_ref(LangItem::Sized) here? This may make no-core code harder to write.
|
|
||||||
let sized = tcx.lang_items().sized_trait()?;
|
|
||||||
let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(sized, [param_ty]));
|
|
||||||
Some((trait_ref.without_const().to_predicate(tcx), span))
|
|
||||||
});
|
|
||||||
|
|
||||||
let region_preds = self.region_bounds.iter().map(move |&(region_bound, span)| {
|
pub fn push_trait_bound(
|
||||||
let pred = region_bound
|
&mut self,
|
||||||
.map_bound(|region_bound| ty::OutlivesPredicate(param_ty, region_bound))
|
tcx: TyCtxt<'tcx>,
|
||||||
.to_predicate(tcx);
|
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
(pred, span)
|
span: Span,
|
||||||
});
|
constness: ty::BoundConstness,
|
||||||
let trait_bounds =
|
) {
|
||||||
self.trait_bounds.iter().map(move |&(bound_trait_ref, span, constness)| {
|
self.predicates.push((trait_ref.with_constness(constness).to_predicate(tcx), span));
|
||||||
let predicate = bound_trait_ref.with_constness(constness).to_predicate(tcx);
|
}
|
||||||
(predicate, span)
|
|
||||||
});
|
|
||||||
let projection_bounds = self
|
|
||||||
.projection_bounds
|
|
||||||
.iter()
|
|
||||||
.map(move |&(projection, span)| (projection.to_predicate(tcx), span));
|
|
||||||
|
|
||||||
sized_predicate.into_iter().chain(region_preds).chain(trait_bounds).chain(projection_bounds)
|
pub fn push_projection_bound(
|
||||||
|
&mut self,
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
projection: ty::PolyProjectionPredicate<'tcx>,
|
||||||
|
span: Span,
|
||||||
|
) {
|
||||||
|
self.predicates.push((projection.to_predicate(tcx), span));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) {
|
||||||
|
let sized_def_id = tcx.require_lang_item(LangItem::Sized, Some(span));
|
||||||
|
let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(sized_def_id, [ty]));
|
||||||
|
// Preferrable to put this obligation first, since we report better errors for sized ambiguity.
|
||||||
|
self.predicates.insert(0, (trait_ref.without_const().to_predicate(tcx), span));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn predicates(&self) -> impl Iterator<Item = (ty::Predicate<'tcx>, Span)> + '_ {
|
||||||
|
self.predicates.iter().cloned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ fn associated_type_bounds<'tcx>(
|
||||||
let icx = ItemCtxt::new(tcx, assoc_item_def_id);
|
let icx = ItemCtxt::new(tcx, assoc_item_def_id);
|
||||||
let mut bounds = <dyn AstConv<'_>>::compute_bounds(&icx, item_ty, ast_bounds);
|
let mut bounds = <dyn AstConv<'_>>::compute_bounds(&icx, item_ty, ast_bounds);
|
||||||
// Associated types are implicitly sized unless a `?Sized` bound is found
|
// Associated types are implicitly sized unless a `?Sized` bound is found
|
||||||
<dyn AstConv<'_>>::add_implicitly_sized(&icx, &mut bounds, ast_bounds, None, span);
|
<dyn AstConv<'_>>::add_implicitly_sized(&icx, &mut bounds, item_ty, ast_bounds, None, span);
|
||||||
|
|
||||||
let trait_def_id = tcx.parent(assoc_item_def_id);
|
let trait_def_id = tcx.parent(assoc_item_def_id);
|
||||||
let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id.expect_local());
|
let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id.expect_local());
|
||||||
|
@ -44,9 +44,7 @@ fn associated_type_bounds<'tcx>(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let all_bounds = tcx
|
let all_bounds = tcx.arena.alloc_from_iter(bounds.predicates().chain(bounds_from_parent));
|
||||||
.arena
|
|
||||||
.alloc_from_iter(bounds.predicates(tcx, item_ty).into_iter().chain(bounds_from_parent));
|
|
||||||
debug!("associated_type_bounds({}) = {:?}", tcx.def_path_str(assoc_item_def_id), all_bounds);
|
debug!("associated_type_bounds({}) = {:?}", tcx.def_path_str(assoc_item_def_id), all_bounds);
|
||||||
all_bounds
|
all_bounds
|
||||||
}
|
}
|
||||||
|
@ -74,10 +72,10 @@ fn opaque_type_bounds<'tcx>(
|
||||||
let icx = ItemCtxt::new(tcx, opaque_def_id);
|
let icx = ItemCtxt::new(tcx, opaque_def_id);
|
||||||
let mut bounds = <dyn AstConv<'_>>::compute_bounds(&icx, item_ty, ast_bounds);
|
let mut bounds = <dyn AstConv<'_>>::compute_bounds(&icx, item_ty, ast_bounds);
|
||||||
// Opaque types are implicitly sized unless a `?Sized` bound is found
|
// Opaque types are implicitly sized unless a `?Sized` bound is found
|
||||||
<dyn AstConv<'_>>::add_implicitly_sized(&icx, &mut bounds, ast_bounds, None, span);
|
<dyn AstConv<'_>>::add_implicitly_sized(&icx, &mut bounds, item_ty, ast_bounds, None, span);
|
||||||
debug!(?bounds);
|
debug!(?bounds);
|
||||||
|
|
||||||
tcx.arena.alloc_from_iter(bounds.predicates(tcx, item_ty))
|
tcx.arena.alloc_from_iter(bounds.predicates())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,12 +165,13 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
||||||
<dyn AstConv<'_>>::add_implicitly_sized(
|
<dyn AstConv<'_>>::add_implicitly_sized(
|
||||||
&icx,
|
&icx,
|
||||||
&mut bounds,
|
&mut bounds,
|
||||||
|
param_ty,
|
||||||
&[],
|
&[],
|
||||||
Some((param.def_id, ast_generics.predicates)),
|
Some((param.def_id, ast_generics.predicates)),
|
||||||
param.span,
|
param.span,
|
||||||
);
|
);
|
||||||
trace!(?bounds);
|
trace!(?bounds);
|
||||||
predicates.extend(bounds.predicates(tcx, param_ty));
|
predicates.extend(bounds.predicates());
|
||||||
trace!(?predicates);
|
trace!(?predicates);
|
||||||
}
|
}
|
||||||
GenericParamKind::Const { .. } => {
|
GenericParamKind::Const { .. } => {
|
||||||
|
@ -217,7 +218,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
||||||
&mut bounds,
|
&mut bounds,
|
||||||
bound_vars,
|
bound_vars,
|
||||||
);
|
);
|
||||||
predicates.extend(bounds.predicates(tcx, ty));
|
predicates.extend(bounds.predicates());
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::WherePredicate::RegionPredicate(region_pred) => {
|
hir::WherePredicate::RegionPredicate(region_pred) => {
|
||||||
|
@ -536,7 +537,7 @@ pub(super) fn super_predicates_that_define_assoc_type(
|
||||||
<dyn AstConv<'_>>::compute_bounds(&icx, self_param_ty, bounds)
|
<dyn AstConv<'_>>::compute_bounds(&icx, self_param_ty, bounds)
|
||||||
};
|
};
|
||||||
|
|
||||||
let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
|
let superbounds1 = superbounds1.predicates();
|
||||||
|
|
||||||
// Convert any explicit superbounds in the where-clause,
|
// Convert any explicit superbounds in the where-clause,
|
||||||
// e.g., `trait Foo where Self: Bar`.
|
// e.g., `trait Foo where Self: Bar`.
|
||||||
|
@ -745,5 +746,5 @@ fn predicates_from_bound<'tcx>(
|
||||||
) -> Vec<(ty::Predicate<'tcx>, Span)> {
|
) -> Vec<(ty::Predicate<'tcx>, Span)> {
|
||||||
let mut bounds = Bounds::default();
|
let mut bounds = Bounds::default();
|
||||||
astconv.add_bounds(param_ty, [bound].into_iter(), &mut bounds, bound_vars);
|
astconv.add_bounds(param_ty, [bound].into_iter(), &mut bounds, bound_vars);
|
||||||
bounds.predicates(astconv.tcx(), param_ty).collect()
|
bounds.predicates().collect()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1223,19 +1223,22 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
|
||||||
self.tcx.types.never,
|
self.tcx.types.never,
|
||||||
);
|
);
|
||||||
|
|
||||||
for (trait_predicate, _, _) in bounds.trait_bounds {
|
for (pred, _) in bounds.predicates() {
|
||||||
if self.visit_trait(trait_predicate.skip_binder()).is_break() {
|
match pred.kind().skip_binder() {
|
||||||
return;
|
ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) => {
|
||||||
}
|
if self.visit_trait(trait_predicate.trait_ref).is_break() {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
for (poly_predicate, _) in bounds.projection_bounds {
|
}
|
||||||
let pred = poly_predicate.skip_binder();
|
ty::PredicateKind::Clause(ty::Clause::Projection(proj_predicate)) => {
|
||||||
let poly_pred_term = self.visit(pred.term);
|
let term = self.visit(proj_predicate.term);
|
||||||
if poly_pred_term.is_break()
|
if term.is_break()
|
||||||
|| self.visit_projection_ty(pred.projection_ty).is_break()
|
|| self.visit_projection_ty(proj_predicate.projection_ty).is_break()
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue