match item.node {
ItemKind::Fn(.., ref generics, _)
| ItemKind::Impl(_, _, _, ref generics, ..)
- | ItemKind::Ty(_, ref generics)
- | ItemKind::Existential(ExistTy {
+ | ItemKind::TyAlias(_, ref generics)
+ | ItemKind::OpaqueTy(OpaqueTy {
ref generics,
impl_trait_fn: None,
..
}
// Desugared from `impl Trait`, so visited by the function's return type.
- hir::ItemKind::Existential(hir::ExistTy {
+ hir::ItemKind::OpaqueTy(hir::OpaqueTy {
impl_trait_fn: Some(_),
..
}) => {}
- hir::ItemKind::Existential(..)
- | hir::ItemKind::Ty(..)
+ hir::ItemKind::OpaqueTy(..)
+ | hir::ItemKind::TyAlias(..)
| hir::ItemKind::Static(..)
| hir::ItemKind::Const(..)
| hir::ItemKind::Fn(..) => {
..
}) => Some(tcx.closure_base_def_id(def_id)),
Node::Item(item) => match item.node {
- ItemKind::Existential(hir::ExistTy { impl_trait_fn, .. }) => impl_trait_fn,
+ ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn, .. }) => impl_trait_fn,
_ => None,
},
_ => None,
generics
}
- ItemKind::Ty(_, ref generics)
+ ItemKind::TyAlias(_, ref generics)
| ItemKind::Enum(_, ref generics)
| ItemKind::Struct(_, ref generics)
- | ItemKind::Existential(hir::ExistTy { ref generics, .. })
+ | ItemKind::OpaqueTy(hir::OpaqueTy { ref generics, .. })
| ItemKind::Union(_, ref generics) => {
allow_defaults = true;
generics
icx.to_ty(ty)
}
},
- ImplItemKind::Existential(_) => {
+ ImplItemKind::OpaqueTy(_) => {
if tcx
.impl_trait_ref(tcx.hir().get_parent_did(hir_id))
.is_none()
report_assoc_ty_on_inherent_impl(tcx, item.span);
}
- find_existential_constraints(tcx, def_id)
+ find_opaque_ty_constraints(tcx, def_id)
}
ImplItemKind::Type(ref ty) => {
if tcx
icx.to_ty(ty)
}
},
- ItemKind::Ty(ref ty, _)
+ ItemKind::TyAlias(ref ty, _)
| ItemKind::Impl(.., ref ty, _) => icx.to_ty(ty),
ItemKind::Fn(..) => {
let substs = InternalSubsts::identity_for_item(tcx, def_id);
let substs = InternalSubsts::identity_for_item(tcx, def_id);
tcx.mk_adt(def, substs)
}
- ItemKind::Existential(hir::ExistTy {
+ ItemKind::OpaqueTy(hir::OpaqueTy {
impl_trait_fn: None,
..
- }) => find_existential_constraints(tcx, def_id),
- // Existential types desugared from `impl Trait`.
- ItemKind::Existential(hir::ExistTy {
+ }) => find_opaque_ty_constraints(tcx, def_id),
+ // Opaque types desugared from `impl Trait`.
+ ItemKind::OpaqueTy(hir::OpaqueTy {
impl_trait_fn: Some(owner),
..
}) => {
tcx.typeck_tables_of(owner)
- .concrete_existential_types
+ .concrete_opaque_types
.get(&def_id)
.map(|opaque| opaque.concrete_type)
.unwrap_or_else(|| {
// This can occur if some error in the
// owner fn prevented us from populating
- // the `concrete_existential_types` table.
+ // the `concrete_opaque_types` table.
tcx.sess.delay_span_bug(
DUMMY_SP,
&format!(
- "owner {:?} has no existential type for {:?} in its tables",
+ "owner {:?} has no opaque type for {:?} in its tables",
owner, def_id,
),
);
})
}
-fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
+fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
use rustc::hir::{ImplItem, Item, TraitItem};
- debug!("find_existential_constraints({:?})", def_id);
+ debug!("find_opaque_ty_constraints({:?})", def_id);
struct ConstraintLocator<'tcx> {
tcx: TyCtxt<'tcx>,
def_id: DefId,
- // (first found type span, actual type, mapping from the existential type's generic
+ // (first found type span, actual type, mapping from the opaque type's generic
// parameters to the concrete type's generic parameters)
//
// The mapping is an index for each use site of a generic parameter in the concrete type
//
- // The indices index into the generic parameters on the existential type.
+ // The indices index into the generic parameters on the opaque type.
found: Option<(Span, Ty<'tcx>, Vec<usize>)>,
}
// Don't try to check items that cannot possibly constrain the type.
if !self.tcx.has_typeck_tables(def_id) {
debug!(
- "find_existential_constraints: no constraint for `{:?}` at `{:?}`: no tables",
+ "find_opaque_ty_constraints: no constraint for `{:?}` at `{:?}`: no tables",
self.def_id,
def_id,
);
let ty = self
.tcx
.typeck_tables_of(def_id)
- .concrete_existential_types
+ .concrete_opaque_types
.get(&self.def_id);
if let Some(ty::ResolvedOpaqueTy { concrete_type, substs }) = ty {
debug!(
- "find_existential_constraints: found constraint for `{:?}` at `{:?}`: {:?}",
+ "find_opaque_ty_constraints: found constraint for `{:?}` at `{:?}`: {:?}",
self.def_id,
def_id,
ty,
self.tcx.sess.span_err(
span,
&format!(
- "defining existential type use restricts existential \
+ "defining opaque type use restricts opaque \
type by using the generic parameter `{}` twice",
p.name
),
self.tcx.sess.delay_span_bug(
span,
&format!(
- "non-defining exist ty use in defining scope: {:?}, {:?}",
+ "non-defining opaque ty use in defining scope: {:?}, {:?}",
concrete_type, substs,
),
);
}
}
}
- // Compute the index within the existential type for each generic parameter used in
+ // Compute the index within the opaque type for each generic parameter used in
// the concrete type.
let indices = concrete_type
.subst(self.tcx, substs)
if !substs.types().all(is_param) {
self.tcx.sess.span_err(
span,
- "defining existential type use does not fully define existential type",
+ "defining opaque type use does not fully define opaque type",
);
} else if let Some((prev_span, prev_ty, ref prev_indices)) = self.found {
let mut ty = concrete_type.walk().fuse();
_ => t == p,
});
if !iter_eq || ty.next().is_some() || p_ty.next().is_some() {
- debug!("find_existential_constraints: span={:?}", span);
- // Found different concrete types for the existential type.
+ debug!("find_opaque_ty_constraints: span={:?}", span);
+ // Found different concrete types for the opaque type.
let mut err = self.tcx.sess.struct_span_err(
span,
- "concrete type differs from previous defining existential type use",
+ "concrete type differs from previous defining opaque type use",
);
err.span_label(
span,
}
} else {
debug!(
- "find_existential_constraints: no constraint for `{:?}` at `{:?}`",
+ "find_opaque_ty_constraints: no constraint for `{:?}` at `{:?}`",
self.def_id,
def_id,
);
intravisit::NestedVisitorMap::All(&self.tcx.hir())
}
fn visit_item(&mut self, it: &'tcx Item) {
+ debug!("find_existential_constraints: visiting {:?}", it);
let def_id = self.tcx.hir().local_def_id(it.hir_id);
- // The existential type itself or its children are not within its reveal scope.
+ // The opaque type itself or its children are not within its reveal scope.
if def_id != self.def_id {
self.check(def_id);
intravisit::walk_item(self, it);
}
}
fn visit_impl_item(&mut self, it: &'tcx ImplItem) {
+ debug!("find_existential_constraints: visiting {:?}", it);
let def_id = self.tcx.hir().local_def_id(it.hir_id);
- // The existential type itself or its children are not within its reveal scope.
+ // The opaque type itself or its children are not within its reveal scope.
if def_id != self.def_id {
self.check(def_id);
intravisit::walk_impl_item(self, it);
}
}
fn visit_trait_item(&mut self, it: &'tcx TraitItem) {
+ debug!("find_existential_constraints: visiting {:?}", it);
let def_id = self.tcx.hir().local_def_id(it.hir_id);
self.check(def_id);
intravisit::walk_trait_item(self, it);
found: None,
};
- debug!("find_existential_constraints: scope={:?}", scope);
+ debug!("find_opaque_ty_constraints: scope={:?}", scope);
if scope == hir::CRATE_HIR_ID {
intravisit::walk_crate(&mut locator, tcx.hir().krate());
} else {
- debug!("find_existential_constraints: scope={:?}", tcx.hir().get(scope));
+ debug!("find_opaque_ty_constraints: scope={:?}", tcx.hir().get(scope));
match tcx.hir().get(scope) {
- Node::Item(ref it) => intravisit::walk_item(&mut locator, it),
- Node::ImplItem(ref it) => intravisit::walk_impl_item(&mut locator, it),
- Node::TraitItem(ref it) => intravisit::walk_trait_item(&mut locator, it),
+ // We explicitly call `visit_*` methods, instead of using `intravisit::walk_*` methods
+ // This allows our visitor to process the defining item itself, causing
+ // it to pick up any 'sibling' defining uses.
+ //
+ // For example, this code:
+ // ```
+ // fn foo() {
+ // type Blah = impl Debug;
+ // let my_closure = || -> Blah { true };
+ // }
+ // ```
+ //
+ // requires us to explicitly process `foo()` in order
+ // to notice the defining usage of `Blah`.
+ Node::Item(ref it) => locator.visit_item(it),
+ Node::ImplItem(ref it) => locator.visit_impl_item(it),
+ Node::TraitItem(ref it) => locator.visit_trait_item(it),
other => bug!(
- "{:?} is not a valid scope for an existential type item",
+ "{:?} is not a valid scope for an opaque type item",
other
),
}
Node::TraitItem(item) => &item.generics,
Node::ImplItem(item) => match item.node {
- ImplItemKind::Existential(ref bounds) => {
+ ImplItemKind::OpaqueTy(ref bounds) => {
let substs = InternalSubsts::identity_for_item(tcx, def_id);
let opaque_ty = tcx.mk_opaque(def_id, substs);
generics
}
ItemKind::Fn(.., ref generics, _)
- | ItemKind::Ty(_, ref generics)
+ | ItemKind::TyAlias(_, ref generics)
| ItemKind::Enum(_, ref generics)
| ItemKind::Struct(_, ref generics)
| ItemKind::Union(_, ref generics) => generics,
is_trait = Some((ty::TraitRef::identity(tcx, def_id), &empty_trait_items));
generics
}
- ItemKind::Existential(ExistTy {
+ ItemKind::OpaqueTy(OpaqueTy {
ref bounds,
impl_trait_fn,
ref generics,
predicates: bounds_predicates,
});
} else {
- // named existential types
+ // named opaque types
predicates.extend(bounds_predicates);
generics
}