Get rid of `TyImplTraitExistential`
This commit is contained in:
parent
45935640f0
commit
6e5b9c1472
|
@ -607,13 +607,6 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
|
||||||
}
|
}
|
||||||
visitor.visit_lifetime(lifetime);
|
visitor.visit_lifetime(lifetime);
|
||||||
}
|
}
|
||||||
TyImplTraitExistential(_, def_id, ref lifetimes) => {
|
|
||||||
// we are not recursing into the `existential` item, because it is already being visited
|
|
||||||
// as part of the surrounding module. The `NodeId` just exists so we don't have to look
|
|
||||||
// it up everywhere else in the compiler
|
|
||||||
visitor.visit_def_mention(Def::Existential(def_id));
|
|
||||||
walk_list!(visitor, visit_lifetime, lifetimes);
|
|
||||||
}
|
|
||||||
TyTypeof(ref expression) => {
|
TyTypeof(ref expression) => {
|
||||||
visitor.visit_anon_const(expression)
|
visitor.visit_anon_const(expression)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1306,13 +1306,20 @@ impl<'a> LoweringContext<'a> {
|
||||||
lctx.items.insert(exist_ty_id.node_id, exist_ty_item);
|
lctx.items.insert(exist_ty_id.node_id, exist_ty_item);
|
||||||
|
|
||||||
// `impl Trait` now just becomes `Foo<'a, 'b, ..>`
|
// `impl Trait` now just becomes `Foo<'a, 'b, ..>`
|
||||||
hir::TyImplTraitExistential(
|
let path = P(hir::Path {
|
||||||
hir::ItemId {
|
span: exist_ty_span,
|
||||||
id: exist_ty_id.node_id
|
def: Def::Existential(DefId::local(exist_ty_def_index)),
|
||||||
},
|
segments: hir_vec![hir::PathSegment {
|
||||||
DefId::local(exist_ty_def_index),
|
infer_types: false,
|
||||||
lifetimes,
|
ident: Ident::new(keywords::Invalid.name(), exist_ty_span),
|
||||||
)
|
args: Some(P(hir::GenericArgs {
|
||||||
|
parenthesized: false,
|
||||||
|
bindings: HirVec::new(),
|
||||||
|
args: lifetimes,
|
||||||
|
}))
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
hir::TyPath(hir::QPath::Resolved(None, path))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1321,7 +1328,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
exist_ty_id: NodeId,
|
exist_ty_id: NodeId,
|
||||||
parent_index: DefIndex,
|
parent_index: DefIndex,
|
||||||
bounds: &hir::GenericBounds,
|
bounds: &hir::GenericBounds,
|
||||||
) -> (HirVec<hir::Lifetime>, HirVec<hir::GenericParam>) {
|
) -> (HirVec<hir::GenericArg>, HirVec<hir::GenericParam>) {
|
||||||
// This visitor walks over impl trait bounds and creates defs for all lifetimes which
|
// This visitor walks over impl trait bounds and creates defs for all lifetimes which
|
||||||
// appear in the bounds, excluding lifetimes that are created within the bounds.
|
// appear in the bounds, excluding lifetimes that are created within the bounds.
|
||||||
// e.g. 'a, 'b, but not 'c in `impl for<'c> SomeTrait<'a, 'b, 'c>`
|
// e.g. 'a, 'b, but not 'c in `impl for<'c> SomeTrait<'a, 'b, 'c>`
|
||||||
|
@ -1332,7 +1339,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
collect_elided_lifetimes: bool,
|
collect_elided_lifetimes: bool,
|
||||||
currently_bound_lifetimes: Vec<hir::LifetimeName>,
|
currently_bound_lifetimes: Vec<hir::LifetimeName>,
|
||||||
already_defined_lifetimes: HashSet<hir::LifetimeName>,
|
already_defined_lifetimes: HashSet<hir::LifetimeName>,
|
||||||
output_lifetimes: Vec<hir::Lifetime>,
|
output_lifetimes: Vec<hir::GenericArg>,
|
||||||
output_lifetime_params: Vec<hir::GenericParam>,
|
output_lifetime_params: Vec<hir::GenericParam>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1416,11 +1423,11 @@ impl<'a> LoweringContext<'a> {
|
||||||
&& !self.already_defined_lifetimes.contains(&name) {
|
&& !self.already_defined_lifetimes.contains(&name) {
|
||||||
self.already_defined_lifetimes.insert(name);
|
self.already_defined_lifetimes.insert(name);
|
||||||
|
|
||||||
self.output_lifetimes.push(hir::Lifetime {
|
self.output_lifetimes.push(hir::GenericArg::Lifetime(hir::Lifetime {
|
||||||
id: self.context.next_id().node_id,
|
id: self.context.next_id().node_id,
|
||||||
span: lifetime.span,
|
span: lifetime.span,
|
||||||
name,
|
name,
|
||||||
});
|
}));
|
||||||
|
|
||||||
// We need to manually create the ids here, because the
|
// We need to manually create the ids here, because the
|
||||||
// definitions will go into the explicit `existential type`
|
// definitions will go into the explicit `existential type`
|
||||||
|
|
|
@ -1692,18 +1692,6 @@ pub enum Ty_ {
|
||||||
/// A trait object type `Bound1 + Bound2 + Bound3`
|
/// A trait object type `Bound1 + Bound2 + Bound3`
|
||||||
/// where `Bound` is a trait or a lifetime.
|
/// where `Bound` is a trait or a lifetime.
|
||||||
TyTraitObject(HirVec<PolyTraitRef>, Lifetime),
|
TyTraitObject(HirVec<PolyTraitRef>, Lifetime),
|
||||||
/// An existentially quantified (there exists a type satisfying) `impl
|
|
||||||
/// Bound1 + Bound2 + Bound3` type where `Bound` is a trait or a lifetime.
|
|
||||||
///
|
|
||||||
/// The `Item` is the generated
|
|
||||||
/// `existential type Foo<'a, 'b>: MyTrait<'a, 'b>;`.
|
|
||||||
///
|
|
||||||
/// The `HirVec<Lifetime>` is the list of lifetimes applied as parameters
|
|
||||||
/// to the `abstract type`, e.g. the `'c` and `'d` in `-> Foo<'c, 'd>`.
|
|
||||||
/// This list is only a list of lifetimes and not type parameters
|
|
||||||
/// because all in-scope type parameters are captured by `impl Trait`,
|
|
||||||
/// so they are resolved directly through the parent `Generics`.
|
|
||||||
TyImplTraitExistential(ItemId, DefId, HirVec<Lifetime>),
|
|
||||||
/// Unused for now
|
/// Unused for now
|
||||||
TyTypeof(AnonConst),
|
TyTypeof(AnonConst),
|
||||||
/// TyInfer means the type should be inferred instead of it having been
|
/// TyInfer means the type should be inferred instead of it having been
|
||||||
|
|
|
@ -420,15 +420,6 @@ impl<'a> State<'a> {
|
||||||
self.print_lifetime(lifetime)?;
|
self.print_lifetime(lifetime)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::TyImplTraitExistential(hir_id, _def_id, ref _lifetimes) => {
|
|
||||||
match self.ann.try_fetch_item(hir_id.id).map(|it| &it.node) {
|
|
||||||
None => self.word_space("impl {{Trait}}")?,
|
|
||||||
Some(&hir::ItemExistential(ref exist_ty)) => {
|
|
||||||
self.print_bounds("impl", &exist_ty.bounds)?;
|
|
||||||
},
|
|
||||||
other => bug!("impl Trait pointed to {:#?}", other),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hir::TyArray(ref ty, ref length) => {
|
hir::TyArray(ref ty, ref length) => {
|
||||||
self.s.word("[")?;
|
self.s.word("[")?;
|
||||||
self.print_type(&ty)?;
|
self.print_type(&ty)?;
|
||||||
|
|
|
@ -340,7 +340,6 @@ impl_stable_hash_for!(enum hir::Ty_ {
|
||||||
TyTup(ts),
|
TyTup(ts),
|
||||||
TyPath(qpath),
|
TyPath(qpath),
|
||||||
TyTraitObject(trait_refs, lifetime),
|
TyTraitObject(trait_refs, lifetime),
|
||||||
TyImplTraitExistential(existty, def_id, lifetimes),
|
|
||||||
TyTypeof(body_id),
|
TyTypeof(body_id),
|
||||||
TyErr,
|
TyErr,
|
||||||
TyInfer
|
TyInfer
|
||||||
|
|
|
@ -625,122 +625,131 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
self.with(scope, |_, this| this.visit_ty(&mt.ty));
|
self.with(scope, |_, this| this.visit_ty(&mt.ty));
|
||||||
}
|
}
|
||||||
hir::TyImplTraitExistential(item_id, _, ref lifetimes) => {
|
hir::TyPath(hir::QPath::Resolved(None, ref path)) => {
|
||||||
// Resolve the lifetimes that are applied to the existential type.
|
if let Def::Existential(exist_ty_did) = path.def {
|
||||||
// These are resolved in the current scope.
|
assert!(exist_ty_did.is_local());
|
||||||
// `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
|
// Resolve the lifetimes that are applied to the existential type.
|
||||||
// `fn foo<'a>() -> MyAnonTy<'a> { ... }`
|
// These are resolved in the current scope.
|
||||||
// ^ ^this gets resolved in the current scope
|
// `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
|
||||||
for lifetime in lifetimes {
|
// `fn foo<'a>() -> MyAnonTy<'a> { ... }`
|
||||||
self.visit_lifetime(lifetime);
|
// ^ ^this gets resolved in the current scope
|
||||||
|
for lifetime in &path.segments[0].args.as_ref().unwrap().args {
|
||||||
|
if let hir::GenericArg::Lifetime(lifetime) = lifetime {
|
||||||
|
self.visit_lifetime(lifetime);
|
||||||
|
|
||||||
// Check for predicates like `impl for<'a> SomeTrait<impl OtherTrait<'a>>`
|
// Check for predicates like `impl for<'a> Trait<impl OtherTrait<'a>>`
|
||||||
// and ban them. Type variables instantiated inside binders aren't
|
// and ban them. Type variables instantiated inside binders aren't
|
||||||
// well-supported at the moment, so this doesn't work.
|
// well-supported at the moment, so this doesn't work.
|
||||||
// In the future, this should be fixed and this error should be removed.
|
// In the future, this should be fixed and this error should be removed.
|
||||||
let def = self.map.defs.get(&lifetime.id).cloned();
|
let def = self.map.defs.get(&lifetime.id).cloned();
|
||||||
if let Some(Region::LateBound(_, def_id, _)) = def {
|
if let Some(Region::LateBound(_, def_id, _)) = def {
|
||||||
if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
|
if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
|
||||||
// Ensure that the parent of the def is an item, not HRTB
|
// Ensure that the parent of the def is an item, not HRTB
|
||||||
let parent_id = self.tcx.hir.get_parent_node(node_id);
|
let parent_id = self.tcx.hir.get_parent_node(node_id);
|
||||||
let parent_impl_id = hir::ImplItemId { node_id: parent_id };
|
let parent_impl_id = hir::ImplItemId { node_id: parent_id };
|
||||||
let parent_trait_id = hir::TraitItemId { node_id: parent_id };
|
let parent_trait_id = hir::TraitItemId { node_id: parent_id };
|
||||||
let krate = self.tcx.hir.forest.krate();
|
let krate = self.tcx.hir.forest.krate();
|
||||||
if !(krate.items.contains_key(&parent_id)
|
if !(krate.items.contains_key(&parent_id)
|
||||||
|| krate.impl_items.contains_key(&parent_impl_id)
|
|| krate.impl_items.contains_key(&parent_impl_id)
|
||||||
|| krate.trait_items.contains_key(&parent_trait_id))
|
|| krate.trait_items.contains_key(&parent_trait_id))
|
||||||
{
|
{
|
||||||
span_err!(
|
span_err!(
|
||||||
self.tcx.sess,
|
self.tcx.sess,
|
||||||
lifetime.span,
|
lifetime.span,
|
||||||
E0657,
|
E0657,
|
||||||
"`impl Trait` can only capture lifetimes \
|
"`impl Trait` can only capture lifetimes \
|
||||||
bound at the fn or impl level"
|
bound at the fn or impl level"
|
||||||
);
|
);
|
||||||
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
|
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve the lifetimes in the bounds to the lifetime defs in the generics.
|
let id = self.tcx.hir.as_local_node_id(exist_ty_did).unwrap();
|
||||||
// `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
|
|
||||||
// `abstract type MyAnonTy<'b>: MyTrait<'b>;`
|
|
||||||
// ^ ^ this gets resolved in the scope of
|
|
||||||
// the exist_ty generics
|
|
||||||
let (generics, bounds) = match self.tcx.hir.expect_item(item_id.id).node {
|
|
||||||
hir::ItemExistential(hir::ExistTy{ ref generics, ref bounds, .. }) => (
|
|
||||||
generics,
|
|
||||||
bounds,
|
|
||||||
),
|
|
||||||
ref i => bug!("impl Trait pointed to non-existential type?? {:#?}", i),
|
|
||||||
};
|
|
||||||
|
|
||||||
// We want to start our early-bound indices at the end of the parent scope,
|
// Resolve the lifetimes in the bounds to the lifetime defs in the generics.
|
||||||
// not including any parent `impl Trait`s.
|
// `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
|
||||||
let mut index = self.next_early_index_for_abstract_type();
|
// `abstract type MyAnonTy<'b>: MyTrait<'b>;`
|
||||||
debug!("visit_ty: index = {}", index);
|
// ^ ^ this gets resolved in the scope of
|
||||||
|
// the exist_ty generics
|
||||||
|
let (generics, bounds) = match self.tcx.hir.expect_item(id).node {
|
||||||
|
hir::ItemExistential(hir::ExistTy{ ref generics, ref bounds, .. }) => (
|
||||||
|
generics,
|
||||||
|
bounds,
|
||||||
|
),
|
||||||
|
ref i => bug!("impl Trait pointed to non-existential type?? {:#?}", i),
|
||||||
|
};
|
||||||
|
|
||||||
let mut elision = None;
|
// We want to start our early-bound indices at the end of the parent scope,
|
||||||
let mut lifetimes = FxHashMap();
|
// not including any parent `impl Trait`s.
|
||||||
let mut type_count = 0;
|
let mut index = self.next_early_index_for_abstract_type();
|
||||||
for param in &generics.params {
|
debug!("visit_ty: index = {}", index);
|
||||||
match param.kind {
|
|
||||||
GenericParamKind::Lifetime { .. } => {
|
let mut elision = None;
|
||||||
let (name, reg) = Region::early(&self.tcx.hir, &mut index, ¶m);
|
let mut lifetimes = FxHashMap();
|
||||||
if let hir::ParamName::Plain(param_name) = name {
|
let mut type_count = 0;
|
||||||
if param_name.name == keywords::UnderscoreLifetime.name() {
|
for param in &generics.params {
|
||||||
// Pick the elided lifetime "definition" if one exists
|
match param.kind {
|
||||||
// and use it to make an elision scope.
|
GenericParamKind::Lifetime { .. } => {
|
||||||
elision = Some(reg);
|
let (name, reg) = Region::early(&self.tcx.hir, &mut index, ¶m);
|
||||||
|
if let hir::ParamName::Plain(param_name) = name {
|
||||||
|
if param_name.name == keywords::UnderscoreLifetime.name() {
|
||||||
|
// Pick the elided lifetime "definition" if one exists
|
||||||
|
// and use it to make an elision scope.
|
||||||
|
elision = Some(reg);
|
||||||
|
} else {
|
||||||
|
lifetimes.insert(name, reg);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
lifetimes.insert(name, reg);
|
lifetimes.insert(name, reg);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
lifetimes.insert(name, reg);
|
GenericParamKind::Type { .. } => {
|
||||||
|
type_count += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GenericParamKind::Type { .. } => {
|
|
||||||
type_count += 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
let next_early_index = index + type_count;
|
||||||
let next_early_index = index + type_count;
|
|
||||||
|
|
||||||
if let Some(elision_region) = elision {
|
if let Some(elision_region) = elision {
|
||||||
let scope = Scope::Elision {
|
let scope = Scope::Elision {
|
||||||
elide: Elide::Exact(elision_region),
|
elide: Elide::Exact(elision_region),
|
||||||
s: self.scope,
|
s: self.scope,
|
||||||
};
|
};
|
||||||
self.with(scope, |_old_scope, this| {
|
self.with(scope, |_old_scope, this| {
|
||||||
|
let scope = Scope::Binder {
|
||||||
|
lifetimes,
|
||||||
|
next_early_index,
|
||||||
|
s: this.scope,
|
||||||
|
track_lifetime_uses: true,
|
||||||
|
abstract_type_parent: false,
|
||||||
|
};
|
||||||
|
this.with(scope, |_old_scope, this| {
|
||||||
|
this.visit_generics(generics);
|
||||||
|
for bound in bounds {
|
||||||
|
this.visit_param_bound(bound);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
let scope = Scope::Binder {
|
let scope = Scope::Binder {
|
||||||
lifetimes,
|
lifetimes,
|
||||||
next_early_index,
|
next_early_index,
|
||||||
s: this.scope,
|
s: self.scope,
|
||||||
track_lifetime_uses: true,
|
track_lifetime_uses: true,
|
||||||
abstract_type_parent: false,
|
abstract_type_parent: false,
|
||||||
};
|
};
|
||||||
this.with(scope, |_old_scope, this| {
|
self.with(scope, |_old_scope, this| {
|
||||||
this.visit_generics(generics);
|
this.visit_generics(generics);
|
||||||
for bound in bounds {
|
for bound in bounds {
|
||||||
this.visit_param_bound(bound);
|
this.visit_param_bound(bound);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
} else {
|
} else {
|
||||||
let scope = Scope::Binder {
|
intravisit::walk_ty(self, ty)
|
||||||
lifetimes,
|
|
||||||
next_early_index,
|
|
||||||
s: self.scope,
|
|
||||||
track_lifetime_uses: true,
|
|
||||||
abstract_type_parent: false,
|
|
||||||
};
|
|
||||||
self.with(scope, |_old_scope, this| {
|
|
||||||
this.visit_generics(generics);
|
|
||||||
for bound in bounds {
|
|
||||||
this.visit_param_bound(bound);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => intravisit::walk_ty(self, ty),
|
_ => intravisit::walk_ty(self, ty),
|
||||||
|
|
|
@ -229,8 +229,12 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
|
||||||
hir::ItemUse(..) => {}
|
hir::ItemUse(..) => {}
|
||||||
// The interface is empty
|
// The interface is empty
|
||||||
hir::ItemGlobalAsm(..) => {}
|
hir::ItemGlobalAsm(..) => {}
|
||||||
// Checked by visit_ty
|
hir::ItemExistential(..) => {
|
||||||
hir::ItemExistential(..) => {}
|
if item_level.is_some() {
|
||||||
|
// Reach the (potentially private) type and the API being exposed
|
||||||
|
self.reach(item.id).ty().predicates();
|
||||||
|
}
|
||||||
|
}
|
||||||
// Visit everything
|
// Visit everything
|
||||||
hir::ItemConst(..) | hir::ItemStatic(..) |
|
hir::ItemConst(..) | hir::ItemStatic(..) |
|
||||||
hir::ItemFn(..) | hir::ItemTy(..) => {
|
hir::ItemFn(..) | hir::ItemTy(..) => {
|
||||||
|
@ -390,17 +394,6 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
|
||||||
module_id = self.tcx.hir.get_parent_node(module_id);
|
module_id = self.tcx.hir.get_parent_node(module_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
|
|
||||||
if let hir::TyImplTraitExistential(item_id, _, _) = ty.node {
|
|
||||||
if self.get(item_id.id).is_some() {
|
|
||||||
// Reach the (potentially private) type and the API being exposed
|
|
||||||
self.reach(item_id.id).ty().predicates();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
intravisit::walk_ty(self, ty);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'b, 'a, 'tcx> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> {
|
impl<'b, 'a, 'tcx> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> {
|
||||||
|
@ -1568,8 +1561,15 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx>
|
||||||
hir::ItemUse(..) => {}
|
hir::ItemUse(..) => {}
|
||||||
// No subitems
|
// No subitems
|
||||||
hir::ItemGlobalAsm(..) => {}
|
hir::ItemGlobalAsm(..) => {}
|
||||||
// Checked in visit_ty
|
hir::ItemExistential(..) => {
|
||||||
hir::ItemExistential(..) => {}
|
// Check the traits being exposed, as they're separate,
|
||||||
|
// e.g. `impl Iterator<Item=T>` has two predicates,
|
||||||
|
// `X: Iterator` and `<X as Iterator>::Item == T`,
|
||||||
|
// where `X` is the `impl Iterator<Item=T>` itself,
|
||||||
|
// stored in `predicates_of`, not in the `Ty` itself.
|
||||||
|
|
||||||
|
self.check(item.id, self.inner_visibility).predicates();
|
||||||
|
}
|
||||||
// Subitems of these items have inherited publicity
|
// Subitems of these items have inherited publicity
|
||||||
hir::ItemConst(..) | hir::ItemStatic(..) | hir::ItemFn(..) |
|
hir::ItemConst(..) | hir::ItemStatic(..) | hir::ItemFn(..) |
|
||||||
hir::ItemTy(..) => {
|
hir::ItemTy(..) => {
|
||||||
|
@ -1667,20 +1667,6 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx>
|
||||||
// handled in `visit_item` above
|
// handled in `visit_item` above
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
|
|
||||||
if let hir::TyImplTraitExistential(ref exist_item, _, _) = ty.node {
|
|
||||||
// Check the traits being exposed, as they're separate,
|
|
||||||
// e.g. `impl Iterator<Item=T>` has two predicates,
|
|
||||||
// `X: Iterator` and `<X as Iterator>::Item == T`,
|
|
||||||
// where `X` is the `impl Iterator<Item=T>` itself,
|
|
||||||
// stored in `predicates_of`, not in the `Ty` itself.
|
|
||||||
|
|
||||||
self.check(exist_item.id, self.inner_visibility).predicates();
|
|
||||||
}
|
|
||||||
|
|
||||||
intravisit::walk_ty(self, ty);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't recurse into expressions in array sizes or const initializers
|
// Don't recurse into expressions in array sizes or const initializers
|
||||||
fn visit_expr(&mut self, _: &'tcx hir::Expr) {}
|
fn visit_expr(&mut self, _: &'tcx hir::Expr) {}
|
||||||
// Don't recurse into patterns in function arguments
|
// Don't recurse into patterns in function arguments
|
||||||
|
|
|
@ -1095,6 +1095,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||||
hir::TyStr => tcx.mk_str()
|
hir::TyStr => tcx.mk_str()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Def::Existential(exist_ty_did) => {
|
||||||
|
assert!(exist_ty_did.is_local());
|
||||||
|
let lifetimes = &path.segments[0].args.as_ref().unwrap().args;
|
||||||
|
self.impl_trait_ty_to_ty(exist_ty_did, lifetimes)
|
||||||
|
}
|
||||||
Def::Err => {
|
Def::Err => {
|
||||||
self.set_tainted_by_errors();
|
self.set_tainted_by_errors();
|
||||||
return self.tcx().types.err;
|
return self.tcx().types.err;
|
||||||
|
@ -1140,9 +1145,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||||
hir::TyTraitObject(ref bounds, ref lifetime) => {
|
hir::TyTraitObject(ref bounds, ref lifetime) => {
|
||||||
self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime)
|
self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime)
|
||||||
}
|
}
|
||||||
hir::TyImplTraitExistential(_, def_id, ref lifetimes) => {
|
|
||||||
self.impl_trait_ty_to_ty(def_id, lifetimes)
|
|
||||||
}
|
|
||||||
hir::TyPath(hir::QPath::Resolved(ref maybe_qself, ref path)) => {
|
hir::TyPath(hir::QPath::Resolved(ref maybe_qself, ref path)) => {
|
||||||
debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path);
|
debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path);
|
||||||
let opt_self_ty = maybe_qself.as_ref().map(|qself| {
|
let opt_self_ty = maybe_qself.as_ref().map(|qself| {
|
||||||
|
@ -1195,7 +1197,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||||
pub fn impl_trait_ty_to_ty(
|
pub fn impl_trait_ty_to_ty(
|
||||||
&self,
|
&self,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
lifetimes: &[hir::Lifetime],
|
lifetimes: &[hir::GenericArg],
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
debug!("impl_trait_ty_to_ty(def_id={:?}, lifetimes={:?})", def_id, lifetimes);
|
debug!("impl_trait_ty_to_ty(def_id={:?}, lifetimes={:?})", def_id, lifetimes);
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
@ -1208,7 +1210,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||||
// Our own parameters are the resolved lifetimes.
|
// Our own parameters are the resolved lifetimes.
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamDefKind::Lifetime => {
|
GenericParamDefKind::Lifetime => {
|
||||||
self.ast_region_to_region(&lifetimes[i], None).into()
|
if let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] {
|
||||||
|
self.ast_region_to_region(lifetime, None).into()
|
||||||
|
} else {
|
||||||
|
bug!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => bug!()
|
_ => bug!()
|
||||||
}
|
}
|
||||||
|
|
|
@ -875,10 +875,6 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeTy(&hir::Ty { node: hir::TyImplTraitExistential(..), .. }) => {
|
|
||||||
bug!("impl Trait is desugared to existential type items");
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => &no_generics,
|
_ => &no_generics,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue