Replace "existential" by "opaque"

This commit is contained in:
varkor 2019-08-01 00:41:54 +01:00
parent fc48541ab1
commit c28ce3e4ca
175 changed files with 1018 additions and 418 deletions

View File

@ -27,7 +27,7 @@ pub(crate) enum Target {
ForeignMod, ForeignMod,
GlobalAsm, GlobalAsm,
Ty, Ty,
Existential, OpaqueTy,
Enum, Enum,
Struct, Struct,
Union, Union,
@ -51,7 +51,7 @@ impl Display for Target {
Target::ForeignMod => "foreign module", Target::ForeignMod => "foreign module",
Target::GlobalAsm => "global asm", Target::GlobalAsm => "global asm",
Target::Ty => "type alias", Target::Ty => "type alias",
Target::Existential => "existential type", Target::OpaqueTy => "opaque type",
Target::Enum => "enum", Target::Enum => "enum",
Target::Struct => "struct", Target::Struct => "struct",
Target::Union => "union", Target::Union => "union",
@ -76,7 +76,7 @@ impl Target {
hir::ItemKind::ForeignMod(..) => Target::ForeignMod, hir::ItemKind::ForeignMod(..) => Target::ForeignMod,
hir::ItemKind::GlobalAsm(..) => Target::GlobalAsm, hir::ItemKind::GlobalAsm(..) => Target::GlobalAsm,
hir::ItemKind::Ty(..) => Target::Ty, hir::ItemKind::Ty(..) => Target::Ty,
hir::ItemKind::Existential(..) => Target::Existential, hir::ItemKind::OpaqueTy(..) => Target::OpaqueTy,
hir::ItemKind::Enum(..) => Target::Enum, hir::ItemKind::Enum(..) => Target::Enum,
hir::ItemKind::Struct(..) => Target::Struct, hir::ItemKind::Struct(..) => Target::Struct,
hir::ItemKind::Union(..) => Target::Union, hir::ItemKind::Union(..) => Target::Union,

View File

@ -55,15 +55,15 @@ pub enum DefKind {
/// Refers to the variant itself, `DefKind::Ctor` refers to its constructor if it exists. /// Refers to the variant itself, `DefKind::Ctor` refers to its constructor if it exists.
Variant, Variant,
Trait, Trait,
/// `existential type Foo: Bar;` /// `type Foo = impl Bar;`
Existential, OpaqueTy,
/// `type Foo = Bar;` /// `type Foo = Bar;`
TyAlias, TyAlias,
ForeignTy, ForeignTy,
TraitAlias, TraitAlias,
AssocTy, AssocTy,
/// `existential type Foo: Bar;` /// `type Foo = impl Bar;`
AssocExistential, AssocOpaqueTy,
TyParam, TyParam,
// Value namespace // Value namespace
@ -96,11 +96,11 @@ impl DefKind {
DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct", DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct",
DefKind::Ctor(CtorOf::Struct, CtorKind::Fictive) => DefKind::Ctor(CtorOf::Struct, CtorKind::Fictive) =>
bug!("impossible struct constructor"), bug!("impossible struct constructor"),
DefKind::Existential => "existential type", DefKind::OpaqueTy => "opaque type",
DefKind::TyAlias => "type alias", DefKind::TyAlias => "type alias",
DefKind::TraitAlias => "trait alias", DefKind::TraitAlias => "trait alias",
DefKind::AssocTy => "associated type", DefKind::AssocTy => "associated type",
DefKind::AssocExistential => "associated existential type", DefKind::AssocOpaqueTy => "associated opaque type",
DefKind::Union => "union", DefKind::Union => "union",
DefKind::Trait => "trait", DefKind::Trait => "trait",
DefKind::ForeignTy => "foreign type", DefKind::ForeignTy => "foreign type",
@ -118,9 +118,9 @@ impl DefKind {
match *self { match *self {
DefKind::AssocTy DefKind::AssocTy
| DefKind::AssocConst | DefKind::AssocConst
| DefKind::AssocExistential | DefKind::AssocOpaqueTy
| DefKind::Enum | DefKind::Enum
| DefKind::Existential => "an", | DefKind::OpaqueTy => "an",
DefKind::Macro(macro_kind) => macro_kind.article(), DefKind::Macro(macro_kind) => macro_kind.article(),
_ => "a", _ => "a",
} }

View File

@ -505,7 +505,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
visitor.visit_ty(ty); visitor.visit_ty(ty);
visitor.visit_generics(generics) visitor.visit_generics(generics)
} }
ItemKind::Existential(ExistTy { ItemKind::OpaqueTy(ExistTy {
ref generics, ref generics,
ref bounds, ref bounds,
.. ..
@ -930,7 +930,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
visitor.visit_id(impl_item.hir_id); visitor.visit_id(impl_item.hir_id);
visitor.visit_ty(ty); visitor.visit_ty(ty);
} }
ImplItemKind::Existential(ref bounds) => { ImplItemKind::OpaqueTy(ref bounds) => {
visitor.visit_id(impl_item.hir_id); visitor.visit_id(impl_item.hir_id);
walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_param_bound, bounds);
} }

View File

@ -189,14 +189,14 @@ enum ImplTraitContext<'a> {
/// Newly generated parameters should be inserted into the given `Vec`. /// Newly generated parameters should be inserted into the given `Vec`.
Universal(&'a mut Vec<hir::GenericParam>), Universal(&'a mut Vec<hir::GenericParam>),
/// Treat `impl Trait` as shorthand for a new existential parameter. /// Treat `impl Trait` as shorthand for a new opaque type.
/// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
/// equivalent to a fresh existential parameter like `existential type T; fn foo() -> T`. /// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.
/// ///
/// We optionally store a `DefId` for the parent item here so we can look up necessary /// We optionally store a `DefId` for the parent item here so we can look up necessary
/// information later. It is `None` when no information about the context should be stored /// information later. It is `None` when no information about the context should be stored
/// (e.g., for consts and statics). /// (e.g., for consts and statics).
Existential(Option<DefId> /* fn def-ID */), OpaqueTy(Option<DefId> /* fn def-ID */),
/// `impl Trait` is not accepted in this position. /// `impl Trait` is not accepted in this position.
Disallowed(ImplTraitPosition), Disallowed(ImplTraitPosition),
@ -222,7 +222,7 @@ impl<'a> ImplTraitContext<'a> {
use self::ImplTraitContext::*; use self::ImplTraitContext::*;
match self { match self {
Universal(params) => Universal(params), Universal(params) => Universal(params),
Existential(fn_def_id) => Existential(*fn_def_id), OpaqueTy(fn_def_id) => OpaqueTy(*fn_def_id),
Disallowed(pos) => Disallowed(*pos), Disallowed(pos) => Disallowed(*pos),
} }
} }
@ -487,7 +487,7 @@ impl<'a> LoweringContext<'a> {
| ItemKind::Union(_, ref generics) | ItemKind::Union(_, ref generics)
| ItemKind::Enum(_, ref generics) | ItemKind::Enum(_, ref generics)
| ItemKind::Ty(_, ref generics) | ItemKind::Ty(_, ref generics)
| ItemKind::Existential(_, ref generics) | ItemKind::OpaqueTy(_, ref generics)
| ItemKind::Trait(_, _, ref generics, ..) => { | ItemKind::Trait(_, _, ref generics, ..) => {
let def_id = self.lctx.resolver.definitions().local_def_id(item.id); let def_id = self.lctx.resolver.definitions().local_def_id(item.id);
let count = generics let count = generics
@ -1422,7 +1422,7 @@ impl<'a> LoweringContext<'a> {
// so desugar to // so desugar to
// //
// fn foo() -> impl Iterator<Item = impl Debug> // fn foo() -> impl Iterator<Item = impl Debug>
ImplTraitContext::Existential(_) => (true, itctx), ImplTraitContext::OpaqueTy(_) => (true, itctx),
// We are in the argument position, but within a dyn type: // We are in the argument position, but within a dyn type:
// //
@ -1436,11 +1436,11 @@ impl<'a> LoweringContext<'a> {
// In `type Foo = dyn Iterator<Item: Debug>` we desugar to // In `type Foo = dyn Iterator<Item: Debug>` we desugar to
// `type Foo = dyn Iterator<Item = impl Debug>` but we have to override the // `type Foo = dyn Iterator<Item = impl Debug>` but we have to override the
// "impl trait context" to permit `impl Debug` in this position (it desugars // "impl trait context" to permit `impl Debug` in this position (it desugars
// then to an existential type). // then to an opaque type).
// //
// FIXME: this is only needed until `impl Trait` is allowed in type aliases. // FIXME: this is only needed until `impl Trait` is allowed in type aliases.
ImplTraitContext::Disallowed(_) if self.is_in_dyn_type => ImplTraitContext::Disallowed(_) if self.is_in_dyn_type =>
(true, ImplTraitContext::Existential(None)), (true, ImplTraitContext::OpaqueTy(None)),
// We are in the argument position, but not within a dyn type: // We are in the argument position, but not within a dyn type:
// //
@ -1634,8 +1634,8 @@ impl<'a> LoweringContext<'a> {
TyKind::ImplTrait(def_node_id, ref bounds) => { TyKind::ImplTrait(def_node_id, ref bounds) => {
let span = t.span; let span = t.span;
match itctx { match itctx {
ImplTraitContext::Existential(fn_def_id) => { ImplTraitContext::OpaqueTy(fn_def_id) => {
self.lower_existential_impl_trait( self.lower_opaque_impl_trait(
span, fn_def_id, def_node_id, span, fn_def_id, def_node_id,
|this| this.lower_param_bounds(bounds, itctx), |this| this.lower_param_bounds(bounds, itctx),
) )
@ -1717,7 +1717,7 @@ impl<'a> LoweringContext<'a> {
} }
} }
fn lower_existential_impl_trait( fn lower_opaque_impl_trait(
&mut self, &mut self,
span: Span, span: Span,
fn_def_id: Option<DefId>, fn_def_id: Option<DefId>,
@ -1730,7 +1730,7 @@ impl<'a> LoweringContext<'a> {
// Not tracking it makes lints in rustc and clippy very fragile, as // Not tracking it makes lints in rustc and clippy very fragile, as
// frequently opened issues show. // frequently opened issues show.
let exist_ty_span = self.mark_span_with_reason( let exist_ty_span = self.mark_span_with_reason(
DesugaringKind::ExistentialType, DesugaringKind::OpaqueTy,
span, span,
None, None,
); );
@ -1763,11 +1763,11 @@ impl<'a> LoweringContext<'a> {
}, },
bounds: hir_bounds, bounds: hir_bounds,
impl_trait_fn: fn_def_id, impl_trait_fn: fn_def_id,
origin: hir::ExistTyOrigin::ReturnImplTrait, origin: hir::OpaqueTyOrigin::ReturnImplTrait,
}; };
trace!("exist ty from impl trait def-index: {:#?}", exist_ty_def_index); trace!("exist ty from impl trait def-index: {:#?}", exist_ty_def_index);
let exist_ty_id = lctx.generate_existential_type( let exist_ty_id = lctx.generate_opaque_type(
exist_ty_node_id, exist_ty_node_id,
exist_ty_item, exist_ty_item,
span, span,
@ -1779,19 +1779,19 @@ impl<'a> LoweringContext<'a> {
}) })
} }
/// Registers a new existential type with the proper `NodeId`s and /// Registers a new opaque type with the proper `NodeId`s and
/// returns the lowered node-ID for the existential type. /// returns the lowered node-ID for the opaque type.
fn generate_existential_type( fn generate_opaque_type(
&mut self, &mut self,
exist_ty_node_id: NodeId, exist_ty_node_id: NodeId,
exist_ty_item: hir::ExistTy, exist_ty_item: hir::ExistTy,
span: Span, span: Span,
exist_ty_span: Span, exist_ty_span: Span,
) -> hir::HirId { ) -> hir::HirId {
let exist_ty_item_kind = hir::ItemKind::Existential(exist_ty_item); let exist_ty_item_kind = hir::ItemKind::OpaqueTy(exist_ty_item);
let exist_ty_id = self.lower_node_id(exist_ty_node_id); let exist_ty_id = self.lower_node_id(exist_ty_node_id);
// Generate an `existential type Foo: Trait;` declaration. // Generate an `type Foo = impl Trait;` declaration.
trace!("registering existential type with id {:#?}", exist_ty_id); trace!("registering opaque type with id {:#?}", exist_ty_id);
let exist_ty_item = hir::Item { let exist_ty_item = hir::Item {
hir_id: exist_ty_id, hir_id: exist_ty_id,
ident: Ident::invalid(), ident: Ident::invalid(),
@ -1802,7 +1802,7 @@ impl<'a> LoweringContext<'a> {
}; };
// Insert the item into the global item list. This usually happens // Insert the item into the global item list. This usually happens
// automatically for all AST items. But this existential type item // automatically for all AST items. But this opaque type item
// does not actually exist in the AST. // does not actually exist in the AST.
self.insert_item(exist_ty_item); self.insert_item(exist_ty_item);
exist_ty_id exist_ty_id
@ -2439,7 +2439,7 @@ impl<'a> LoweringContext<'a> {
.as_ref() .as_ref()
.map(|t| self.lower_ty(t, .map(|t| self.lower_ty(t,
if self.sess.features_untracked().impl_trait_in_bindings { if self.sess.features_untracked().impl_trait_in_bindings {
ImplTraitContext::Existential(Some(parent_def_id)) ImplTraitContext::OpaqueTy(Some(parent_def_id))
} else { } else {
ImplTraitContext::Disallowed(ImplTraitPosition::Binding) ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
} }
@ -2500,7 +2500,7 @@ impl<'a> LoweringContext<'a> {
let lt_mode = if make_ret_async.is_some() { let lt_mode = if make_ret_async.is_some() {
// In `async fn`, argument-position elided lifetimes // In `async fn`, argument-position elided lifetimes
// must be transformed into fresh generic parameters so that // must be transformed into fresh generic parameters so that
// they can be applied to the existential return type. // they can be applied to the opaque `impl Trait` return type.
AnonymousLifetimeMode::CreateParameter AnonymousLifetimeMode::CreateParameter
} else { } else {
self.anonymous_lifetime_mode self.anonymous_lifetime_mode
@ -2539,7 +2539,7 @@ impl<'a> LoweringContext<'a> {
FunctionRetTy::Ty(ref ty) => match in_band_ty_params { FunctionRetTy::Ty(ref ty) => match in_band_ty_params {
Some((def_id, _)) if impl_trait_return_allow => { Some((def_id, _)) if impl_trait_return_allow => {
hir::Return(self.lower_ty(ty, hir::Return(self.lower_ty(ty,
ImplTraitContext::Existential(Some(def_id)) ImplTraitContext::OpaqueTy(Some(def_id))
)) ))
} }
_ => { _ => {
@ -2585,12 +2585,12 @@ impl<'a> LoweringContext<'a> {
// Transforms `-> T` for `async fn` into `-> ExistTy { .. }` // Transforms `-> T` for `async fn` into `-> ExistTy { .. }`
// combined with the following definition of `ExistTy`: // combined with the following definition of `ExistTy`:
// //
// existential type ExistTy<generics_from_parent_fn>: Future<Output = T>; // type ExistTy<generics_from_parent_fn> = impl Future<Output = T>;
// //
// `inputs`: lowered types of arguments to the function (used to collect lifetimes) // `inputs`: lowered types of arguments to the function (used to collect lifetimes)
// `output`: unlowered output type (`T` in `-> T`) // `output`: unlowered output type (`T` in `-> T`)
// `fn_def_id`: `DefId` of the parent function (used to create child impl trait definition) // `fn_def_id`: `DefId` of the parent function (used to create child impl trait definition)
// `exist_ty_node_id`: `NodeId` of the existential type that should be created // `exist_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created
// `elided_lt_replacement`: replacement for elided lifetimes in the return type // `elided_lt_replacement`: replacement for elided lifetimes in the return type
fn lower_async_fn_ret_ty( fn lower_async_fn_ret_ty(
&mut self, &mut self,
@ -2626,7 +2626,7 @@ impl<'a> LoweringContext<'a> {
); );
// Calculate all the lifetimes that should be captured // Calculate all the lifetimes that should be captured
// by the existential type. This should include all in-scope // by the opaque type. This should include all in-scope
// lifetime parameters, including those defined in-band. // lifetime parameters, including those defined in-band.
// //
// Note: this must be done after lowering the output type, // Note: this must be done after lowering the output type,
@ -2657,11 +2657,11 @@ impl<'a> LoweringContext<'a> {
}, },
bounds: hir_vec![future_bound], bounds: hir_vec![future_bound],
impl_trait_fn: Some(fn_def_id), impl_trait_fn: Some(fn_def_id),
origin: hir::ExistTyOrigin::AsyncFn, origin: hir::OpaqueTyOrigin::AsyncFn,
}; };
trace!("exist ty from async fn def index: {:#?}", exist_ty_def_index); trace!("exist ty from async fn def index: {:#?}", exist_ty_def_index);
let exist_ty_id = this.generate_existential_type( let exist_ty_id = this.generate_opaque_type(
exist_ty_node_id, exist_ty_node_id,
exist_ty_item, exist_ty_item,
span, span,
@ -2702,7 +2702,7 @@ impl<'a> LoweringContext<'a> {
// Compute the `T` in `Future<Output = T>` from the return type. // Compute the `T` in `Future<Output = T>` from the return type.
let output_ty = match output { let output_ty = match output {
FunctionRetTy::Ty(ty) => { FunctionRetTy::Ty(ty) => {
self.lower_ty(ty, ImplTraitContext::Existential(Some(fn_def_id))) self.lower_ty(ty, ImplTraitContext::OpaqueTy(Some(fn_def_id)))
} }
FunctionRetTy::Default(ret_ty_span) => { FunctionRetTy::Default(ret_ty_span) => {
P(hir::Ty { P(hir::Ty {
@ -2905,7 +2905,7 @@ impl<'a> LoweringContext<'a> {
let kind = hir::GenericParamKind::Type { let kind = hir::GenericParamKind::Type {
default: default.as_ref().map(|x| { default: default.as_ref().map(|x| {
self.lower_ty(x, ImplTraitContext::Existential(None)) self.lower_ty(x, ImplTraitContext::OpaqueTy(None))
}), }),
synthetic: param.attrs.iter() synthetic: param.attrs.iter()
.filter(|attr| attr.check_name(sym::rustc_synthetic)) .filter(|attr| attr.check_name(sym::rustc_synthetic))
@ -3384,7 +3384,7 @@ impl<'a> LoweringContext<'a> {
self.lower_ty( self.lower_ty(
t, t,
if self.sess.features_untracked().impl_trait_in_bindings { if self.sess.features_untracked().impl_trait_in_bindings {
ImplTraitContext::Existential(None) ImplTraitContext::OpaqueTy(None)
} else { } else {
ImplTraitContext::Disallowed(ImplTraitPosition::Binding) ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
} }
@ -3398,7 +3398,7 @@ impl<'a> LoweringContext<'a> {
self.lower_ty( self.lower_ty(
t, t,
if self.sess.features_untracked().impl_trait_in_bindings { if self.sess.features_untracked().impl_trait_in_bindings {
ImplTraitContext::Existential(None) ImplTraitContext::OpaqueTy(None)
} else { } else {
ImplTraitContext::Disallowed(ImplTraitPosition::Binding) ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
} }
@ -3444,14 +3444,14 @@ impl<'a> LoweringContext<'a> {
self.lower_ty(t, ImplTraitContext::disallowed()), self.lower_ty(t, ImplTraitContext::disallowed()),
self.lower_generics(generics, ImplTraitContext::disallowed()), self.lower_generics(generics, ImplTraitContext::disallowed()),
), ),
ItemKind::Existential(ref b, ref generics) => hir::ItemKind::Existential( ItemKind::OpaqueTy(ref b, ref generics) => hir::ItemKind::OpaqueTy(
hir::ExistTy { hir::ExistTy {
generics: self.lower_generics(generics, generics: self.lower_generics(generics,
ImplTraitContext::Existential(None)), ImplTraitContext::OpaqueTy(None)),
bounds: self.lower_param_bounds(b, bounds: self.lower_param_bounds(b,
ImplTraitContext::Existential(None)), ImplTraitContext::OpaqueTy(None)),
impl_trait_fn: None, impl_trait_fn: None,
origin: hir::ExistTyOrigin::ExistentialType, origin: hir::OpaqueTyOrigin::TraitAliasImplTrait,
}, },
), ),
ItemKind::Enum(ref enum_definition, ref generics) => { ItemKind::Enum(ref enum_definition, ref generics) => {
@ -3918,9 +3918,9 @@ impl<'a> LoweringContext<'a> {
self.lower_generics(&i.generics, ImplTraitContext::disallowed()), self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
hir::ImplItemKind::Type(self.lower_ty(ty, ImplTraitContext::disallowed())), hir::ImplItemKind::Type(self.lower_ty(ty, ImplTraitContext::disallowed())),
), ),
ImplItemKind::Existential(ref bounds) => ( ImplItemKind::OpaqueTy(ref bounds) => (
self.lower_generics(&i.generics, ImplTraitContext::disallowed()), self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
hir::ImplItemKind::Existential( hir::ImplItemKind::OpaqueTy(
self.lower_param_bounds(bounds, ImplTraitContext::disallowed()), self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
), ),
), ),
@ -3951,7 +3951,7 @@ impl<'a> LoweringContext<'a> {
kind: match i.node { kind: match i.node {
ImplItemKind::Const(..) => hir::AssocItemKind::Const, ImplItemKind::Const(..) => hir::AssocItemKind::Const,
ImplItemKind::Type(..) => hir::AssocItemKind::Type, ImplItemKind::Type(..) => hir::AssocItemKind::Type,
ImplItemKind::Existential(..) => hir::AssocItemKind::Existential, ImplItemKind::OpaqueTy(..) => hir::AssocItemKind::OpaqueTy,
ImplItemKind::Method(ref sig, _) => hir::AssocItemKind::Method { ImplItemKind::Method(ref sig, _) => hir::AssocItemKind::Method {
has_self: sig.decl.has_self(), has_self: sig.decl.has_self(),
}, },

View File

@ -92,7 +92,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
} }
ItemKind::Mod(..) | ItemKind::Trait(..) | ItemKind::TraitAlias(..) | ItemKind::Mod(..) | ItemKind::Trait(..) | ItemKind::TraitAlias(..) |
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) | ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) |
ItemKind::Existential(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::OpaqueTy(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) |
ItemKind::Ty(..) => DefPathData::TypeNs(i.ident.as_interned_str()), ItemKind::Ty(..) => DefPathData::TypeNs(i.ident.as_interned_str()),
ItemKind::Fn( ItemKind::Fn(
ref decl, ref decl,
@ -223,7 +223,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
ImplItemKind::Method(..) | ImplItemKind::Const(..) => ImplItemKind::Method(..) | ImplItemKind::Const(..) =>
DefPathData::ValueNs(ii.ident.as_interned_str()), DefPathData::ValueNs(ii.ident.as_interned_str()),
ImplItemKind::Type(..) | ImplItemKind::Type(..) |
ImplItemKind::Existential(..) => { ImplItemKind::OpaqueTy(..) => {
DefPathData::TypeNs(ii.ident.as_interned_str()) DefPathData::TypeNs(ii.ident.as_interned_str())
}, },
ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id), ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id),

View File

@ -301,7 +301,7 @@ impl<'hir> Map<'hir> {
ItemKind::Const(..) => DefKind::Const, ItemKind::Const(..) => DefKind::Const,
ItemKind::Fn(..) => DefKind::Fn, ItemKind::Fn(..) => DefKind::Fn,
ItemKind::Mod(..) => DefKind::Mod, ItemKind::Mod(..) => DefKind::Mod,
ItemKind::Existential(..) => DefKind::Existential, ItemKind::OpaqueTy(..) => DefKind::OpaqueTy,
ItemKind::Ty(..) => DefKind::TyAlias, ItemKind::Ty(..) => DefKind::TyAlias,
ItemKind::Enum(..) => DefKind::Enum, ItemKind::Enum(..) => DefKind::Enum,
ItemKind::Struct(..) => DefKind::Struct, ItemKind::Struct(..) => DefKind::Struct,
@ -334,7 +334,7 @@ impl<'hir> Map<'hir> {
ImplItemKind::Const(..) => DefKind::AssocConst, ImplItemKind::Const(..) => DefKind::AssocConst,
ImplItemKind::Method(..) => DefKind::Method, ImplItemKind::Method(..) => DefKind::Method,
ImplItemKind::Type(..) => DefKind::AssocTy, ImplItemKind::Type(..) => DefKind::AssocTy,
ImplItemKind::Existential(..) => DefKind::AssocExistential, ImplItemKind::OpaqueTy(..) => DefKind::AssocOpaqueTy,
} }
} }
Node::Variant(_) => DefKind::Variant, Node::Variant(_) => DefKind::Variant,
@ -816,7 +816,7 @@ impl<'hir> Map<'hir> {
}, |_| false).ok() }, |_| false).ok()
} }
/// Returns the defining scope for an existential type definition. /// Returns the defining scope for an opaque type definition.
pub fn get_defining_scope(&self, id: HirId) -> Option<HirId> { pub fn get_defining_scope(&self, id: HirId) -> Option<HirId> {
let mut scope = id; let mut scope = id;
loop { loop {
@ -827,7 +827,7 @@ impl<'hir> Map<'hir> {
match self.get(scope) { match self.get(scope) {
Node::Item(i) => { Node::Item(i) => {
match i.node { match i.node {
ItemKind::Existential(ExistTy { impl_trait_fn: None, .. }) => {} ItemKind::OpaqueTy(ExistTy { impl_trait_fn: None, .. }) => {}
_ => break, _ => break,
} }
} }
@ -1270,7 +1270,7 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String {
ItemKind::ForeignMod(..) => "foreign mod", ItemKind::ForeignMod(..) => "foreign mod",
ItemKind::GlobalAsm(..) => "global asm", ItemKind::GlobalAsm(..) => "global asm",
ItemKind::Ty(..) => "ty", ItemKind::Ty(..) => "ty",
ItemKind::Existential(..) => "existential type", ItemKind::OpaqueTy(..) => "opaque type",
ItemKind::Enum(..) => "enum", ItemKind::Enum(..) => "enum",
ItemKind::Struct(..) => "struct", ItemKind::Struct(..) => "struct",
ItemKind::Union(..) => "union", ItemKind::Union(..) => "union",
@ -1294,8 +1294,8 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String {
ImplItemKind::Type(_) => { ImplItemKind::Type(_) => {
format!("assoc type {} in {}{}", ii.ident, path_str(), id_str) format!("assoc type {} in {}{}", ii.ident, path_str(), id_str)
} }
ImplItemKind::Existential(_) => { ImplItemKind::OpaqueTy(_) => {
format!("assoc existential type {} in {}{}", ii.ident, path_str(), id_str) format!("assoc opaque type {} in {}{}", ii.ident, path_str(), id_str)
} }
} }
} }

View File

@ -1815,7 +1815,7 @@ pub struct ImplItemId {
pub hir_id: HirId, pub hir_id: HirId,
} }
/// Represents anything within an `impl` block /// Represents anything within an `impl` block.
#[derive(RustcEncodable, RustcDecodable, Debug)] #[derive(RustcEncodable, RustcDecodable, Debug)]
pub struct ImplItem { pub struct ImplItem {
pub ident: Ident, pub ident: Ident,
@ -1832,14 +1832,14 @@ pub struct ImplItem {
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum ImplItemKind { pub enum ImplItemKind {
/// An associated constant of the given type, set to the constant result /// An associated constant of the given type, set to the constant result
/// of the expression /// of the expression.
Const(P<Ty>, BodyId), Const(P<Ty>, BodyId),
/// A method implementation with the given signature and body /// A method implementation with the given signature and body.
Method(MethodSig, BodyId), Method(MethodSig, BodyId),
/// An associated type /// An associated type.
Type(P<Ty>), Type(P<Ty>),
/// An associated existential type /// An associated `type = impl Trait`.
Existential(GenericBounds), OpaqueTy(GenericBounds),
} }
/// Bind a type to an associated type (i.e., `A = Foo`). /// Bind a type to an associated type (i.e., `A = Foo`).
@ -1926,14 +1926,14 @@ pub struct ExistTy {
pub generics: Generics, pub generics: Generics,
pub bounds: GenericBounds, pub bounds: GenericBounds,
pub impl_trait_fn: Option<DefId>, pub impl_trait_fn: Option<DefId>,
pub origin: ExistTyOrigin, pub origin: OpaqueTyOrigin,
} }
/// Where the existential type came from /// Where the opaque type came from
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum ExistTyOrigin { pub enum OpaqueTyOrigin {
/// `existential type Foo: Trait;` /// `type Foo = impl Trait;`
ExistentialType, TraitAliasImplTrait,
/// `-> impl Trait` /// `-> impl Trait`
ReturnImplTrait, ReturnImplTrait,
/// `async fn` /// `async fn`
@ -1962,7 +1962,7 @@ pub enum TyKind {
/// ///
/// Type parameters may be stored in each `PathSegment`. /// Type parameters may be stored in each `PathSegment`.
Path(QPath), Path(QPath),
/// A type definition itself. This is currently only used for the `existential type` /// A type definition itself. This is currently only used for the `type Foo = impl Trait`
/// item that `impl Trait` in return position desugars to. /// item that `impl Trait` in return position desugars to.
/// ///
/// The generic argument list contains the lifetimes (and in the future possibly parameters) /// The generic argument list contains the lifetimes (and in the future possibly parameters)
@ -2421,17 +2421,17 @@ pub enum ItemKind {
GlobalAsm(P<GlobalAsm>), GlobalAsm(P<GlobalAsm>),
/// A type alias, e.g., `type Foo = Bar<u8>` /// A type alias, e.g., `type Foo = Bar<u8>`
Ty(P<Ty>, Generics), Ty(P<Ty>, Generics),
/// An existential type definition, e.g., `existential type Foo: Bar;` /// An opaque `impl Trait` type alias, e.g., `type Foo = impl Bar;`
Existential(ExistTy), OpaqueTy(ExistTy),
/// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}` /// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`
Enum(EnumDef, Generics), Enum(EnumDef, Generics),
/// A struct definition, e.g., `struct Foo<A> {x: A}` /// A struct definition, e.g., `struct Foo<A> {x: A}`
Struct(VariantData, Generics), Struct(VariantData, Generics),
/// A union definition, e.g., `union Foo<A, B> {x: A, y: B}` /// A union definition, e.g., `union Foo<A, B> {x: A, y: B}`
Union(VariantData, Generics), Union(VariantData, Generics),
/// Represents a Trait Declaration /// A trait definition
Trait(IsAuto, Unsafety, Generics, GenericBounds, HirVec<TraitItemRef>), Trait(IsAuto, Unsafety, Generics, GenericBounds, HirVec<TraitItemRef>),
/// Represents a Trait Alias Declaration /// A trait alias
TraitAlias(Generics, GenericBounds), TraitAlias(Generics, GenericBounds),
/// An implementation, eg `impl<A> Trait for Foo { .. }` /// An implementation, eg `impl<A> Trait for Foo { .. }`
@ -2456,7 +2456,7 @@ impl ItemKind {
ItemKind::ForeignMod(..) => "foreign module", ItemKind::ForeignMod(..) => "foreign module",
ItemKind::GlobalAsm(..) => "global asm", ItemKind::GlobalAsm(..) => "global asm",
ItemKind::Ty(..) => "type alias", ItemKind::Ty(..) => "type alias",
ItemKind::Existential(..) => "existential type", ItemKind::OpaqueTy(..) => "opaque type",
ItemKind::Enum(..) => "enum", ItemKind::Enum(..) => "enum",
ItemKind::Struct(..) => "struct", ItemKind::Struct(..) => "struct",
ItemKind::Union(..) => "union", ItemKind::Union(..) => "union",
@ -2479,7 +2479,7 @@ impl ItemKind {
Some(match *self { Some(match *self {
ItemKind::Fn(_, _, ref generics, _) | ItemKind::Fn(_, _, ref generics, _) |
ItemKind::Ty(_, ref generics) | ItemKind::Ty(_, ref generics) |
ItemKind::Existential(ExistTy { ref generics, impl_trait_fn: None, .. }) | ItemKind::OpaqueTy(ExistTy { ref generics, impl_trait_fn: None, .. }) |
ItemKind::Enum(_, ref generics) | ItemKind::Enum(_, ref generics) |
ItemKind::Struct(_, ref generics) | ItemKind::Struct(_, ref generics) |
ItemKind::Union(_, ref generics) | ItemKind::Union(_, ref generics) |
@ -2528,7 +2528,7 @@ pub enum AssocItemKind {
Const, Const,
Method { has_self: bool }, Method { has_self: bool },
Type, Type,
Existential, OpaqueTy,
} }
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]

View File

@ -565,9 +565,10 @@ impl<'a> State<'a> {
self.s.word(";"); self.s.word(";");
self.end(); // end the outer ibox self.end(); // end the outer ibox
} }
hir::ItemKind::Existential(ref exist) => { hir::ItemKind::OpaqueTy(ref exist) => {
self.head(visibility_qualified(&item.vis, "existential type")); self.head(visibility_qualified(&item.vis, "type"));
self.print_ident(item.ident); self.print_ident(item.ident);
self.word_space("= impl");
self.print_generic_params(&exist.generics.params); self.print_generic_params(&exist.generics.params);
self.end(); // end the inner ibox self.end(); // end the inner ibox
@ -908,9 +909,11 @@ impl<'a> State<'a> {
hir::ImplItemKind::Type(ref ty) => { hir::ImplItemKind::Type(ref ty) => {
self.print_associated_type(ii.ident, None, Some(ty)); self.print_associated_type(ii.ident, None, Some(ty));
} }
hir::ImplItemKind::Existential(ref bounds) => { hir::ImplItemKind::OpaqueTy(ref bounds) => {
self.word_space("existential"); self.word_space("type");
self.print_associated_type(ii.ident, Some(bounds), None); self.print_ident(ii.ident);
self.print_bounds("= impl", bounds);
self.s.word(";");
} }
} }
self.ann.post(self, AnnNode::SubItem(ii.hir_id)) self.ann.post(self, AnnNode::SubItem(ii.hir_id))

View File

@ -418,7 +418,7 @@ impl_stable_hash_for!(enum ::syntax_pos::hygiene::DesugaringKind {
Async, Async,
Await, Await,
QuestionMark, QuestionMark,
ExistentialType, OpaqueTy,
ForLoop, ForLoop,
TryBlock TryBlock
}); });

View File

@ -269,7 +269,7 @@ impl<'tcx> TyCtxt<'tcx> {
match item.node { match item.node {
hir::ImplItemKind::Method(..) => "method body", hir::ImplItemKind::Method(..) => "method body",
hir::ImplItemKind::Const(..) hir::ImplItemKind::Const(..)
| hir::ImplItemKind::Existential(..) | hir::ImplItemKind::OpaqueTy(..)
| hir::ImplItemKind::Type(..) => "associated item", | hir::ImplItemKind::Type(..) => "associated item",
} }
} }

View File

@ -40,7 +40,7 @@ pub struct OpaqueTypeDecl<'tcx> {
/// for example: /// for example:
/// ///
/// ``` /// ```
/// existential type Foo; /// type Foo = impl Baz;
/// fn bar() -> Foo { /// fn bar() -> Foo {
/// ^^^ This is the span we are looking for! /// ^^^ This is the span we are looking for!
/// ``` /// ```
@ -87,8 +87,8 @@ pub struct OpaqueTypeDecl<'tcx> {
/// check.) /// check.)
pub has_required_region_bounds: bool, pub has_required_region_bounds: bool,
/// The origin of the existential type /// The origin of the opaque type.
pub origin: hir::ExistTyOrigin, pub origin: hir::OpaqueTyOrigin,
} }
impl<'a, 'tcx> InferCtxt<'a, 'tcx> { impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
@ -143,8 +143,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
InferOk { value: (value, instantiator.opaque_types), obligations: instantiator.obligations } InferOk { value: (value, instantiator.opaque_types), obligations: instantiator.obligations }
} }
/// Given the map `opaque_types` containing the existential `impl /// Given the map `opaque_types` containing the opaque
/// Trait` types whose underlying, hidden types are being /// `impl Trait` types whose underlying, hidden types are being
/// inferred, this method adds constraints to the regions /// inferred, this method adds constraints to the regions
/// appearing in those underlying hidden types to ensure that they /// appearing in those underlying hidden types to ensure that they
/// at least do not refer to random scopes within the current /// at least do not refer to random scopes within the current
@ -265,14 +265,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
/// } /// }
/// ///
/// // Equivalent to: /// // Equivalent to:
/// existential type FooReturn<'a, T>: Foo<'a>; /// type FooReturn<'a, T> = impl Foo<'a>;
/// fn foo<'a, T>(..) -> FooReturn<'a, T> { .. } /// fn foo<'a, T>(..) -> FooReturn<'a, T> { .. }
/// ``` /// ```
/// ///
/// then the hidden type `Tc` would be `(&'0 u32, T)` (where `'0` /// then the hidden type `Tc` would be `(&'0 u32, T)` (where `'0`
/// is an inference variable). If we generated a constraint that /// is an inference variable). If we generated a constraint that
/// `Tc: 'a`, then this would incorrectly require that `T: 'a` -- /// `Tc: 'a`, then this would incorrectly require that `T: 'a` --
/// but this is not necessary, because the existential type we /// but this is not necessary, because the opaque type we
/// create will be allowed to reference `T`. So we only generate a /// create will be allowed to reference `T`. So we only generate a
/// constraint that `'0: 'a`. /// constraint that `'0: 'a`.
/// ///
@ -492,11 +492,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// Without a feature-gate, we only generate member-constraints for async-await. // Without a feature-gate, we only generate member-constraints for async-await.
let context_name = match opaque_defn.origin { let context_name = match opaque_defn.origin {
// No feature-gate required for `async fn`. // No feature-gate required for `async fn`.
hir::ExistTyOrigin::AsyncFn => return false, hir::OpaqueTyOrigin::AsyncFn => return false,
// Otherwise, generate the label we'll use in the error message. // Otherwise, generate the label we'll use in the error message.
hir::ExistTyOrigin::ExistentialType => "existential type", hir::OpaqueTyOrigin::TraitAliasImplTrait => "impl Trait",
hir::ExistTyOrigin::ReturnImplTrait => "impl Trait", hir::OpaqueTyOrigin::ReturnImplTrait => "impl Trait",
}; };
let msg = format!("ambiguous lifetime bound in `{}`", context_name); let msg = format!("ambiguous lifetime bound in `{}`", context_name);
let mut err = self.tcx.sess.struct_span_err(span, &msg); let mut err = self.tcx.sess.struct_span_err(span, &msg);
@ -842,12 +842,12 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
self.tcx.sess self.tcx.sess
.struct_span_err( .struct_span_err(
self.span, self.span,
"non-defining existential type use in defining scope" "non-defining opaque type use in defining scope"
) )
.span_label( .span_label(
self.span, self.span,
format!("lifetime `{}` is part of concrete type but not used in \ format!("lifetime `{}` is part of concrete type but not used in \
parameter list of existential type", r), parameter list of the `impl Trait` type alias", r),
) )
.emit(); .emit();
@ -863,7 +863,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
// we encounter a closure here, it is always a closure // we encounter a closure here, it is always a closure
// from within the function that we are currently // from within the function that we are currently
// type-checking -- one that is now being encapsulated // type-checking -- one that is now being encapsulated
// in an existential abstract type. Ideally, we would // in an opaque type. Ideally, we would
// go through the types/lifetimes that it references // go through the types/lifetimes that it references
// and treat them just like we would any other type, // and treat them just like we would any other type,
// which means we would error out if we find any // which means we would error out if we find any
@ -918,7 +918,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
// Look it up in the substitution list. // Look it up in the substitution list.
match self.map.get(&ty.into()).map(|k| k.unpack()) { match self.map.get(&ty.into()).map(|k| k.unpack()) {
// Found it in the substitution list; replace with the parameter from the // Found it in the substitution list; replace with the parameter from the
// existential type. // opaque type.
Some(UnpackedKind::Type(t1)) => t1, Some(UnpackedKind::Type(t1)) => t1,
Some(u) => panic!("type mapped to unexpected kind: {:?}", u), Some(u) => panic!("type mapped to unexpected kind: {:?}", u),
None => { None => {
@ -926,7 +926,8 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
.struct_span_err( .struct_span_err(
self.span, self.span,
&format!("type parameter `{}` is part of concrete type but not \ &format!("type parameter `{}` is part of concrete type but not \
used in parameter list for existential type", ty), used in parameter list for the `impl Trait` type alias",
ty),
) )
.emit(); .emit();
@ -947,7 +948,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
// Look it up in the substitution list. // Look it up in the substitution list.
match self.map.get(&ct.into()).map(|k| k.unpack()) { match self.map.get(&ct.into()).map(|k| k.unpack()) {
// Found it in the substitution list, replace with the parameter from the // Found it in the substitution list, replace with the parameter from the
// existential type. // opaque type.
Some(UnpackedKind::Const(c1)) => c1, Some(UnpackedKind::Const(c1)) => c1,
Some(u) => panic!("const mapped to unexpected kind: {:?}", u), Some(u) => panic!("const mapped to unexpected kind: {:?}", u),
None => { None => {
@ -955,7 +956,8 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
.struct_span_err( .struct_span_err(
self.span, self.span,
&format!("const parameter `{}` is part of concrete type but not \ &format!("const parameter `{}` is part of concrete type but not \
used in parameter list for existential type", ct) used in parameter list for the `impl Trait` type alias",
ct)
) )
.emit(); .emit();
@ -1031,36 +1033,40 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
let (in_definition_scope, origin) = match tcx.hir().find(opaque_hir_id) { let (in_definition_scope, origin) = match tcx.hir().find(opaque_hir_id) {
Some(Node::Item(item)) => match item.node { Some(Node::Item(item)) => match item.node {
// Anonymous `impl Trait` // Anonymous `impl Trait`
hir::ItemKind::Existential(hir::ExistTy { hir::ItemKind::OpaqueTy(hir::ExistTy {
impl_trait_fn: Some(parent), impl_trait_fn: Some(parent),
origin, origin,
.. ..
}) => (parent == self.parent_def_id, origin), }) => (parent == self.parent_def_id, origin),
// Named `existential type` // Named `type Foo = impl Bar;`
hir::ItemKind::Existential(hir::ExistTy { hir::ItemKind::OpaqueTy(hir::ExistTy {
impl_trait_fn: None, impl_trait_fn: None,
origin, origin,
.. ..
}) => ( }) => (
may_define_existential_type( may_define_opaque_type(
tcx, tcx,
self.parent_def_id, self.parent_def_id,
opaque_hir_id, opaque_hir_id,
), ),
origin, origin,
), ),
_ => (def_scope_default(), hir::ExistTyOrigin::ExistentialType), _ => {
(def_scope_default(), hir::OpaqueTyOrigin::TraitAliasImplTrait)
}
}, },
Some(Node::ImplItem(item)) => match item.node { Some(Node::ImplItem(item)) => match item.node {
hir::ImplItemKind::Existential(_) => ( hir::ImplItemKind::OpaqueTy(_) => (
may_define_existential_type( may_define_opaque_type(
tcx, tcx,
self.parent_def_id, self.parent_def_id,
opaque_hir_id, opaque_hir_id,
), ),
hir::ExistTyOrigin::ExistentialType, hir::OpaqueTyOrigin::TraitAliasImplTrait,
), ),
_ => (def_scope_default(), hir::ExistTyOrigin::ExistentialType), _ => {
(def_scope_default(), hir::OpaqueTyOrigin::TraitAliasImplTrait)
}
}, },
_ => bug!( _ => bug!(
"expected (impl) item, found {}", "expected (impl) item, found {}",
@ -1092,7 +1098,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
ty: Ty<'tcx>, ty: Ty<'tcx>,
def_id: DefId, def_id: DefId,
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
origin: hir::ExistTyOrigin, origin: hir::OpaqueTyOrigin,
) -> Ty<'tcx> { ) -> Ty<'tcx> {
let infcx = self.infcx; let infcx = self.infcx;
let tcx = infcx.tcx; let tcx = infcx.tcx;
@ -1123,7 +1129,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
debug!("instantiate_opaque_types: required_region_bounds={:?}", required_region_bounds); debug!("instantiate_opaque_types: required_region_bounds={:?}", required_region_bounds);
// Make sure that we are in fact defining the *entire* type // Make sure that we are in fact defining the *entire* type
// (e.g., `existential type Foo<T: Bound>: Bar;` needs to be // (e.g., `type Foo<T: Bound> = impl Bar;` needs to be
// defined by a function like `fn foo<T: Bound>() -> Foo<T>`). // defined by a function like `fn foo<T: Bound>() -> Foo<T>`).
debug!("instantiate_opaque_types: param_env={:#?}", self.param_env,); debug!("instantiate_opaque_types: param_env={:#?}", self.param_env,);
debug!("instantiate_opaque_types: generics={:#?}", tcx.generics_of(def_id),); debug!("instantiate_opaque_types: generics={:#?}", tcx.generics_of(def_id),);
@ -1171,7 +1177,9 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
/// ```rust /// ```rust
/// pub mod foo { /// pub mod foo {
/// pub mod bar { /// pub mod bar {
/// pub existential type Baz; /// pub trait Bar { .. }
///
/// pub type Baz = impl Bar;
/// ///
/// fn f1() -> Baz { .. } /// fn f1() -> Baz { .. }
/// } /// }
@ -1180,18 +1188,17 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
/// } /// }
/// ``` /// ```
/// ///
/// Here, `def_id` is the `DefId` of the defining use of the existential type (e.g., `f1` or `f2`), /// Here, `def_id` is the `DefId` of the defining use of the opaque type (e.g., `f1` or `f2`),
/// and `opaque_hir_id` is the `HirId` of the definition of the existential type `Baz`. /// and `opaque_hir_id` is the `HirId` of the definition of the opaque type `Baz`.
/// For the above example, this function returns `true` for `f1` and `false` for `f2`. /// For the above example, this function returns `true` for `f1` and `false` for `f2`.
pub fn may_define_existential_type( pub fn may_define_opaque_type(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
def_id: DefId, def_id: DefId,
opaque_hir_id: hir::HirId, opaque_hir_id: hir::HirId,
) -> bool { ) -> bool {
let mut hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); let mut hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
// Named opaque types can be defined by any siblings or children of siblings.
// Named existential types can be defined by any siblings or children of siblings.
let scope = tcx.hir().get_defining_scope(opaque_hir_id).expect("could not get defining scope"); let scope = tcx.hir().get_defining_scope(opaque_hir_id).expect("could not get defining scope");
// We walk up the node tree until we hit the root or the scope of the opaque type. // We walk up the node tree until we hit the root or the scope of the opaque type.
while hir_id != scope && hir_id != hir::CRATE_HIR_ID { while hir_id != scope && hir_id != hir::CRATE_HIR_ID {

View File

@ -638,7 +638,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> {
} }
self.visit_nested_body(body_id) self.visit_nested_body(body_id)
} }
hir::ImplItemKind::Existential(..) | hir::ImplItemKind::OpaqueTy(..) |
hir::ImplItemKind::Type(..) => {} hir::ImplItemKind::Type(..) => {}
} }
} }

View File

@ -188,7 +188,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
} }
} }
} }
hir::ImplItemKind::Existential(..) | hir::ImplItemKind::OpaqueTy(..) |
hir::ImplItemKind::Type(_) => false, hir::ImplItemKind::Type(_) => false,
} }
} }
@ -263,7 +263,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
// worklist, as determined by the privacy pass // worklist, as determined by the privacy pass
hir::ItemKind::ExternCrate(_) | hir::ItemKind::ExternCrate(_) |
hir::ItemKind::Use(..) | hir::ItemKind::Use(..) |
hir::ItemKind::Existential(..) | hir::ItemKind::OpaqueTy(..) |
hir::ItemKind::Ty(..) | hir::ItemKind::Ty(..) |
hir::ItemKind::Static(..) | hir::ItemKind::Static(..) |
hir::ItemKind::Mod(..) | hir::ItemKind::Mod(..) |
@ -301,7 +301,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
self.visit_nested_body(body) self.visit_nested_body(body)
} }
} }
hir::ImplItemKind::Existential(..) | hir::ImplItemKind::OpaqueTy(..) |
hir::ImplItemKind::Type(_) => {} hir::ImplItemKind::Type(_) => {}
} }
} }

View File

@ -480,16 +480,16 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
}; };
self.with(scope, |_, this| intravisit::walk_item(this, item)); self.with(scope, |_, this| intravisit::walk_item(this, item));
} }
hir::ItemKind::Existential(hir::ExistTy { hir::ItemKind::OpaqueTy(hir::ExistTy {
impl_trait_fn: Some(_), impl_trait_fn: Some(_),
.. ..
}) => { }) => {
// currently existential type declarations are just generated from impl Trait // Currently opaque type declarations are just generated from `impl Trait`
// items. doing anything on this node is irrelevant, as we currently don't need // items. Doing anything on this node is irrelevant, as we currently don't need
// it. // it.
} }
hir::ItemKind::Ty(_, ref generics) hir::ItemKind::Ty(_, ref generics)
| hir::ItemKind::Existential(hir::ExistTy { | hir::ItemKind::OpaqueTy(hir::ExistTy {
impl_trait_fn: None, impl_trait_fn: None,
ref generics, ref generics,
.. ..
@ -627,9 +627,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
// the exist_ty generics // the exist_ty generics
let (generics, bounds) = match self.tcx.hir().expect_item(item_id.id).node let (generics, bounds) = match self.tcx.hir().expect_item(item_id.id).node
{ {
// named existential types are reached via TyKind::Path // Named opaque `impl Trait` types are reached via `TyKind::Path`.
// this arm is for `impl Trait` in the types of statics, constants and locals // This arm is for `impl Trait` in the types of statics, constants and locals.
hir::ItemKind::Existential(hir::ExistTy { hir::ItemKind::OpaqueTy(hir::ExistTy {
impl_trait_fn: None, impl_trait_fn: None,
.. ..
}) => { }) => {
@ -637,15 +637,15 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
return; return;
} }
// RPIT (return position impl trait) // RPIT (return position impl trait)
hir::ItemKind::Existential(hir::ExistTy { hir::ItemKind::OpaqueTy(hir::ExistTy {
ref generics, ref generics,
ref bounds, ref bounds,
.. ..
}) => (generics, bounds), }) => (generics, bounds),
ref i => bug!("impl Trait pointed to non-existential type?? {:#?}", i), ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
}; };
// Resolve the lifetimes that are applied to the existential type. // Resolve the lifetimes that are applied to the opaque type.
// These are resolved in the current scope. // These are resolved in the current scope.
// `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
// `fn foo<'a>() -> MyAnonTy<'a> { ... }` // `fn foo<'a>() -> MyAnonTy<'a> { ... }`
@ -855,7 +855,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
this.visit_ty(ty); this.visit_ty(ty);
}); });
} }
Existential(ref bounds) => { OpaqueTy(ref bounds) => {
let generics = &impl_item.generics; let generics = &impl_item.generics;
let mut index = self.next_early_index(); let mut index = self.next_early_index();
let mut next_early_index = index; let mut next_early_index = index;
@ -1254,7 +1254,7 @@ fn compute_object_lifetime_defaults(tcx: TyCtxt<'_>) -> HirIdMap<Vec<ObjectLifet
hir::ItemKind::Struct(_, ref generics) hir::ItemKind::Struct(_, ref generics)
| hir::ItemKind::Union(_, ref generics) | hir::ItemKind::Union(_, ref generics)
| hir::ItemKind::Enum(_, ref generics) | hir::ItemKind::Enum(_, ref generics)
| hir::ItemKind::Existential(hir::ExistTy { | hir::ItemKind::OpaqueTy(hir::ExistTy {
ref generics, ref generics,
impl_trait_fn: None, impl_trait_fn: None,
.. ..

View File

@ -1492,7 +1492,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
}; };
} }
let substs = translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.node); let substs = translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.node);
let ty = if let ty::AssocKind::Existential = assoc_ty.item.kind { let ty = if let ty::AssocKind::OpaqueTy = assoc_ty.item.kind {
let item_substs = InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id); let item_substs = InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id);
tcx.mk_opaque(assoc_ty.item.def_id, item_substs) tcx.mk_opaque(assoc_ty.item.def_id, item_substs)
} else { } else {

View File

@ -484,13 +484,13 @@ impl<'tcx> Ancestors<'tcx> {
| (Const, Const) | (Const, Const)
| (Method, Method) | (Method, Method)
| (Type, Type) | (Type, Type)
| (Type, Existential) | (Type, OpaqueTy)
=> tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id), => tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id),
| (Const, _) | (Const, _)
| (Method, _) | (Method, _)
| (Type, _) | (Type, _)
| (Existential, _) | (OpaqueTy, _)
=> false, => false,
}).map(move |item| NodeItem { node: node, item: item }) }).map(move |item| NodeItem { node: node, item: item })
}) })

View File

@ -281,14 +281,14 @@ impl<'a, V> LocalTableInContextMut<'a, V> {
} }
} }
/// All information necessary to validate and reveal an `impl Trait` or `existential Type` /// All information necessary to validate and reveal an `impl Trait`.
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct ResolvedOpaqueTy<'tcx> { pub struct ResolvedOpaqueTy<'tcx> {
/// The revealed type as seen by this function. /// The revealed type as seen by this function.
pub concrete_type: Ty<'tcx>, pub concrete_type: Ty<'tcx>,
/// Generic parameters on the opaque type as passed by this function. /// Generic parameters on the opaque type as passed by this function.
/// For `existential type Foo<A, B>; fn foo<T, U>() -> Foo<T, U> { .. }` this is `[T, U]`, not /// For `type Foo<A, B> = impl Bar<A, B>; fn foo<T, U>() -> Foo<T, U> { .. }`
/// `[A, B]` /// this is `[T, U]`, not `[A, B]`.
pub substs: SubstsRef<'tcx>, pub substs: SubstsRef<'tcx>,
} }
@ -392,9 +392,9 @@ pub struct TypeckTables<'tcx> {
/// read-again by borrowck. /// read-again by borrowck.
pub free_region_map: FreeRegionMap<'tcx>, pub free_region_map: FreeRegionMap<'tcx>,
/// All the existential types that are restricted to concrete types /// All the opaque types that are restricted to concrete types
/// by this function /// by this function
pub concrete_existential_types: FxHashMap<DefId, ResolvedOpaqueTy<'tcx>>, pub concrete_opaque_types: FxHashMap<DefId, ResolvedOpaqueTy<'tcx>>,
/// Given the closure ID this map provides the list of UpvarIDs used by it. /// Given the closure ID this map provides the list of UpvarIDs used by it.
/// The upvarID contains the HIR node ID and it also contains the full path /// The upvarID contains the HIR node ID and it also contains the full path
@ -424,7 +424,7 @@ impl<'tcx> TypeckTables<'tcx> {
used_trait_imports: Lrc::new(Default::default()), used_trait_imports: Lrc::new(Default::default()),
tainted_by_errors: false, tainted_by_errors: false,
free_region_map: Default::default(), free_region_map: Default::default(),
concrete_existential_types: Default::default(), concrete_opaque_types: Default::default(),
upvar_list: Default::default(), upvar_list: Default::default(),
} }
} }
@ -733,7 +733,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckTables<'tcx> {
ref used_trait_imports, ref used_trait_imports,
tainted_by_errors, tainted_by_errors,
ref free_region_map, ref free_region_map,
ref concrete_existential_types, ref concrete_opaque_types,
ref upvar_list, ref upvar_list,
} = *self; } = *self;
@ -777,7 +777,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckTables<'tcx> {
used_trait_imports.hash_stable(hcx, hasher); used_trait_imports.hash_stable(hcx, hasher);
tainted_by_errors.hash_stable(hcx, hasher); tainted_by_errors.hash_stable(hcx, hasher);
free_region_map.hash_stable(hcx, hasher); free_region_map.hash_stable(hcx, hasher);
concrete_existential_types.hash_stable(hcx, hasher); concrete_opaque_types.hash_stable(hcx, hasher);
upvar_list.hash_stable(hcx, hasher); upvar_list.hash_stable(hcx, hasher);
}) })
} }

View File

@ -185,7 +185,7 @@ pub struct AssocItem {
pub enum AssocKind { pub enum AssocKind {
Const, Const,
Method, Method,
Existential, OpaqueTy,
Type Type
} }
@ -195,7 +195,7 @@ impl AssocItem {
AssocKind::Const => DefKind::AssocConst, AssocKind::Const => DefKind::AssocConst,
AssocKind::Method => DefKind::Method, AssocKind::Method => DefKind::Method,
AssocKind::Type => DefKind::AssocTy, AssocKind::Type => DefKind::AssocTy,
AssocKind::Existential => DefKind::AssocExistential, AssocKind::OpaqueTy => DefKind::AssocOpaqueTy,
} }
} }
@ -203,7 +203,7 @@ impl AssocItem {
/// for ! /// for !
pub fn relevant_for_never(&self) -> bool { pub fn relevant_for_never(&self) -> bool {
match self.kind { match self.kind {
AssocKind::Existential | AssocKind::OpaqueTy |
AssocKind::Const | AssocKind::Const |
AssocKind::Type => true, AssocKind::Type => true,
// FIXME(canndrew): Be more thorough here, check if any argument is uninhabited. // FIXME(canndrew): Be more thorough here, check if any argument is uninhabited.
@ -221,7 +221,8 @@ impl AssocItem {
tcx.fn_sig(self.def_id).skip_binder().to_string() tcx.fn_sig(self.def_id).skip_binder().to_string()
} }
ty::AssocKind::Type => format!("type {};", self.ident), ty::AssocKind::Type => format!("type {};", self.ident),
ty::AssocKind::Existential => format!("existential type {};", self.ident), // FIXME(trait_alias_impl_trait): we should print bounds here too.
ty::AssocKind::OpaqueTy => format!("type {};", self.ident),
ty::AssocKind::Const => { ty::AssocKind::Const => {
format!("const {}: {:?};", self.ident, tcx.type_of(self.def_id)) format!("const {}: {:?};", self.ident, tcx.type_of(self.def_id))
} }
@ -2822,7 +2823,7 @@ impl<'tcx> TyCtxt<'tcx> {
(ty::AssocKind::Method, has_self) (ty::AssocKind::Method, has_self)
} }
hir::AssocItemKind::Type => (ty::AssocKind::Type, false), hir::AssocItemKind::Type => (ty::AssocKind::Type, false),
hir::AssocItemKind::Existential => bug!("only impls can have existentials"), hir::AssocItemKind::OpaqueTy => bug!("only impls can have opaque types"),
}; };
AssocItem { AssocItem {
@ -2848,7 +2849,7 @@ impl<'tcx> TyCtxt<'tcx> {
(ty::AssocKind::Method, has_self) (ty::AssocKind::Method, has_self)
} }
hir::AssocItemKind::Type => (ty::AssocKind::Type, false), hir::AssocItemKind::Type => (ty::AssocKind::Type, false),
hir::AssocItemKind::Existential => (ty::AssocKind::Existential, false), hir::AssocItemKind::OpaqueTy => (ty::AssocKind::OpaqueTy, false),
}; };
AssocItem { AssocItem {
@ -3213,7 +3214,7 @@ fn trait_of_item(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> { pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) { if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) {
if let Node::Item(item) = tcx.hir().get(hir_id) { if let Node::Item(item) = tcx.hir().get(hir_id) {
if let hir::ItemKind::Existential(ref exist_ty) = item.node { if let hir::ItemKind::OpaqueTy(ref exist_ty) = item.node {
return exist_ty.impl_trait_fn; return exist_ty.impl_trait_fn;
} }
} }

View File

@ -185,7 +185,7 @@ pub enum TyKind<'tcx> {
/// Opaque (`impl Trait`) type found in a return type. /// Opaque (`impl Trait`) type found in a return type.
/// The `DefId` comes either from /// The `DefId` comes either from
/// * the `impl Trait` ast::Ty node, /// * the `impl Trait` ast::Ty node,
/// * or the `existential type` declaration /// * or the `type Foo = impl Trait` declaration
/// The substitutions are for the generics of the function in question. /// The substitutions are for the generics of the function in question.
/// After typeck, the concrete type can be found in the `types` map. /// After typeck, the concrete type can be found in the `types` map.
Opaque(DefId, SubstsRef<'tcx>), Opaque(DefId, SubstsRef<'tcx>),

View File

@ -362,7 +362,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
// should've been checked by the instantiation // should've been checked by the instantiation
// of whatever returned this exact `impl Trait`. // of whatever returned this exact `impl Trait`.
// for named existential types we still need to check them // for named opaque `impl Trait` types we still need to check them
if super::is_impl_trait_defn(self.infcx.tcx, did).is_none() { if super::is_impl_trait_defn(self.infcx.tcx, did).is_none() {
let obligations = self.nominal_obligations(did, substs); let obligations = self.nominal_obligations(did, substs);
self.out.extend(obligations); self.out.extend(obligations);

View File

@ -406,7 +406,7 @@ impl DirtyCleanVisitor<'tcx> {
ImplItemKind::Method(..) => ("Node::ImplItem", LABELS_FN_IN_IMPL), ImplItemKind::Method(..) => ("Node::ImplItem", LABELS_FN_IN_IMPL),
ImplItemKind::Const(..) => ("NodeImplConst", LABELS_CONST_IN_IMPL), ImplItemKind::Const(..) => ("NodeImplConst", LABELS_CONST_IN_IMPL),
ImplItemKind::Type(..) => ("NodeImplType", LABELS_CONST_IN_IMPL), ImplItemKind::Type(..) => ("NodeImplType", LABELS_CONST_IN_IMPL),
ImplItemKind::Existential(..) => ("NodeImplType", LABELS_CONST_IN_IMPL), ImplItemKind::OpaqueTy(..) => ("NodeImplType", LABELS_CONST_IN_IMPL),
} }
}, },
_ => self.tcx.sess.span_fatal( _ => self.tcx.sess.span_fatal(

View File

@ -461,7 +461,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
hir::ImplItemKind::Const(..) => "an associated constant", hir::ImplItemKind::Const(..) => "an associated constant",
hir::ImplItemKind::Method(..) => "a method", hir::ImplItemKind::Method(..) => "a method",
hir::ImplItemKind::Type(_) => "an associated type", hir::ImplItemKind::Type(_) => "an associated type",
hir::ImplItemKind::Existential(_) => "an associated existential type", hir::ImplItemKind::OpaqueTy(_) => "an associated `impl Trait` type",
}; };
self.check_missing_docs_attrs(cx, self.check_missing_docs_attrs(cx,
Some(impl_item.hir_id), Some(impl_item.hir_id),

View File

@ -413,9 +413,9 @@ impl<'tcx> EntryKind<'tcx> {
EntryKind::Type => DefKind::TyAlias, EntryKind::Type => DefKind::TyAlias,
EntryKind::TypeParam => DefKind::TyParam, EntryKind::TypeParam => DefKind::TyParam,
EntryKind::ConstParam => DefKind::ConstParam, EntryKind::ConstParam => DefKind::ConstParam,
EntryKind::Existential => DefKind::Existential, EntryKind::OpaqueTy => DefKind::OpaqueTy,
EntryKind::AssocType(_) => DefKind::AssocTy, EntryKind::AssocType(_) => DefKind::AssocTy,
EntryKind::AssocExistential(_) => DefKind::AssocExistential, EntryKind::AssocOpaqueTy(_) => DefKind::AssocOpaqueTy,
EntryKind::Mod(_) => DefKind::Mod, EntryKind::Mod(_) => DefKind::Mod,
EntryKind::Variant(_) => DefKind::Variant, EntryKind::Variant(_) => DefKind::Variant,
EntryKind::Trait(_) => DefKind::Trait, EntryKind::Trait(_) => DefKind::Trait,
@ -910,8 +910,8 @@ impl<'a, 'tcx> CrateMetadata {
EntryKind::AssocType(container) => { EntryKind::AssocType(container) => {
(ty::AssocKind::Type, container, false) (ty::AssocKind::Type, container, false)
} }
EntryKind::AssocExistential(container) => { EntryKind::AssocOpaqueTy(container) => {
(ty::AssocKind::Existential, container, false) (ty::AssocKind::OpaqueTy, container, false)
} }
_ => bug!("cannot get associated-item of `{:?}`", def_key) _ => bug!("cannot get associated-item of `{:?}`", def_key)
}; };

View File

@ -868,8 +868,7 @@ impl EncodeContext<'tcx> {
})) }))
} }
ty::AssocKind::Type => EntryKind::AssocType(container), ty::AssocKind::Type => EntryKind::AssocType(container),
ty::AssocKind::Existential => ty::AssocKind::OpaqueTy => span_bug!(ast_item.span, "opaque type in trait"),
span_bug!(ast_item.span, "existential type in trait"),
}; };
Entry { Entry {
@ -893,7 +892,7 @@ impl EncodeContext<'tcx> {
None None
} }
} }
ty::AssocKind::Existential => unreachable!(), ty::AssocKind::OpaqueTy => unreachable!(),
}, },
inherent_impls: LazySeq::empty(), inherent_impls: LazySeq::empty(),
variances: if trait_item.kind == ty::AssocKind::Method { variances: if trait_item.kind == ty::AssocKind::Method {
@ -964,7 +963,7 @@ impl EncodeContext<'tcx> {
has_self: impl_item.method_has_self_argument, has_self: impl_item.method_has_self_argument,
})) }))
} }
ty::AssocKind::Existential => EntryKind::AssocExistential(container), ty::AssocKind::OpaqueTy => EntryKind::AssocOpaqueTy(container),
ty::AssocKind::Type => EntryKind::AssocType(container) ty::AssocKind::Type => EntryKind::AssocType(container)
}; };
@ -980,7 +979,7 @@ impl EncodeContext<'tcx> {
let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir; let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
needs_inline || is_const_fn || always_encode_mir needs_inline || is_const_fn || always_encode_mir
}, },
hir::ImplItemKind::Existential(..) | hir::ImplItemKind::OpaqueTy(..) |
hir::ImplItemKind::Type(..) => false, hir::ImplItemKind::Type(..) => false,
}; };
@ -1096,7 +1095,7 @@ impl EncodeContext<'tcx> {
hir::ItemKind::ForeignMod(_) => EntryKind::ForeignMod, hir::ItemKind::ForeignMod(_) => EntryKind::ForeignMod,
hir::ItemKind::GlobalAsm(..) => EntryKind::GlobalAsm, hir::ItemKind::GlobalAsm(..) => EntryKind::GlobalAsm,
hir::ItemKind::Ty(..) => EntryKind::Type, hir::ItemKind::Ty(..) => EntryKind::Type,
hir::ItemKind::Existential(..) => EntryKind::Existential, hir::ItemKind::OpaqueTy(..) => EntryKind::OpaqueTy,
hir::ItemKind::Enum(..) => EntryKind::Enum(get_repr_options(tcx, def_id)), hir::ItemKind::Enum(..) => EntryKind::Enum(get_repr_options(tcx, def_id)),
hir::ItemKind::Struct(ref struct_def, _) => { hir::ItemKind::Struct(ref struct_def, _) => {
let variant = tcx.adt_def(def_id).non_enum_variant(); let variant = tcx.adt_def(def_id).non_enum_variant();
@ -1229,7 +1228,7 @@ impl EncodeContext<'tcx> {
hir::ItemKind::Const(..) | hir::ItemKind::Const(..) |
hir::ItemKind::Fn(..) | hir::ItemKind::Fn(..) |
hir::ItemKind::Ty(..) | hir::ItemKind::Ty(..) |
hir::ItemKind::Existential(..) | hir::ItemKind::OpaqueTy(..) |
hir::ItemKind::Enum(..) | hir::ItemKind::Enum(..) |
hir::ItemKind::Struct(..) | hir::ItemKind::Struct(..) |
hir::ItemKind::Union(..) | hir::ItemKind::Union(..) |
@ -1253,7 +1252,7 @@ impl EncodeContext<'tcx> {
hir::ItemKind::Struct(..) | hir::ItemKind::Struct(..) |
hir::ItemKind::Union(..) | hir::ItemKind::Union(..) |
hir::ItemKind::Impl(..) | hir::ItemKind::Impl(..) |
hir::ItemKind::Existential(..) | hir::ItemKind::OpaqueTy(..) |
hir::ItemKind::Trait(..) => Some(self.encode_generics(def_id)), hir::ItemKind::Trait(..) => Some(self.encode_generics(def_id)),
hir::ItemKind::TraitAlias(..) => Some(self.encode_generics(def_id)), hir::ItemKind::TraitAlias(..) => Some(self.encode_generics(def_id)),
_ => None, _ => None,
@ -1267,7 +1266,7 @@ impl EncodeContext<'tcx> {
hir::ItemKind::Struct(..) | hir::ItemKind::Struct(..) |
hir::ItemKind::Union(..) | hir::ItemKind::Union(..) |
hir::ItemKind::Impl(..) | hir::ItemKind::Impl(..) |
hir::ItemKind::Existential(..) | hir::ItemKind::OpaqueTy(..) |
hir::ItemKind::Trait(..) | hir::ItemKind::Trait(..) |
hir::ItemKind::TraitAlias(..) => Some(self.encode_predicates(def_id)), hir::ItemKind::TraitAlias(..) => Some(self.encode_predicates(def_id)),
_ => None, _ => None,
@ -1763,7 +1762,7 @@ impl EncodeContext<'tcx> {
hir::ItemKind::ExternCrate(..) | hir::ItemKind::ExternCrate(..) |
hir::ItemKind::Use(..) | hir::ItemKind::Use(..) |
hir::ItemKind::Ty(..) | hir::ItemKind::Ty(..) |
hir::ItemKind::Existential(..) | hir::ItemKind::OpaqueTy(..) |
hir::ItemKind::TraitAlias(..) => { hir::ItemKind::TraitAlias(..) => {
// no sub-item recording needed in these cases // no sub-item recording needed in these cases
} }

View File

@ -239,7 +239,7 @@ pub enum EntryKind<'tcx> {
Type, Type,
TypeParam, TypeParam,
ConstParam, ConstParam,
Existential, OpaqueTy,
Enum(ReprOptions), Enum(ReprOptions),
Field, Field,
Variant(Lazy<VariantData<'tcx>>), Variant(Lazy<VariantData<'tcx>>),
@ -255,7 +255,7 @@ pub enum EntryKind<'tcx> {
Impl(Lazy<ImplData<'tcx>>), Impl(Lazy<ImplData<'tcx>>),
Method(Lazy<MethodData<'tcx>>), Method(Lazy<MethodData<'tcx>>),
AssocType(AssocContainer), AssocType(AssocContainer),
AssocExistential(AssocContainer), AssocOpaqueTy(AssocContainer),
AssocConst(AssocContainer, ConstQualif, Lazy<RenderedConst>), AssocConst(AssocContainer, ConstQualif, Lazy<RenderedConst>),
TraitAlias(Lazy<TraitAliasData<'tcx>>), TraitAlias(Lazy<TraitAliasData<'tcx>>),
} }

View File

@ -1,7 +1,7 @@
//! This module contains code to equate the input/output types appearing //! This module contains code to equate the input/output types appearing
//! in the MIR with the expected input/output types from the function //! in the MIR with the expected input/output types from the function
//! signature. This requires a bit of processing, as the expected types //! signature. This requires a bit of processing, as the expected types
//! are supplied to us before normalization and may contain existential //! are supplied to us before normalization and may contain opaque
//! `impl Trait` instances. In contrast, the input/output types found in //! `impl Trait` instances. In contrast, the input/output types found in
//! the MIR (specifically, in the special local variables for the //! the MIR (specifically, in the special local variables for the
//! `RETURN_PLACE` the MIR arguments) are always fully normalized (and //! `RETURN_PLACE` the MIR arguments) are always fully normalized (and
@ -113,8 +113,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
self.equate_normalized_input_or_output(ur_yield_ty, mir_yield_ty, yield_span); self.equate_normalized_input_or_output(ur_yield_ty, mir_yield_ty, yield_span);
} }
// Return types are a bit more complex. They may contain existential `impl Trait` // Return types are a bit more complex. They may contain opaque `impl Trait` types.
// types.
let mir_output_ty = body.local_decls[RETURN_PLACE].ty; let mir_output_ty = body.local_decls[RETURN_PLACE].ty;
let output_span = body.local_decls[RETURN_PLACE].source_info.span; let output_span = body.local_decls[RETURN_PLACE].source_info.span;
if let Err(terr) = self.eq_opaque_type_and_type( if let Err(terr) = self.eq_opaque_type_and_type(

View File

@ -1291,10 +1291,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
concrete_is_opaque concrete_is_opaque
); );
// concrete_is_opaque is `true` when we're using an existential // concrete_is_opaque is `true` when we're using an opaque `impl Trait`
// type without 'revealing' it. For example, code like this: // type without 'revealing' it. For example, code like this:
// //
// existential type Foo: Debug; // type Foo = impl Debug;
// fn foo1() -> Foo { ... } // fn foo1() -> Foo { ... }
// fn foo2() -> Foo { foo1() } // fn foo2() -> Foo { foo1() }
// //
@ -1303,8 +1303,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// //
// When this occurs, we do *not* want to try to equate // When this occurs, we do *not* want to try to equate
// the concrete type with the underlying defining type // the concrete type with the underlying defining type
// of the existential type - this will always fail, since // of the opaque type - this will always fail, since
// the defining type of an existential type is always // the defining type of an opaque type is always
// some other type (e.g. not itself) // some other type (e.g. not itself)
// Essentially, none of the normal obligations apply here - // Essentially, none of the normal obligations apply here -
// we're just passing around some unknown opaque type, // we're just passing around some unknown opaque type,

View File

@ -972,7 +972,7 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> {
hir::ItemKind::Ty(..) | hir::ItemKind::Ty(..) |
hir::ItemKind::Trait(..) | hir::ItemKind::Trait(..) |
hir::ItemKind::TraitAlias(..) | hir::ItemKind::TraitAlias(..) |
hir::ItemKind::Existential(..) | hir::ItemKind::OpaqueTy(..) |
hir::ItemKind::Mod(..) => { hir::ItemKind::Mod(..) => {
// Nothing to do, just keep recursing... // Nothing to do, just keep recursing...
} }

View File

@ -667,7 +667,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
"unions cannot have zero fields"); "unions cannot have zero fields");
} }
} }
ItemKind::Existential(ref bounds, _) => { ItemKind::OpaqueTy(ref bounds, _) => {
if !bounds.iter() if !bounds.iter()
.any(|b| if let GenericBound::Trait(..) = *b { true } else { false }) { .any(|b| if let GenericBound::Trait(..) = *b { true } else { false }) {
let msp = MultiSpan::from_spans(bounds.iter() let msp = MultiSpan::from_spans(bounds.iter()

View File

@ -533,7 +533,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
hir::ItemKind::GlobalAsm(..) | hir::ItemKind::Fn(..) | hir::ItemKind::Mod(..) | hir::ItemKind::GlobalAsm(..) | hir::ItemKind::Fn(..) | hir::ItemKind::Mod(..) |
hir::ItemKind::Static(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Static(..) | hir::ItemKind::Struct(..) |
hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) | hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) |
hir::ItemKind::Existential(..) | hir::ItemKind::OpaqueTy(..) |
hir::ItemKind::Ty(..) | hir::ItemKind::Union(..) | hir::ItemKind::Use(..) => { hir::ItemKind::Ty(..) | hir::ItemKind::Union(..) | hir::ItemKind::Use(..) => {
if item.vis.node.is_pub() { self.prev_level } else { None } if item.vis.node.is_pub() { self.prev_level } else { None }
} }
@ -584,7 +584,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
} }
} }
} }
hir::ItemKind::Existential(..) | hir::ItemKind::OpaqueTy(..) |
hir::ItemKind::Use(..) | hir::ItemKind::Use(..) |
hir::ItemKind::Static(..) | hir::ItemKind::Static(..) |
hir::ItemKind::Const(..) | hir::ItemKind::Const(..) |
@ -612,7 +612,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
} }
// The interface is empty. // The interface is empty.
hir::ItemKind::GlobalAsm(..) => {} hir::ItemKind::GlobalAsm(..) => {}
hir::ItemKind::Existential(..) => { hir::ItemKind::OpaqueTy(..) => {
// FIXME: This is some serious pessimization intended to workaround deficiencies // FIXME: This is some serious pessimization intended to workaround deficiencies
// in the reachability pass (`middle/reachable.rs`). Types are marked as link-time // in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
// reachable if they are returned via `impl Trait`, even from private functions. // reachable if they are returned via `impl Trait`, even from private functions.
@ -1113,7 +1113,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
DefKind::Method DefKind::Method
| DefKind::AssocConst | DefKind::AssocConst
| DefKind::AssocTy | DefKind::AssocTy
| DefKind::AssocExistential | DefKind::AssocOpaqueTy
| DefKind::Static => true, | DefKind::Static => true,
_ => false, _ => false,
} }
@ -1370,7 +1370,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
self.access_levels.is_reachable( self.access_levels.is_reachable(
impl_item_ref.id.hir_id) impl_item_ref.id.hir_id)
} }
hir::ImplItemKind::Existential(..) | hir::ImplItemKind::OpaqueTy(..) |
hir::ImplItemKind::Type(_) => false, hir::ImplItemKind::Type(_) => false,
} }
}); });
@ -1707,9 +1707,9 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> {
let (check_ty, is_assoc_ty) = match assoc_item_kind { let (check_ty, is_assoc_ty) = match assoc_item_kind {
AssocItemKind::Const | AssocItemKind::Method { .. } => (true, false), AssocItemKind::Const | AssocItemKind::Method { .. } => (true, false),
AssocItemKind::Type => (defaultness.has_value(), true), AssocItemKind::Type => (defaultness.has_value(), true),
// `ty()` for existential types is the underlying type, // `ty()` for opaque types is the underlying type,
// it's not a part of interface, so we skip it. // it's not a part of interface, so we skip it.
AssocItemKind::Existential => (false, true), AssocItemKind::OpaqueTy => (false, true),
}; };
check.in_assoc_ty = is_assoc_ty; check.in_assoc_ty = is_assoc_ty;
check.generics().predicates(); check.generics().predicates();
@ -1742,8 +1742,8 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx>
hir::ItemKind::Fn(..) | hir::ItemKind::Ty(..) => { hir::ItemKind::Fn(..) | hir::ItemKind::Ty(..) => {
self.check(item.hir_id, item_visibility).generics().predicates().ty(); self.check(item.hir_id, item_visibility).generics().predicates().ty();
} }
hir::ItemKind::Existential(..) => { hir::ItemKind::OpaqueTy(..) => {
// `ty()` for existential types is the underlying type, // `ty()` for opaque types is the underlying type,
// it's not a part of interface, so we skip it. // it's not a part of interface, so we skip it.
self.check(item.hir_id, item_visibility).generics().predicates(); self.check(item.hir_id, item_visibility).generics().predicates();
} }

View File

@ -464,8 +464,8 @@ impl<'a> Resolver<'a> {
self.define(parent, ident, TypeNS, (res, vis, sp, expansion)); self.define(parent, ident, TypeNS, (res, vis, sp, expansion));
} }
ItemKind::Existential(_, _) => { ItemKind::OpaqueTy(_, _) => {
let res = Res::Def(DefKind::Existential, self.definitions.local_def_id(item.id)); let res = Res::Def(DefKind::OpaqueTy, self.definitions.local_def_id(item.id));
self.define(parent, ident, TypeNS, (res, vis, sp, expansion)); self.define(parent, ident, TypeNS, (res, vis, sp, expansion));
} }
@ -656,7 +656,7 @@ impl<'a> Resolver<'a> {
Res::Def(DefKind::Variant, _) Res::Def(DefKind::Variant, _)
| Res::Def(DefKind::TyAlias, _) | Res::Def(DefKind::TyAlias, _)
| Res::Def(DefKind::ForeignTy, _) | Res::Def(DefKind::ForeignTy, _)
| Res::Def(DefKind::Existential, _) | Res::Def(DefKind::OpaqueTy, _)
| Res::Def(DefKind::TraitAlias, _) | Res::Def(DefKind::TraitAlias, _)
| Res::PrimTy(..) | Res::PrimTy(..)
| Res::ToolMod => { | Res::ToolMod => {

View File

@ -605,7 +605,7 @@ impl<'a> PathSource<'a> {
| Res::PrimTy(..) | Res::PrimTy(..)
| Res::Def(DefKind::TyParam, _) | Res::Def(DefKind::TyParam, _)
| Res::SelfTy(..) | Res::SelfTy(..)
| Res::Def(DefKind::Existential, _) | Res::Def(DefKind::OpaqueTy, _)
| Res::Def(DefKind::ForeignTy, _) => true, | Res::Def(DefKind::ForeignTy, _) => true,
_ => false, _ => false,
}, },
@ -2710,7 +2710,7 @@ impl<'a> Resolver<'a> {
match item.node { match item.node {
ItemKind::Ty(_, ref generics) | ItemKind::Ty(_, ref generics) |
ItemKind::Existential(_, ref generics) | ItemKind::OpaqueTy(_, ref generics) |
ItemKind::Fn(_, _, ref generics, _) => { ItemKind::Fn(_, _, ref generics, _) => {
self.with_generic_param_rib( self.with_generic_param_rib(
HasGenericParams(generics, ItemRibKind), HasGenericParams(generics, ItemRibKind),
@ -3089,7 +3089,7 @@ impl<'a> Resolver<'a> {
this.visit_ty(ty); this.visit_ty(ty);
} }
ImplItemKind::Existential(ref bounds) => { ImplItemKind::OpaqueTy(ref bounds) => {
// If this is a trait impl, ensure the type // If this is a trait impl, ensure the type
// exists in trait // exists in trait
this.check_trait_item(impl_item.ident, this.check_trait_item(impl_item.ident,

View File

@ -1173,7 +1173,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
// trait. // trait.
self.visit_ty(ty) self.visit_ty(ty)
} }
ast::ImplItemKind::Existential(ref bounds) => { ast::ImplItemKind::OpaqueTy(ref bounds) => {
// FIXME: uses of the assoc type should ideally point to this // FIXME: uses of the assoc type should ideally point to this
// 'def' and the name here should be a ref to the def in the // 'def' and the name here should be a ref to the def in the
// trait. // trait.
@ -1428,7 +1428,7 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
self.visit_ty(&ty); self.visit_ty(&ty);
self.process_generic_params(ty_params, &qualname, item.id); self.process_generic_params(ty_params, &qualname, item.id);
} }
Existential(ref _bounds, ref ty_params) => { OpaqueTy(ref _bounds, ref ty_params) => {
let qualname = format!("::{}", let qualname = format!("::{}",
self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id))); self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)));
// FIXME do something with _bounds // FIXME do something with _bounds

View File

@ -725,10 +725,10 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
Res::Def(HirDefKind::TyAlias, def_id) | Res::Def(HirDefKind::TyAlias, def_id) |
Res::Def(HirDefKind::ForeignTy, def_id) | Res::Def(HirDefKind::ForeignTy, def_id) |
Res::Def(HirDefKind::TraitAlias, def_id) | Res::Def(HirDefKind::TraitAlias, def_id) |
Res::Def(HirDefKind::AssocExistential, def_id) | Res::Def(HirDefKind::AssocOpaqueTy, def_id) |
Res::Def(HirDefKind::AssocTy, def_id) | Res::Def(HirDefKind::AssocTy, def_id) |
Res::Def(HirDefKind::Trait, def_id) | Res::Def(HirDefKind::Trait, def_id) |
Res::Def(HirDefKind::Existential, def_id) | Res::Def(HirDefKind::OpaqueTy, def_id) |
Res::Def(HirDefKind::TyParam, def_id) => { Res::Def(HirDefKind::TyParam, def_id) => {
Some(Ref { Some(Ref {
kind: RefKind::Type, kind: RefKind::Type,

View File

@ -438,12 +438,12 @@ impl Sig for ast::Item {
refs: vec![], refs: vec![],
}) })
} }
ast::ItemKind::Existential(ref bounds, ref generics) => { ast::ItemKind::OpaqueTy(ref bounds, ref generics) => {
let text = "existential type ".to_owned(); let text = "type ".to_owned();
let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?; let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?;
if !bounds.is_empty() { if !bounds.is_empty() {
sig.text.push_str(": "); sig.text.push_str(" = impl ");
sig.text.push_str(&pprust::bounds_to_string(bounds)); sig.text.push_str(&pprust::bounds_to_string(bounds));
} }
sig.text.push(';'); sig.text.push(';');

View File

@ -173,7 +173,7 @@ crate fn program_clauses_for(tcx: TyCtxt<'_>, def_id: DefId) -> Clauses<'_> {
| Some(DefKind::Enum) | Some(DefKind::Enum)
| Some(DefKind::TyAlias) | Some(DefKind::TyAlias)
| Some(DefKind::Union) | Some(DefKind::Union)
| Some(DefKind::Existential) => program_clauses_for_type_def(tcx, def_id), | Some(DefKind::OpaqueTy) => program_clauses_for_type_def(tcx, def_id),
_ => List::empty(), _ => List::empty(),
}, },
DefPathData::Impl => program_clauses_for_impl(tcx, def_id), DefPathData::Impl => program_clauses_for_impl(tcx, def_id),

View File

@ -1956,7 +1956,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let span = path.span; let span = path.span;
match path.res { match path.res {
Res::Def(DefKind::Existential, did) => { Res::Def(DefKind::OpaqueTy, did) => {
// Check for desugared `impl Trait`. // Check for desugared `impl Trait`.
assert!(ty::is_impl_trait_defn(tcx, did).is_none()); assert!(ty::is_impl_trait_defn(tcx, did).is_none());
let item_segment = path.segments.split_last().unwrap(); let item_segment = path.segments.split_last().unwrap();

View File

@ -1489,7 +1489,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
match self.mode { match self.mode {
Mode::MethodCall => item.method_has_self_argument, Mode::MethodCall => item.method_has_self_argument,
Mode::Path => match item.kind { Mode::Path => match item.kind {
ty::AssocKind::Existential | ty::AssocKind::OpaqueTy |
ty::AssocKind::Type => false, ty::AssocKind::Type => false,
ty::AssocKind::Method | ty::AssocKind::Const => true ty::AssocKind::Method | ty::AssocKind::Const => true
}, },

View File

@ -1330,10 +1330,10 @@ fn check_opaque<'tcx>(
def_id: DefId, def_id: DefId,
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
span: Span, span: Span,
origin: &hir::ExistTyOrigin origin: &hir::OpaqueTyOrigin
) { ) {
if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id, substs) { if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id, substs) {
if let hir::ExistTyOrigin::AsyncFn = origin { if let hir::OpaqueTyOrigin::AsyncFn = origin {
struct_span_err!( struct_span_err!(
tcx.sess, span, E0733, tcx.sess, span, E0733,
"recursion in an `async fn` requires boxing", "recursion in an `async fn` requires boxing",
@ -1403,7 +1403,7 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
hir::ItemKind::Union(..) => { hir::ItemKind::Union(..) => {
check_union(tcx, it.hir_id, it.span); check_union(tcx, it.hir_id, it.span);
} }
hir::ItemKind::Existential(hir::ExistTy{origin, ..}) => { hir::ItemKind::OpaqueTy(hir::ExistTy{origin, ..}) => {
let def_id = tcx.hir().local_def_id(it.hir_id); let def_id = tcx.hir().local_def_id(it.hir_id);
let substs = InternalSubsts::identity_for_item(tcx, def_id); let substs = InternalSubsts::identity_for_item(tcx, def_id);
@ -1542,7 +1542,7 @@ fn check_specialization_validity<'tcx>(
let kind = match impl_item.node { let kind = match impl_item.node {
hir::ImplItemKind::Const(..) => ty::AssocKind::Const, hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
hir::ImplItemKind::Method(..) => ty::AssocKind::Method, hir::ImplItemKind::Method(..) => ty::AssocKind::Method,
hir::ImplItemKind::Existential(..) => ty::AssocKind::Existential, hir::ImplItemKind::OpaqueTy(..) => ty::AssocKind::OpaqueTy,
hir::ImplItemKind::Type(_) => ty::AssocKind::Type hir::ImplItemKind::Type(_) => ty::AssocKind::Type
}; };
@ -1639,7 +1639,7 @@ fn check_impl_items_against_trait<'tcx>(
err.emit() err.emit()
} }
} }
hir::ImplItemKind::Existential(..) | hir::ImplItemKind::OpaqueTy(..) |
hir::ImplItemKind::Type(_) => { hir::ImplItemKind::Type(_) => {
if ty_trait_item.kind == ty::AssocKind::Type { if ty_trait_item.kind == ty::AssocKind::Type {
if ty_trait_item.defaultness.has_value() { if ty_trait_item.defaultness.has_value() {

View File

@ -8,7 +8,7 @@ use rustc::ty::subst::{Subst, InternalSubsts};
use rustc::util::nodemap::{FxHashSet, FxHashMap}; use rustc::util::nodemap::{FxHashSet, FxHashMap};
use rustc::mir::interpret::ConstValue; use rustc::mir::interpret::ConstValue;
use rustc::middle::lang_items; use rustc::middle::lang_items;
use rustc::infer::opaque_types::may_define_existential_type; use rustc::infer::opaque_types::may_define_opaque_type;
use syntax::ast; use syntax::ast;
use syntax::feature_gate::{self, GateIssue}; use syntax::feature_gate::{self, GateIssue};
@ -218,8 +218,8 @@ fn check_associated_item(
fcx.register_wf_obligation(ty, span, code.clone()); fcx.register_wf_obligation(ty, span, code.clone());
} }
} }
ty::AssocKind::Existential => { ty::AssocKind::OpaqueTy => {
// do nothing, existential types check themselves // do nothing, opaque types check themselves
} }
} }
@ -560,7 +560,7 @@ fn check_where_clauses<'tcx, 'fcx>(
let mut predicates = predicates.instantiate_identity(fcx.tcx); let mut predicates = predicates.instantiate_identity(fcx.tcx);
if let Some(return_ty) = return_ty { if let Some(return_ty) = return_ty {
predicates.predicates.extend(check_existential_types(tcx, fcx, def_id, span, return_ty)); predicates.predicates.extend(check_opaque_types(tcx, fcx, def_id, span, return_ty));
} }
let predicates = fcx.normalize_associated_types_in(span, &predicates); let predicates = fcx.normalize_associated_types_in(span, &predicates);
@ -605,14 +605,14 @@ fn check_fn_or_method<'fcx, 'tcx>(
check_where_clauses(tcx, fcx, span, def_id, Some(sig.output())); check_where_clauses(tcx, fcx, span, def_id, Some(sig.output()));
} }
/// Checks "defining uses" of existential types to ensure that they meet the restrictions laid for /// Checks "defining uses" of opaque `impl Trait` types to ensure that they meet the restrictions
/// "higher-order pattern unification". /// laid for "higher-order pattern unification".
/// This ensures that inference is tractable. /// This ensures that inference is tractable.
/// In particular, definitions of existential types can only use other generics as arguments, /// In particular, definitions of opaque types can only use other generics as arguments,
/// and they cannot repeat an argument. Example: /// and they cannot repeat an argument. Example:
/// ///
/// ```rust /// ```rust
/// existential type Foo<A, B>; /// type Foo<A, B> = impl Bar<A, B>;
/// ///
/// // Okay -- `Foo` is applied to two distinct, generic types. /// // Okay -- `Foo` is applied to two distinct, generic types.
/// fn a<T, U>() -> Foo<T, U> { .. } /// fn a<T, U>() -> Foo<T, U> { .. }
@ -624,26 +624,26 @@ fn check_fn_or_method<'fcx, 'tcx>(
/// fn b<T>() -> Foo<T, u32> { .. } /// fn b<T>() -> Foo<T, u32> { .. }
/// ``` /// ```
/// ///
fn check_existential_types<'fcx, 'tcx>( fn check_opaque_types<'fcx, 'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
fcx: &FnCtxt<'fcx, 'tcx>, fcx: &FnCtxt<'fcx, 'tcx>,
fn_def_id: DefId, fn_def_id: DefId,
span: Span, span: Span,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> Vec<ty::Predicate<'tcx>> { ) -> Vec<ty::Predicate<'tcx>> {
trace!("check_existential_types(ty={:?})", ty); trace!("check_opaque_types(ty={:?})", ty);
let mut substituted_predicates = Vec::new(); let mut substituted_predicates = Vec::new();
ty.fold_with(&mut ty::fold::BottomUpFolder { ty.fold_with(&mut ty::fold::BottomUpFolder {
tcx: fcx.tcx, tcx: fcx.tcx,
ty_op: |ty| { ty_op: |ty| {
if let ty::Opaque(def_id, substs) = ty.sty { if let ty::Opaque(def_id, substs) = ty.sty {
trace!("check_existential_types: opaque_ty, {:?}, {:?}", def_id, substs); trace!("check_opaque_types: opaque_ty, {:?}, {:?}", def_id, substs);
let generics = tcx.generics_of(def_id); let generics = tcx.generics_of(def_id);
// Only check named existential types defined in this crate. // Only check named `impl Trait` types defined in this crate.
if generics.parent.is_none() && def_id.is_local() { if generics.parent.is_none() && def_id.is_local() {
let opaque_hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); let opaque_hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
if may_define_existential_type(tcx, fn_def_id, opaque_hir_id) { if may_define_opaque_type(tcx, fn_def_id, opaque_hir_id) {
trace!("check_existential_types: may define, generics={:#?}", generics); trace!("check_opaque_types: may define, generics={:#?}", generics);
let mut seen: FxHashMap<_, Vec<_>> = FxHashMap::default(); let mut seen: FxHashMap<_, Vec<_>> = FxHashMap::default();
for (subst, param) in substs.iter().zip(&generics.params) { for (subst, param) in substs.iter().zip(&generics.params) {
match subst.unpack() { match subst.unpack() {
@ -654,7 +654,7 @@ fn check_existential_types<'fcx, 'tcx>(
tcx.sess tcx.sess
.struct_span_err( .struct_span_err(
span, span,
"non-defining existential type use \ "non-defining opaque type use \
in defining scope", in defining scope",
) )
.span_note( .span_note(
@ -676,14 +676,14 @@ fn check_existential_types<'fcx, 'tcx>(
.sess .sess
.struct_span_err( .struct_span_err(
span, span,
"non-defining existential type use \ "non-defining opaque type use \
in defining scope", in defining scope",
) )
.span_label( .span_label(
param_span, param_span,
"cannot use static lifetime, use a bound lifetime \ "cannot use static lifetime; use a bound lifetime \
instead or remove the lifetime parameter from the \ instead or remove the lifetime parameter from the \
existential type", opaque type",
) )
.emit(); .emit();
} else { } else {
@ -697,7 +697,7 @@ fn check_existential_types<'fcx, 'tcx>(
tcx.sess tcx.sess
.struct_span_err( .struct_span_err(
span, span,
"non-defining existential type use \ "non-defining opaque type use \
in defining scope", in defining scope",
) )
.span_note( .span_note(
@ -719,7 +719,7 @@ fn check_existential_types<'fcx, 'tcx>(
.sess .sess
.struct_span_err( .struct_span_err(
span, span,
"non-defining existential type use \ "non-defining opaque type use \
in defining scope", in defining scope",
). ).
span_note( span_note(
@ -729,21 +729,21 @@ fn check_existential_types<'fcx, 'tcx>(
.emit(); .emit();
} }
} }
} // if may_define_existential_type } // if may_define_opaque_type
// Now register the bounds on the parameters of the existential type // Now register the bounds on the parameters of the opaque type
// so the parameters given by the function need to fulfill them. // so the parameters given by the function need to fulfill them.
// //
// existential type Foo<T: Bar>: 'static; // type Foo<T: Bar> = impl Baz + 'static;
// fn foo<U>() -> Foo<U> { .. *} // fn foo<U>() -> Foo<U> { .. *}
// //
// becomes // becomes
// //
// existential type Foo<T: Bar>: 'static; // type Foo<T: Bar> = impl Baz + 'static;
// fn foo<U: Bar>() -> Foo<U> { .. *} // fn foo<U: Bar>() -> Foo<U> { .. *}
let predicates = tcx.predicates_of(def_id); let predicates = tcx.predicates_of(def_id);
trace!( trace!(
"check_existential_types: may define, predicates={:#?}", "check_opaque_types: may define, predicates={:#?}",
predicates, predicates,
); );
for &(pred, _) in predicates.predicates.iter() { for &(pred, _) in predicates.predicates.iter() {
@ -753,7 +753,7 @@ fn check_existential_types<'fcx, 'tcx>(
substituted_predicates.push(substituted_pred); substituted_predicates.push(substituted_pred);
} }
} }
} // if is_named_existential_type } // if is_named_opaque_type
} // if let Opaque } // if let Opaque
ty ty
}, },

View File

@ -443,10 +443,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
// * `fn foo<T: Bound + Other>() -> Foo<T>` // * `fn foo<T: Bound + Other>() -> Foo<T>`
// from being defining. // from being defining.
// Also replace all generic params with the ones from the existential type // Also replace all generic params with the ones from the opaque type
// definition so that // definition so that
// ```rust // ```rust
// existential type Foo<T>: 'static; // type Foo<T> = impl Baz + 'static;
// fn foo<U>() -> Foo<U> { .. } // fn foo<U>() -> Foo<U> { .. }
// ``` // ```
// figures out the concrete type with `U`, but the stored type is with `T`. // figures out the concrete type with `U`, but the stored type is with `T`.
@ -464,8 +464,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
} }
if !opaque_defn.substs.has_local_value() { if !opaque_defn.substs.has_local_value() {
// We only want to add an entry into `concrete_existential_types` // We only want to add an entry into `concrete_opaque_types`
// if we actually found a defining usage of this existential type. // if we actually found a defining usage of this opaque type.
// Otherwise, we do nothing - we'll either find a defining usage // Otherwise, we do nothing - we'll either find a defining usage
// in some other location, or we'll end up emitting an error due // in some other location, or we'll end up emitting an error due
// to the lack of defining usage // to the lack of defining usage
@ -476,14 +476,14 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
}; };
let old = self.tables let old = self.tables
.concrete_existential_types .concrete_opaque_types
.insert(def_id, new); .insert(def_id, new);
if let Some(old) = old { if let Some(old) = old {
if old.concrete_type != definition_ty || old.substs != opaque_defn.substs { if old.concrete_type != definition_ty || old.substs != opaque_defn.substs {
span_bug!( span_bug!(
span, span,
"visit_opaque_types tried to write different types for the same \ "visit_opaque_types tried to write different types for the same \
existential type: {:?}, {:?}, {:?}, {:?}", opaque type: {:?}, {:?}, {:?}, {:?}",
def_id, def_id,
definition_ty, definition_ty,
opaque_defn, opaque_defn,

View File

@ -294,7 +294,7 @@ fn type_param_predicates(
ItemKind::Fn(.., ref generics, _) ItemKind::Fn(.., ref generics, _)
| ItemKind::Impl(_, _, _, ref generics, ..) | ItemKind::Impl(_, _, _, ref generics, ..)
| ItemKind::Ty(_, ref generics) | ItemKind::Ty(_, ref generics)
| ItemKind::Existential(ExistTy { | ItemKind::OpaqueTy(ExistTy {
ref generics, ref generics,
impl_trait_fn: None, impl_trait_fn: None,
.. ..
@ -456,12 +456,12 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::HirId) {
} }
// Desugared from `impl Trait`, so visited by the function's return type. // Desugared from `impl Trait`, so visited by the function's return type.
hir::ItemKind::Existential(hir::ExistTy { hir::ItemKind::OpaqueTy(hir::ExistTy {
impl_trait_fn: Some(_), impl_trait_fn: Some(_),
.. ..
}) => {} }) => {}
hir::ItemKind::Existential(..) hir::ItemKind::OpaqueTy(..)
| hir::ItemKind::Ty(..) | hir::ItemKind::Ty(..)
| hir::ItemKind::Static(..) | hir::ItemKind::Static(..)
| hir::ItemKind::Const(..) | hir::ItemKind::Const(..)
@ -896,7 +896,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics {
.. ..
}) => Some(tcx.closure_base_def_id(def_id)), }) => Some(tcx.closure_base_def_id(def_id)),
Node::Item(item) => match item.node { Node::Item(item) => match item.node {
ItemKind::Existential(hir::ExistTy { impl_trait_fn, .. }) => impl_trait_fn, ItemKind::OpaqueTy(hir::ExistTy { impl_trait_fn, .. }) => impl_trait_fn,
_ => None, _ => None,
}, },
_ => None, _ => None,
@ -920,7 +920,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics {
ItemKind::Ty(_, ref generics) ItemKind::Ty(_, ref generics)
| ItemKind::Enum(_, ref generics) | ItemKind::Enum(_, ref generics)
| ItemKind::Struct(_, ref generics) | ItemKind::Struct(_, ref generics)
| ItemKind::Existential(hir::ExistTy { ref generics, .. }) | ItemKind::OpaqueTy(hir::ExistTy { ref generics, .. })
| ItemKind::Union(_, ref generics) => { | ItemKind::Union(_, ref generics) => {
allow_defaults = true; allow_defaults = true;
generics generics
@ -1210,7 +1210,7 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
icx.to_ty(ty) icx.to_ty(ty)
} }
}, },
ImplItemKind::Existential(_) => { ImplItemKind::OpaqueTy(_) => {
if tcx if tcx
.impl_trait_ref(tcx.hir().get_parent_did(hir_id)) .impl_trait_ref(tcx.hir().get_parent_did(hir_id))
.is_none() .is_none()
@ -1218,7 +1218,7 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
report_assoc_ty_on_inherent_impl(tcx, item.span); 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) => { ImplItemKind::Type(ref ty) => {
if tcx if tcx
@ -1253,27 +1253,27 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
let substs = InternalSubsts::identity_for_item(tcx, def_id); let substs = InternalSubsts::identity_for_item(tcx, def_id);
tcx.mk_adt(def, substs) tcx.mk_adt(def, substs)
} }
ItemKind::Existential(hir::ExistTy { ItemKind::OpaqueTy(hir::ExistTy {
impl_trait_fn: None, impl_trait_fn: None,
.. ..
}) => find_existential_constraints(tcx, def_id), }) => find_opaque_ty_constraints(tcx, def_id),
// Existential types desugared from `impl Trait`. // Opaque types desugared from `impl Trait`.
ItemKind::Existential(hir::ExistTy { ItemKind::OpaqueTy(hir::ExistTy {
impl_trait_fn: Some(owner), impl_trait_fn: Some(owner),
.. ..
}) => { }) => {
tcx.typeck_tables_of(owner) tcx.typeck_tables_of(owner)
.concrete_existential_types .concrete_opaque_types
.get(&def_id) .get(&def_id)
.map(|opaque| opaque.concrete_type) .map(|opaque| opaque.concrete_type)
.unwrap_or_else(|| { .unwrap_or_else(|| {
// This can occur if some error in the // This can occur if some error in the
// owner fn prevented us from populating // owner fn prevented us from populating
// the `concrete_existential_types` table. // the `concrete_opaque_types` table.
tcx.sess.delay_span_bug( tcx.sess.delay_span_bug(
DUMMY_SP, DUMMY_SP,
&format!( &format!(
"owner {:?} has no existential type for {:?} in its tables", "owner {:?} has no opaque type for {:?} in its tables",
owner, def_id, owner, def_id,
), ),
); );
@ -1505,20 +1505,20 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
}) })
} }
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}; use rustc::hir::{ImplItem, Item, TraitItem};
debug!("find_existential_constraints({:?})", def_id); debug!("find_opaque_ty_constraints({:?})", def_id);
struct ConstraintLocator<'tcx> { struct ConstraintLocator<'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
def_id: DefId, 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) // 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 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>)>, found: Option<(Span, Ty<'tcx>, Vec<usize>)>,
} }
@ -1527,7 +1527,7 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
// Don't try to check items that cannot possibly constrain the type. // Don't try to check items that cannot possibly constrain the type.
if !self.tcx.has_typeck_tables(def_id) { if !self.tcx.has_typeck_tables(def_id) {
debug!( debug!(
"find_existential_constraints: no constraint for `{:?}` at `{:?}`: no tables", "find_opaque_ty_constraints: no constraint for `{:?}` at `{:?}`: no tables",
self.def_id, self.def_id,
def_id, def_id,
); );
@ -1536,11 +1536,11 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
let ty = self let ty = self
.tcx .tcx
.typeck_tables_of(def_id) .typeck_tables_of(def_id)
.concrete_existential_types .concrete_opaque_types
.get(&self.def_id); .get(&self.def_id);
if let Some(ty::ResolvedOpaqueTy { concrete_type, substs }) = ty { if let Some(ty::ResolvedOpaqueTy { concrete_type, substs }) = ty {
debug!( debug!(
"find_existential_constraints: found constraint for `{:?}` at `{:?}`: {:?}", "find_opaque_ty_constraints: found constraint for `{:?}` at `{:?}`: {:?}",
self.def_id, self.def_id,
def_id, def_id,
ty, ty,
@ -1561,7 +1561,7 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
self.tcx.sess.span_err( self.tcx.sess.span_err(
span, span,
&format!( &format!(
"defining existential type use restricts existential \ "defining opaque type use restricts opaque \
type by using the generic parameter `{}` twice", type by using the generic parameter `{}` twice",
p.name p.name
), ),
@ -1572,14 +1572,14 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
self.tcx.sess.delay_span_bug( self.tcx.sess.delay_span_bug(
span, span,
&format!( &format!(
"non-defining exist ty use in defining scope: {:?}, {:?}", "non-defining opaque ty use in defining scope: {:?}, {:?}",
concrete_type, substs, 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. // the concrete type.
let indices = concrete_type let indices = concrete_type
.subst(self.tcx, substs) .subst(self.tcx, substs)
@ -1595,7 +1595,7 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
if !substs.types().all(is_param) { if !substs.types().all(is_param) {
self.tcx.sess.span_err( self.tcx.sess.span_err(
span, 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 { } else if let Some((prev_span, prev_ty, ref prev_indices)) = self.found {
let mut ty = concrete_type.walk().fuse(); let mut ty = concrete_type.walk().fuse();
@ -1608,11 +1608,11 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
_ => t == p, _ => t == p,
}); });
if !iter_eq || ty.next().is_some() || p_ty.next().is_some() { if !iter_eq || ty.next().is_some() || p_ty.next().is_some() {
debug!("find_existential_constraints: span={:?}", span); debug!("find_opaque_ty_constraints: span={:?}", span);
// Found different concrete types for the existential type. // Found different concrete types for the opaque type.
let mut err = self.tcx.sess.struct_span_err( let mut err = self.tcx.sess.struct_span_err(
span, span,
"concrete type differs from previous defining existential type use", "concrete type differs from previous defining opaque type use",
); );
err.span_label( err.span_label(
span, span,
@ -1651,7 +1651,7 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
} }
} else { } else {
debug!( debug!(
"find_existential_constraints: no constraint for `{:?}` at `{:?}`", "find_opaque_ty_constraints: no constraint for `{:?}` at `{:?}`",
self.def_id, self.def_id,
def_id, def_id,
); );
@ -1666,7 +1666,7 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
fn visit_item(&mut self, it: &'tcx Item) { fn visit_item(&mut self, it: &'tcx Item) {
debug!("find_existential_constraints: visiting {:?}", it); debug!("find_existential_constraints: visiting {:?}", it);
let def_id = self.tcx.hir().local_def_id(it.hir_id); 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 { if def_id != self.def_id {
self.check(def_id); self.check(def_id);
intravisit::walk_item(self, it); intravisit::walk_item(self, it);
@ -1675,7 +1675,7 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
fn visit_impl_item(&mut self, it: &'tcx ImplItem) { fn visit_impl_item(&mut self, it: &'tcx ImplItem) {
debug!("find_existential_constraints: visiting {:?}", it); debug!("find_existential_constraints: visiting {:?}", it);
let def_id = self.tcx.hir().local_def_id(it.hir_id); 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 { if def_id != self.def_id {
self.check(def_id); self.check(def_id);
intravisit::walk_impl_item(self, it); intravisit::walk_impl_item(self, it);
@ -1699,12 +1699,12 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
found: None, found: None,
}; };
debug!("find_existential_constraints: scope={:?}", scope); debug!("find_opaque_ty_constraints: scope={:?}", scope);
if scope == hir::CRATE_HIR_ID { if scope == hir::CRATE_HIR_ID {
intravisit::walk_crate(&mut locator, tcx.hir().krate()); intravisit::walk_crate(&mut locator, tcx.hir().krate());
} else { } 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) { match tcx.hir().get(scope) {
// We explicitly call `visit_*` methods, instead of using `intravisit::walk_*` methods // We explicitly call `visit_*` methods, instead of using `intravisit::walk_*` methods
// This allows our visitor to process the defining item itself, causing // This allows our visitor to process the defining item itself, causing
@ -1724,7 +1724,7 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
Node::ImplItem(ref it) => locator.visit_impl_item(it), Node::ImplItem(ref it) => locator.visit_impl_item(it),
Node::TraitItem(ref it) => locator.visit_trait_item(it), Node::TraitItem(ref it) => locator.visit_trait_item(it),
other => bug!( other => bug!(
"{:?} is not a valid scope for an existential type item", "{:?} is not a valid scope for an opaque type item",
other other
), ),
} }
@ -2010,7 +2010,7 @@ fn explicit_predicates_of(
Node::TraitItem(item) => &item.generics, Node::TraitItem(item) => &item.generics,
Node::ImplItem(item) => match item.node { Node::ImplItem(item) => match item.node {
ImplItemKind::Existential(ref bounds) => { ImplItemKind::OpaqueTy(ref bounds) => {
let substs = InternalSubsts::identity_for_item(tcx, def_id); let substs = InternalSubsts::identity_for_item(tcx, def_id);
let opaque_ty = tcx.mk_opaque(def_id, substs); let opaque_ty = tcx.mk_opaque(def_id, substs);
@ -2051,7 +2051,7 @@ fn explicit_predicates_of(
is_trait = Some((ty::TraitRef::identity(tcx, def_id), &empty_trait_items)); is_trait = Some((ty::TraitRef::identity(tcx, def_id), &empty_trait_items));
generics generics
} }
ItemKind::Existential(ExistTy { ItemKind::OpaqueTy(ExistTy {
ref bounds, ref bounds,
impl_trait_fn, impl_trait_fn,
ref generics, ref generics,
@ -2077,7 +2077,7 @@ fn explicit_predicates_of(
predicates: bounds_predicates, predicates: bounds_predicates,
}); });
} else { } else {
// named existential types // named opaque types
predicates.extend(bounds_predicates); predicates.extend(bounds_predicates);
generics generics
} }

View File

@ -11,7 +11,7 @@ pub enum Namespace {
impl From<ty::AssocKind> for Namespace { impl From<ty::AssocKind> for Namespace {
fn from(a_kind: ty::AssocKind) -> Self { fn from(a_kind: ty::AssocKind) -> Self {
match a_kind { match a_kind {
ty::AssocKind::Existential | ty::AssocKind::OpaqueTy |
ty::AssocKind::Type => Namespace::Type, ty::AssocKind::Type => Namespace::Type,
ty::AssocKind::Const | ty::AssocKind::Const |
ty::AssocKind::Method => Namespace::Value, ty::AssocKind::Method => Namespace::Value,
@ -22,7 +22,7 @@ impl From<ty::AssocKind> for Namespace {
impl<'a> From <&'a hir::ImplItemKind> for Namespace { impl<'a> From <&'a hir::ImplItemKind> for Namespace {
fn from(impl_kind: &'a hir::ImplItemKind) -> Self { fn from(impl_kind: &'a hir::ImplItemKind) -> Self {
match *impl_kind { match *impl_kind {
hir::ImplItemKind::Existential(..) | hir::ImplItemKind::OpaqueTy(..) |
hir::ImplItemKind::Type(..) => Namespace::Type, hir::ImplItemKind::Type(..) => Namespace::Type,
hir::ImplItemKind::Const(..) | hir::ImplItemKind::Const(..) |
hir::ImplItemKind::Method(..) => Namespace::Value, hir::ImplItemKind::Method(..) => Namespace::Value,

View File

@ -296,7 +296,7 @@ pub fn check_explicit_predicates<'tcx>(
// struct MyStruct<'x, X> { field: Box<dyn Trait<'x, X>> } // struct MyStruct<'x, X> { field: Box<dyn Trait<'x, X>> }
// ``` // ```
// //
// The `where Self: 'a` predicate refers to the *existential, hidden type* // The `where Self: 'a` predicate refers to the *opaque, hidden type*
// that is represented by the `dyn Trait`, not to the `X` type parameter // that is represented by the `dyn Trait`, not to the `X` type parameter
// (or any other generic parameter) declared on `MyStruct`. // (or any other generic parameter) declared on `MyStruct`.
// //

View File

@ -538,7 +538,7 @@ pub enum ItemEnum {
FunctionItem(Function), FunctionItem(Function),
ModuleItem(Module), ModuleItem(Module),
TypedefItem(Typedef, bool /* is associated type */), TypedefItem(Typedef, bool /* is associated type */),
ExistentialItem(Existential, bool /* is associated type */), OpaqueTyItem(OpaqueTy, bool /* is associated type */),
StaticItem(Static), StaticItem(Static),
ConstantItem(Constant), ConstantItem(Constant),
TraitItem(Trait), TraitItem(Trait),
@ -574,7 +574,7 @@ impl ItemEnum {
ItemEnum::EnumItem(ref e) => &e.generics, ItemEnum::EnumItem(ref e) => &e.generics,
ItemEnum::FunctionItem(ref f) => &f.generics, ItemEnum::FunctionItem(ref f) => &f.generics,
ItemEnum::TypedefItem(ref t, _) => &t.generics, ItemEnum::TypedefItem(ref t, _) => &t.generics,
ItemEnum::ExistentialItem(ref t, _) => &t.generics, ItemEnum::OpaqueTyItem(ref t, _) => &t.generics,
ItemEnum::TraitItem(ref t) => &t.generics, ItemEnum::TraitItem(ref t) => &t.generics,
ItemEnum::ImplItem(ref i) => &i.generics, ItemEnum::ImplItem(ref i) => &i.generics,
ItemEnum::TyMethodItem(ref i) => &i.generics, ItemEnum::TyMethodItem(ref i) => &i.generics,
@ -623,7 +623,7 @@ impl Clean<Item> for doctree::Module<'_> {
items.extend(self.foreigns.iter().map(|x| x.clean(cx))); items.extend(self.foreigns.iter().map(|x| x.clean(cx)));
items.extend(self.mods.iter().map(|x| x.clean(cx))); items.extend(self.mods.iter().map(|x| x.clean(cx)));
items.extend(self.typedefs.iter().map(|x| x.clean(cx))); items.extend(self.typedefs.iter().map(|x| x.clean(cx)));
items.extend(self.existentials.iter().map(|x| x.clean(cx))); items.extend(self.opaque_tys.iter().map(|x| x.clean(cx)));
items.extend(self.statics.iter().map(|x| x.clean(cx))); items.extend(self.statics.iter().map(|x| x.clean(cx)));
items.extend(self.constants.iter().map(|x| x.clean(cx))); items.extend(self.constants.iter().map(|x| x.clean(cx)));
items.extend(self.traits.iter().map(|x| x.clean(cx))); items.extend(self.traits.iter().map(|x| x.clean(cx)));
@ -2257,7 +2257,7 @@ impl Clean<Item> for hir::ImplItem {
type_: ty.clean(cx), type_: ty.clean(cx),
generics: Generics::default(), generics: Generics::default(),
}, true), }, true),
hir::ImplItemKind::Existential(ref bounds) => ExistentialItem(Existential { hir::ImplItemKind::OpaqueTy(ref bounds) => OpaqueTyItem(OpaqueTy {
bounds: bounds.clean(cx), bounds: bounds.clean(cx),
generics: Generics::default(), generics: Generics::default(),
}, true), }, true),
@ -2415,7 +2415,7 @@ impl Clean<Item> for ty::AssocItem {
}, true) }, true)
} }
} }
ty::AssocKind::Existential => unimplemented!(), ty::AssocKind::OpaqueTy => unimplemented!(),
}; };
let visibility = match self.container { let visibility = match self.container {
@ -2776,7 +2776,7 @@ impl Clean<Type> for hir::Ty {
TyKind::Tup(ref tys) => Tuple(tys.clean(cx)), TyKind::Tup(ref tys) => Tuple(tys.clean(cx)),
TyKind::Def(item_id, _) => { TyKind::Def(item_id, _) => {
let item = cx.tcx.hir().expect_item(item_id.id); let item = cx.tcx.hir().expect_item(item_id.id);
if let hir::ItemKind::Existential(ref ty) = item.node { if let hir::ItemKind::OpaqueTy(ref ty) = item.node {
ImplTrait(ty.bounds.clean(cx)) ImplTrait(ty.bounds.clean(cx))
} else { } else {
unreachable!() unreachable!()
@ -3648,12 +3648,12 @@ impl Clean<Item> for doctree::Typedef<'_> {
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Existential { pub struct OpaqueTy {
pub bounds: Vec<GenericBound>, pub bounds: Vec<GenericBound>,
pub generics: Generics, pub generics: Generics,
} }
impl Clean<Item> for doctree::Existential<'_> { impl Clean<Item> for doctree::OpaqueTy<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item { fn clean(&self, cx: &DocContext<'_>) -> Item {
Item { Item {
name: Some(self.name.clean(cx)), name: Some(self.name.clean(cx)),
@ -3663,7 +3663,7 @@ impl Clean<Item> for doctree::Existential<'_> {
visibility: self.vis.clean(cx), visibility: self.vis.clean(cx),
stability: self.stab.clean(cx), stability: self.stab.clean(cx),
deprecation: self.depr.clean(cx), deprecation: self.depr.clean(cx),
inner: ExistentialItem(Existential { inner: OpaqueTyItem(OpaqueTy {
bounds: self.exist_ty.bounds.clean(cx), bounds: self.exist_ty.bounds.clean(cx),
generics: self.exist_ty.generics.clean(cx), generics: self.exist_ty.generics.clean(cx),
}, false), }, false),

View File

@ -26,7 +26,7 @@ pub struct Module<'hir> {
pub mods: Vec<Module<'hir>>, pub mods: Vec<Module<'hir>>,
pub id: NodeId, pub id: NodeId,
pub typedefs: Vec<Typedef<'hir>>, pub typedefs: Vec<Typedef<'hir>>,
pub existentials: Vec<Existential<'hir>>, pub opaque_tys: Vec<OpaqueTy<'hir>>,
pub statics: Vec<Static<'hir>>, pub statics: Vec<Static<'hir>>,
pub constants: Vec<Constant<'hir>>, pub constants: Vec<Constant<'hir>>,
pub traits: Vec<Trait<'hir>>, pub traits: Vec<Trait<'hir>>,
@ -64,7 +64,7 @@ impl Module<'hir> {
fns : Vec::new(), fns : Vec::new(),
mods : Vec::new(), mods : Vec::new(),
typedefs : Vec::new(), typedefs : Vec::new(),
existentials: Vec::new(), opaque_tys : Vec::new(),
statics : Vec::new(), statics : Vec::new(),
constants : Vec::new(), constants : Vec::new(),
traits : Vec::new(), traits : Vec::new(),
@ -162,8 +162,8 @@ pub struct Typedef<'hir> {
pub depr: Option<attr::Deprecation>, pub depr: Option<attr::Deprecation>,
} }
pub struct Existential<'hir> { pub struct OpaqueTy<'hir> {
pub exist_ty: &'hir hir::ExistTy, pub opaque_ty: &'hir hir::OpaqueTy,
pub name: Name, pub name: Name,
pub id: hir::HirId, pub id: hir::HirId,
pub attrs: &'hir hir::HirVec<ast::Attribute>, pub attrs: &'hir hir::HirVec<ast::Attribute>,

View File

@ -39,7 +39,7 @@ pub enum ItemType {
Union = 19, Union = 19,
ForeignType = 20, ForeignType = 20,
Keyword = 21, Keyword = 21,
Existential = 22, OpaqueTy = 22,
ProcAttribute = 23, ProcAttribute = 23,
ProcDerive = 24, ProcDerive = 24,
TraitAlias = 25, TraitAlias = 25,
@ -70,7 +70,7 @@ impl<'a> From<&'a clean::Item> for ItemType {
clean::EnumItem(..) => ItemType::Enum, clean::EnumItem(..) => ItemType::Enum,
clean::FunctionItem(..) => ItemType::Function, clean::FunctionItem(..) => ItemType::Function,
clean::TypedefItem(..) => ItemType::Typedef, clean::TypedefItem(..) => ItemType::Typedef,
clean::ExistentialItem(..) => ItemType::Existential, clean::OpaqueTyItem(..) => ItemType::OpaqueTy,
clean::StaticItem(..) => ItemType::Static, clean::StaticItem(..) => ItemType::Static,
clean::ConstantItem(..) => ItemType::Constant, clean::ConstantItem(..) => ItemType::Constant,
clean::TraitItem(..) => ItemType::Trait, clean::TraitItem(..) => ItemType::Trait,
@ -144,7 +144,7 @@ impl ItemType {
ItemType::AssocConst => "associatedconstant", ItemType::AssocConst => "associatedconstant",
ItemType::ForeignType => "foreigntype", ItemType::ForeignType => "foreigntype",
ItemType::Keyword => "keyword", ItemType::Keyword => "keyword",
ItemType::Existential => "existential", ItemType::OpaqueTy => "opaque",
ItemType::ProcAttribute => "attr", ItemType::ProcAttribute => "attr",
ItemType::ProcDerive => "derive", ItemType::ProcDerive => "derive",
ItemType::TraitAlias => "traitalias", ItemType::TraitAlias => "traitalias",
@ -161,7 +161,7 @@ impl ItemType {
ItemType::Trait | ItemType::Trait |
ItemType::Primitive | ItemType::Primitive |
ItemType::AssocType | ItemType::AssocType |
ItemType::Existential | ItemType::OpaqueTy |
ItemType::TraitAlias | ItemType::TraitAlias |
ItemType::ForeignType => NameSpace::Type, ItemType::ForeignType => NameSpace::Type,

View File

@ -1883,7 +1883,7 @@ struct AllTypes {
macros: FxHashSet<ItemEntry>, macros: FxHashSet<ItemEntry>,
functions: FxHashSet<ItemEntry>, functions: FxHashSet<ItemEntry>,
typedefs: FxHashSet<ItemEntry>, typedefs: FxHashSet<ItemEntry>,
existentials: FxHashSet<ItemEntry>, opaque_tys: FxHashSet<ItemEntry>,
statics: FxHashSet<ItemEntry>, statics: FxHashSet<ItemEntry>,
constants: FxHashSet<ItemEntry>, constants: FxHashSet<ItemEntry>,
keywords: FxHashSet<ItemEntry>, keywords: FxHashSet<ItemEntry>,
@ -1904,7 +1904,7 @@ impl AllTypes {
macros: new_set(100), macros: new_set(100),
functions: new_set(100), functions: new_set(100),
typedefs: new_set(100), typedefs: new_set(100),
existentials: new_set(100), opaque_tys: new_set(100),
statics: new_set(100), statics: new_set(100),
constants: new_set(100), constants: new_set(100),
keywords: new_set(100), keywords: new_set(100),
@ -1929,7 +1929,7 @@ impl AllTypes {
ItemType::Macro => self.macros.insert(ItemEntry::new(new_url, name)), ItemType::Macro => self.macros.insert(ItemEntry::new(new_url, name)),
ItemType::Function => self.functions.insert(ItemEntry::new(new_url, name)), ItemType::Function => self.functions.insert(ItemEntry::new(new_url, name)),
ItemType::Typedef => self.typedefs.insert(ItemEntry::new(new_url, name)), ItemType::Typedef => self.typedefs.insert(ItemEntry::new(new_url, name)),
ItemType::Existential => self.existentials.insert(ItemEntry::new(new_url, name)), ItemType::OpaqueTy => self.opaque_tys.insert(ItemEntry::new(new_url, name)),
ItemType::Static => self.statics.insert(ItemEntry::new(new_url, name)), ItemType::Static => self.statics.insert(ItemEntry::new(new_url, name)),
ItemType::Constant => self.constants.insert(ItemEntry::new(new_url, name)), ItemType::Constant => self.constants.insert(ItemEntry::new(new_url, name)),
ItemType::ProcAttribute => self.attributes.insert(ItemEntry::new(new_url, name)), ItemType::ProcAttribute => self.attributes.insert(ItemEntry::new(new_url, name)),
@ -1979,7 +1979,7 @@ impl fmt::Display for AllTypes {
print_entries(f, &self.functions, "Functions", "functions")?; print_entries(f, &self.functions, "Functions", "functions")?;
print_entries(f, &self.typedefs, "Typedefs", "typedefs")?; print_entries(f, &self.typedefs, "Typedefs", "typedefs")?;
print_entries(f, &self.trait_aliases, "Trait Aliases", "trait-aliases")?; print_entries(f, &self.trait_aliases, "Trait Aliases", "trait-aliases")?;
print_entries(f, &self.existentials, "Existentials", "existentials")?; print_entries(f, &self.opaque_tys, "Opaque Types", "opaque-types")?;
print_entries(f, &self.statics, "Statics", "statics")?; print_entries(f, &self.statics, "Statics", "statics")?;
print_entries(f, &self.constants, "Constants", "constants") print_entries(f, &self.constants, "Constants", "constants")
} }
@ -2477,7 +2477,7 @@ impl<'a> fmt::Display for Item<'a> {
clean::ConstantItem(..) => write!(fmt, "Constant ")?, clean::ConstantItem(..) => write!(fmt, "Constant ")?,
clean::ForeignTypeItem => write!(fmt, "Foreign Type ")?, clean::ForeignTypeItem => write!(fmt, "Foreign Type ")?,
clean::KeywordItem(..) => write!(fmt, "Keyword ")?, clean::KeywordItem(..) => write!(fmt, "Keyword ")?,
clean::ExistentialItem(..) => write!(fmt, "Existential Type ")?, clean::OpaqueTyItem(..) => write!(fmt, "Opaque Type ")?,
clean::TraitAliasItem(..) => write!(fmt, "Trait Alias ")?, clean::TraitAliasItem(..) => write!(fmt, "Trait Alias ")?,
_ => { _ => {
// We don't generate pages for any other type. // We don't generate pages for any other type.
@ -2516,7 +2516,7 @@ impl<'a> fmt::Display for Item<'a> {
clean::ConstantItem(ref c) => item_constant(fmt, self.cx, self.item, c), clean::ConstantItem(ref c) => item_constant(fmt, self.cx, self.item, c),
clean::ForeignTypeItem => item_foreign_type(fmt, self.cx, self.item), clean::ForeignTypeItem => item_foreign_type(fmt, self.cx, self.item),
clean::KeywordItem(ref k) => item_keyword(fmt, self.cx, self.item, k), clean::KeywordItem(ref k) => item_keyword(fmt, self.cx, self.item, k),
clean::ExistentialItem(ref e, _) => item_existential(fmt, self.cx, self.item, e), clean::OpaqueTyItem(ref e, _) => item_opaque_ty(fmt, self.cx, self.item, e),
clean::TraitAliasItem(ref ta) => item_trait_alias(fmt, self.cx, self.item, ta), clean::TraitAliasItem(ref ta) => item_trait_alias(fmt, self.cx, self.item, ta),
_ => { _ => {
// We don't generate pages for any other type. // We don't generate pages for any other type.
@ -4387,15 +4387,15 @@ fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocIt
Ok(()) Ok(())
} }
fn item_existential( fn item_opaque_ty(
w: &mut fmt::Formatter<'_>, w: &mut fmt::Formatter<'_>,
cx: &Context, cx: &Context,
it: &clean::Item, it: &clean::Item,
t: &clean::Existential, t: &clean::OpaqueTy,
) -> fmt::Result { ) -> fmt::Result {
write!(w, "<pre class='rust existential'>")?; write!(w, "<pre class='rust opaque'>")?;
render_attributes(w, it, false)?; render_attributes(w, it, false)?;
write!(w, "existential type {}{}{where_clause}: {bounds};</pre>", write!(w, "type {}{}{where_clause} = impl {bounds};</pre>",
it.name.as_ref().unwrap(), it.name.as_ref().unwrap(),
t.generics, t.generics,
where_clause = WhereClause { gens: &t.generics, indent: 0, end_newline: true }, where_clause = WhereClause { gens: &t.generics, indent: 0, end_newline: true },
@ -4983,7 +4983,7 @@ fn item_ty_to_strs(ty: &ItemType) -> (&'static str, &'static str) {
ItemType::AssocConst => ("associated-consts", "Associated Constants"), ItemType::AssocConst => ("associated-consts", "Associated Constants"),
ItemType::ForeignType => ("foreign-types", "Foreign Types"), ItemType::ForeignType => ("foreign-types", "Foreign Types"),
ItemType::Keyword => ("keywords", "Keywords"), ItemType::Keyword => ("keywords", "Keywords"),
ItemType::Existential => ("existentials", "Existentials"), ItemType::OpaqueTy => ("opaque-types", "Opaque Types"),
ItemType::ProcAttribute => ("attributes", "Attribute Macros"), ItemType::ProcAttribute => ("attributes", "Attribute Macros"),
ItemType::ProcDerive => ("derives", "Derive Macros"), ItemType::ProcDerive => ("derives", "Derive Macros"),
ItemType::TraitAlias => ("trait-aliases", "Trait aliases"), ItemType::TraitAlias => ("trait-aliases", "Trait aliases"),

View File

@ -159,7 +159,7 @@ impl<'a> DocFolder for Stripper<'a> {
return ret; return ret;
} }
// These items can all get re-exported // These items can all get re-exported
clean::ExistentialItem(..) clean::OpaqueTyItem(..)
| clean::TypedefItem(..) | clean::TypedefItem(..)
| clean::StaticItem(..) | clean::StaticItem(..)
| clean::StructItem(..) | clean::StructItem(..)

View File

@ -472,8 +472,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
}; };
om.typedefs.push(t); om.typedefs.push(t);
}, },
hir::ItemKind::Existential(ref exist_ty) => { hir::ItemKind::OpaqueTy(ref exist_ty) => {
let t = Existential { let t = OpaqueTy {
exist_ty, exist_ty,
name: ident.name, name: ident.name,
id: item.hir_id, id: item.hir_id,
@ -483,7 +483,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
stab: self.stability(item.hir_id), stab: self.stability(item.hir_id),
depr: self.deprecation(item.hir_id), depr: self.deprecation(item.hir_id),
}; };
om.existentials.push(t); om.opaque_tys.push(t);
}, },
hir::ItemKind::Static(ref type_, mutability, expr) => { hir::ItemKind::Static(ref type_, mutability, expr) => {
let s = Static { let s = Static {

View File

@ -1485,6 +1485,7 @@ pub enum TraitItemKind {
Macro(Mac), Macro(Mac),
} }
/// Represents anything within an `impl` block.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct ImplItem { pub struct ImplItem {
pub id: NodeId, pub id: NodeId,
@ -1499,12 +1500,13 @@ pub struct ImplItem {
pub tokens: Option<TokenStream>, pub tokens: Option<TokenStream>,
} }
/// Represents various kinds of content within an `impl`.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub enum ImplItemKind { pub enum ImplItemKind {
Const(P<Ty>, P<Expr>), Const(P<Ty>, P<Expr>),
Method(MethodSig, P<Block>), Method(MethodSig, P<Block>),
Type(P<Ty>), Type(P<Ty>),
Existential(GenericBounds), OpaqueTy(GenericBounds),
Macro(Mac), Macro(Mac),
} }
@ -1707,7 +1709,7 @@ pub enum TyKind {
/// ///
/// The `NodeId` exists to prevent lowering from having to /// The `NodeId` exists to prevent lowering from having to
/// generate `NodeId`s on the fly, which would complicate /// generate `NodeId`s on the fly, which would complicate
/// the generation of `existential type` items significantly. /// the generation of opaque `type Foo = impl Trait` items significantly.
ImplTrait(NodeId, GenericBounds), ImplTrait(NodeId, GenericBounds),
/// No-op; kept solely so that we can pretty-print faithfully. /// No-op; kept solely so that we can pretty-print faithfully.
Paren(P<Ty>), Paren(P<Ty>),
@ -2331,10 +2333,10 @@ pub enum ItemKind {
/// ///
/// E.g., `type Foo = Bar<u8>;`. /// E.g., `type Foo = Bar<u8>;`.
Ty(P<Ty>, Generics), Ty(P<Ty>, Generics),
/// An existential type declaration (`existential type`). /// An opaque `impl Trait` type alias.
/// ///
/// E.g., `existential type Foo: Bar + Boo;`. /// E.g., `type Foo = impl Bar + Boo;`.
Existential(GenericBounds, Generics), OpaqueTy(GenericBounds, Generics),
/// An enum definition (`enum` or `pub enum`). /// An enum definition (`enum` or `pub enum`).
/// ///
/// E.g., `enum Foo<A, B> { C<A>, D<B> }`. /// E.g., `enum Foo<A, B> { C<A>, D<B> }`.
@ -2388,7 +2390,7 @@ impl ItemKind {
ItemKind::ForeignMod(..) => "foreign module", ItemKind::ForeignMod(..) => "foreign module",
ItemKind::GlobalAsm(..) => "global asm", ItemKind::GlobalAsm(..) => "global asm",
ItemKind::Ty(..) => "type alias", ItemKind::Ty(..) => "type alias",
ItemKind::Existential(..) => "existential type", ItemKind::OpaqueTy(..) => "opaque type",
ItemKind::Enum(..) => "enum", ItemKind::Enum(..) => "enum",
ItemKind::Struct(..) => "struct", ItemKind::Struct(..) => "struct",
ItemKind::Union(..) => "union", ItemKind::Union(..) => "union",

View File

@ -2017,12 +2017,12 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
gate_feature_post!(&self, decl_macro, i.span, msg); gate_feature_post!(&self, decl_macro, i.span, msg);
} }
ast::ItemKind::Existential(..) => { ast::ItemKind::OpaqueTy(..) => {
gate_feature_post!( gate_feature_post!(
&self, &self,
type_alias_impl_trait, type_alias_impl_trait,
i.span, i.span,
"existential types are unstable" "`impl Trait` in type aliases is unstable"
); );
} }
@ -2246,12 +2246,12 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
match ii.node { match ii.node {
ast::ImplItemKind::Method(..) => {} ast::ImplItemKind::Method(..) => {}
ast::ImplItemKind::Existential(..) => { ast::ImplItemKind::OpaqueTy(..) => {
gate_feature_post!( gate_feature_post!(
&self, &self,
type_alias_impl_trait, type_alias_impl_trait,
ii.span, ii.span,
"existential types are unstable" "`impl Trait` in type aliases is unstable"
); );
} }
ast::ImplItemKind::Type(_) => { ast::ImplItemKind::Type(_) => {

View File

@ -848,7 +848,7 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
vis.visit_ty(ty); vis.visit_ty(ty);
vis.visit_generics(generics); vis.visit_generics(generics);
} }
ItemKind::Existential(bounds, generics) => { ItemKind::OpaqueTy(bounds, generics) => {
visit_bounds(bounds, vis); visit_bounds(bounds, vis);
vis.visit_generics(generics); vis.visit_generics(generics);
} }
@ -931,7 +931,7 @@ pub fn noop_flat_map_impl_item<T: MutVisitor>(mut item: ImplItem, visitor: &mut
visitor.visit_block(body); visitor.visit_block(body);
} }
ImplItemKind::Type(ty) => visitor.visit_ty(ty), ImplItemKind::Type(ty) => visitor.visit_ty(ty),
ImplItemKind::Existential(bounds) => visit_bounds(bounds, visitor), ImplItemKind::OpaqueTy(bounds) => visit_bounds(bounds, visitor),
ImplItemKind::Macro(mac) => visitor.visit_mac(mac), ImplItemKind::Macro(mac) => visitor.visit_mac(mac),
} }
visitor.visit_span(span); visitor.visit_span(span);

View File

@ -62,12 +62,12 @@ use std::path::{self, Path, PathBuf};
use std::slice; use std::slice;
#[derive(Debug)] #[derive(Debug)]
/// Whether the type alias or associated type is a concrete type or an existential type /// Whether the type alias or associated type is a concrete type or an opaque type
pub enum AliasKind { pub enum AliasKind {
/// Just a new name for the same type /// Just a new name for the same type
Weak(P<Ty>), Weak(P<Ty>),
/// Only trait impls of the type will be usable, not the actual type itself /// Only trait impls of the type will be usable, not the actual type itself
Existential(GenericBounds), OpaqueTy(GenericBounds),
} }
bitflags::bitflags! { bitflags::bitflags! {
@ -4265,11 +4265,6 @@ impl<'a> Parser<'a> {
self.token.is_keyword(kw::Crate) && self.look_ahead(1, |t| t != &token::ModSep) self.token.is_keyword(kw::Crate) && self.look_ahead(1, |t| t != &token::ModSep)
} }
fn is_existential_type_decl(&self) -> bool {
self.token.is_keyword(kw::Existential) &&
self.is_keyword_ahead(1, &[kw::Type])
}
fn is_auto_trait_item(&self) -> bool { fn is_auto_trait_item(&self) -> bool {
// auto trait // auto trait
(self.token.is_keyword(kw::Auto) && (self.token.is_keyword(kw::Auto) &&
@ -4367,7 +4362,6 @@ impl<'a> Parser<'a> {
!self.token.is_qpath_start() && !self.token.is_qpath_start() &&
!self.is_union_item() && !self.is_union_item() &&
!self.is_crate_vis() && !self.is_crate_vis() &&
!self.is_existential_type_decl() &&
!self.is_auto_trait_item() && !self.is_auto_trait_item() &&
!self.is_async_fn() { !self.is_async_fn() {
let path = self.parse_path(PathStyle::Expr)?; let path = self.parse_path(PathStyle::Expr)?;
@ -5686,7 +5680,7 @@ impl<'a> Parser<'a> {
let (name, alias, generics) = type_?; let (name, alias, generics) = type_?;
let kind = match alias { let kind = match alias {
AliasKind::Weak(typ) => ast::ImplItemKind::Type(typ), AliasKind::Weak(typ) => ast::ImplItemKind::Type(typ),
AliasKind::Existential(bounds) => ast::ImplItemKind::Existential(bounds), AliasKind::OpaqueTy(bounds) => ast::ImplItemKind::OpaqueTy(bounds),
}; };
(name, kind, generics) (name, kind, generics)
} else if self.is_const_item() { } else if self.is_const_item() {
@ -6817,7 +6811,7 @@ impl<'a> Parser<'a> {
} }
} }
/// Parses a type alias or existential type. /// Parses a type alias or opaque type.
fn parse_type_alias(&mut self) -> PResult<'a, (Ident, AliasKind, ast::Generics)> { fn parse_type_alias(&mut self) -> PResult<'a, (Ident, AliasKind, ast::Generics)> {
let ident = self.parse_ident()?; let ident = self.parse_ident()?;
let mut tps = self.parse_generics()?; let mut tps = self.parse_generics()?;
@ -6826,7 +6820,7 @@ impl<'a> Parser<'a> {
let alias = if self.check_keyword(kw::Impl) { let alias = if self.check_keyword(kw::Impl) {
self.bump(); self.bump();
let bounds = self.parse_generic_bounds(Some(self.prev_span))?; let bounds = self.parse_generic_bounds(Some(self.prev_span))?;
AliasKind::Existential(bounds) AliasKind::OpaqueTy(bounds)
} else { } else {
let ty = self.parse_ty()?; let ty = self.parse_ty()?;
AliasKind::Weak(ty) AliasKind::Weak(ty)
@ -7249,7 +7243,7 @@ impl<'a> Parser<'a> {
// TYPE ITEM // TYPE ITEM
let item_ = match alias { let item_ = match alias {
AliasKind::Weak(ty) => ItemKind::Ty(ty, generics), AliasKind::Weak(ty) => ItemKind::Ty(ty, generics),
AliasKind::Existential(bounds) => ItemKind::Existential(bounds, generics), AliasKind::OpaqueTy(bounds) => ItemKind::OpaqueTy(bounds, generics),
}; };
let prev_span = self.prev_span; let prev_span = self.prev_span;
let item = self.mk_item(lo.to(prev_span), let item = self.mk_item(lo.to(prev_span),

View File

@ -1238,9 +1238,10 @@ impl<'a> State<'a> {
self.s.word(";"); self.s.word(";");
self.end(); // end the outer ibox self.end(); // end the outer ibox
} }
ast::ItemKind::Existential(ref bounds, ref generics) => { ast::ItemKind::OpaqueTy(ref bounds, ref generics) => {
self.head(visibility_qualified(&item.vis, "existential type")); self.head(visibility_qualified(&item.vis, "type"));
self.print_ident(item.ident); self.print_ident(item.ident);
self.word_space("= impl");
self.print_generic_params(&generics.params); self.print_generic_params(&generics.params);
self.end(); // end the inner ibox self.end(); // end the inner ibox
@ -1598,9 +1599,12 @@ impl<'a> State<'a> {
ast::ImplItemKind::Type(ref ty) => { ast::ImplItemKind::Type(ref ty) => {
self.print_associated_type(ii.ident, None, Some(ty)); self.print_associated_type(ii.ident, None, Some(ty));
} }
ast::ImplItemKind::Existential(ref bounds) => { ast::ImplItemKind::OpaqueTy(ref bounds) => {
self.word_space("existential"); self.word_space("type");
self.print_associated_type(ii.ident, Some(bounds), None); self.print_ident(ii.ident);
self.word_space("= impl");
self.print_type_bounds(":", bounds);
self.s.word(";");
} }
ast::ImplItemKind::Macro(ref mac) => { ast::ImplItemKind::Macro(ref mac) => {
self.print_mac(mac); self.print_mac(mac);

View File

@ -259,7 +259,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
visitor.visit_ty(typ); visitor.visit_ty(typ);
visitor.visit_generics(generics) visitor.visit_generics(generics)
} }
ItemKind::Existential(ref bounds, ref generics) => { ItemKind::OpaqueTy(ref bounds, ref generics) => {
walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_param_bound, bounds);
visitor.visit_generics(generics) visitor.visit_generics(generics)
} }
@ -619,7 +619,7 @@ pub fn walk_impl_item<'a, V: Visitor<'a>>(visitor: &mut V, impl_item: &'a ImplIt
ImplItemKind::Type(ref ty) => { ImplItemKind::Type(ref ty) => {
visitor.visit_ty(ty); visitor.visit_ty(ty);
} }
ImplItemKind::Existential(ref bounds) => { ImplItemKind::OpaqueTy(ref bounds) => {
walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_param_bound, bounds);
} }
ImplItemKind::Macro(ref mac) => { ImplItemKind::Macro(ref mac) => {

View File

@ -744,9 +744,9 @@ pub enum DesugaringKind {
QuestionMark, QuestionMark,
TryBlock, TryBlock,
/// Desugaring of an `impl Trait` in return type position /// Desugaring of an `impl Trait` in return type position
/// to an `existential type Foo: Trait;` and replacing the /// to an `type Foo = impl Trait;` and replacing the
/// `impl Trait` with `Foo`. /// `impl Trait` with `Foo`.
ExistentialType, OpaqueTy,
Async, Async,
Await, Await,
ForLoop, ForLoop,
@ -761,7 +761,7 @@ impl DesugaringKind {
DesugaringKind::Await => "`await` expression", DesugaringKind::Await => "`await` expression",
DesugaringKind::QuestionMark => "operator `?`", DesugaringKind::QuestionMark => "operator `?`",
DesugaringKind::TryBlock => "`try` block", DesugaringKind::TryBlock => "`try` block",
DesugaringKind::ExistentialType => "`existential type`", DesugaringKind::OpaqueTy => "`impl Trait`",
DesugaringKind::ForLoop => "`for` loop", DesugaringKind::ForLoop => "`for` loop",
} }
} }

View File

@ -95,7 +95,6 @@ symbols! {
Auto: "auto", Auto: "auto",
Catch: "catch", Catch: "catch",
Default: "default", Default: "default",
Existential: "existential",
Union: "union", Union: "union",
} }

View File

@ -29,9 +29,10 @@ impl ThisTrait for SomeStruct {
/// but what about those aliases? i hear they're pretty exotic /// but what about those aliases? i hear they're pretty exotic
pub trait MyAlias = ThisTrait + Send + Sync; pub trait MyAlias = ThisTrait + Send + Sync;
// FIXME(58624): once rustdoc can process existential types, we need to make sure they're counted // FIXME(58624): once rustdoc can process opaque `impl Trait` types,
// /// woah, getting all existential in here // we need to make sure they're counted
// pub existential type ThisExists: ThisTrait; // /// woah, getting all abstract in here
// pub type ThisExists = impl ThisTrait;
// //
// /// why don't we get a little more concrete // /// why don't we get a little more concrete
// pub fn defines() -> ThisExists { SomeStruct {} } // pub fn defines() -> ThisExists { SomeStruct {} }

View File

@ -28,7 +28,7 @@ impl Case1 for S1 {
type B = Range<u16>; type B = Range<u16>;
} }
// Ensure we don't have existential desugaring: // Ensure we don't have opaque `impl Trait` desugaring:
pub trait Foo { type Out: Baz<Assoc: Default>; } pub trait Foo { type Out: Baz<Assoc: Default>; }
pub trait Baz { type Assoc; } pub trait Baz { type Assoc; }

View File

@ -99,7 +99,7 @@ fn async_fn_with_impl_future_named_lifetime<'a>(x: &'a u8) -> impl Future<Output
} }
} }
/* FIXME(cramertj) support when `existential type T<'a, 'b>:;` works /* FIXME(cramertj) support when `type T<'a, 'b> = impl;` works
async fn async_fn_multiple_args(x: &u8, _y: &u8) -> u8 { async fn async_fn_multiple_args(x: &u8, _y: &u8) -> u8 {
await!(wake_and_yield_once()); await!(wake_and_yield_once());
*x *x

View File

@ -0,0 +1,230 @@
// run-pass
// edition:2018
// aux-build:arc_wake.rs
#![feature(async_await, async_closure, await_macro)]
extern crate arc_wake;
use std::pin::Pin;
use std::future::Future;
use std::sync::{
Arc,
atomic::{self, AtomicUsize},
};
use std::task::{Context, Poll};
use arc_wake::ArcWake;
struct Counter {
wakes: AtomicUsize,
}
impl ArcWake for Counter {
fn wake(self: Arc<Self>) {
Self::wake_by_ref(&self)
}
fn wake_by_ref(arc_self: &Arc<Self>) {
arc_self.wakes.fetch_add(1, atomic::Ordering::SeqCst);
}
}
struct WakeOnceThenComplete(bool);
fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) }
impl Future for WakeOnceThenComplete {
type Output = ();
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
if self.0 {
Poll::Ready(())
} else {
cx.waker().wake_by_ref();
self.0 = true;
Poll::Pending
}
}
}
fn async_block(x: u8) -> impl Future<Output = u8> {
async move {
await!(wake_and_yield_once());
x
}
}
fn async_block_with_borrow_named_lifetime<'a>(x: &'a u8) -> impl Future<Output = u8> + 'a {
async move {
await!(wake_and_yield_once());
*x
}
}
fn async_nonmove_block(x: u8) -> impl Future<Output = u8> {
async move {
let future = async {
await!(wake_and_yield_once());
x
};
await!(future)
}
}
fn async_closure(x: u8) -> impl Future<Output = u8> {
(async move |x: u8| -> u8 {
await!(wake_and_yield_once());
x
})(x)
}
fn async_closure_in_unsafe_block(x: u8) -> impl Future<Output = u8> {
(unsafe {
async move |x: u8| unsafe_fn(await!(unsafe_async_fn(x)))
})(x)
}
async fn async_fn(x: u8) -> u8 {
await!(wake_and_yield_once());
x
}
async fn generic_async_fn<T>(x: T) -> T {
await!(wake_and_yield_once());
x
}
async fn async_fn_with_borrow(x: &u8) -> u8 {
await!(wake_and_yield_once());
*x
}
async fn async_fn_with_borrow_named_lifetime<'a>(x: &'a u8) -> u8 {
await!(wake_and_yield_once());
*x
}
fn async_fn_with_impl_future_named_lifetime<'a>(x: &'a u8) -> impl Future<Output = u8> + 'a {
async move {
await!(wake_and_yield_once());
*x
}
}
/* FIXME(cramertj) support when `type T<'a, 'b> = impl;` works
async fn async_fn_multiple_args(x: &u8, _y: &u8) -> u8 {
await!(wake_and_yield_once());
*x
}
*/
async fn async_fn_multiple_args_named_lifetime<'a>(x: &'a u8, _y: &'a u8) -> u8 {
await!(wake_and_yield_once());
*x
}
fn async_fn_with_internal_borrow(y: u8) -> impl Future<Output = u8> {
async move {
await!(async_fn_with_borrow_named_lifetime(&y))
}
}
async unsafe fn unsafe_async_fn(x: u8) -> u8 {
await!(wake_and_yield_once());
x
}
unsafe fn unsafe_fn(x: u8) -> u8 {
x
}
fn async_block_in_unsafe_block(x: u8) -> impl Future<Output = u8> {
unsafe {
async move {
unsafe_fn(await!(unsafe_async_fn(x)))
}
}
}
struct Foo;
trait Bar {
fn foo() {}
}
impl Foo {
async fn async_assoc_item(x: u8) -> u8 {
unsafe {
await!(unsafe_async_fn(x))
}
}
async unsafe fn async_unsafe_assoc_item(x: u8) -> u8 {
await!(unsafe_async_fn(x))
}
}
fn test_future_yields_once_then_returns<F, Fut>(f: F)
where
F: FnOnce(u8) -> Fut,
Fut: Future<Output = u8>,
{
let mut fut = Box::pin(f(9));
let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) });
let waker = ArcWake::into_waker(counter.clone());
let mut cx = Context::from_waker(&waker);
assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst));
assert_eq!(Poll::Pending, fut.as_mut().poll(&mut cx));
assert_eq!(1, counter.wakes.load(atomic::Ordering::SeqCst));
assert_eq!(Poll::Ready(9), fut.as_mut().poll(&mut cx));
}
fn main() {
macro_rules! test {
($($fn_name:expr,)*) => { $(
test_future_yields_once_then_returns($fn_name);
)* }
}
macro_rules! test_with_borrow {
($($fn_name:expr,)*) => { $(
test_future_yields_once_then_returns(|x| {
async move {
await!($fn_name(&x))
}
});
)* }
}
test! {
async_block,
async_nonmove_block,
async_closure,
async_closure_in_unsafe_block,
async_fn,
generic_async_fn,
async_fn_with_internal_borrow,
async_block_in_unsafe_block,
Foo::async_assoc_item,
|x| {
async move {
unsafe { await!(unsafe_async_fn(x)) }
}
},
|x| {
async move {
unsafe { await!(Foo::async_unsafe_assoc_item(x)) }
}
},
}
test_with_borrow! {
async_block_with_borrow_named_lifetime,
async_fn_with_borrow,
async_fn_with_borrow_named_lifetime,
async_fn_with_impl_future_named_lifetime,
|x| {
async move {
await!(async_fn_multiple_args_named_lifetime(x, x))
}
},
}
}

View File

@ -1,4 +1,4 @@
// Test that existential types are allowed to contain late-bound regions. // Test that opaque `impl Trait` types are allowed to contain late-bound regions.
// build-pass (FIXME(62277): could be check-pass?) // build-pass (FIXME(62277): could be check-pass?)
// edition:2018 // edition:2018

View File

@ -9,6 +9,6 @@ type Two<T, U> = impl Debug;
//~^ could not find defining uses //~^ could not find defining uses
fn one<T: Debug>(t: T) -> Two<T, T> { fn one<T: Debug>(t: T) -> Two<T, T> {
//~^ ERROR defining existential type use restricts existential type //~^ ERROR defining opaque type use restricts opaque type
t t
} }

View File

@ -1,4 +1,4 @@
error: defining existential type use restricts existential type by using the generic parameter `T` twice error: defining opaque type use restricts opaque type by using the generic parameter `T` twice
--> $DIR/generic_duplicate_param_use.rs:11:1 --> $DIR/generic_duplicate_param_use.rs:11:1
| |
LL | / fn one<T: Debug>(t: T) -> Two<T, T> { LL | / fn one<T: Debug>(t: T) -> Two<T, T> {

View File

@ -8,7 +8,7 @@ fn main() {}
type Two<T, U> = impl Debug; type Two<T, U> = impl Debug;
fn one<T: Debug>(t: T) -> Two<T, T> { fn one<T: Debug>(t: T) -> Two<T, T> {
//~^ defining existential type use restricts existential type //~^ defining opaque type use restricts opaque type
t t
} }

View File

@ -8,7 +8,7 @@ fn main() {}
type Two<T, U> = impl Debug; type Two<T, U> = impl Debug;
fn one<T: Debug>(t: T) -> Two<T, T> { fn one<T: Debug>(t: T) -> Two<T, T> {
//~^ defining existential type use restricts existential type //~^ defining opaque type use restricts opaque type
t t
} }

View File

@ -8,7 +8,7 @@ fn main() {}
type Two<T, U> = impl Debug; type Two<T, U> = impl Debug;
fn one<T: Debug>(t: T) -> Two<T, T> { fn one<T: Debug>(t: T) -> Two<T, T> {
//~^ ERROR defining existential type use restricts existential type //~^ ERROR defining opaque type use restricts opaque type
t t
} }

View File

@ -1,4 +1,4 @@
error: type parameter `T` is part of concrete type but not used in parameter list for existential type error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
--> $DIR/issue-58887.rs:16:41 --> $DIR/issue-58887.rs:16:41
| |
LL | fn unwrap_items(self) -> Self::Iter { LL | fn unwrap_items(self) -> Self::Iter {
@ -9,7 +9,7 @@ LL | | self.map(|x| x.unwrap())
LL | | } LL | | }
| |_____^ | |_____^
error: type parameter `E` is part of concrete type but not used in parameter list for existential type error: type parameter `E` is part of concrete type but not used in parameter list for the `impl Trait` type alias
--> $DIR/issue-58887.rs:16:41 --> $DIR/issue-58887.rs:16:41
| |
LL | fn unwrap_items(self) -> Self::Iter { LL | fn unwrap_items(self) -> Self::Iter {

View File

@ -5,7 +5,7 @@ trait Bug {
} }
impl Bug for &() { impl Bug for &() {
type Item = impl Bug; //~ ERROR existential types are unstable type Item = impl Bug; //~ ERROR `impl Trait` in type aliases is unstable
//~^ ERROR the trait bound `(): Bug` is not satisfied //~^ ERROR the trait bound `(): Bug` is not satisfied
//~^^ ERROR could not find defining uses //~^^ ERROR could not find defining uses

View File

@ -1,4 +1,4 @@
error[E0658]: existential types are unstable error[E0658]: `impl Trait` in type aliases is unstable
--> $DIR/issue-60371.rs:8:5 --> $DIR/issue-60371.rs:8:5
| |
LL | type Item = impl Bug; LL | type Item = impl Bug;

View File

@ -1,4 +1,4 @@
// Issue 52985: user code provides no use case that allows an existential type // Issue 52985: user code provides no use case that allows a type alias `impl Trait`
// We now emit a 'could not find defining uses' error // We now emit a 'could not find defining uses' error
#![feature(type_alias_impl_trait)] #![feature(type_alias_impl_trait)]

View File

@ -7,7 +7,7 @@ fn main() {}
type Two<T, U> = impl Debug; type Two<T, U> = impl Debug;
fn two<T: Debug>(t: T) -> Two<T, u32> { fn two<T: Debug>(t: T) -> Two<T, u32> {
//~^ ERROR defining existential type use does not fully define existential type //~^ ERROR defining opaque type use does not fully define opaque type
(t, 4i8) (t, 4i8)
} }

View File

@ -1,4 +1,4 @@
error: defining existential type use does not fully define existential type error: defining opaque type use does not fully define opaque type
--> $DIR/not_a_defining_use.rs:9:1 --> $DIR/not_a_defining_use.rs:9:1
| |
LL | / fn two<T: Debug>(t: T) -> Two<T, u32> { LL | / fn two<T: Debug>(t: T) -> Two<T, u32> {
@ -7,7 +7,7 @@ LL | | (t, 4i8)
LL | | } LL | | }
| |_^ | |_^
error: concrete type differs from previous defining existential type use error: concrete type differs from previous defining opaque type use
--> $DIR/not_a_defining_use.rs:30:1 --> $DIR/not_a_defining_use.rs:30:1
| |
LL | / fn four<T: Debug, U: Bar>(t: T) -> Two<T, U> { LL | / fn four<T: Debug, U: Bar>(t: T) -> Two<T, U> {

View File

@ -1,4 +1,4 @@
type Foo = impl std::fmt::Debug; //~ ERROR existential types are unstable type Foo = impl std::fmt::Debug; //~ ERROR `impl Trait` in type aliases is unstable
trait Bar { trait Bar {
type Baa: std::fmt::Debug; type Baa: std::fmt::Debug;
@ -6,7 +6,7 @@ trait Bar {
} }
impl Bar for () { impl Bar for () {
type Baa = impl std::fmt::Debug; //~ ERROR existential types are unstable type Baa = impl std::fmt::Debug; //~ ERROR `impl Trait` in type aliases is unstable
fn define() -> Self::Baa { 0 } fn define() -> Self::Baa { 0 }
} }

View File

@ -1,4 +1,4 @@
error[E0658]: existential types are unstable error[E0658]: `impl Trait` in type aliases is unstable
--> $DIR/feature-gate-type_alias_impl_trait.rs:1:1 --> $DIR/feature-gate-type_alias_impl_trait.rs:1:1
| |
LL | type Foo = impl std::fmt::Debug; LL | type Foo = impl std::fmt::Debug;
@ -7,7 +7,7 @@ LL | type Foo = impl std::fmt::Debug;
= note: for more information, see https://github.com/rust-lang/rust/issues/63063 = note: for more information, see https://github.com/rust-lang/rust/issues/63063
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
error[E0658]: existential types are unstable error[E0658]: `impl Trait` in type aliases is unstable
--> $DIR/feature-gate-type_alias_impl_trait.rs:9:5 --> $DIR/feature-gate-type_alias_impl_trait.rs:9:5
| |
LL | type Baa = impl std::fmt::Debug; LL | type Baa = impl std::fmt::Debug;

View File

@ -14,7 +14,7 @@ impl<S: Default> Bar for S {
//~^^ ERROR the trait bound `T: std::marker::Copy` is not satisfied in `(S, T)` [E0277] //~^^ ERROR the trait bound `T: std::marker::Copy` is not satisfied in `(S, T)` [E0277]
fn foo<T: Default>() -> Self::E { fn foo<T: Default>() -> Self::E {
//~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for existential type //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
(S::default(), T::default()) (S::default(), T::default())
} }
} }

View File

@ -18,7 +18,7 @@ LL | type E = impl Copy;
= note: required because it appears within the type `(S, T)` = note: required because it appears within the type `(S, T)`
= note: the return type of a function must have a statically known size = note: the return type of a function must have a statically known size
error: type parameter `T` is part of concrete type but not used in parameter list for existential type error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
--> $DIR/issue-55872-1.rs:16:37 --> $DIR/issue-55872-1.rs:16:37
| |
LL | fn foo<T: Default>() -> Self::E { LL | fn foo<T: Default>() -> Self::E {

View File

@ -12,7 +12,7 @@ impl<S> Bar for S {
type E = impl Copy; type E = impl Copy;
//~^ ERROR the trait bound `impl std::future::Future: std::marker::Copy` is not satisfied [E0277] //~^ ERROR the trait bound `impl std::future::Future: std::marker::Copy` is not satisfied [E0277]
fn foo<T>() -> Self::E { fn foo<T>() -> Self::E {
//~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for existential type //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
async {} async {}
} }
} }

View File

@ -6,7 +6,7 @@ LL | type E = impl Copy;
| |
= note: the return type of a function must have a statically known size = note: the return type of a function must have a statically known size
error: type parameter `T` is part of concrete type but not used in parameter list for existential type error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
--> $DIR/issue-55872-2.rs:14:28 --> $DIR/issue-55872-2.rs:14:28
| |
LL | fn foo<T>() -> Self::E { LL | fn foo<T>() -> Self::E {

View File

@ -11,7 +11,7 @@ impl<S> Bar for S {
type E = impl Copy; type E = impl Copy;
fn foo<T>() -> Self::E { fn foo<T>() -> Self::E {
//~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for existential type //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
|| () || ()
} }
} }

View File

@ -1,4 +1,4 @@
error: type parameter `T` is part of concrete type but not used in parameter list for existential type error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
--> $DIR/issue-55872.rs:13:28 --> $DIR/issue-55872.rs:13:28
| |
LL | fn foo<T>() -> Self::E { LL | fn foo<T>() -> Self::E {

View File

@ -120,7 +120,7 @@ trait DummyTrait {
} }
impl DummyTrait for () { impl DummyTrait for () {
type Out = impl Debug; type Out = impl Debug;
//~^ ERROR existential types are unstable //~^ ERROR `impl Trait` in type aliases is unstable
//~^^ ERROR could not find defining uses //~^^ ERROR could not find defining uses
fn in_trait_impl_parameter(_: impl Debug) { } fn in_trait_impl_parameter(_: impl Debug) { }
@ -156,7 +156,7 @@ extern "C" fn in_extern_fn_return() -> impl Debug {
} }
type InTypeAlias<R> = impl Debug; type InTypeAlias<R> = impl Debug;
//~^ ERROR existential types are unstable //~^ ERROR `impl Trait` in type aliases is unstable
//~^^ ERROR could not find defining uses //~^^ ERROR could not find defining uses
type InReturnInTypeAlias<R> = fn() -> impl Debug; type InReturnInTypeAlias<R> = fn() -> impl Debug;

View File

@ -16,7 +16,7 @@ LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic
| | nested `impl Trait` here | | nested `impl Trait` here
| outer `impl Trait` | outer `impl Trait`
error[E0658]: existential types are unstable error[E0658]: `impl Trait` in type aliases is unstable
--> $DIR/where-allowed.rs:122:5 --> $DIR/where-allowed.rs:122:5
| |
LL | type Out = impl Debug; LL | type Out = impl Debug;
@ -25,7 +25,7 @@ LL | type Out = impl Debug;
= note: for more information, see https://github.com/rust-lang/rust/issues/63063 = note: for more information, see https://github.com/rust-lang/rust/issues/63063
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
error[E0658]: existential types are unstable error[E0658]: `impl Trait` in type aliases is unstable
--> $DIR/where-allowed.rs:158:1 --> $DIR/where-allowed.rs:158:1
| |
LL | type InTypeAlias<R> = impl Debug; LL | type InTypeAlias<R> = impl Debug;

View File

@ -77,19 +77,19 @@ fn impl_trait_in_band(x: &impl MyTrait<'a>) {}
trait FunkyTrait<'a> { } trait FunkyTrait<'a> { }
impl<'a, T> FunkyTrait<'a> for T { } impl<'a, T> FunkyTrait<'a> for T { }
fn existential_impl_trait_in_band_outlives(x: &'a u32) -> impl ::std::fmt::Debug + 'a { fn ret_pos_impl_trait_in_band_outlives(x: &'a u32) -> impl ::std::fmt::Debug + 'a {
x x
} }
fn existential_impl_trait_in_band_param(x: &'a u32) -> impl FunkyTrait<'a> { fn ret_pos_impl_trait_in_band_param(x: &'a u32) -> impl FunkyTrait<'a> {
x x
} }
fn existential_impl_trait_in_band_param_static(x: &'a u32) -> impl FunkyTrait<'static> + 'a { fn ret_pos_impl_trait_in_band_param_static(x: &'a u32) -> impl FunkyTrait<'static> + 'a {
x x
} }
fn existential_impl_trait_in_band_param_outlives(x: &'a u32) -> impl FunkyTrait<'a> + 'a { fn ret_pos_impl_trait_in_band_param_outlives(x: &'a u32) -> impl FunkyTrait<'a> + 'a {
x x
} }
fn existential_impl_trait_in_band_higher_ranked(x: &'a u32) -> impl for<'b> FunkyTrait<'b> + 'a { fn ret_pos_impl_trait_in_band_higher_ranked(x: &'a u32) -> impl for<'b> FunkyTrait<'b> + 'a {
x x
} }

View File

@ -10,5 +10,5 @@ extern crate std;
trait Animal { } trait Animal { }
fn main() { fn main() {
pub existential type ServeFut : Animal; pub type ServeFut= impl : Animal;
} }

View File

@ -0,0 +1,89 @@
// run-pass
#![allow(dead_code)]
#![allow(unused_assignments)]
#![allow(unused_variables)]
#![feature(type_alias_impl_trait)]
fn main() {
assert_eq!(foo().to_string(), "foo");
assert_eq!(bar1().to_string(), "bar1");
assert_eq!(bar2().to_string(), "bar2");
let mut x = bar1();
x = bar2();
assert_eq!(boo::boo().to_string(), "boo");
assert_eq!(my_iter(42u8).collect::<Vec<u8>>(), vec![42u8]);
}
// single definition
type Foo = impl std::fmt::Display;
fn foo() -> Foo {
"foo"
}
// two definitions
type Bar = impl std::fmt::Display;
fn bar1() -> Bar {
"bar1"
}
fn bar2() -> Bar {
"bar2"
}
// definition in submodule
type Boo = impl std::fmt::Display;
mod boo {
pub fn boo() -> super::Boo {
"boo"
}
}
type MyIter<T> = impl Iterator<Item = T>;
fn my_iter<T>(t: T) -> MyIter<T> {
std::iter::once(t)
}
fn my_iter2<T>(t: T) -> MyIter<T> {
std::iter::once(t)
}
// param names should not have an effect!
fn my_iter3<U>(u: U) -> MyIter<U> {
std::iter::once(u)
}
// param position should not have an effect!
fn my_iter4<U, V>(_: U, v: V) -> MyIter<V> {
std::iter::once(v)
}
// param names should not have an effect!
type MyOtherIter<T> = impl Iterator<Item = T>;
fn my_other_iter<U>(u: U) -> MyOtherIter<U> {
std::iter::once(u)
}
trait Trait {}
type GenericBound<'a, T: Trait> = impl Sized + 'a;
fn generic_bound<'a, T: Trait + 'a>(t: T) -> GenericBound<'a, T> {
t
}
mod pass_through {
pub type Passthrough<T> = impl Sized + 'static;
fn define_passthrough<T: 'static>(t: T) -> Passthrough<T> {
t
}
}
fn use_passthrough(x: pass_through::Passthrough<u32>) -> pass_through::Passthrough<u32> {
x
}

View File

@ -1,4 +1,4 @@
// Crate that exports an existential type. Used for testing cross-crate. // Crate that exports an opaque `impl Trait` type. Used for testing cross-crate.
#![crate_type="rlib"] #![crate_type="rlib"]

View File

@ -1,4 +1,4 @@
// Crate that exports an existential type. Used for testing cross-crate. // Crate that exports an opaque `impl Trait` type. Used for testing cross-crate.
#![crate_type="rlib"] #![crate_type="rlib"]

Some files were not shown because too many files have changed in this diff Show More