Use both existential-type desugaring and where-clause (predicate) desugaring depending on context.
This commit is contained in:
parent
aaa53ec853
commit
01f49f0bb2
@ -106,6 +106,7 @@ pub struct LoweringContext<'a> {
|
||||
loop_scopes: Vec<NodeId>,
|
||||
is_in_loop_condition: bool,
|
||||
is_in_trait_impl: bool,
|
||||
is_in_dyn_type: bool,
|
||||
|
||||
/// What to do when we encounter either an "anonymous lifetime
|
||||
/// reference". The term "anonymous" is meant to encompass both
|
||||
@ -195,12 +196,6 @@ enum ImplTraitContext<'a> {
|
||||
/// (e.g., for consts and statics).
|
||||
Existential(Option<DefId> /* fn def-ID */),
|
||||
|
||||
/// Treat `impl Trait` as a bound on the associated type applied to the trait.
|
||||
/// Example: `trait Foo { type Bar: Iterator<Item = impl Debug>; }` is conceptually
|
||||
/// equivalent to `trait Foo where <Self::Bar as Iterator>::Item: Debug
|
||||
/// { type Bar: Iterator; }`.
|
||||
AssociatedTy,
|
||||
|
||||
/// `impl Trait` is not accepted in this position.
|
||||
Disallowed(ImplTraitPosition),
|
||||
}
|
||||
@ -208,7 +203,10 @@ enum ImplTraitContext<'a> {
|
||||
/// Position in which `impl Trait` is disallowed. Used for error reporting.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
enum ImplTraitPosition {
|
||||
/// Disallowed in `let` / `const` / `static` bindings.
|
||||
Binding,
|
||||
|
||||
/// All other posiitons.
|
||||
Other,
|
||||
}
|
||||
|
||||
@ -223,7 +221,6 @@ impl<'a> ImplTraitContext<'a> {
|
||||
match self {
|
||||
Universal(params) => Universal(params),
|
||||
Existential(fn_def_id) => Existential(*fn_def_id),
|
||||
AssociatedTy => AssociatedTy,
|
||||
Disallowed(pos) => Disallowed(*pos),
|
||||
}
|
||||
}
|
||||
@ -256,6 +253,8 @@ pub fn lower_crate(
|
||||
catch_scopes: Vec::new(),
|
||||
loop_scopes: Vec::new(),
|
||||
is_in_loop_condition: false,
|
||||
is_in_trait_impl: false,
|
||||
is_in_dyn_type: false,
|
||||
anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
|
||||
type_def_lifetime_params: Default::default(),
|
||||
current_module: CRATE_NODE_ID,
|
||||
@ -265,7 +264,6 @@ pub fn lower_crate(
|
||||
is_generator: false,
|
||||
is_async_body: false,
|
||||
current_item: None,
|
||||
is_in_trait_impl: false,
|
||||
lifetimes_to_define: Vec::new(),
|
||||
is_collecting_in_band_lifetimes: false,
|
||||
in_scope_lifetimes: Vec::new(),
|
||||
@ -1230,6 +1228,20 @@ impl<'a> LoweringContext<'a> {
|
||||
result
|
||||
}
|
||||
|
||||
fn with_dyn_type_scope<T, F>(&mut self, in_scope: bool, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut LoweringContext<'_>) -> T,
|
||||
{
|
||||
let was_in_dyn_type = self.is_in_dyn_type;
|
||||
self.is_in_dyn_type = in_scope;
|
||||
|
||||
let result = f(self);
|
||||
|
||||
self.is_in_dyn_type = was_in_dyn_type;
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn with_new_scopes<T, F>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut LoweringContext<'_>) -> T,
|
||||
@ -1353,24 +1365,58 @@ impl<'a> LoweringContext<'a> {
|
||||
c: &AssocTyConstraint,
|
||||
itctx: ImplTraitContext<'_>)
|
||||
-> hir::TypeBinding {
|
||||
debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", c, itctx);
|
||||
|
||||
let ty = match c.kind {
|
||||
AssocTyConstraintKind::Equality { ref ty } => self.lower_ty(ty, itctx),
|
||||
AssocTyConstraintKind::Bound { ref bounds } => {
|
||||
// Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`.
|
||||
let impl_ty_node_id = self.sess.next_node_id();
|
||||
let parent_def_index = self.current_hir_id_owner.last().unwrap().0;
|
||||
self.resolver.definitions().create_def_with_parent(
|
||||
parent_def_index,
|
||||
impl_ty_node_id,
|
||||
DefPathData::Misc,
|
||||
DefIndexAddressSpace::High,
|
||||
Mark::root(),
|
||||
DUMMY_SP);
|
||||
self.lower_ty(&Ty {
|
||||
id: self.sess.next_node_id(),
|
||||
node: TyKind::ImplTrait(impl_ty_node_id, bounds.clone()),
|
||||
span: DUMMY_SP,
|
||||
}, itctx)
|
||||
let (existential_desugaring, itctx) = match itctx {
|
||||
ImplTraitContext::Existential(_) => (true, itctx),
|
||||
ImplTraitContext::Universal(_) if self.is_in_dyn_type => (true, itctx),
|
||||
// FIXME: this is only needed until `impl Trait` is allowed in type aliases.
|
||||
ImplTraitContext::Disallowed(_) if self.is_in_dyn_type =>
|
||||
(true, ImplTraitContext::Existential(None)),
|
||||
_ => (false, itctx),
|
||||
};
|
||||
|
||||
if existential_desugaring {
|
||||
// Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`.
|
||||
|
||||
let impl_ty_node_id = self.sess.next_node_id();
|
||||
let parent_def_index = self.current_hir_id_owner.last().unwrap().0;
|
||||
self.resolver.definitions().create_def_with_parent(
|
||||
parent_def_index,
|
||||
impl_ty_node_id,
|
||||
DefPathData::Misc,
|
||||
DefIndexAddressSpace::High,
|
||||
Mark::root(),
|
||||
DUMMY_SP
|
||||
);
|
||||
|
||||
self.with_dyn_type_scope(false, |this| {
|
||||
this.lower_ty(
|
||||
&Ty {
|
||||
id: this.sess.next_node_id(),
|
||||
node: TyKind::ImplTrait(impl_ty_node_id, bounds.clone()),
|
||||
span: DUMMY_SP,
|
||||
},
|
||||
itctx,
|
||||
)
|
||||
})
|
||||
} else {
|
||||
// Desugar `AssocTy: Bounds` into `AssocTy = ∃ T (T: Bounds)`, where the
|
||||
// "false existential" later desugars into a trait predicate.
|
||||
|
||||
let bounds = self.lower_param_bounds(bounds, itctx);
|
||||
|
||||
let id = self.sess.next_node_id();
|
||||
let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(id);
|
||||
P(hir::Ty {
|
||||
hir_id,
|
||||
node: hir::TyKind::AssocTyExistential(bounds),
|
||||
span: DUMMY_SP,
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -1477,23 +1523,26 @@ impl<'a> LoweringContext<'a> {
|
||||
}
|
||||
TyKind::TraitObject(ref bounds, kind) => {
|
||||
let mut lifetime_bound = None;
|
||||
let bounds = bounds
|
||||
.iter()
|
||||
.filter_map(|bound| match *bound {
|
||||
GenericBound::Trait(ref ty, TraitBoundModifier::None) => {
|
||||
Some(self.lower_poly_trait_ref(ty, itctx.reborrow()))
|
||||
}
|
||||
GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
|
||||
GenericBound::Outlives(ref lifetime) => {
|
||||
if lifetime_bound.is_none() {
|
||||
lifetime_bound = Some(self.lower_lifetime(lifetime));
|
||||
let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
|
||||
let bounds = bounds
|
||||
.iter()
|
||||
.filter_map(|bound| match *bound {
|
||||
GenericBound::Trait(ref ty, TraitBoundModifier::None) => {
|
||||
Some(this.lower_poly_trait_ref(ty, itctx.reborrow()))
|
||||
}
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let lifetime_bound =
|
||||
lifetime_bound.unwrap_or_else(|| self.elided_dyn_bound(t.span));
|
||||
GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
|
||||
GenericBound::Outlives(ref lifetime) => {
|
||||
if lifetime_bound.is_none() {
|
||||
lifetime_bound = Some(this.lower_lifetime(lifetime));
|
||||
}
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let lifetime_bound =
|
||||
lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
|
||||
(bounds, lifetime_bound)
|
||||
});
|
||||
if kind != TraitObjectSyntax::Dyn {
|
||||
self.maybe_lint_bare_trait(t.span, t.id, false);
|
||||
}
|
||||
@ -1544,16 +1593,6 @@ impl<'a> LoweringContext<'a> {
|
||||
}),
|
||||
))
|
||||
}
|
||||
ImplTraitContext::AssociatedTy => {
|
||||
let hir_bounds = self.lower_param_bounds(
|
||||
bounds,
|
||||
ImplTraitContext::AssociatedTy,
|
||||
);
|
||||
|
||||
hir::TyKind::AssocTyExistential(
|
||||
hir_bounds,
|
||||
)
|
||||
}
|
||||
ImplTraitContext::Disallowed(pos) => {
|
||||
let allowed_in = if self.sess.features_untracked()
|
||||
.impl_trait_in_bindings {
|
||||
@ -2407,7 +2446,8 @@ impl<'a> LoweringContext<'a> {
|
||||
FunctionRetTy::Ty(ref ty) => match in_band_ty_params {
|
||||
Some((def_id, _)) if impl_trait_return_allow => {
|
||||
hir::Return(self.lower_ty(ty,
|
||||
ImplTraitContext::Existential(Some(def_id))))
|
||||
ImplTraitContext::Existential(Some(def_id))
|
||||
))
|
||||
}
|
||||
_ => {
|
||||
hir::Return(self.lower_ty(ty, ImplTraitContext::disallowed()))
|
||||
@ -2770,7 +2810,7 @@ impl<'a> LoweringContext<'a> {
|
||||
|
||||
let kind = hir::GenericParamKind::Type {
|
||||
default: default.as_ref().map(|x| {
|
||||
self.lower_ty(x, ImplTraitContext::disallowed())
|
||||
self.lower_ty(x, ImplTraitContext::Existential(None))
|
||||
}),
|
||||
synthetic: param.attrs.iter()
|
||||
.filter(|attr| attr.check_name(sym::rustc_synthetic))
|
||||
@ -3275,39 +3315,43 @@ impl<'a> LoweringContext<'a> {
|
||||
ItemKind::ForeignMod(ref nm) => hir::ItemKind::ForeignMod(self.lower_foreign_mod(nm)),
|
||||
ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)),
|
||||
ItemKind::Ty(ref t, ref generics) => hir::ItemKind::Ty(
|
||||
self.lower_ty(t, ImplTraitContext::AssociatedTy),
|
||||
self.lower_generics(generics, ImplTraitContext::AssociatedTy),
|
||||
self.lower_ty(t, ImplTraitContext::disallowed()),
|
||||
self.lower_generics(generics, ImplTraitContext::disallowed()),
|
||||
),
|
||||
ItemKind::Existential(ref b, ref generics) => hir::ItemKind::Existential(
|
||||
hir::ExistTy {
|
||||
generics: self.lower_generics(generics, ImplTraitContext::AssociatedTy),
|
||||
bounds: self.lower_param_bounds(b, ImplTraitContext::AssociatedTy),
|
||||
generics: self.lower_generics(generics,
|
||||
ImplTraitContext::Existential(None)),
|
||||
bounds: self.lower_param_bounds(b,
|
||||
ImplTraitContext::Existential(None)),
|
||||
impl_trait_fn: None,
|
||||
origin: hir::ExistTyOrigin::ExistentialType,
|
||||
},
|
||||
),
|
||||
ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemKind::Enum(
|
||||
hir::EnumDef {
|
||||
variants: enum_definition
|
||||
.variants
|
||||
.iter()
|
||||
.map(|x| self.lower_variant(x))
|
||||
.collect(),
|
||||
},
|
||||
self.lower_generics(generics, ImplTraitContext::AssociatedTy),
|
||||
),
|
||||
ItemKind::Enum(ref enum_definition, ref generics) => {
|
||||
hir::ItemKind::Enum(
|
||||
hir::EnumDef {
|
||||
variants: enum_definition
|
||||
.variants
|
||||
.iter()
|
||||
.map(|x| self.lower_variant(x))
|
||||
.collect(),
|
||||
},
|
||||
self.lower_generics(generics, ImplTraitContext::disallowed()),
|
||||
)
|
||||
},
|
||||
ItemKind::Struct(ref struct_def, ref generics) => {
|
||||
let struct_def = self.lower_variant_data(struct_def);
|
||||
hir::ItemKind::Struct(
|
||||
struct_def,
|
||||
self.lower_generics(generics, ImplTraitContext::AssociatedTy),
|
||||
self.lower_generics(generics, ImplTraitContext::disallowed()),
|
||||
)
|
||||
}
|
||||
ItemKind::Union(ref vdata, ref generics) => {
|
||||
let vdata = self.lower_variant_data(vdata);
|
||||
hir::ItemKind::Union(
|
||||
vdata,
|
||||
self.lower_generics(generics, ImplTraitContext::AssociatedTy),
|
||||
self.lower_generics(generics, ImplTraitContext::disallowed()),
|
||||
)
|
||||
}
|
||||
ItemKind::Impl(
|
||||
@ -3675,9 +3719,9 @@ impl<'a> LoweringContext<'a> {
|
||||
(generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Provided(body_id)))
|
||||
}
|
||||
TraitItemKind::Type(ref bounds, ref default) => {
|
||||
let generics = self.lower_generics(&i.generics, ImplTraitContext::AssociatedTy);
|
||||
let generics = self.lower_generics(&i.generics, ImplTraitContext::disallowed());
|
||||
let node = hir::TraitItemKind::Type(
|
||||
self.lower_param_bounds(bounds, ImplTraitContext::AssociatedTy),
|
||||
self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
|
||||
default
|
||||
.as_ref()
|
||||
.map(|x| self.lower_ty(x, ImplTraitContext::disallowed())),
|
||||
|
@ -63,6 +63,10 @@ struct AstValidator<'a> {
|
||||
/// or `Foo::Bar<impl Trait>`
|
||||
is_impl_trait_banned: bool,
|
||||
|
||||
/// Used to ban associated type bounds (i.e., `Type<AssocType: Bounds>`) in
|
||||
/// certain positions.
|
||||
is_assoc_ty_bound_banned: bool,
|
||||
|
||||
/// rust-lang/rust#57979: the ban of nested `impl Trait` was buggy
|
||||
/// until PRs #57730 and #57981 landed: it would jump directly to
|
||||
/// walk_ty rather than visit_ty (or skip recurring entirely for
|
||||
@ -87,6 +91,12 @@ impl<'a> AstValidator<'a> {
|
||||
self.is_impl_trait_banned = old;
|
||||
}
|
||||
|
||||
fn with_banned_assoc_ty_bound(&mut self, f: impl FnOnce(&mut Self)) {
|
||||
let old = mem::replace(&mut self.is_assoc_ty_bound_banned, true);
|
||||
f(self);
|
||||
self.is_assoc_ty_bound_banned = old;
|
||||
}
|
||||
|
||||
fn with_impl_trait(&mut self, outer: Option<OuterImplTrait>, f: impl FnOnce(&mut Self)) {
|
||||
let old = mem::replace(&mut self.outer_impl_trait, outer);
|
||||
f(self);
|
||||
@ -94,12 +104,21 @@ impl<'a> AstValidator<'a> {
|
||||
}
|
||||
|
||||
fn visit_assoc_ty_constraint_from_generic_args(&mut self, constraint: &'a AssocTyConstraint) {
|
||||
if let AssocTyConstraintKind::Equality { ref ty } = constraint.kind {
|
||||
// rust-lang/rust#57979: bug in old `visit_generic_args` called
|
||||
// `walk_ty` rather than `visit_ty`, skipping outer `impl Trait`
|
||||
// if it happened to occur at `ty`.
|
||||
if let TyKind::ImplTrait(..) = ty.node {
|
||||
self.warning_period_57979_didnt_record_next_impl_trait = true;
|
||||
match constraint.kind {
|
||||
AssocTyConstraintKind::Equality { ref ty } => {
|
||||
// rust-lang/rust#57979: bug in old `visit_generic_args` called
|
||||
// `walk_ty` rather than `visit_ty`, skipping outer `impl Trait`
|
||||
// if it happened to occur at `ty`.
|
||||
if let TyKind::ImplTrait(..) = ty.node {
|
||||
self.warning_period_57979_didnt_record_next_impl_trait = true;
|
||||
}
|
||||
}
|
||||
AssocTyConstraintKind::Bound { .. } => {
|
||||
if self.is_assoc_ty_bound_banned {
|
||||
self.err_handler().span_err(constraint.span,
|
||||
"associated type bounds are not allowed within structs, enums, or unions"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
self.visit_assoc_ty_constraint(constraint);
|
||||
@ -726,7 +745,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
// Type bindings such as `Item = impl Debug` in `Iterator<Item = Debug>`
|
||||
// are allowed to contain nested `impl Trait`.
|
||||
self.with_impl_trait(None, |this| {
|
||||
walk_list!(this, visit_assoc_ty_constraint_from_generic_args, &data.constraints);
|
||||
walk_list!(this, visit_assoc_ty_constraint_from_generic_args,
|
||||
&data.constraints);
|
||||
});
|
||||
}
|
||||
GenericArgs::Parenthesized(ref data) => {
|
||||
@ -819,6 +839,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
visit::walk_poly_trait_ref(self, t, m);
|
||||
}
|
||||
|
||||
fn visit_variant_data(&mut self, s: &'a VariantData, _: Ident,
|
||||
_: &'a Generics, _: NodeId, _: Span) {
|
||||
self.with_banned_assoc_ty_bound(|this| visit::walk_struct_def(this, s))
|
||||
}
|
||||
|
||||
fn visit_enum_def(&mut self, enum_definition: &'a EnumDef,
|
||||
generics: &'a Generics, item_id: NodeId, _: Span) {
|
||||
self.with_banned_assoc_ty_bound(
|
||||
|this| visit::walk_enum_def(this, enum_definition, generics, item_id))
|
||||
}
|
||||
|
||||
fn visit_mac(&mut self, mac: &Spanned<Mac_>) {
|
||||
// when a new macro kind is added but the author forgets to set it up for expansion
|
||||
// because that's the only part that won't cause a compiler error
|
||||
@ -842,6 +873,7 @@ pub fn check_crate(session: &Session, krate: &Crate) -> (bool, bool) {
|
||||
has_global_allocator: false,
|
||||
outer_impl_trait: None,
|
||||
is_impl_trait_banned: false,
|
||||
is_assoc_ty_bound_banned: false,
|
||||
warning_period_57979_didnt_record_next_impl_trait: false,
|
||||
warning_period_57979_impl_trait_in_proj: false,
|
||||
};
|
||||
|
@ -930,13 +930,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
.into_iter()
|
||||
.map(|r| (self.ast_region_to_region(r, None), r.span))
|
||||
);
|
||||
|
||||
bounds.trait_bounds.sort_by_key(|(t, _)| t.def_id());
|
||||
}
|
||||
|
||||
/// Translates the AST's notion of ty param bounds (which are an enum consisting of a newtyped `Ty`
|
||||
/// or a region) to ty's notion of ty param bounds, which can either be user-defined traits or the
|
||||
/// built-in trait `Send`.
|
||||
/// Translates the AST's notion of ty param bounds (which are an enum consisting of a newtyped
|
||||
/// `Ty` or a region) to ty's notion of ty param bounds, which can either be user-defined traits
|
||||
/// or the built-in trait `Send`.
|
||||
pub fn compute_bounds(&self,
|
||||
param_ty: Ty<'tcx>,
|
||||
ast_bounds: &[hir::GenericBound],
|
||||
@ -944,7 +942,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
span: Span,
|
||||
) -> Bounds<'tcx> {
|
||||
let mut bounds = Bounds::default();
|
||||
|
||||
self.add_bounds(param_ty, ast_bounds, &mut bounds);
|
||||
bounds.trait_bounds.sort_by_key(|(t, _)| t.def_id());
|
||||
|
||||
bounds.implicitly_sized = if let SizedByDefault::Yes = sized_by_default {
|
||||
if !self.is_unsized(ast_bounds, span) {
|
||||
Some(span)
|
||||
@ -954,6 +955,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
bounds
|
||||
}
|
||||
|
||||
@ -993,7 +995,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
// for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
|
||||
// for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
|
||||
if let ConvertedBindingKind::Equality(ty) = binding.kind {
|
||||
let late_bound_in_trait_ref = tcx.collect_constrained_late_bound_regions(&trait_ref);
|
||||
let late_bound_in_trait_ref =
|
||||
tcx.collect_constrained_late_bound_regions(&trait_ref);
|
||||
let late_bound_in_ty =
|
||||
tcx.collect_referenced_late_bound_regions(&ty::Binder::bind(ty));
|
||||
debug!("late_bound_in_trait_ref = {:?}", late_bound_in_trait_ref);
|
||||
@ -1074,8 +1077,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
}), binding.span));
|
||||
}
|
||||
ConvertedBindingKind::Constraint(ref ast_bounds) => {
|
||||
// Calling `skip_binder` is okay, because the predicates are re-bound later by
|
||||
// `instantiate_poly_trait_ref`.
|
||||
let param_ty = tcx.mk_projection(assoc_ty.def_id, candidate.skip_binder().substs);
|
||||
self.add_bounds(
|
||||
trait_ref.self_ty(),
|
||||
param_ty,
|
||||
ast_bounds,
|
||||
bounds,
|
||||
);
|
||||
@ -2050,6 +2056,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
}
|
||||
};
|
||||
|
||||
debug!("ast_ty_to_ty: result_ty={:?}", result_ty);
|
||||
|
||||
self.record_ty(ast_ty.hir_id, result_ty, ast_ty.span);
|
||||
result_ty
|
||||
}
|
||||
@ -2135,7 +2143,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
}
|
||||
}
|
||||
});
|
||||
debug!("impl_trait_ty_to_ty: final substs = {:?}", substs);
|
||||
debug!("impl_trait_ty_to_ty: substs={:?}", substs);
|
||||
|
||||
let ty = tcx.mk_opaque(def_id, substs);
|
||||
debug!("impl_trait_ty_to_ty: {}", ty);
|
||||
|
@ -703,7 +703,8 @@ fn super_predicates_of<'a, 'tcx>(
|
||||
|
||||
// Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo: Bar + Zed`.
|
||||
let self_param_ty = tcx.mk_self_type();
|
||||
let superbounds1 = AstConv::compute_bounds(&icx, self_param_ty, bounds, SizedByDefault::No, item.span);
|
||||
let superbounds1 = AstConv::compute_bounds(&icx, self_param_ty, bounds, SizedByDefault::No,
|
||||
item.span);
|
||||
|
||||
let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
|
||||
|
||||
@ -1988,15 +1989,16 @@ fn explicit_predicates_of<'a, 'tcx>(
|
||||
tcx.def_span(def_id),
|
||||
);
|
||||
|
||||
let bounds_predicates = bounds.predicates(tcx, opaque_ty);
|
||||
if impl_trait_fn.is_some() {
|
||||
// opaque types
|
||||
return tcx.arena.alloc(ty::GenericPredicates {
|
||||
parent: None,
|
||||
predicates: bounds.predicates(tcx, opaque_ty),
|
||||
predicates: bounds_predicates,
|
||||
});
|
||||
} else {
|
||||
// named existential types
|
||||
predicates.extend(bounds.predicates(tcx, opaque_ty));
|
||||
predicates.extend(bounds_predicates);
|
||||
generics
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user