mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
Replace "existential" by "opaque"
This commit is contained in:
parent
fc48541ab1
commit
c28ce3e4ca
@ -27,7 +27,7 @@ pub(crate) enum Target {
|
||||
ForeignMod,
|
||||
GlobalAsm,
|
||||
Ty,
|
||||
Existential,
|
||||
OpaqueTy,
|
||||
Enum,
|
||||
Struct,
|
||||
Union,
|
||||
@ -51,7 +51,7 @@ impl Display for Target {
|
||||
Target::ForeignMod => "foreign module",
|
||||
Target::GlobalAsm => "global asm",
|
||||
Target::Ty => "type alias",
|
||||
Target::Existential => "existential type",
|
||||
Target::OpaqueTy => "opaque type",
|
||||
Target::Enum => "enum",
|
||||
Target::Struct => "struct",
|
||||
Target::Union => "union",
|
||||
@ -76,7 +76,7 @@ impl Target {
|
||||
hir::ItemKind::ForeignMod(..) => Target::ForeignMod,
|
||||
hir::ItemKind::GlobalAsm(..) => Target::GlobalAsm,
|
||||
hir::ItemKind::Ty(..) => Target::Ty,
|
||||
hir::ItemKind::Existential(..) => Target::Existential,
|
||||
hir::ItemKind::OpaqueTy(..) => Target::OpaqueTy,
|
||||
hir::ItemKind::Enum(..) => Target::Enum,
|
||||
hir::ItemKind::Struct(..) => Target::Struct,
|
||||
hir::ItemKind::Union(..) => Target::Union,
|
||||
|
@ -55,15 +55,15 @@ pub enum DefKind {
|
||||
/// Refers to the variant itself, `DefKind::Ctor` refers to its constructor if it exists.
|
||||
Variant,
|
||||
Trait,
|
||||
/// `existential type Foo: Bar;`
|
||||
Existential,
|
||||
/// `type Foo = impl Bar;`
|
||||
OpaqueTy,
|
||||
/// `type Foo = Bar;`
|
||||
TyAlias,
|
||||
ForeignTy,
|
||||
TraitAlias,
|
||||
AssocTy,
|
||||
/// `existential type Foo: Bar;`
|
||||
AssocExistential,
|
||||
/// `type Foo = impl Bar;`
|
||||
AssocOpaqueTy,
|
||||
TyParam,
|
||||
|
||||
// Value namespace
|
||||
@ -96,11 +96,11 @@ impl DefKind {
|
||||
DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct",
|
||||
DefKind::Ctor(CtorOf::Struct, CtorKind::Fictive) =>
|
||||
bug!("impossible struct constructor"),
|
||||
DefKind::Existential => "existential type",
|
||||
DefKind::OpaqueTy => "opaque type",
|
||||
DefKind::TyAlias => "type alias",
|
||||
DefKind::TraitAlias => "trait alias",
|
||||
DefKind::AssocTy => "associated type",
|
||||
DefKind::AssocExistential => "associated existential type",
|
||||
DefKind::AssocOpaqueTy => "associated opaque type",
|
||||
DefKind::Union => "union",
|
||||
DefKind::Trait => "trait",
|
||||
DefKind::ForeignTy => "foreign type",
|
||||
@ -118,9 +118,9 @@ impl DefKind {
|
||||
match *self {
|
||||
DefKind::AssocTy
|
||||
| DefKind::AssocConst
|
||||
| DefKind::AssocExistential
|
||||
| DefKind::AssocOpaqueTy
|
||||
| DefKind::Enum
|
||||
| DefKind::Existential => "an",
|
||||
| DefKind::OpaqueTy => "an",
|
||||
DefKind::Macro(macro_kind) => macro_kind.article(),
|
||||
_ => "a",
|
||||
}
|
||||
|
@ -505,7 +505,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
|
||||
visitor.visit_ty(ty);
|
||||
visitor.visit_generics(generics)
|
||||
}
|
||||
ItemKind::Existential(ExistTy {
|
||||
ItemKind::OpaqueTy(ExistTy {
|
||||
ref generics,
|
||||
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_ty(ty);
|
||||
}
|
||||
ImplItemKind::Existential(ref bounds) => {
|
||||
ImplItemKind::OpaqueTy(ref bounds) => {
|
||||
visitor.visit_id(impl_item.hir_id);
|
||||
walk_list!(visitor, visit_param_bound, bounds);
|
||||
}
|
||||
|
@ -189,14 +189,14 @@ enum ImplTraitContext<'a> {
|
||||
/// Newly generated parameters should be inserted into the given `Vec`.
|
||||
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
|
||||
/// 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
|
||||
/// information later. It is `None` when no information about the context should be stored
|
||||
/// (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.
|
||||
Disallowed(ImplTraitPosition),
|
||||
@ -222,7 +222,7 @@ impl<'a> ImplTraitContext<'a> {
|
||||
use self::ImplTraitContext::*;
|
||||
match self {
|
||||
Universal(params) => Universal(params),
|
||||
Existential(fn_def_id) => Existential(*fn_def_id),
|
||||
OpaqueTy(fn_def_id) => OpaqueTy(*fn_def_id),
|
||||
Disallowed(pos) => Disallowed(*pos),
|
||||
}
|
||||
}
|
||||
@ -487,7 +487,7 @@ impl<'a> LoweringContext<'a> {
|
||||
| ItemKind::Union(_, ref generics)
|
||||
| ItemKind::Enum(_, ref generics)
|
||||
| ItemKind::Ty(_, ref generics)
|
||||
| ItemKind::Existential(_, ref generics)
|
||||
| ItemKind::OpaqueTy(_, ref generics)
|
||||
| ItemKind::Trait(_, _, ref generics, ..) => {
|
||||
let def_id = self.lctx.resolver.definitions().local_def_id(item.id);
|
||||
let count = generics
|
||||
@ -1422,7 +1422,7 @@ impl<'a> LoweringContext<'a> {
|
||||
// so desugar to
|
||||
//
|
||||
// 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:
|
||||
//
|
||||
@ -1436,11 +1436,11 @@ impl<'a> LoweringContext<'a> {
|
||||
// In `type Foo = dyn Iterator<Item: Debug>` we desugar to
|
||||
// `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
|
||||
// then to an existential type).
|
||||
// then to an opaque type).
|
||||
//
|
||||
// FIXME: this is only needed until `impl Trait` is allowed in type aliases.
|
||||
ImplTraitContext::Disallowed(_) if self.is_in_dyn_type =>
|
||||
(true, ImplTraitContext::Existential(None)),
|
||||
(true, ImplTraitContext::OpaqueTy(None)),
|
||||
|
||||
// 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) => {
|
||||
let span = t.span;
|
||||
match itctx {
|
||||
ImplTraitContext::Existential(fn_def_id) => {
|
||||
self.lower_existential_impl_trait(
|
||||
ImplTraitContext::OpaqueTy(fn_def_id) => {
|
||||
self.lower_opaque_impl_trait(
|
||||
span, fn_def_id, def_node_id,
|
||||
|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,
|
||||
span: Span,
|
||||
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
|
||||
// frequently opened issues show.
|
||||
let exist_ty_span = self.mark_span_with_reason(
|
||||
DesugaringKind::ExistentialType,
|
||||
DesugaringKind::OpaqueTy,
|
||||
span,
|
||||
None,
|
||||
);
|
||||
@ -1763,11 +1763,11 @@ impl<'a> LoweringContext<'a> {
|
||||
},
|
||||
bounds: hir_bounds,
|
||||
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);
|
||||
let exist_ty_id = lctx.generate_existential_type(
|
||||
let exist_ty_id = lctx.generate_opaque_type(
|
||||
exist_ty_node_id,
|
||||
exist_ty_item,
|
||||
span,
|
||||
@ -1779,19 +1779,19 @@ impl<'a> LoweringContext<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Registers a new existential type with the proper `NodeId`s and
|
||||
/// returns the lowered node-ID for the existential type.
|
||||
fn generate_existential_type(
|
||||
/// Registers a new opaque type with the proper `NodeId`s and
|
||||
/// returns the lowered node-ID for the opaque type.
|
||||
fn generate_opaque_type(
|
||||
&mut self,
|
||||
exist_ty_node_id: NodeId,
|
||||
exist_ty_item: hir::ExistTy,
|
||||
span: Span,
|
||||
exist_ty_span: Span,
|
||||
) -> 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);
|
||||
// Generate an `existential type Foo: Trait;` declaration.
|
||||
trace!("registering existential type with id {:#?}", exist_ty_id);
|
||||
// Generate an `type Foo = impl Trait;` declaration.
|
||||
trace!("registering opaque type with id {:#?}", exist_ty_id);
|
||||
let exist_ty_item = hir::Item {
|
||||
hir_id: exist_ty_id,
|
||||
ident: Ident::invalid(),
|
||||
@ -1802,7 +1802,7 @@ impl<'a> LoweringContext<'a> {
|
||||
};
|
||||
|
||||
// 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.
|
||||
self.insert_item(exist_ty_item);
|
||||
exist_ty_id
|
||||
@ -2439,7 +2439,7 @@ impl<'a> LoweringContext<'a> {
|
||||
.as_ref()
|
||||
.map(|t| self.lower_ty(t,
|
||||
if self.sess.features_untracked().impl_trait_in_bindings {
|
||||
ImplTraitContext::Existential(Some(parent_def_id))
|
||||
ImplTraitContext::OpaqueTy(Some(parent_def_id))
|
||||
} else {
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
|
||||
}
|
||||
@ -2500,7 +2500,7 @@ impl<'a> LoweringContext<'a> {
|
||||
let lt_mode = if make_ret_async.is_some() {
|
||||
// In `async fn`, argument-position elided lifetimes
|
||||
// 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
|
||||
} else {
|
||||
self.anonymous_lifetime_mode
|
||||
@ -2539,7 +2539,7 @@ impl<'a> LoweringContext<'a> {
|
||||
FunctionRetTy::Ty(ref ty) => match in_band_ty_params {
|
||||
Some((def_id, _)) if impl_trait_return_allow => {
|
||||
hir::Return(self.lower_ty(ty,
|
||||
ImplTraitContext::Existential(Some(def_id))
|
||||
ImplTraitContext::OpaqueTy(Some(def_id))
|
||||
))
|
||||
}
|
||||
_ => {
|
||||
@ -2585,12 +2585,12 @@ impl<'a> LoweringContext<'a> {
|
||||
// Transforms `-> T` for `async fn` into `-> 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)
|
||||
// `output`: unlowered output type (`T` in `-> T`)
|
||||
// `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
|
||||
fn lower_async_fn_ret_ty(
|
||||
&mut self,
|
||||
@ -2626,7 +2626,7 @@ impl<'a> LoweringContext<'a> {
|
||||
);
|
||||
|
||||
// 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.
|
||||
//
|
||||
// Note: this must be done after lowering the output type,
|
||||
@ -2657,11 +2657,11 @@ impl<'a> LoweringContext<'a> {
|
||||
},
|
||||
bounds: hir_vec![future_bound],
|
||||
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);
|
||||
let exist_ty_id = this.generate_existential_type(
|
||||
let exist_ty_id = this.generate_opaque_type(
|
||||
exist_ty_node_id,
|
||||
exist_ty_item,
|
||||
span,
|
||||
@ -2702,7 +2702,7 @@ impl<'a> LoweringContext<'a> {
|
||||
// Compute the `T` in `Future<Output = T>` from the return type.
|
||||
let output_ty = match output {
|
||||
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) => {
|
||||
P(hir::Ty {
|
||||
@ -2905,7 +2905,7 @@ impl<'a> LoweringContext<'a> {
|
||||
|
||||
let kind = hir::GenericParamKind::Type {
|
||||
default: default.as_ref().map(|x| {
|
||||
self.lower_ty(x, ImplTraitContext::Existential(None))
|
||||
self.lower_ty(x, ImplTraitContext::OpaqueTy(None))
|
||||
}),
|
||||
synthetic: param.attrs.iter()
|
||||
.filter(|attr| attr.check_name(sym::rustc_synthetic))
|
||||
@ -3384,7 +3384,7 @@ impl<'a> LoweringContext<'a> {
|
||||
self.lower_ty(
|
||||
t,
|
||||
if self.sess.features_untracked().impl_trait_in_bindings {
|
||||
ImplTraitContext::Existential(None)
|
||||
ImplTraitContext::OpaqueTy(None)
|
||||
} else {
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
|
||||
}
|
||||
@ -3398,7 +3398,7 @@ impl<'a> LoweringContext<'a> {
|
||||
self.lower_ty(
|
||||
t,
|
||||
if self.sess.features_untracked().impl_trait_in_bindings {
|
||||
ImplTraitContext::Existential(None)
|
||||
ImplTraitContext::OpaqueTy(None)
|
||||
} else {
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
|
||||
}
|
||||
@ -3444,14 +3444,14 @@ impl<'a> LoweringContext<'a> {
|
||||
self.lower_ty(t, 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 {
|
||||
generics: self.lower_generics(generics,
|
||||
ImplTraitContext::Existential(None)),
|
||||
ImplTraitContext::OpaqueTy(None)),
|
||||
bounds: self.lower_param_bounds(b,
|
||||
ImplTraitContext::Existential(None)),
|
||||
ImplTraitContext::OpaqueTy(None)),
|
||||
impl_trait_fn: None,
|
||||
origin: hir::ExistTyOrigin::ExistentialType,
|
||||
origin: hir::OpaqueTyOrigin::TraitAliasImplTrait,
|
||||
},
|
||||
),
|
||||
ItemKind::Enum(ref enum_definition, ref generics) => {
|
||||
@ -3918,9 +3918,9 @@ impl<'a> LoweringContext<'a> {
|
||||
self.lower_generics(&i.generics, 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()),
|
||||
hir::ImplItemKind::Existential(
|
||||
hir::ImplItemKind::OpaqueTy(
|
||||
self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
|
||||
),
|
||||
),
|
||||
@ -3951,7 +3951,7 @@ impl<'a> LoweringContext<'a> {
|
||||
kind: match i.node {
|
||||
ImplItemKind::Const(..) => hir::AssocItemKind::Const,
|
||||
ImplItemKind::Type(..) => hir::AssocItemKind::Type,
|
||||
ImplItemKind::Existential(..) => hir::AssocItemKind::Existential,
|
||||
ImplItemKind::OpaqueTy(..) => hir::AssocItemKind::OpaqueTy,
|
||||
ImplItemKind::Method(ref sig, _) => hir::AssocItemKind::Method {
|
||||
has_self: sig.decl.has_self(),
|
||||
},
|
||||
|
@ -92,7 +92,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||
}
|
||||
ItemKind::Mod(..) | ItemKind::Trait(..) | ItemKind::TraitAlias(..) |
|
||||
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::Fn(
|
||||
ref decl,
|
||||
@ -223,7 +223,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||
ImplItemKind::Method(..) | ImplItemKind::Const(..) =>
|
||||
DefPathData::ValueNs(ii.ident.as_interned_str()),
|
||||
ImplItemKind::Type(..) |
|
||||
ImplItemKind::Existential(..) => {
|
||||
ImplItemKind::OpaqueTy(..) => {
|
||||
DefPathData::TypeNs(ii.ident.as_interned_str())
|
||||
},
|
||||
ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id),
|
||||
|
@ -301,7 +301,7 @@ impl<'hir> Map<'hir> {
|
||||
ItemKind::Const(..) => DefKind::Const,
|
||||
ItemKind::Fn(..) => DefKind::Fn,
|
||||
ItemKind::Mod(..) => DefKind::Mod,
|
||||
ItemKind::Existential(..) => DefKind::Existential,
|
||||
ItemKind::OpaqueTy(..) => DefKind::OpaqueTy,
|
||||
ItemKind::Ty(..) => DefKind::TyAlias,
|
||||
ItemKind::Enum(..) => DefKind::Enum,
|
||||
ItemKind::Struct(..) => DefKind::Struct,
|
||||
@ -334,7 +334,7 @@ impl<'hir> Map<'hir> {
|
||||
ImplItemKind::Const(..) => DefKind::AssocConst,
|
||||
ImplItemKind::Method(..) => DefKind::Method,
|
||||
ImplItemKind::Type(..) => DefKind::AssocTy,
|
||||
ImplItemKind::Existential(..) => DefKind::AssocExistential,
|
||||
ImplItemKind::OpaqueTy(..) => DefKind::AssocOpaqueTy,
|
||||
}
|
||||
}
|
||||
Node::Variant(_) => DefKind::Variant,
|
||||
@ -816,7 +816,7 @@ impl<'hir> Map<'hir> {
|
||||
}, |_| 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> {
|
||||
let mut scope = id;
|
||||
loop {
|
||||
@ -827,7 +827,7 @@ impl<'hir> Map<'hir> {
|
||||
match self.get(scope) {
|
||||
Node::Item(i) => {
|
||||
match i.node {
|
||||
ItemKind::Existential(ExistTy { impl_trait_fn: None, .. }) => {}
|
||||
ItemKind::OpaqueTy(ExistTy { impl_trait_fn: None, .. }) => {}
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
@ -1270,7 +1270,7 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String {
|
||||
ItemKind::ForeignMod(..) => "foreign mod",
|
||||
ItemKind::GlobalAsm(..) => "global asm",
|
||||
ItemKind::Ty(..) => "ty",
|
||||
ItemKind::Existential(..) => "existential type",
|
||||
ItemKind::OpaqueTy(..) => "opaque type",
|
||||
ItemKind::Enum(..) => "enum",
|
||||
ItemKind::Struct(..) => "struct",
|
||||
ItemKind::Union(..) => "union",
|
||||
@ -1294,8 +1294,8 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String {
|
||||
ImplItemKind::Type(_) => {
|
||||
format!("assoc type {} in {}{}", ii.ident, path_str(), id_str)
|
||||
}
|
||||
ImplItemKind::Existential(_) => {
|
||||
format!("assoc existential type {} in {}{}", ii.ident, path_str(), id_str)
|
||||
ImplItemKind::OpaqueTy(_) => {
|
||||
format!("assoc opaque type {} in {}{}", ii.ident, path_str(), id_str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1815,7 +1815,7 @@ pub struct ImplItemId {
|
||||
pub hir_id: HirId,
|
||||
}
|
||||
|
||||
/// Represents anything within an `impl` block
|
||||
/// Represents anything within an `impl` block.
|
||||
#[derive(RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct ImplItem {
|
||||
pub ident: Ident,
|
||||
@ -1832,14 +1832,14 @@ pub struct ImplItem {
|
||||
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
|
||||
pub enum ImplItemKind {
|
||||
/// An associated constant of the given type, set to the constant result
|
||||
/// of the expression
|
||||
/// of the expression.
|
||||
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),
|
||||
/// An associated type
|
||||
/// An associated type.
|
||||
Type(P<Ty>),
|
||||
/// An associated existential type
|
||||
Existential(GenericBounds),
|
||||
/// An associated `type = impl Trait`.
|
||||
OpaqueTy(GenericBounds),
|
||||
}
|
||||
|
||||
/// Bind a type to an associated type (i.e., `A = Foo`).
|
||||
@ -1926,14 +1926,14 @@ pub struct ExistTy {
|
||||
pub generics: Generics,
|
||||
pub bounds: GenericBounds,
|
||||
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)]
|
||||
pub enum ExistTyOrigin {
|
||||
/// `existential type Foo: Trait;`
|
||||
ExistentialType,
|
||||
pub enum OpaqueTyOrigin {
|
||||
/// `type Foo = impl Trait;`
|
||||
TraitAliasImplTrait,
|
||||
/// `-> impl Trait`
|
||||
ReturnImplTrait,
|
||||
/// `async fn`
|
||||
@ -1962,7 +1962,7 @@ pub enum TyKind {
|
||||
///
|
||||
/// Type parameters may be stored in each `PathSegment`.
|
||||
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.
|
||||
///
|
||||
/// The generic argument list contains the lifetimes (and in the future possibly parameters)
|
||||
@ -2421,17 +2421,17 @@ pub enum ItemKind {
|
||||
GlobalAsm(P<GlobalAsm>),
|
||||
/// A type alias, e.g., `type Foo = Bar<u8>`
|
||||
Ty(P<Ty>, Generics),
|
||||
/// An existential type definition, e.g., `existential type Foo: Bar;`
|
||||
Existential(ExistTy),
|
||||
/// An opaque `impl Trait` type alias, e.g., `type Foo = impl Bar;`
|
||||
OpaqueTy(ExistTy),
|
||||
/// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`
|
||||
Enum(EnumDef, Generics),
|
||||
/// A struct definition, e.g., `struct Foo<A> {x: A}`
|
||||
Struct(VariantData, Generics),
|
||||
/// A union definition, e.g., `union Foo<A, B> {x: A, y: B}`
|
||||
Union(VariantData, Generics),
|
||||
/// Represents a Trait Declaration
|
||||
/// A trait definition
|
||||
Trait(IsAuto, Unsafety, Generics, GenericBounds, HirVec<TraitItemRef>),
|
||||
/// Represents a Trait Alias Declaration
|
||||
/// A trait alias
|
||||
TraitAlias(Generics, GenericBounds),
|
||||
|
||||
/// An implementation, eg `impl<A> Trait for Foo { .. }`
|
||||
@ -2456,7 +2456,7 @@ impl ItemKind {
|
||||
ItemKind::ForeignMod(..) => "foreign module",
|
||||
ItemKind::GlobalAsm(..) => "global asm",
|
||||
ItemKind::Ty(..) => "type alias",
|
||||
ItemKind::Existential(..) => "existential type",
|
||||
ItemKind::OpaqueTy(..) => "opaque type",
|
||||
ItemKind::Enum(..) => "enum",
|
||||
ItemKind::Struct(..) => "struct",
|
||||
ItemKind::Union(..) => "union",
|
||||
@ -2479,7 +2479,7 @@ impl ItemKind {
|
||||
Some(match *self {
|
||||
ItemKind::Fn(_, _, 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::Struct(_, ref generics) |
|
||||
ItemKind::Union(_, ref generics) |
|
||||
@ -2528,7 +2528,7 @@ pub enum AssocItemKind {
|
||||
Const,
|
||||
Method { has_self: bool },
|
||||
Type,
|
||||
Existential,
|
||||
OpaqueTy,
|
||||
}
|
||||
|
||||
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
|
||||
|
@ -565,9 +565,10 @@ impl<'a> State<'a> {
|
||||
self.s.word(";");
|
||||
self.end(); // end the outer ibox
|
||||
}
|
||||
hir::ItemKind::Existential(ref exist) => {
|
||||
self.head(visibility_qualified(&item.vis, "existential type"));
|
||||
hir::ItemKind::OpaqueTy(ref exist) => {
|
||||
self.head(visibility_qualified(&item.vis, "type"));
|
||||
self.print_ident(item.ident);
|
||||
self.word_space("= impl");
|
||||
self.print_generic_params(&exist.generics.params);
|
||||
self.end(); // end the inner ibox
|
||||
|
||||
@ -908,9 +909,11 @@ impl<'a> State<'a> {
|
||||
hir::ImplItemKind::Type(ref ty) => {
|
||||
self.print_associated_type(ii.ident, None, Some(ty));
|
||||
}
|
||||
hir::ImplItemKind::Existential(ref bounds) => {
|
||||
self.word_space("existential");
|
||||
self.print_associated_type(ii.ident, Some(bounds), None);
|
||||
hir::ImplItemKind::OpaqueTy(ref bounds) => {
|
||||
self.word_space("type");
|
||||
self.print_ident(ii.ident);
|
||||
self.print_bounds("= impl", bounds);
|
||||
self.s.word(";");
|
||||
}
|
||||
}
|
||||
self.ann.post(self, AnnNode::SubItem(ii.hir_id))
|
||||
|
@ -418,7 +418,7 @@ impl_stable_hash_for!(enum ::syntax_pos::hygiene::DesugaringKind {
|
||||
Async,
|
||||
Await,
|
||||
QuestionMark,
|
||||
ExistentialType,
|
||||
OpaqueTy,
|
||||
ForLoop,
|
||||
TryBlock
|
||||
});
|
||||
|
@ -269,7 +269,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
match item.node {
|
||||
hir::ImplItemKind::Method(..) => "method body",
|
||||
hir::ImplItemKind::Const(..)
|
||||
| hir::ImplItemKind::Existential(..)
|
||||
| hir::ImplItemKind::OpaqueTy(..)
|
||||
| hir::ImplItemKind::Type(..) => "associated item",
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ pub struct OpaqueTypeDecl<'tcx> {
|
||||
/// for example:
|
||||
///
|
||||
/// ```
|
||||
/// existential type Foo;
|
||||
/// type Foo = impl Baz;
|
||||
/// fn bar() -> Foo {
|
||||
/// ^^^ This is the span we are looking for!
|
||||
/// ```
|
||||
@ -87,8 +87,8 @@ pub struct OpaqueTypeDecl<'tcx> {
|
||||
/// check.)
|
||||
pub has_required_region_bounds: bool,
|
||||
|
||||
/// The origin of the existential type
|
||||
pub origin: hir::ExistTyOrigin,
|
||||
/// The origin of the opaque type.
|
||||
pub origin: hir::OpaqueTyOrigin,
|
||||
}
|
||||
|
||||
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 }
|
||||
}
|
||||
|
||||
/// Given the map `opaque_types` containing the existential `impl
|
||||
/// Trait` types whose underlying, hidden types are being
|
||||
/// Given the map `opaque_types` containing the opaque
|
||||
/// `impl Trait` types whose underlying, hidden types are being
|
||||
/// inferred, this method adds constraints to the regions
|
||||
/// appearing in those underlying hidden types to ensure that they
|
||||
/// at least do not refer to random scopes within the current
|
||||
@ -265,14 +265,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
/// }
|
||||
///
|
||||
/// // Equivalent to:
|
||||
/// existential type FooReturn<'a, T>: Foo<'a>;
|
||||
/// type FooReturn<'a, T> = impl Foo<'a>;
|
||||
/// fn foo<'a, T>(..) -> FooReturn<'a, T> { .. }
|
||||
/// ```
|
||||
///
|
||||
/// then the hidden type `Tc` would be `(&'0 u32, T)` (where `'0`
|
||||
/// is an inference variable). If we generated a constraint that
|
||||
/// `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
|
||||
/// 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.
|
||||
let context_name = match opaque_defn.origin {
|
||||
// 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.
|
||||
hir::ExistTyOrigin::ExistentialType => "existential type",
|
||||
hir::ExistTyOrigin::ReturnImplTrait => "impl Trait",
|
||||
hir::OpaqueTyOrigin::TraitAliasImplTrait => "impl Trait",
|
||||
hir::OpaqueTyOrigin::ReturnImplTrait => "impl Trait",
|
||||
};
|
||||
let msg = format!("ambiguous lifetime bound in `{}`", context_name);
|
||||
let mut err = self.tcx.sess.struct_span_err(span, &msg);
|
||||
@ -842,12 +842,12 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||
self.tcx.sess
|
||||
.struct_span_err(
|
||||
self.span,
|
||||
"non-defining existential type use in defining scope"
|
||||
"non-defining opaque type use in defining scope"
|
||||
)
|
||||
.span_label(
|
||||
self.span,
|
||||
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();
|
||||
|
||||
@ -863,7 +863,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||
// we encounter a closure here, it is always a closure
|
||||
// from within the function that we are currently
|
||||
// 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
|
||||
// and treat them just like we would any other type,
|
||||
// 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.
|
||||
match self.map.get(&ty.into()).map(|k| k.unpack()) {
|
||||
// Found it in the substitution list; replace with the parameter from the
|
||||
// existential type.
|
||||
// opaque type.
|
||||
Some(UnpackedKind::Type(t1)) => t1,
|
||||
Some(u) => panic!("type mapped to unexpected kind: {:?}", u),
|
||||
None => {
|
||||
@ -926,7 +926,8 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||
.struct_span_err(
|
||||
self.span,
|
||||
&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();
|
||||
|
||||
@ -947,7 +948,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||
// Look it up in the substitution list.
|
||||
match self.map.get(&ct.into()).map(|k| k.unpack()) {
|
||||
// Found it in the substitution list, replace with the parameter from the
|
||||
// existential type.
|
||||
// opaque type.
|
||||
Some(UnpackedKind::Const(c1)) => c1,
|
||||
Some(u) => panic!("const mapped to unexpected kind: {:?}", u),
|
||||
None => {
|
||||
@ -955,7 +956,8 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||
.struct_span_err(
|
||||
self.span,
|
||||
&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();
|
||||
|
||||
@ -1031,36 +1033,40 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
|
||||
let (in_definition_scope, origin) = match tcx.hir().find(opaque_hir_id) {
|
||||
Some(Node::Item(item)) => match item.node {
|
||||
// Anonymous `impl Trait`
|
||||
hir::ItemKind::Existential(hir::ExistTy {
|
||||
hir::ItemKind::OpaqueTy(hir::ExistTy {
|
||||
impl_trait_fn: Some(parent),
|
||||
origin,
|
||||
..
|
||||
}) => (parent == self.parent_def_id, origin),
|
||||
// Named `existential type`
|
||||
hir::ItemKind::Existential(hir::ExistTy {
|
||||
// Named `type Foo = impl Bar;`
|
||||
hir::ItemKind::OpaqueTy(hir::ExistTy {
|
||||
impl_trait_fn: None,
|
||||
origin,
|
||||
..
|
||||
}) => (
|
||||
may_define_existential_type(
|
||||
may_define_opaque_type(
|
||||
tcx,
|
||||
self.parent_def_id,
|
||||
opaque_hir_id,
|
||||
),
|
||||
origin,
|
||||
),
|
||||
_ => (def_scope_default(), hir::ExistTyOrigin::ExistentialType),
|
||||
_ => {
|
||||
(def_scope_default(), hir::OpaqueTyOrigin::TraitAliasImplTrait)
|
||||
}
|
||||
},
|
||||
Some(Node::ImplItem(item)) => match item.node {
|
||||
hir::ImplItemKind::Existential(_) => (
|
||||
may_define_existential_type(
|
||||
hir::ImplItemKind::OpaqueTy(_) => (
|
||||
may_define_opaque_type(
|
||||
tcx,
|
||||
self.parent_def_id,
|
||||
opaque_hir_id,
|
||||
),
|
||||
hir::ExistTyOrigin::ExistentialType,
|
||||
hir::OpaqueTyOrigin::TraitAliasImplTrait,
|
||||
),
|
||||
_ => (def_scope_default(), hir::ExistTyOrigin::ExistentialType),
|
||||
_ => {
|
||||
(def_scope_default(), hir::OpaqueTyOrigin::TraitAliasImplTrait)
|
||||
}
|
||||
},
|
||||
_ => bug!(
|
||||
"expected (impl) item, found {}",
|
||||
@ -1092,7 +1098,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
|
||||
ty: Ty<'tcx>,
|
||||
def_id: DefId,
|
||||
substs: SubstsRef<'tcx>,
|
||||
origin: hir::ExistTyOrigin,
|
||||
origin: hir::OpaqueTyOrigin,
|
||||
) -> Ty<'tcx> {
|
||||
let infcx = self.infcx;
|
||||
let tcx = infcx.tcx;
|
||||
@ -1123,7 +1129,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
|
||||
debug!("instantiate_opaque_types: required_region_bounds={:?}", required_region_bounds);
|
||||
|
||||
// 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>`).
|
||||
debug!("instantiate_opaque_types: param_env={:#?}", self.param_env,);
|
||||
debug!("instantiate_opaque_types: generics={:#?}", tcx.generics_of(def_id),);
|
||||
@ -1171,7 +1177,9 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
|
||||
/// ```rust
|
||||
/// pub mod foo {
|
||||
/// pub mod bar {
|
||||
/// pub existential type Baz;
|
||||
/// pub trait Bar { .. }
|
||||
///
|
||||
/// pub type Baz = impl Bar;
|
||||
///
|
||||
/// 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`),
|
||||
/// and `opaque_hir_id` is the `HirId` of the definition of the existential type `Baz`.
|
||||
/// 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 opaque type `Baz`.
|
||||
/// 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<'_>,
|
||||
def_id: DefId,
|
||||
opaque_hir_id: hir::HirId,
|
||||
) -> bool {
|
||||
let mut hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
|
||||
|
||||
|
||||
// Named existential types can be defined by any siblings or children of siblings.
|
||||
// Named opaque 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");
|
||||
// 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 {
|
||||
|
@ -638,7 +638,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> {
|
||||
}
|
||||
self.visit_nested_body(body_id)
|
||||
}
|
||||
hir::ImplItemKind::Existential(..) |
|
||||
hir::ImplItemKind::OpaqueTy(..) |
|
||||
hir::ImplItemKind::Type(..) => {}
|
||||
}
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
hir::ImplItemKind::Existential(..) |
|
||||
hir::ImplItemKind::OpaqueTy(..) |
|
||||
hir::ImplItemKind::Type(_) => false,
|
||||
}
|
||||
}
|
||||
@ -263,7 +263,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
|
||||
// worklist, as determined by the privacy pass
|
||||
hir::ItemKind::ExternCrate(_) |
|
||||
hir::ItemKind::Use(..) |
|
||||
hir::ItemKind::Existential(..) |
|
||||
hir::ItemKind::OpaqueTy(..) |
|
||||
hir::ItemKind::Ty(..) |
|
||||
hir::ItemKind::Static(..) |
|
||||
hir::ItemKind::Mod(..) |
|
||||
@ -301,7 +301,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
|
||||
self.visit_nested_body(body)
|
||||
}
|
||||
}
|
||||
hir::ImplItemKind::Existential(..) |
|
||||
hir::ImplItemKind::OpaqueTy(..) |
|
||||
hir::ImplItemKind::Type(_) => {}
|
||||
}
|
||||
}
|
||||
|
@ -480,16 +480,16 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
};
|
||||
self.with(scope, |_, this| intravisit::walk_item(this, item));
|
||||
}
|
||||
hir::ItemKind::Existential(hir::ExistTy {
|
||||
hir::ItemKind::OpaqueTy(hir::ExistTy {
|
||||
impl_trait_fn: Some(_),
|
||||
..
|
||||
}) => {
|
||||
// currently existential type declarations are just generated from impl Trait
|
||||
// items. doing anything on this node is irrelevant, as we currently don't need
|
||||
// Currently opaque type declarations are just generated from `impl Trait`
|
||||
// items. Doing anything on this node is irrelevant, as we currently don't need
|
||||
// it.
|
||||
}
|
||||
hir::ItemKind::Ty(_, ref generics)
|
||||
| hir::ItemKind::Existential(hir::ExistTy {
|
||||
| hir::ItemKind::OpaqueTy(hir::ExistTy {
|
||||
impl_trait_fn: None,
|
||||
ref generics,
|
||||
..
|
||||
@ -627,9 +627,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
// the exist_ty generics
|
||||
let (generics, bounds) = match self.tcx.hir().expect_item(item_id.id).node
|
||||
{
|
||||
// named existential types are reached via TyKind::Path
|
||||
// this arm is for `impl Trait` in the types of statics, constants and locals
|
||||
hir::ItemKind::Existential(hir::ExistTy {
|
||||
// Named opaque `impl Trait` types are reached via `TyKind::Path`.
|
||||
// This arm is for `impl Trait` in the types of statics, constants and locals.
|
||||
hir::ItemKind::OpaqueTy(hir::ExistTy {
|
||||
impl_trait_fn: None,
|
||||
..
|
||||
}) => {
|
||||
@ -637,15 +637,15 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
return;
|
||||
}
|
||||
// RPIT (return position impl trait)
|
||||
hir::ItemKind::Existential(hir::ExistTy {
|
||||
hir::ItemKind::OpaqueTy(hir::ExistTy {
|
||||
ref generics,
|
||||
ref 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.
|
||||
// `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
|
||||
// `fn foo<'a>() -> MyAnonTy<'a> { ... }`
|
||||
@ -855,7 +855,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
this.visit_ty(ty);
|
||||
});
|
||||
}
|
||||
Existential(ref bounds) => {
|
||||
OpaqueTy(ref bounds) => {
|
||||
let generics = &impl_item.generics;
|
||||
let mut index = self.next_early_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::Union(_, ref generics)
|
||||
| hir::ItemKind::Enum(_, ref generics)
|
||||
| hir::ItemKind::Existential(hir::ExistTy {
|
||||
| hir::ItemKind::OpaqueTy(hir::ExistTy {
|
||||
ref generics,
|
||||
impl_trait_fn: None,
|
||||
..
|
||||
|
@ -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 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);
|
||||
tcx.mk_opaque(assoc_ty.item.def_id, item_substs)
|
||||
} else {
|
||||
|
@ -484,13 +484,13 @@ impl<'tcx> Ancestors<'tcx> {
|
||||
| (Const, Const)
|
||||
| (Method, Method)
|
||||
| (Type, Type)
|
||||
| (Type, Existential)
|
||||
| (Type, OpaqueTy)
|
||||
=> tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id),
|
||||
|
||||
| (Const, _)
|
||||
| (Method, _)
|
||||
| (Type, _)
|
||||
| (Existential, _)
|
||||
| (OpaqueTy, _)
|
||||
=> false,
|
||||
}).map(move |item| NodeItem { node: node, item: item })
|
||||
})
|
||||
|
@ -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)]
|
||||
pub struct ResolvedOpaqueTy<'tcx> {
|
||||
/// The revealed type as seen by this function.
|
||||
pub concrete_type: Ty<'tcx>,
|
||||
/// 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
|
||||
/// `[A, B]`
|
||||
/// For `type Foo<A, B> = impl Bar<A, B>; fn foo<T, U>() -> Foo<T, U> { .. }`
|
||||
/// this is `[T, U]`, not `[A, B]`.
|
||||
pub substs: SubstsRef<'tcx>,
|
||||
}
|
||||
|
||||
@ -392,9 +392,9 @@ pub struct TypeckTables<'tcx> {
|
||||
/// read-again by borrowck.
|
||||
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
|
||||
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.
|
||||
/// 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()),
|
||||
tainted_by_errors: false,
|
||||
free_region_map: Default::default(),
|
||||
concrete_existential_types: Default::default(),
|
||||
concrete_opaque_types: Default::default(),
|
||||
upvar_list: Default::default(),
|
||||
}
|
||||
}
|
||||
@ -733,7 +733,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckTables<'tcx> {
|
||||
ref used_trait_imports,
|
||||
tainted_by_errors,
|
||||
ref free_region_map,
|
||||
ref concrete_existential_types,
|
||||
ref concrete_opaque_types,
|
||||
ref upvar_list,
|
||||
|
||||
} = *self;
|
||||
@ -777,7 +777,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckTables<'tcx> {
|
||||
used_trait_imports.hash_stable(hcx, hasher);
|
||||
tainted_by_errors.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);
|
||||
})
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ pub struct AssocItem {
|
||||
pub enum AssocKind {
|
||||
Const,
|
||||
Method,
|
||||
Existential,
|
||||
OpaqueTy,
|
||||
Type
|
||||
}
|
||||
|
||||
@ -195,7 +195,7 @@ impl AssocItem {
|
||||
AssocKind::Const => DefKind::AssocConst,
|
||||
AssocKind::Method => DefKind::Method,
|
||||
AssocKind::Type => DefKind::AssocTy,
|
||||
AssocKind::Existential => DefKind::AssocExistential,
|
||||
AssocKind::OpaqueTy => DefKind::AssocOpaqueTy,
|
||||
}
|
||||
}
|
||||
|
||||
@ -203,7 +203,7 @@ impl AssocItem {
|
||||
/// for !
|
||||
pub fn relevant_for_never(&self) -> bool {
|
||||
match self.kind {
|
||||
AssocKind::Existential |
|
||||
AssocKind::OpaqueTy |
|
||||
AssocKind::Const |
|
||||
AssocKind::Type => true,
|
||||
// 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()
|
||||
}
|
||||
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 => {
|
||||
format!("const {}: {:?};", self.ident, tcx.type_of(self.def_id))
|
||||
}
|
||||
@ -2822,7 +2823,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
(ty::AssocKind::Method, has_self)
|
||||
}
|
||||
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 {
|
||||
@ -2848,7 +2849,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
(ty::AssocKind::Method, has_self)
|
||||
}
|
||||
hir::AssocItemKind::Type => (ty::AssocKind::Type, false),
|
||||
hir::AssocItemKind::Existential => (ty::AssocKind::Existential, false),
|
||||
hir::AssocItemKind::OpaqueTy => (ty::AssocKind::OpaqueTy, false),
|
||||
};
|
||||
|
||||
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> {
|
||||
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 hir::ItemKind::Existential(ref exist_ty) = item.node {
|
||||
if let hir::ItemKind::OpaqueTy(ref exist_ty) = item.node {
|
||||
return exist_ty.impl_trait_fn;
|
||||
}
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ pub enum TyKind<'tcx> {
|
||||
/// Opaque (`impl Trait`) type found in a return type.
|
||||
/// The `DefId` comes either from
|
||||
/// * 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.
|
||||
/// After typeck, the concrete type can be found in the `types` map.
|
||||
Opaque(DefId, SubstsRef<'tcx>),
|
||||
|
@ -362,7 +362,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||
// should've been checked by the instantiation
|
||||
// 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() {
|
||||
let obligations = self.nominal_obligations(did, substs);
|
||||
self.out.extend(obligations);
|
||||
|
@ -406,7 +406,7 @@ impl DirtyCleanVisitor<'tcx> {
|
||||
ImplItemKind::Method(..) => ("Node::ImplItem", LABELS_FN_IN_IMPL),
|
||||
ImplItemKind::Const(..) => ("NodeImplConst", 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(
|
||||
|
@ -461,7 +461,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
|
||||
hir::ImplItemKind::Const(..) => "an associated constant",
|
||||
hir::ImplItemKind::Method(..) => "a method",
|
||||
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,
|
||||
Some(impl_item.hir_id),
|
||||
|
@ -413,9 +413,9 @@ impl<'tcx> EntryKind<'tcx> {
|
||||
EntryKind::Type => DefKind::TyAlias,
|
||||
EntryKind::TypeParam => DefKind::TyParam,
|
||||
EntryKind::ConstParam => DefKind::ConstParam,
|
||||
EntryKind::Existential => DefKind::Existential,
|
||||
EntryKind::OpaqueTy => DefKind::OpaqueTy,
|
||||
EntryKind::AssocType(_) => DefKind::AssocTy,
|
||||
EntryKind::AssocExistential(_) => DefKind::AssocExistential,
|
||||
EntryKind::AssocOpaqueTy(_) => DefKind::AssocOpaqueTy,
|
||||
EntryKind::Mod(_) => DefKind::Mod,
|
||||
EntryKind::Variant(_) => DefKind::Variant,
|
||||
EntryKind::Trait(_) => DefKind::Trait,
|
||||
@ -910,8 +910,8 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
EntryKind::AssocType(container) => {
|
||||
(ty::AssocKind::Type, container, false)
|
||||
}
|
||||
EntryKind::AssocExistential(container) => {
|
||||
(ty::AssocKind::Existential, container, false)
|
||||
EntryKind::AssocOpaqueTy(container) => {
|
||||
(ty::AssocKind::OpaqueTy, container, false)
|
||||
}
|
||||
_ => bug!("cannot get associated-item of `{:?}`", def_key)
|
||||
};
|
||||
|
@ -868,8 +868,7 @@ impl EncodeContext<'tcx> {
|
||||
}))
|
||||
}
|
||||
ty::AssocKind::Type => EntryKind::AssocType(container),
|
||||
ty::AssocKind::Existential =>
|
||||
span_bug!(ast_item.span, "existential type in trait"),
|
||||
ty::AssocKind::OpaqueTy => span_bug!(ast_item.span, "opaque type in trait"),
|
||||
};
|
||||
|
||||
Entry {
|
||||
@ -893,7 +892,7 @@ impl EncodeContext<'tcx> {
|
||||
None
|
||||
}
|
||||
}
|
||||
ty::AssocKind::Existential => unreachable!(),
|
||||
ty::AssocKind::OpaqueTy => unreachable!(),
|
||||
},
|
||||
inherent_impls: LazySeq::empty(),
|
||||
variances: if trait_item.kind == ty::AssocKind::Method {
|
||||
@ -964,7 +963,7 @@ impl EncodeContext<'tcx> {
|
||||
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)
|
||||
};
|
||||
|
||||
@ -980,7 +979,7 @@ impl EncodeContext<'tcx> {
|
||||
let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
|
||||
needs_inline || is_const_fn || always_encode_mir
|
||||
},
|
||||
hir::ImplItemKind::Existential(..) |
|
||||
hir::ImplItemKind::OpaqueTy(..) |
|
||||
hir::ImplItemKind::Type(..) => false,
|
||||
};
|
||||
|
||||
@ -1096,7 +1095,7 @@ impl EncodeContext<'tcx> {
|
||||
hir::ItemKind::ForeignMod(_) => EntryKind::ForeignMod,
|
||||
hir::ItemKind::GlobalAsm(..) => EntryKind::GlobalAsm,
|
||||
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::Struct(ref struct_def, _) => {
|
||||
let variant = tcx.adt_def(def_id).non_enum_variant();
|
||||
@ -1229,7 +1228,7 @@ impl EncodeContext<'tcx> {
|
||||
hir::ItemKind::Const(..) |
|
||||
hir::ItemKind::Fn(..) |
|
||||
hir::ItemKind::Ty(..) |
|
||||
hir::ItemKind::Existential(..) |
|
||||
hir::ItemKind::OpaqueTy(..) |
|
||||
hir::ItemKind::Enum(..) |
|
||||
hir::ItemKind::Struct(..) |
|
||||
hir::ItemKind::Union(..) |
|
||||
@ -1253,7 +1252,7 @@ impl EncodeContext<'tcx> {
|
||||
hir::ItemKind::Struct(..) |
|
||||
hir::ItemKind::Union(..) |
|
||||
hir::ItemKind::Impl(..) |
|
||||
hir::ItemKind::Existential(..) |
|
||||
hir::ItemKind::OpaqueTy(..) |
|
||||
hir::ItemKind::Trait(..) => Some(self.encode_generics(def_id)),
|
||||
hir::ItemKind::TraitAlias(..) => Some(self.encode_generics(def_id)),
|
||||
_ => None,
|
||||
@ -1267,7 +1266,7 @@ impl EncodeContext<'tcx> {
|
||||
hir::ItemKind::Struct(..) |
|
||||
hir::ItemKind::Union(..) |
|
||||
hir::ItemKind::Impl(..) |
|
||||
hir::ItemKind::Existential(..) |
|
||||
hir::ItemKind::OpaqueTy(..) |
|
||||
hir::ItemKind::Trait(..) |
|
||||
hir::ItemKind::TraitAlias(..) => Some(self.encode_predicates(def_id)),
|
||||
_ => None,
|
||||
@ -1763,7 +1762,7 @@ impl EncodeContext<'tcx> {
|
||||
hir::ItemKind::ExternCrate(..) |
|
||||
hir::ItemKind::Use(..) |
|
||||
hir::ItemKind::Ty(..) |
|
||||
hir::ItemKind::Existential(..) |
|
||||
hir::ItemKind::OpaqueTy(..) |
|
||||
hir::ItemKind::TraitAlias(..) => {
|
||||
// no sub-item recording needed in these cases
|
||||
}
|
||||
|
@ -239,7 +239,7 @@ pub enum EntryKind<'tcx> {
|
||||
Type,
|
||||
TypeParam,
|
||||
ConstParam,
|
||||
Existential,
|
||||
OpaqueTy,
|
||||
Enum(ReprOptions),
|
||||
Field,
|
||||
Variant(Lazy<VariantData<'tcx>>),
|
||||
@ -255,7 +255,7 @@ pub enum EntryKind<'tcx> {
|
||||
Impl(Lazy<ImplData<'tcx>>),
|
||||
Method(Lazy<MethodData<'tcx>>),
|
||||
AssocType(AssocContainer),
|
||||
AssocExistential(AssocContainer),
|
||||
AssocOpaqueTy(AssocContainer),
|
||||
AssocConst(AssocContainer, ConstQualif, Lazy<RenderedConst>),
|
||||
TraitAlias(Lazy<TraitAliasData<'tcx>>),
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! This module contains code to equate the input/output types appearing
|
||||
//! in the MIR with the expected input/output types from the function
|
||||
//! 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
|
||||
//! the MIR (specifically, in the special local variables for the
|
||||
//! `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);
|
||||
}
|
||||
|
||||
// Return types are a bit more complex. They may contain existential `impl Trait`
|
||||
// types.
|
||||
// Return types are a bit more complex. They may contain opaque `impl Trait` types.
|
||||
let mir_output_ty = body.local_decls[RETURN_PLACE].ty;
|
||||
let output_span = body.local_decls[RETURN_PLACE].source_info.span;
|
||||
if let Err(terr) = self.eq_opaque_type_and_type(
|
||||
|
@ -1291,10 +1291,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
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:
|
||||
//
|
||||
// existential type Foo: Debug;
|
||||
// type Foo = impl Debug;
|
||||
// fn foo1() -> Foo { ... }
|
||||
// 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
|
||||
// the concrete type with the underlying defining type
|
||||
// of the existential type - this will always fail, since
|
||||
// the defining type of an existential type is always
|
||||
// of the opaque type - this will always fail, since
|
||||
// the defining type of an opaque type is always
|
||||
// some other type (e.g. not itself)
|
||||
// Essentially, none of the normal obligations apply here -
|
||||
// we're just passing around some unknown opaque type,
|
||||
|
@ -972,7 +972,7 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> {
|
||||
hir::ItemKind::Ty(..) |
|
||||
hir::ItemKind::Trait(..) |
|
||||
hir::ItemKind::TraitAlias(..) |
|
||||
hir::ItemKind::Existential(..) |
|
||||
hir::ItemKind::OpaqueTy(..) |
|
||||
hir::ItemKind::Mod(..) => {
|
||||
// Nothing to do, just keep recursing...
|
||||
}
|
||||
|
@ -667,7 +667,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
"unions cannot have zero fields");
|
||||
}
|
||||
}
|
||||
ItemKind::Existential(ref bounds, _) => {
|
||||
ItemKind::OpaqueTy(ref bounds, _) => {
|
||||
if !bounds.iter()
|
||||
.any(|b| if let GenericBound::Trait(..) = *b { true } else { false }) {
|
||||
let msp = MultiSpan::from_spans(bounds.iter()
|
||||
|
@ -533,7 +533,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
|
||||
hir::ItemKind::GlobalAsm(..) | hir::ItemKind::Fn(..) | hir::ItemKind::Mod(..) |
|
||||
hir::ItemKind::Static(..) | hir::ItemKind::Struct(..) |
|
||||
hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) |
|
||||
hir::ItemKind::Existential(..) |
|
||||
hir::ItemKind::OpaqueTy(..) |
|
||||
hir::ItemKind::Ty(..) | hir::ItemKind::Union(..) | hir::ItemKind::Use(..) => {
|
||||
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::Static(..) |
|
||||
hir::ItemKind::Const(..) |
|
||||
@ -612,7 +612,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
|
||||
}
|
||||
// The interface is empty.
|
||||
hir::ItemKind::GlobalAsm(..) => {}
|
||||
hir::ItemKind::Existential(..) => {
|
||||
hir::ItemKind::OpaqueTy(..) => {
|
||||
// FIXME: This is some serious pessimization intended to workaround deficiencies
|
||||
// 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.
|
||||
@ -1113,7 +1113,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
|
||||
DefKind::Method
|
||||
| DefKind::AssocConst
|
||||
| DefKind::AssocTy
|
||||
| DefKind::AssocExistential
|
||||
| DefKind::AssocOpaqueTy
|
||||
| DefKind::Static => true,
|
||||
_ => false,
|
||||
}
|
||||
@ -1370,7 +1370,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
|
||||
self.access_levels.is_reachable(
|
||||
impl_item_ref.id.hir_id)
|
||||
}
|
||||
hir::ImplItemKind::Existential(..) |
|
||||
hir::ImplItemKind::OpaqueTy(..) |
|
||||
hir::ImplItemKind::Type(_) => false,
|
||||
}
|
||||
});
|
||||
@ -1707,9 +1707,9 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> {
|
||||
let (check_ty, is_assoc_ty) = match assoc_item_kind {
|
||||
AssocItemKind::Const | AssocItemKind::Method { .. } => (true, false),
|
||||
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.
|
||||
AssocItemKind::Existential => (false, true),
|
||||
AssocItemKind::OpaqueTy => (false, true),
|
||||
};
|
||||
check.in_assoc_ty = is_assoc_ty;
|
||||
check.generics().predicates();
|
||||
@ -1742,8 +1742,8 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx>
|
||||
hir::ItemKind::Fn(..) | hir::ItemKind::Ty(..) => {
|
||||
self.check(item.hir_id, item_visibility).generics().predicates().ty();
|
||||
}
|
||||
hir::ItemKind::Existential(..) => {
|
||||
// `ty()` for existential types is the underlying type,
|
||||
hir::ItemKind::OpaqueTy(..) => {
|
||||
// `ty()` for opaque types is the underlying type,
|
||||
// it's not a part of interface, so we skip it.
|
||||
self.check(item.hir_id, item_visibility).generics().predicates();
|
||||
}
|
||||
|
@ -464,8 +464,8 @@ impl<'a> Resolver<'a> {
|
||||
self.define(parent, ident, TypeNS, (res, vis, sp, expansion));
|
||||
}
|
||||
|
||||
ItemKind::Existential(_, _) => {
|
||||
let res = Res::Def(DefKind::Existential, self.definitions.local_def_id(item.id));
|
||||
ItemKind::OpaqueTy(_, _) => {
|
||||
let res = Res::Def(DefKind::OpaqueTy, self.definitions.local_def_id(item.id));
|
||||
self.define(parent, ident, TypeNS, (res, vis, sp, expansion));
|
||||
}
|
||||
|
||||
@ -656,7 +656,7 @@ impl<'a> Resolver<'a> {
|
||||
Res::Def(DefKind::Variant, _)
|
||||
| Res::Def(DefKind::TyAlias, _)
|
||||
| Res::Def(DefKind::ForeignTy, _)
|
||||
| Res::Def(DefKind::Existential, _)
|
||||
| Res::Def(DefKind::OpaqueTy, _)
|
||||
| Res::Def(DefKind::TraitAlias, _)
|
||||
| Res::PrimTy(..)
|
||||
| Res::ToolMod => {
|
||||
|
@ -605,7 +605,7 @@ impl<'a> PathSource<'a> {
|
||||
| Res::PrimTy(..)
|
||||
| Res::Def(DefKind::TyParam, _)
|
||||
| Res::SelfTy(..)
|
||||
| Res::Def(DefKind::Existential, _)
|
||||
| Res::Def(DefKind::OpaqueTy, _)
|
||||
| Res::Def(DefKind::ForeignTy, _) => true,
|
||||
_ => false,
|
||||
},
|
||||
@ -2710,7 +2710,7 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
match item.node {
|
||||
ItemKind::Ty(_, ref generics) |
|
||||
ItemKind::Existential(_, ref generics) |
|
||||
ItemKind::OpaqueTy(_, ref generics) |
|
||||
ItemKind::Fn(_, _, ref generics, _) => {
|
||||
self.with_generic_param_rib(
|
||||
HasGenericParams(generics, ItemRibKind),
|
||||
@ -3089,7 +3089,7 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
this.visit_ty(ty);
|
||||
}
|
||||
ImplItemKind::Existential(ref bounds) => {
|
||||
ImplItemKind::OpaqueTy(ref bounds) => {
|
||||
// If this is a trait impl, ensure the type
|
||||
// exists in trait
|
||||
this.check_trait_item(impl_item.ident,
|
||||
|
@ -1173,7 +1173,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
|
||||
// trait.
|
||||
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
|
||||
// 'def' and the name here should be a ref to the def in the
|
||||
// trait.
|
||||
@ -1428,7 +1428,7 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
|
||||
self.visit_ty(&ty);
|
||||
self.process_generic_params(ty_params, &qualname, item.id);
|
||||
}
|
||||
Existential(ref _bounds, ref ty_params) => {
|
||||
OpaqueTy(ref _bounds, ref ty_params) => {
|
||||
let qualname = format!("::{}",
|
||||
self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)));
|
||||
// FIXME do something with _bounds
|
||||
|
@ -725,10 +725,10 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
|
||||
Res::Def(HirDefKind::TyAlias, def_id) |
|
||||
Res::Def(HirDefKind::ForeignTy, 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::Trait, def_id) |
|
||||
Res::Def(HirDefKind::Existential, def_id) |
|
||||
Res::Def(HirDefKind::OpaqueTy, def_id) |
|
||||
Res::Def(HirDefKind::TyParam, def_id) => {
|
||||
Some(Ref {
|
||||
kind: RefKind::Type,
|
||||
|
@ -438,12 +438,12 @@ impl Sig for ast::Item {
|
||||
refs: vec![],
|
||||
})
|
||||
}
|
||||
ast::ItemKind::Existential(ref bounds, ref generics) => {
|
||||
let text = "existential type ".to_owned();
|
||||
ast::ItemKind::OpaqueTy(ref bounds, ref generics) => {
|
||||
let text = "type ".to_owned();
|
||||
let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?;
|
||||
|
||||
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(';');
|
||||
|
@ -173,7 +173,7 @@ crate fn program_clauses_for(tcx: TyCtxt<'_>, def_id: DefId) -> Clauses<'_> {
|
||||
| Some(DefKind::Enum)
|
||||
| Some(DefKind::TyAlias)
|
||||
| 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(),
|
||||
},
|
||||
DefPathData::Impl => program_clauses_for_impl(tcx, def_id),
|
||||
|
@ -1956,7 +1956,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
|
||||
let span = path.span;
|
||||
match path.res {
|
||||
Res::Def(DefKind::Existential, did) => {
|
||||
Res::Def(DefKind::OpaqueTy, did) => {
|
||||
// Check for desugared `impl Trait`.
|
||||
assert!(ty::is_impl_trait_defn(tcx, did).is_none());
|
||||
let item_segment = path.segments.split_last().unwrap();
|
||||
|
@ -1489,7 +1489,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
match self.mode {
|
||||
Mode::MethodCall => item.method_has_self_argument,
|
||||
Mode::Path => match item.kind {
|
||||
ty::AssocKind::Existential |
|
||||
ty::AssocKind::OpaqueTy |
|
||||
ty::AssocKind::Type => false,
|
||||
ty::AssocKind::Method | ty::AssocKind::Const => true
|
||||
},
|
||||
|
@ -1330,10 +1330,10 @@ fn check_opaque<'tcx>(
|
||||
def_id: DefId,
|
||||
substs: SubstsRef<'tcx>,
|
||||
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 hir::ExistTyOrigin::AsyncFn = origin {
|
||||
if let hir::OpaqueTyOrigin::AsyncFn = origin {
|
||||
struct_span_err!(
|
||||
tcx.sess, span, E0733,
|
||||
"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(..) => {
|
||||
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 substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
@ -1542,7 +1542,7 @@ fn check_specialization_validity<'tcx>(
|
||||
let kind = match impl_item.node {
|
||||
hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
|
||||
hir::ImplItemKind::Method(..) => ty::AssocKind::Method,
|
||||
hir::ImplItemKind::Existential(..) => ty::AssocKind::Existential,
|
||||
hir::ImplItemKind::OpaqueTy(..) => ty::AssocKind::OpaqueTy,
|
||||
hir::ImplItemKind::Type(_) => ty::AssocKind::Type
|
||||
};
|
||||
|
||||
@ -1639,7 +1639,7 @@ fn check_impl_items_against_trait<'tcx>(
|
||||
err.emit()
|
||||
}
|
||||
}
|
||||
hir::ImplItemKind::Existential(..) |
|
||||
hir::ImplItemKind::OpaqueTy(..) |
|
||||
hir::ImplItemKind::Type(_) => {
|
||||
if ty_trait_item.kind == ty::AssocKind::Type {
|
||||
if ty_trait_item.defaultness.has_value() {
|
||||
|
@ -8,7 +8,7 @@ use rustc::ty::subst::{Subst, InternalSubsts};
|
||||
use rustc::util::nodemap::{FxHashSet, FxHashMap};
|
||||
use rustc::mir::interpret::ConstValue;
|
||||
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::feature_gate::{self, GateIssue};
|
||||
@ -218,8 +218,8 @@ fn check_associated_item(
|
||||
fcx.register_wf_obligation(ty, span, code.clone());
|
||||
}
|
||||
}
|
||||
ty::AssocKind::Existential => {
|
||||
// do nothing, existential types check themselves
|
||||
ty::AssocKind::OpaqueTy => {
|
||||
// do nothing, opaque types check themselves
|
||||
}
|
||||
}
|
||||
|
||||
@ -560,7 +560,7 @@ fn check_where_clauses<'tcx, 'fcx>(
|
||||
let mut predicates = predicates.instantiate_identity(fcx.tcx);
|
||||
|
||||
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);
|
||||
@ -605,14 +605,14 @@ fn check_fn_or_method<'fcx, 'tcx>(
|
||||
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
|
||||
/// "higher-order pattern unification".
|
||||
/// Checks "defining uses" of opaque `impl Trait` types to ensure that they meet the restrictions
|
||||
/// laid for "higher-order pattern unification".
|
||||
/// 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:
|
||||
///
|
||||
/// ```rust
|
||||
/// existential type Foo<A, B>;
|
||||
/// type Foo<A, B> = impl Bar<A, B>;
|
||||
///
|
||||
/// // Okay -- `Foo` is applied to two distinct, generic types.
|
||||
/// 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 check_existential_types<'fcx, 'tcx>(
|
||||
fn check_opaque_types<'fcx, 'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
fcx: &FnCtxt<'fcx, 'tcx>,
|
||||
fn_def_id: DefId,
|
||||
span: Span,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Vec<ty::Predicate<'tcx>> {
|
||||
trace!("check_existential_types(ty={:?})", ty);
|
||||
trace!("check_opaque_types(ty={:?})", ty);
|
||||
let mut substituted_predicates = Vec::new();
|
||||
ty.fold_with(&mut ty::fold::BottomUpFolder {
|
||||
tcx: fcx.tcx,
|
||||
ty_op: |ty| {
|
||||
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);
|
||||
// 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() {
|
||||
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) {
|
||||
trace!("check_existential_types: may define, generics={:#?}", generics);
|
||||
if may_define_opaque_type(tcx, fn_def_id, opaque_hir_id) {
|
||||
trace!("check_opaque_types: may define, generics={:#?}", generics);
|
||||
let mut seen: FxHashMap<_, Vec<_>> = FxHashMap::default();
|
||||
for (subst, param) in substs.iter().zip(&generics.params) {
|
||||
match subst.unpack() {
|
||||
@ -654,7 +654,7 @@ fn check_existential_types<'fcx, 'tcx>(
|
||||
tcx.sess
|
||||
.struct_span_err(
|
||||
span,
|
||||
"non-defining existential type use \
|
||||
"non-defining opaque type use \
|
||||
in defining scope",
|
||||
)
|
||||
.span_note(
|
||||
@ -676,14 +676,14 @@ fn check_existential_types<'fcx, 'tcx>(
|
||||
.sess
|
||||
.struct_span_err(
|
||||
span,
|
||||
"non-defining existential type use \
|
||||
"non-defining opaque type use \
|
||||
in defining scope",
|
||||
)
|
||||
.span_label(
|
||||
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 \
|
||||
existential type",
|
||||
opaque type",
|
||||
)
|
||||
.emit();
|
||||
} else {
|
||||
@ -697,7 +697,7 @@ fn check_existential_types<'fcx, 'tcx>(
|
||||
tcx.sess
|
||||
.struct_span_err(
|
||||
span,
|
||||
"non-defining existential type use \
|
||||
"non-defining opaque type use \
|
||||
in defining scope",
|
||||
)
|
||||
.span_note(
|
||||
@ -719,7 +719,7 @@ fn check_existential_types<'fcx, 'tcx>(
|
||||
.sess
|
||||
.struct_span_err(
|
||||
span,
|
||||
"non-defining existential type use \
|
||||
"non-defining opaque type use \
|
||||
in defining scope",
|
||||
).
|
||||
span_note(
|
||||
@ -729,21 +729,21 @@ fn check_existential_types<'fcx, 'tcx>(
|
||||
.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.
|
||||
//
|
||||
// existential type Foo<T: Bar>: 'static;
|
||||
// type Foo<T: Bar> = impl Baz + 'static;
|
||||
// fn foo<U>() -> Foo<U> { .. *}
|
||||
//
|
||||
// becomes
|
||||
//
|
||||
// existential type Foo<T: Bar>: 'static;
|
||||
// type Foo<T: Bar> = impl Baz + 'static;
|
||||
// fn foo<U: Bar>() -> Foo<U> { .. *}
|
||||
let predicates = tcx.predicates_of(def_id);
|
||||
trace!(
|
||||
"check_existential_types: may define, predicates={:#?}",
|
||||
"check_opaque_types: may define, predicates={:#?}",
|
||||
predicates,
|
||||
);
|
||||
for &(pred, _) in predicates.predicates.iter() {
|
||||
@ -753,7 +753,7 @@ fn check_existential_types<'fcx, 'tcx>(
|
||||
substituted_predicates.push(substituted_pred);
|
||||
}
|
||||
}
|
||||
} // if is_named_existential_type
|
||||
} // if is_named_opaque_type
|
||||
} // if let Opaque
|
||||
ty
|
||||
},
|
||||
|
@ -443,10 +443,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||
// * `fn foo<T: Bound + Other>() -> Foo<T>`
|
||||
// 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
|
||||
// ```rust
|
||||
// existential type Foo<T>: 'static;
|
||||
// type Foo<T> = impl Baz + 'static;
|
||||
// fn foo<U>() -> Foo<U> { .. }
|
||||
// ```
|
||||
// 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() {
|
||||
// We only want to add an entry into `concrete_existential_types`
|
||||
// if we actually found a defining usage of this existential type.
|
||||
// We only want to add an entry into `concrete_opaque_types`
|
||||
// if we actually found a defining usage of this opaque type.
|
||||
// Otherwise, we do nothing - we'll either find a defining usage
|
||||
// in some other location, or we'll end up emitting an error due
|
||||
// to the lack of defining usage
|
||||
@ -476,14 +476,14 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||
};
|
||||
|
||||
let old = self.tables
|
||||
.concrete_existential_types
|
||||
.concrete_opaque_types
|
||||
.insert(def_id, new);
|
||||
if let Some(old) = old {
|
||||
if old.concrete_type != definition_ty || old.substs != opaque_defn.substs {
|
||||
span_bug!(
|
||||
span,
|
||||
"visit_opaque_types tried to write different types for the same \
|
||||
existential type: {:?}, {:?}, {:?}, {:?}",
|
||||
opaque type: {:?}, {:?}, {:?}, {:?}",
|
||||
def_id,
|
||||
definition_ty,
|
||||
opaque_defn,
|
||||
|
@ -294,7 +294,7 @@ fn type_param_predicates(
|
||||
ItemKind::Fn(.., ref generics, _)
|
||||
| ItemKind::Impl(_, _, _, ref generics, ..)
|
||||
| ItemKind::Ty(_, ref generics)
|
||||
| ItemKind::Existential(ExistTy {
|
||||
| ItemKind::OpaqueTy(ExistTy {
|
||||
ref generics,
|
||||
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.
|
||||
hir::ItemKind::Existential(hir::ExistTy {
|
||||
hir::ItemKind::OpaqueTy(hir::ExistTy {
|
||||
impl_trait_fn: Some(_),
|
||||
..
|
||||
}) => {}
|
||||
|
||||
hir::ItemKind::Existential(..)
|
||||
hir::ItemKind::OpaqueTy(..)
|
||||
| hir::ItemKind::Ty(..)
|
||||
| hir::ItemKind::Static(..)
|
||||
| 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)),
|
||||
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,
|
||||
@ -920,7 +920,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics {
|
||||
ItemKind::Ty(_, ref generics)
|
||||
| ItemKind::Enum(_, ref generics)
|
||||
| ItemKind::Struct(_, ref generics)
|
||||
| ItemKind::Existential(hir::ExistTy { ref generics, .. })
|
||||
| ItemKind::OpaqueTy(hir::ExistTy { ref generics, .. })
|
||||
| ItemKind::Union(_, ref generics) => {
|
||||
allow_defaults = true;
|
||||
generics
|
||||
@ -1210,7 +1210,7 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
|
||||
icx.to_ty(ty)
|
||||
}
|
||||
},
|
||||
ImplItemKind::Existential(_) => {
|
||||
ImplItemKind::OpaqueTy(_) => {
|
||||
if tcx
|
||||
.impl_trait_ref(tcx.hir().get_parent_did(hir_id))
|
||||
.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);
|
||||
}
|
||||
|
||||
find_existential_constraints(tcx, def_id)
|
||||
find_opaque_ty_constraints(tcx, def_id)
|
||||
}
|
||||
ImplItemKind::Type(ref ty) => {
|
||||
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);
|
||||
tcx.mk_adt(def, substs)
|
||||
}
|
||||
ItemKind::Existential(hir::ExistTy {
|
||||
ItemKind::OpaqueTy(hir::ExistTy {
|
||||
impl_trait_fn: None,
|
||||
..
|
||||
}) => find_existential_constraints(tcx, def_id),
|
||||
// Existential types desugared from `impl Trait`.
|
||||
ItemKind::Existential(hir::ExistTy {
|
||||
}) => find_opaque_ty_constraints(tcx, def_id),
|
||||
// Opaque types desugared from `impl Trait`.
|
||||
ItemKind::OpaqueTy(hir::ExistTy {
|
||||
impl_trait_fn: Some(owner),
|
||||
..
|
||||
}) => {
|
||||
tcx.typeck_tables_of(owner)
|
||||
.concrete_existential_types
|
||||
.concrete_opaque_types
|
||||
.get(&def_id)
|
||||
.map(|opaque| opaque.concrete_type)
|
||||
.unwrap_or_else(|| {
|
||||
// This can occur if some error in the
|
||||
// owner fn prevented us from populating
|
||||
// the `concrete_existential_types` table.
|
||||
// the `concrete_opaque_types` table.
|
||||
tcx.sess.delay_span_bug(
|
||||
DUMMY_SP,
|
||||
&format!(
|
||||
"owner {:?} has no existential type for {:?} in its tables",
|
||||
"owner {:?} has no opaque type for {:?} in its tables",
|
||||
owner, def_id,
|
||||
),
|
||||
);
|
||||
@ -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};
|
||||
|
||||
debug!("find_existential_constraints({:?})", def_id);
|
||||
debug!("find_opaque_ty_constraints({:?})", def_id);
|
||||
|
||||
struct ConstraintLocator<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: DefId,
|
||||
// (first found type span, actual type, mapping from the existential type's generic
|
||||
// (first found type span, actual type, mapping from the opaque type's generic
|
||||
// parameters to the concrete type's generic parameters)
|
||||
//
|
||||
// The mapping is an index for each use site of a generic parameter in the concrete type
|
||||
//
|
||||
// The indices index into the generic parameters on the existential type.
|
||||
// The indices index into the generic parameters on the opaque type.
|
||||
found: Option<(Span, Ty<'tcx>, Vec<usize>)>,
|
||||
}
|
||||
|
||||
@ -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.
|
||||
if !self.tcx.has_typeck_tables(def_id) {
|
||||
debug!(
|
||||
"find_existential_constraints: no constraint for `{:?}` at `{:?}`: no tables",
|
||||
"find_opaque_ty_constraints: no constraint for `{:?}` at `{:?}`: no tables",
|
||||
self.def_id,
|
||||
def_id,
|
||||
);
|
||||
@ -1536,11 +1536,11 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
let ty = self
|
||||
.tcx
|
||||
.typeck_tables_of(def_id)
|
||||
.concrete_existential_types
|
||||
.concrete_opaque_types
|
||||
.get(&self.def_id);
|
||||
if let Some(ty::ResolvedOpaqueTy { concrete_type, substs }) = ty {
|
||||
debug!(
|
||||
"find_existential_constraints: found constraint for `{:?}` at `{:?}`: {:?}",
|
||||
"find_opaque_ty_constraints: found constraint for `{:?}` at `{:?}`: {:?}",
|
||||
self.def_id,
|
||||
def_id,
|
||||
ty,
|
||||
@ -1561,7 +1561,7 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
self.tcx.sess.span_err(
|
||||
span,
|
||||
&format!(
|
||||
"defining existential type use restricts existential \
|
||||
"defining opaque type use restricts opaque \
|
||||
type by using the generic parameter `{}` twice",
|
||||
p.name
|
||||
),
|
||||
@ -1572,14 +1572,14 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
self.tcx.sess.delay_span_bug(
|
||||
span,
|
||||
&format!(
|
||||
"non-defining exist ty use in defining scope: {:?}, {:?}",
|
||||
"non-defining opaque ty use in defining scope: {:?}, {:?}",
|
||||
concrete_type, substs,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Compute the index within the existential type for each generic parameter used in
|
||||
// Compute the index within the opaque type for each generic parameter used in
|
||||
// the concrete type.
|
||||
let indices = concrete_type
|
||||
.subst(self.tcx, substs)
|
||||
@ -1595,7 +1595,7 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
if !substs.types().all(is_param) {
|
||||
self.tcx.sess.span_err(
|
||||
span,
|
||||
"defining existential type use does not fully define existential type",
|
||||
"defining opaque type use does not fully define opaque type",
|
||||
);
|
||||
} else if let Some((prev_span, prev_ty, ref prev_indices)) = self.found {
|
||||
let mut ty = concrete_type.walk().fuse();
|
||||
@ -1608,11 +1608,11 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
_ => t == p,
|
||||
});
|
||||
if !iter_eq || ty.next().is_some() || p_ty.next().is_some() {
|
||||
debug!("find_existential_constraints: span={:?}", span);
|
||||
// Found different concrete types for the existential type.
|
||||
debug!("find_opaque_ty_constraints: span={:?}", span);
|
||||
// Found different concrete types for the opaque type.
|
||||
let mut err = self.tcx.sess.struct_span_err(
|
||||
span,
|
||||
"concrete type differs from previous defining existential type use",
|
||||
"concrete type differs from previous defining opaque type use",
|
||||
);
|
||||
err.span_label(
|
||||
span,
|
||||
@ -1651,7 +1651,7 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
}
|
||||
} else {
|
||||
debug!(
|
||||
"find_existential_constraints: no constraint for `{:?}` at `{:?}`",
|
||||
"find_opaque_ty_constraints: no constraint for `{:?}` at `{:?}`",
|
||||
self.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) {
|
||||
debug!("find_existential_constraints: visiting {:?}", it);
|
||||
let def_id = self.tcx.hir().local_def_id(it.hir_id);
|
||||
// The existential type itself or its children are not within its reveal scope.
|
||||
// The opaque type itself or its children are not within its reveal scope.
|
||||
if def_id != self.def_id {
|
||||
self.check(def_id);
|
||||
intravisit::walk_item(self, it);
|
||||
@ -1675,7 +1675,7 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
fn visit_impl_item(&mut self, it: &'tcx ImplItem) {
|
||||
debug!("find_existential_constraints: visiting {:?}", it);
|
||||
let def_id = self.tcx.hir().local_def_id(it.hir_id);
|
||||
// The existential type itself or its children are not within its reveal scope.
|
||||
// The opaque type itself or its children are not within its reveal scope.
|
||||
if def_id != self.def_id {
|
||||
self.check(def_id);
|
||||
intravisit::walk_impl_item(self, it);
|
||||
@ -1699,12 +1699,12 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
found: None,
|
||||
};
|
||||
|
||||
debug!("find_existential_constraints: scope={:?}", scope);
|
||||
debug!("find_opaque_ty_constraints: scope={:?}", scope);
|
||||
|
||||
if scope == hir::CRATE_HIR_ID {
|
||||
intravisit::walk_crate(&mut locator, tcx.hir().krate());
|
||||
} else {
|
||||
debug!("find_existential_constraints: scope={:?}", tcx.hir().get(scope));
|
||||
debug!("find_opaque_ty_constraints: scope={:?}", tcx.hir().get(scope));
|
||||
match tcx.hir().get(scope) {
|
||||
// We explicitly call `visit_*` methods, instead of using `intravisit::walk_*` methods
|
||||
// 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::TraitItem(ref it) => locator.visit_trait_item(it),
|
||||
other => bug!(
|
||||
"{:?} is not a valid scope for an existential type item",
|
||||
"{:?} is not a valid scope for an opaque type item",
|
||||
other
|
||||
),
|
||||
}
|
||||
@ -2010,7 +2010,7 @@ fn explicit_predicates_of(
|
||||
Node::TraitItem(item) => &item.generics,
|
||||
|
||||
Node::ImplItem(item) => match item.node {
|
||||
ImplItemKind::Existential(ref bounds) => {
|
||||
ImplItemKind::OpaqueTy(ref bounds) => {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
let opaque_ty = tcx.mk_opaque(def_id, substs);
|
||||
|
||||
@ -2051,7 +2051,7 @@ fn explicit_predicates_of(
|
||||
is_trait = Some((ty::TraitRef::identity(tcx, def_id), &empty_trait_items));
|
||||
generics
|
||||
}
|
||||
ItemKind::Existential(ExistTy {
|
||||
ItemKind::OpaqueTy(ExistTy {
|
||||
ref bounds,
|
||||
impl_trait_fn,
|
||||
ref generics,
|
||||
@ -2077,7 +2077,7 @@ fn explicit_predicates_of(
|
||||
predicates: bounds_predicates,
|
||||
});
|
||||
} else {
|
||||
// named existential types
|
||||
// named opaque types
|
||||
predicates.extend(bounds_predicates);
|
||||
generics
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ pub enum Namespace {
|
||||
impl From<ty::AssocKind> for Namespace {
|
||||
fn from(a_kind: ty::AssocKind) -> Self {
|
||||
match a_kind {
|
||||
ty::AssocKind::Existential |
|
||||
ty::AssocKind::OpaqueTy |
|
||||
ty::AssocKind::Type => Namespace::Type,
|
||||
ty::AssocKind::Const |
|
||||
ty::AssocKind::Method => Namespace::Value,
|
||||
@ -22,7 +22,7 @@ impl From<ty::AssocKind> for Namespace {
|
||||
impl<'a> From <&'a hir::ImplItemKind> for Namespace {
|
||||
fn from(impl_kind: &'a hir::ImplItemKind) -> Self {
|
||||
match *impl_kind {
|
||||
hir::ImplItemKind::Existential(..) |
|
||||
hir::ImplItemKind::OpaqueTy(..) |
|
||||
hir::ImplItemKind::Type(..) => Namespace::Type,
|
||||
hir::ImplItemKind::Const(..) |
|
||||
hir::ImplItemKind::Method(..) => Namespace::Value,
|
||||
|
@ -296,7 +296,7 @@ pub fn check_explicit_predicates<'tcx>(
|
||||
// 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
|
||||
// (or any other generic parameter) declared on `MyStruct`.
|
||||
//
|
||||
|
@ -538,7 +538,7 @@ pub enum ItemEnum {
|
||||
FunctionItem(Function),
|
||||
ModuleItem(Module),
|
||||
TypedefItem(Typedef, bool /* is associated type */),
|
||||
ExistentialItem(Existential, bool /* is associated type */),
|
||||
OpaqueTyItem(OpaqueTy, bool /* is associated type */),
|
||||
StaticItem(Static),
|
||||
ConstantItem(Constant),
|
||||
TraitItem(Trait),
|
||||
@ -574,7 +574,7 @@ impl ItemEnum {
|
||||
ItemEnum::EnumItem(ref e) => &e.generics,
|
||||
ItemEnum::FunctionItem(ref f) => &f.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::ImplItem(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.mods.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.constants.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),
|
||||
generics: Generics::default(),
|
||||
}, true),
|
||||
hir::ImplItemKind::Existential(ref bounds) => ExistentialItem(Existential {
|
||||
hir::ImplItemKind::OpaqueTy(ref bounds) => OpaqueTyItem(OpaqueTy {
|
||||
bounds: bounds.clean(cx),
|
||||
generics: Generics::default(),
|
||||
}, true),
|
||||
@ -2415,7 +2415,7 @@ impl Clean<Item> for ty::AssocItem {
|
||||
}, true)
|
||||
}
|
||||
}
|
||||
ty::AssocKind::Existential => unimplemented!(),
|
||||
ty::AssocKind::OpaqueTy => unimplemented!(),
|
||||
};
|
||||
|
||||
let visibility = match self.container {
|
||||
@ -2776,7 +2776,7 @@ impl Clean<Type> for hir::Ty {
|
||||
TyKind::Tup(ref tys) => Tuple(tys.clean(cx)),
|
||||
TyKind::Def(item_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))
|
||||
} else {
|
||||
unreachable!()
|
||||
@ -3648,12 +3648,12 @@ impl Clean<Item> for doctree::Typedef<'_> {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Existential {
|
||||
pub struct OpaqueTy {
|
||||
pub bounds: Vec<GenericBound>,
|
||||
pub generics: Generics,
|
||||
}
|
||||
|
||||
impl Clean<Item> for doctree::Existential<'_> {
|
||||
impl Clean<Item> for doctree::OpaqueTy<'_> {
|
||||
fn clean(&self, cx: &DocContext<'_>) -> Item {
|
||||
Item {
|
||||
name: Some(self.name.clean(cx)),
|
||||
@ -3663,7 +3663,7 @@ impl Clean<Item> for doctree::Existential<'_> {
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: self.stab.clean(cx),
|
||||
deprecation: self.depr.clean(cx),
|
||||
inner: ExistentialItem(Existential {
|
||||
inner: OpaqueTyItem(OpaqueTy {
|
||||
bounds: self.exist_ty.bounds.clean(cx),
|
||||
generics: self.exist_ty.generics.clean(cx),
|
||||
}, false),
|
||||
|
@ -26,7 +26,7 @@ pub struct Module<'hir> {
|
||||
pub mods: Vec<Module<'hir>>,
|
||||
pub id: NodeId,
|
||||
pub typedefs: Vec<Typedef<'hir>>,
|
||||
pub existentials: Vec<Existential<'hir>>,
|
||||
pub opaque_tys: Vec<OpaqueTy<'hir>>,
|
||||
pub statics: Vec<Static<'hir>>,
|
||||
pub constants: Vec<Constant<'hir>>,
|
||||
pub traits: Vec<Trait<'hir>>,
|
||||
@ -64,7 +64,7 @@ impl Module<'hir> {
|
||||
fns : Vec::new(),
|
||||
mods : Vec::new(),
|
||||
typedefs : Vec::new(),
|
||||
existentials: Vec::new(),
|
||||
opaque_tys : Vec::new(),
|
||||
statics : Vec::new(),
|
||||
constants : Vec::new(),
|
||||
traits : Vec::new(),
|
||||
@ -162,8 +162,8 @@ pub struct Typedef<'hir> {
|
||||
pub depr: Option<attr::Deprecation>,
|
||||
}
|
||||
|
||||
pub struct Existential<'hir> {
|
||||
pub exist_ty: &'hir hir::ExistTy,
|
||||
pub struct OpaqueTy<'hir> {
|
||||
pub opaque_ty: &'hir hir::OpaqueTy,
|
||||
pub name: Name,
|
||||
pub id: hir::HirId,
|
||||
pub attrs: &'hir hir::HirVec<ast::Attribute>,
|
||||
|
@ -39,7 +39,7 @@ pub enum ItemType {
|
||||
Union = 19,
|
||||
ForeignType = 20,
|
||||
Keyword = 21,
|
||||
Existential = 22,
|
||||
OpaqueTy = 22,
|
||||
ProcAttribute = 23,
|
||||
ProcDerive = 24,
|
||||
TraitAlias = 25,
|
||||
@ -70,7 +70,7 @@ impl<'a> From<&'a clean::Item> for ItemType {
|
||||
clean::EnumItem(..) => ItemType::Enum,
|
||||
clean::FunctionItem(..) => ItemType::Function,
|
||||
clean::TypedefItem(..) => ItemType::Typedef,
|
||||
clean::ExistentialItem(..) => ItemType::Existential,
|
||||
clean::OpaqueTyItem(..) => ItemType::OpaqueTy,
|
||||
clean::StaticItem(..) => ItemType::Static,
|
||||
clean::ConstantItem(..) => ItemType::Constant,
|
||||
clean::TraitItem(..) => ItemType::Trait,
|
||||
@ -144,7 +144,7 @@ impl ItemType {
|
||||
ItemType::AssocConst => "associatedconstant",
|
||||
ItemType::ForeignType => "foreigntype",
|
||||
ItemType::Keyword => "keyword",
|
||||
ItemType::Existential => "existential",
|
||||
ItemType::OpaqueTy => "opaque",
|
||||
ItemType::ProcAttribute => "attr",
|
||||
ItemType::ProcDerive => "derive",
|
||||
ItemType::TraitAlias => "traitalias",
|
||||
@ -161,7 +161,7 @@ impl ItemType {
|
||||
ItemType::Trait |
|
||||
ItemType::Primitive |
|
||||
ItemType::AssocType |
|
||||
ItemType::Existential |
|
||||
ItemType::OpaqueTy |
|
||||
ItemType::TraitAlias |
|
||||
ItemType::ForeignType => NameSpace::Type,
|
||||
|
||||
|
@ -1883,7 +1883,7 @@ struct AllTypes {
|
||||
macros: FxHashSet<ItemEntry>,
|
||||
functions: FxHashSet<ItemEntry>,
|
||||
typedefs: FxHashSet<ItemEntry>,
|
||||
existentials: FxHashSet<ItemEntry>,
|
||||
opaque_tys: FxHashSet<ItemEntry>,
|
||||
statics: FxHashSet<ItemEntry>,
|
||||
constants: FxHashSet<ItemEntry>,
|
||||
keywords: FxHashSet<ItemEntry>,
|
||||
@ -1904,7 +1904,7 @@ impl AllTypes {
|
||||
macros: new_set(100),
|
||||
functions: new_set(100),
|
||||
typedefs: new_set(100),
|
||||
existentials: new_set(100),
|
||||
opaque_tys: new_set(100),
|
||||
statics: new_set(100),
|
||||
constants: new_set(100),
|
||||
keywords: new_set(100),
|
||||
@ -1929,7 +1929,7 @@ impl AllTypes {
|
||||
ItemType::Macro => self.macros.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::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::Constant => self.constants.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.typedefs, "Typedefs", "typedefs")?;
|
||||
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.constants, "Constants", "constants")
|
||||
}
|
||||
@ -2477,7 +2477,7 @@ impl<'a> fmt::Display for Item<'a> {
|
||||
clean::ConstantItem(..) => write!(fmt, "Constant ")?,
|
||||
clean::ForeignTypeItem => write!(fmt, "Foreign Type ")?,
|
||||
clean::KeywordItem(..) => write!(fmt, "Keyword ")?,
|
||||
clean::ExistentialItem(..) => write!(fmt, "Existential Type ")?,
|
||||
clean::OpaqueTyItem(..) => write!(fmt, "Opaque Type ")?,
|
||||
clean::TraitAliasItem(..) => write!(fmt, "Trait Alias ")?,
|
||||
_ => {
|
||||
// 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::ForeignTypeItem => item_foreign_type(fmt, self.cx, self.item),
|
||||
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),
|
||||
_ => {
|
||||
// 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(())
|
||||
}
|
||||
|
||||
fn item_existential(
|
||||
fn item_opaque_ty(
|
||||
w: &mut fmt::Formatter<'_>,
|
||||
cx: &Context,
|
||||
it: &clean::Item,
|
||||
t: &clean::Existential,
|
||||
t: &clean::OpaqueTy,
|
||||
) -> fmt::Result {
|
||||
write!(w, "<pre class='rust existential'>")?;
|
||||
write!(w, "<pre class='rust opaque'>")?;
|
||||
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(),
|
||||
t.generics,
|
||||
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::ForeignType => ("foreign-types", "Foreign Types"),
|
||||
ItemType::Keyword => ("keywords", "Keywords"),
|
||||
ItemType::Existential => ("existentials", "Existentials"),
|
||||
ItemType::OpaqueTy => ("opaque-types", "Opaque Types"),
|
||||
ItemType::ProcAttribute => ("attributes", "Attribute Macros"),
|
||||
ItemType::ProcDerive => ("derives", "Derive Macros"),
|
||||
ItemType::TraitAlias => ("trait-aliases", "Trait aliases"),
|
||||
|
@ -159,7 +159,7 @@ impl<'a> DocFolder for Stripper<'a> {
|
||||
return ret;
|
||||
}
|
||||
// These items can all get re-exported
|
||||
clean::ExistentialItem(..)
|
||||
clean::OpaqueTyItem(..)
|
||||
| clean::TypedefItem(..)
|
||||
| clean::StaticItem(..)
|
||||
| clean::StructItem(..)
|
||||
|
@ -472,8 +472,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
};
|
||||
om.typedefs.push(t);
|
||||
},
|
||||
hir::ItemKind::Existential(ref exist_ty) => {
|
||||
let t = Existential {
|
||||
hir::ItemKind::OpaqueTy(ref exist_ty) => {
|
||||
let t = OpaqueTy {
|
||||
exist_ty,
|
||||
name: ident.name,
|
||||
id: item.hir_id,
|
||||
@ -483,7 +483,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
stab: self.stability(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) => {
|
||||
let s = Static {
|
||||
|
@ -1485,6 +1485,7 @@ pub enum TraitItemKind {
|
||||
Macro(Mac),
|
||||
}
|
||||
|
||||
/// Represents anything within an `impl` block.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct ImplItem {
|
||||
pub id: NodeId,
|
||||
@ -1499,12 +1500,13 @@ pub struct ImplItem {
|
||||
pub tokens: Option<TokenStream>,
|
||||
}
|
||||
|
||||
/// Represents various kinds of content within an `impl`.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub enum ImplItemKind {
|
||||
Const(P<Ty>, P<Expr>),
|
||||
Method(MethodSig, P<Block>),
|
||||
Type(P<Ty>),
|
||||
Existential(GenericBounds),
|
||||
OpaqueTy(GenericBounds),
|
||||
Macro(Mac),
|
||||
}
|
||||
|
||||
@ -1707,7 +1709,7 @@ pub enum TyKind {
|
||||
///
|
||||
/// The `NodeId` exists to prevent lowering from having to
|
||||
/// 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),
|
||||
/// No-op; kept solely so that we can pretty-print faithfully.
|
||||
Paren(P<Ty>),
|
||||
@ -2331,10 +2333,10 @@ pub enum ItemKind {
|
||||
///
|
||||
/// E.g., `type Foo = Bar<u8>;`.
|
||||
Ty(P<Ty>, Generics),
|
||||
/// An existential type declaration (`existential type`).
|
||||
/// An opaque `impl Trait` type alias.
|
||||
///
|
||||
/// E.g., `existential type Foo: Bar + Boo;`.
|
||||
Existential(GenericBounds, Generics),
|
||||
/// E.g., `type Foo = impl Bar + Boo;`.
|
||||
OpaqueTy(GenericBounds, Generics),
|
||||
/// An enum definition (`enum` or `pub enum`).
|
||||
///
|
||||
/// E.g., `enum Foo<A, B> { C<A>, D<B> }`.
|
||||
@ -2388,7 +2390,7 @@ impl ItemKind {
|
||||
ItemKind::ForeignMod(..) => "foreign module",
|
||||
ItemKind::GlobalAsm(..) => "global asm",
|
||||
ItemKind::Ty(..) => "type alias",
|
||||
ItemKind::Existential(..) => "existential type",
|
||||
ItemKind::OpaqueTy(..) => "opaque type",
|
||||
ItemKind::Enum(..) => "enum",
|
||||
ItemKind::Struct(..) => "struct",
|
||||
ItemKind::Union(..) => "union",
|
||||
|
@ -2017,12 +2017,12 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
gate_feature_post!(&self, decl_macro, i.span, msg);
|
||||
}
|
||||
|
||||
ast::ItemKind::Existential(..) => {
|
||||
ast::ItemKind::OpaqueTy(..) => {
|
||||
gate_feature_post!(
|
||||
&self,
|
||||
type_alias_impl_trait,
|
||||
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 {
|
||||
ast::ImplItemKind::Method(..) => {}
|
||||
ast::ImplItemKind::Existential(..) => {
|
||||
ast::ImplItemKind::OpaqueTy(..) => {
|
||||
gate_feature_post!(
|
||||
&self,
|
||||
type_alias_impl_trait,
|
||||
ii.span,
|
||||
"existential types are unstable"
|
||||
"`impl Trait` in type aliases is unstable"
|
||||
);
|
||||
}
|
||||
ast::ImplItemKind::Type(_) => {
|
||||
|
@ -848,7 +848,7 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
|
||||
vis.visit_ty(ty);
|
||||
vis.visit_generics(generics);
|
||||
}
|
||||
ItemKind::Existential(bounds, generics) => {
|
||||
ItemKind::OpaqueTy(bounds, generics) => {
|
||||
visit_bounds(bounds, vis);
|
||||
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);
|
||||
}
|
||||
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),
|
||||
}
|
||||
visitor.visit_span(span);
|
||||
|
@ -62,12 +62,12 @@ use std::path::{self, Path, PathBuf};
|
||||
use std::slice;
|
||||
|
||||
#[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 {
|
||||
/// Just a new name for the same type
|
||||
Weak(P<Ty>),
|
||||
/// Only trait impls of the type will be usable, not the actual type itself
|
||||
Existential(GenericBounds),
|
||||
OpaqueTy(GenericBounds),
|
||||
}
|
||||
|
||||
bitflags::bitflags! {
|
||||
@ -4265,11 +4265,6 @@ impl<'a> Parser<'a> {
|
||||
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 {
|
||||
// auto trait
|
||||
(self.token.is_keyword(kw::Auto) &&
|
||||
@ -4367,7 +4362,6 @@ impl<'a> Parser<'a> {
|
||||
!self.token.is_qpath_start() &&
|
||||
!self.is_union_item() &&
|
||||
!self.is_crate_vis() &&
|
||||
!self.is_existential_type_decl() &&
|
||||
!self.is_auto_trait_item() &&
|
||||
!self.is_async_fn() {
|
||||
let path = self.parse_path(PathStyle::Expr)?;
|
||||
@ -5686,7 +5680,7 @@ impl<'a> Parser<'a> {
|
||||
let (name, alias, generics) = type_?;
|
||||
let kind = match alias {
|
||||
AliasKind::Weak(typ) => ast::ImplItemKind::Type(typ),
|
||||
AliasKind::Existential(bounds) => ast::ImplItemKind::Existential(bounds),
|
||||
AliasKind::OpaqueTy(bounds) => ast::ImplItemKind::OpaqueTy(bounds),
|
||||
};
|
||||
(name, kind, generics)
|
||||
} 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)> {
|
||||
let ident = self.parse_ident()?;
|
||||
let mut tps = self.parse_generics()?;
|
||||
@ -6826,7 +6820,7 @@ impl<'a> Parser<'a> {
|
||||
let alias = if self.check_keyword(kw::Impl) {
|
||||
self.bump();
|
||||
let bounds = self.parse_generic_bounds(Some(self.prev_span))?;
|
||||
AliasKind::Existential(bounds)
|
||||
AliasKind::OpaqueTy(bounds)
|
||||
} else {
|
||||
let ty = self.parse_ty()?;
|
||||
AliasKind::Weak(ty)
|
||||
@ -7249,7 +7243,7 @@ impl<'a> Parser<'a> {
|
||||
// TYPE ITEM
|
||||
let item_ = match alias {
|
||||
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 item = self.mk_item(lo.to(prev_span),
|
||||
|
@ -1238,9 +1238,10 @@ impl<'a> State<'a> {
|
||||
self.s.word(";");
|
||||
self.end(); // end the outer ibox
|
||||
}
|
||||
ast::ItemKind::Existential(ref bounds, ref generics) => {
|
||||
self.head(visibility_qualified(&item.vis, "existential type"));
|
||||
ast::ItemKind::OpaqueTy(ref bounds, ref generics) => {
|
||||
self.head(visibility_qualified(&item.vis, "type"));
|
||||
self.print_ident(item.ident);
|
||||
self.word_space("= impl");
|
||||
self.print_generic_params(&generics.params);
|
||||
self.end(); // end the inner ibox
|
||||
|
||||
@ -1598,9 +1599,12 @@ impl<'a> State<'a> {
|
||||
ast::ImplItemKind::Type(ref ty) => {
|
||||
self.print_associated_type(ii.ident, None, Some(ty));
|
||||
}
|
||||
ast::ImplItemKind::Existential(ref bounds) => {
|
||||
self.word_space("existential");
|
||||
self.print_associated_type(ii.ident, Some(bounds), None);
|
||||
ast::ImplItemKind::OpaqueTy(ref bounds) => {
|
||||
self.word_space("type");
|
||||
self.print_ident(ii.ident);
|
||||
self.word_space("= impl");
|
||||
self.print_type_bounds(":", bounds);
|
||||
self.s.word(";");
|
||||
}
|
||||
ast::ImplItemKind::Macro(ref mac) => {
|
||||
self.print_mac(mac);
|
||||
|
@ -259,7 +259,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
|
||||
visitor.visit_ty(typ);
|
||||
visitor.visit_generics(generics)
|
||||
}
|
||||
ItemKind::Existential(ref bounds, ref generics) => {
|
||||
ItemKind::OpaqueTy(ref bounds, ref generics) => {
|
||||
walk_list!(visitor, visit_param_bound, bounds);
|
||||
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) => {
|
||||
visitor.visit_ty(ty);
|
||||
}
|
||||
ImplItemKind::Existential(ref bounds) => {
|
||||
ImplItemKind::OpaqueTy(ref bounds) => {
|
||||
walk_list!(visitor, visit_param_bound, bounds);
|
||||
}
|
||||
ImplItemKind::Macro(ref mac) => {
|
||||
|
@ -744,9 +744,9 @@ pub enum DesugaringKind {
|
||||
QuestionMark,
|
||||
TryBlock,
|
||||
/// 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`.
|
||||
ExistentialType,
|
||||
OpaqueTy,
|
||||
Async,
|
||||
Await,
|
||||
ForLoop,
|
||||
@ -761,7 +761,7 @@ impl DesugaringKind {
|
||||
DesugaringKind::Await => "`await` expression",
|
||||
DesugaringKind::QuestionMark => "operator `?`",
|
||||
DesugaringKind::TryBlock => "`try` block",
|
||||
DesugaringKind::ExistentialType => "`existential type`",
|
||||
DesugaringKind::OpaqueTy => "`impl Trait`",
|
||||
DesugaringKind::ForLoop => "`for` loop",
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,6 @@ symbols! {
|
||||
Auto: "auto",
|
||||
Catch: "catch",
|
||||
Default: "default",
|
||||
Existential: "existential",
|
||||
Union: "union",
|
||||
}
|
||||
|
||||
|
@ -29,9 +29,10 @@ impl ThisTrait for SomeStruct {
|
||||
/// but what about those aliases? i hear they're pretty exotic
|
||||
pub trait MyAlias = ThisTrait + Send + Sync;
|
||||
|
||||
// FIXME(58624): once rustdoc can process existential types, we need to make sure they're counted
|
||||
// /// woah, getting all existential in here
|
||||
// pub existential type ThisExists: ThisTrait;
|
||||
// FIXME(58624): once rustdoc can process opaque `impl Trait` types,
|
||||
// we need to make sure they're counted
|
||||
// /// woah, getting all abstract in here
|
||||
// pub type ThisExists = impl ThisTrait;
|
||||
//
|
||||
// /// why don't we get a little more concrete
|
||||
// pub fn defines() -> ThisExists { SomeStruct {} }
|
||||
|
@ -28,7 +28,7 @@ impl Case1 for S1 {
|
||||
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 Baz { type Assoc; }
|
||||
|
@ -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 {
|
||||
await!(wake_and_yield_once());
|
||||
*x
|
||||
|
230
src/test/ui/async-await/await-macro.rs
Normal file
230
src/test/ui/async-await/await-macro.rs
Normal 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))
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
@ -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?)
|
||||
// edition:2018
|
||||
|
@ -9,6 +9,6 @@ type Two<T, U> = impl Debug;
|
||||
//~^ could not find defining uses
|
||||
|
||||
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
|
||||
}
|
||||
|
@ -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
|
||||
|
|
||||
LL | / fn one<T: Debug>(t: T) -> Two<T, T> {
|
||||
|
@ -8,7 +8,7 @@ fn main() {}
|
||||
type Two<T, U> = impl Debug;
|
||||
|
||||
fn one<T: Debug>(t: T) -> Two<T, T> {
|
||||
//~^ defining existential type use restricts existential type
|
||||
//~^ defining opaque type use restricts opaque type
|
||||
t
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ fn main() {}
|
||||
type Two<T, U> = impl Debug;
|
||||
|
||||
fn one<T: Debug>(t: T) -> Two<T, T> {
|
||||
//~^ defining existential type use restricts existential type
|
||||
//~^ defining opaque type use restricts opaque type
|
||||
t
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ fn main() {}
|
||||
type Two<T, U> = impl Debug;
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
|
||||
LL | fn unwrap_items(self) -> Self::Iter {
|
||||
@ -9,7 +9,7 @@ LL | | self.map(|x| x.unwrap())
|
||||
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
|
||||
|
|
||||
LL | fn unwrap_items(self) -> Self::Iter {
|
||||
|
@ -5,7 +5,7 @@ trait Bug {
|
||||
}
|
||||
|
||||
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 could not find defining uses
|
||||
|
||||
|
@ -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
|
||||
|
|
||||
LL | type Item = impl Bug;
|
||||
|
@ -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
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
@ -7,7 +7,7 @@ fn main() {}
|
||||
type Two<T, U> = impl Debug;
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
|
||||
LL | / fn two<T: Debug>(t: T) -> Two<T, u32> {
|
||||
@ -7,7 +7,7 @@ LL | | (t, 4i8)
|
||||
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
|
||||
|
|
||||
LL | / fn four<T: Debug, U: Bar>(t: T) -> Two<T, U> {
|
||||
|
@ -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 {
|
||||
type Baa: std::fmt::Debug;
|
||||
@ -6,7 +6,7 @@ trait Bar {
|
||||
}
|
||||
|
||||
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 }
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
|
||||
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
|
||||
= 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
|
||||
|
|
||||
LL | type Baa = impl std::fmt::Debug;
|
||||
|
@ -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]
|
||||
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ LL | type E = impl Copy;
|
||||
= note: required because it appears within the type `(S, T)`
|
||||
= 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
|
||||
|
|
||||
LL | fn foo<T: Default>() -> Self::E {
|
||||
|
@ -12,7 +12,7 @@ impl<S> Bar for S {
|
||||
type E = impl Copy;
|
||||
//~^ ERROR the trait bound `impl std::future::Future: std::marker::Copy` is not satisfied [E0277]
|
||||
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 {}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ LL | type E = impl Copy;
|
||||
|
|
||||
= 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
|
||||
|
|
||||
LL | fn foo<T>() -> Self::E {
|
||||
|
@ -11,7 +11,7 @@ impl<S> Bar for S {
|
||||
type E = impl Copy;
|
||||
|
||||
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
|
||||
|| ()
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
|
||||
LL | fn foo<T>() -> Self::E {
|
||||
|
@ -120,7 +120,7 @@ trait DummyTrait {
|
||||
}
|
||||
impl DummyTrait for () {
|
||||
type Out = impl Debug;
|
||||
//~^ ERROR existential types are unstable
|
||||
//~^ ERROR `impl Trait` in type aliases is unstable
|
||||
//~^^ ERROR could not find defining uses
|
||||
|
||||
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;
|
||||
//~^ ERROR existential types are unstable
|
||||
//~^ ERROR `impl Trait` in type aliases is unstable
|
||||
//~^^ ERROR could not find defining uses
|
||||
|
||||
type InReturnInTypeAlias<R> = fn() -> impl Debug;
|
||||
|
@ -16,7 +16,7 @@ LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic
|
||||
| | nested `impl Trait` here
|
||||
| outer `impl Trait`
|
||||
|
||||
error[E0658]: existential types are unstable
|
||||
error[E0658]: `impl Trait` in type aliases is unstable
|
||||
--> $DIR/where-allowed.rs:122:5
|
||||
|
|
||||
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
|
||||
= 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
|
||||
|
|
||||
LL | type InTypeAlias<R> = impl Debug;
|
||||
|
@ -77,19 +77,19 @@ fn impl_trait_in_band(x: &impl MyTrait<'a>) {}
|
||||
|
||||
trait FunkyTrait<'a> { }
|
||||
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
|
||||
}
|
||||
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
|
||||
}
|
||||
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
|
||||
}
|
||||
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
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -10,5 +10,5 @@ extern crate std;
|
||||
trait Animal { }
|
||||
|
||||
fn main() {
|
||||
pub existential type ServeFut : Animal;
|
||||
pub type ServeFut= impl : Animal;
|
||||
}
|
||||
|
89
src/test/ui/type-alias-impl-trait.rs
Normal file
89
src/test/ui/type-alias-impl-trait.rs
Normal 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
|
||||
}
|
@ -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"]
|
||||
|
@ -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"]
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user