mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 07:22:42 +00:00
Auto merge of #63180 - varkor:trait-alias-impl-trait, r=Centril
Change opaque type syntax from `existential type` to type alias `impl Trait` This implements a new feature gate `type_alias_impl_trait` (this is slightly different from the originally proposed feature name, but matches what has been used in discussion since), deprecating the old `existential_types` feature. The syntax for opaque types has been changed. In addition, the "existential" terminology has been replaced with "opaque", as per previous discussion and the RFC. This makes partial progress towards implementing https://github.com/rust-lang/rust/issues/63063. r? @Centril
This commit is contained in:
commit
d7270712cb
@ -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(OpaqueTy {
|
||||
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,11 +1717,11 @@ impl<'a> LoweringContext<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_existential_impl_trait(
|
||||
fn lower_opaque_impl_trait(
|
||||
&mut self,
|
||||
span: Span,
|
||||
fn_def_id: Option<DefId>,
|
||||
exist_ty_node_id: NodeId,
|
||||
opaque_ty_node_id: NodeId,
|
||||
lower_bounds: impl FnOnce(&mut LoweringContext<'_>) -> hir::GenericBounds,
|
||||
) -> hir::TyKind {
|
||||
// Make sure we know that some funky desugaring has been going on here.
|
||||
@ -1729,30 +1729,30 @@ impl<'a> LoweringContext<'a> {
|
||||
// desugaring that explicitly states that we don't want to track that.
|
||||
// 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,
|
||||
let opaque_ty_span = self.mark_span_with_reason(
|
||||
DesugaringKind::OpaqueTy,
|
||||
span,
|
||||
None,
|
||||
);
|
||||
|
||||
let exist_ty_def_index = self
|
||||
let opaque_ty_def_index = self
|
||||
.resolver
|
||||
.definitions()
|
||||
.opt_def_index(exist_ty_node_id)
|
||||
.opt_def_index(opaque_ty_node_id)
|
||||
.unwrap();
|
||||
|
||||
self.allocate_hir_id_counter(exist_ty_node_id);
|
||||
self.allocate_hir_id_counter(opaque_ty_node_id);
|
||||
|
||||
let hir_bounds = self.with_hir_id_owner(exist_ty_node_id, lower_bounds);
|
||||
let hir_bounds = self.with_hir_id_owner(opaque_ty_node_id, lower_bounds);
|
||||
|
||||
let (lifetimes, lifetime_defs) = self.lifetimes_from_impl_trait_bounds(
|
||||
exist_ty_node_id,
|
||||
exist_ty_def_index,
|
||||
opaque_ty_node_id,
|
||||
opaque_ty_def_index,
|
||||
&hir_bounds,
|
||||
);
|
||||
|
||||
self.with_hir_id_owner(exist_ty_node_id, |lctx| {
|
||||
let exist_ty_item = hir::ExistTy {
|
||||
self.with_hir_id_owner(opaque_ty_node_id, |lctx| {
|
||||
let opaque_ty_item = hir::OpaqueTy {
|
||||
generics: hir::Generics {
|
||||
params: lifetime_defs,
|
||||
where_clause: hir::WhereClause {
|
||||
@ -1763,54 +1763,54 @@ impl<'a> LoweringContext<'a> {
|
||||
},
|
||||
bounds: hir_bounds,
|
||||
impl_trait_fn: fn_def_id,
|
||||
origin: hir::ExistTyOrigin::ReturnImplTrait,
|
||||
origin: hir::OpaqueTyOrigin::FnReturn,
|
||||
};
|
||||
|
||||
trace!("exist ty from impl trait def-index: {:#?}", exist_ty_def_index);
|
||||
let exist_ty_id = lctx.generate_existential_type(
|
||||
exist_ty_node_id,
|
||||
exist_ty_item,
|
||||
trace!("exist ty from impl trait def-index: {:#?}", opaque_ty_def_index);
|
||||
let opaque_ty_id = lctx.generate_opaque_type(
|
||||
opaque_ty_node_id,
|
||||
opaque_ty_item,
|
||||
span,
|
||||
exist_ty_span,
|
||||
opaque_ty_span,
|
||||
);
|
||||
|
||||
// `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
|
||||
hir::TyKind::Def(hir::ItemId { id: exist_ty_id }, lifetimes)
|
||||
hir::TyKind::Def(hir::ItemId { id: opaque_ty_id }, lifetimes)
|
||||
})
|
||||
}
|
||||
|
||||
/// 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,
|
||||
opaque_ty_node_id: NodeId,
|
||||
opaque_ty_item: hir::OpaqueTy,
|
||||
span: Span,
|
||||
exist_ty_span: Span,
|
||||
opaque_ty_span: Span,
|
||||
) -> hir::HirId {
|
||||
let exist_ty_item_kind = hir::ItemKind::Existential(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);
|
||||
let exist_ty_item = hir::Item {
|
||||
hir_id: exist_ty_id,
|
||||
let opaque_ty_item_kind = hir::ItemKind::OpaqueTy(opaque_ty_item);
|
||||
let opaque_ty_id = self.lower_node_id(opaque_ty_node_id);
|
||||
// Generate an `type Foo = impl Trait;` declaration.
|
||||
trace!("registering opaque type with id {:#?}", opaque_ty_id);
|
||||
let opaque_ty_item = hir::Item {
|
||||
hir_id: opaque_ty_id,
|
||||
ident: Ident::invalid(),
|
||||
attrs: Default::default(),
|
||||
node: exist_ty_item_kind,
|
||||
node: opaque_ty_item_kind,
|
||||
vis: respan(span.shrink_to_lo(), hir::VisibilityKind::Inherited),
|
||||
span: exist_ty_span,
|
||||
span: opaque_ty_span,
|
||||
};
|
||||
|
||||
// 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
|
||||
self.insert_item(opaque_ty_item);
|
||||
opaque_ty_id
|
||||
}
|
||||
|
||||
fn lifetimes_from_impl_trait_bounds(
|
||||
&mut self,
|
||||
exist_ty_id: NodeId,
|
||||
opaque_ty_id: NodeId,
|
||||
parent_index: DefIndex,
|
||||
bounds: &hir::GenericBounds,
|
||||
) -> (HirVec<hir::GenericArg>, HirVec<hir::GenericParam>) {
|
||||
@ -1820,7 +1820,7 @@ impl<'a> LoweringContext<'a> {
|
||||
struct ImplTraitLifetimeCollector<'r, 'a> {
|
||||
context: &'r mut LoweringContext<'a>,
|
||||
parent: DefIndex,
|
||||
exist_ty_id: NodeId,
|
||||
opaque_ty_id: NodeId,
|
||||
collect_elided_lifetimes: bool,
|
||||
currently_bound_lifetimes: Vec<hir::LifetimeName>,
|
||||
already_defined_lifetimes: FxHashSet<hir::LifetimeName>,
|
||||
@ -1894,7 +1894,7 @@ impl<'a> LoweringContext<'a> {
|
||||
hir::LifetimeName::Implicit | hir::LifetimeName::Underscore => {
|
||||
if self.collect_elided_lifetimes {
|
||||
// Use `'_` for both implicit and underscore lifetimes in
|
||||
// `abstract type Foo<'_>: SomeTrait<'_>;`.
|
||||
// `type Foo<'_> = impl SomeTrait<'_>;`.
|
||||
hir::LifetimeName::Underscore
|
||||
} else {
|
||||
return;
|
||||
@ -1916,7 +1916,7 @@ impl<'a> LoweringContext<'a> {
|
||||
|
||||
let def_node_id = self.context.sess.next_node_id();
|
||||
let hir_id =
|
||||
self.context.lower_node_id_with_owner(def_node_id, self.exist_ty_id);
|
||||
self.context.lower_node_id_with_owner(def_node_id, self.opaque_ty_id);
|
||||
self.context.resolver.definitions().create_def_with_parent(
|
||||
self.parent,
|
||||
def_node_id,
|
||||
@ -1952,7 +1952,7 @@ impl<'a> LoweringContext<'a> {
|
||||
let mut lifetime_collector = ImplTraitLifetimeCollector {
|
||||
context: self,
|
||||
parent: parent_index,
|
||||
exist_ty_id,
|
||||
opaque_ty_id,
|
||||
collect_elided_lifetimes: true,
|
||||
currently_bound_lifetimes: Vec::new(),
|
||||
already_defined_lifetimes: FxHashSet::default(),
|
||||
@ -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))
|
||||
))
|
||||
}
|
||||
_ => {
|
||||
@ -2582,40 +2582,40 @@ impl<'a> LoweringContext<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
// Transforms `-> T` for `async fn` into `-> ExistTy { .. }`
|
||||
// combined with the following definition of `ExistTy`:
|
||||
// Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`
|
||||
// combined with the following definition of `OpaqueTy`:
|
||||
//
|
||||
// existential type ExistTy<generics_from_parent_fn>: Future<Output = T>;
|
||||
// type OpaqueTy<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
|
||||
// `opaque_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,
|
||||
output: &FunctionRetTy,
|
||||
fn_def_id: DefId,
|
||||
exist_ty_node_id: NodeId,
|
||||
opaque_ty_node_id: NodeId,
|
||||
elided_lt_replacement: LtReplacement,
|
||||
) -> hir::FunctionRetTy {
|
||||
let span = output.span();
|
||||
|
||||
let exist_ty_span = self.mark_span_with_reason(
|
||||
let opaque_ty_span = self.mark_span_with_reason(
|
||||
DesugaringKind::Async,
|
||||
span,
|
||||
None,
|
||||
);
|
||||
|
||||
let exist_ty_def_index = self
|
||||
let opaque_ty_def_index = self
|
||||
.resolver
|
||||
.definitions()
|
||||
.opt_def_index(exist_ty_node_id)
|
||||
.opt_def_index(opaque_ty_node_id)
|
||||
.unwrap();
|
||||
|
||||
self.allocate_hir_id_counter(exist_ty_node_id);
|
||||
self.allocate_hir_id_counter(opaque_ty_node_id);
|
||||
|
||||
let (exist_ty_id, lifetime_params) = self.with_hir_id_owner(exist_ty_node_id, |this| {
|
||||
let (opaque_ty_id, lifetime_params) = self.with_hir_id_owner(opaque_ty_node_id, |this| {
|
||||
let future_bound = this.with_anonymous_lifetime_mode(
|
||||
AnonymousLifetimeMode::Replace(elided_lt_replacement),
|
||||
|this| this.lower_async_fn_output_type_to_future_bound(
|
||||
@ -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,
|
||||
@ -2642,11 +2642,11 @@ impl<'a> LoweringContext<'a> {
|
||||
lifetime_params
|
||||
.iter().cloned()
|
||||
.map(|(span, hir_name)| {
|
||||
this.lifetime_to_generic_param(span, hir_name, exist_ty_def_index)
|
||||
this.lifetime_to_generic_param(span, hir_name, opaque_ty_def_index)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let exist_ty_item = hir::ExistTy {
|
||||
let opaque_ty_item = hir::OpaqueTy {
|
||||
generics: hir::Generics {
|
||||
params: generic_params,
|
||||
where_clause: hir::WhereClause {
|
||||
@ -2657,18 +2657,18 @@ 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(
|
||||
exist_ty_node_id,
|
||||
exist_ty_item,
|
||||
trace!("exist ty from async fn def index: {:#?}", opaque_ty_def_index);
|
||||
let opaque_ty_id = this.generate_opaque_type(
|
||||
opaque_ty_node_id,
|
||||
opaque_ty_item,
|
||||
span,
|
||||
exist_ty_span,
|
||||
opaque_ty_span,
|
||||
);
|
||||
|
||||
(exist_ty_id, lifetime_params)
|
||||
(opaque_ty_id, lifetime_params)
|
||||
});
|
||||
|
||||
let generic_args =
|
||||
@ -2683,10 +2683,10 @@ impl<'a> LoweringContext<'a> {
|
||||
})
|
||||
.collect();
|
||||
|
||||
let exist_ty_ref = hir::TyKind::Def(hir::ItemId { id: exist_ty_id }, generic_args);
|
||||
let opaque_ty_ref = hir::TyKind::Def(hir::ItemId { id: opaque_ty_id }, generic_args);
|
||||
|
||||
hir::FunctionRetTy::Return(P(hir::Ty {
|
||||
node: exist_ty_ref,
|
||||
node: opaque_ty_ref,
|
||||
span,
|
||||
hir_id: self.next_id(),
|
||||
}))
|
||||
@ -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(
|
||||
hir::ExistTy {
|
||||
ItemKind::OpaqueTy(ref b, ref generics) => hir::ItemKind::OpaqueTy(
|
||||
hir::OpaqueTy {
|
||||
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::TypeAlias,
|
||||
},
|
||||
),
|
||||
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(OpaqueTy { 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`).
|
||||
@ -1922,20 +1922,20 @@ pub struct BareFnTy {
|
||||
}
|
||||
|
||||
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
|
||||
pub struct ExistTy {
|
||||
pub struct OpaqueTy {
|
||||
pub generics: Generics,
|
||||
pub bounds: GenericBounds,
|
||||
pub impl_trait_fn: Option<DefId>,
|
||||
pub origin: ExistTyOrigin,
|
||||
pub origin: OpaqueTyOrigin,
|
||||
}
|
||||
|
||||
/// Where the existential type came from
|
||||
/// From whence the opaque type came.
|
||||
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
|
||||
pub enum ExistTyOrigin {
|
||||
/// `existential type Foo: Trait;`
|
||||
ExistentialType,
|
||||
pub enum OpaqueTyOrigin {
|
||||
/// `type Foo = impl Trait;`
|
||||
TypeAlias,
|
||||
/// `-> impl Trait`
|
||||
ReturnImplTrait,
|
||||
FnReturn,
|
||||
/// `async fn`
|
||||
AsyncFn,
|
||||
}
|
||||
@ -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(OpaqueTy),
|
||||
/// 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(OpaqueTy { 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)]
|
||||
|
@ -450,6 +450,24 @@ impl<'a> State<'a> {
|
||||
self.s.word(";")
|
||||
}
|
||||
|
||||
fn print_item_type(
|
||||
&mut self,
|
||||
item: &hir::Item,
|
||||
generics: &hir::Generics,
|
||||
inner: impl Fn(&mut Self),
|
||||
) {
|
||||
self.head(visibility_qualified(&item.vis, "type"));
|
||||
self.print_ident(item.ident);
|
||||
self.print_generic_params(&generics.params);
|
||||
self.end(); // end the inner ibox
|
||||
|
||||
self.print_where_clause(&generics.where_clause);
|
||||
self.s.space();
|
||||
inner(self);
|
||||
self.s.word(";");
|
||||
self.end(); // end the outer ibox
|
||||
}
|
||||
|
||||
/// Pretty-print an item
|
||||
pub fn print_item(&mut self, item: &hir::Item) {
|
||||
self.hardbreak_if_not_bol();
|
||||
@ -553,43 +571,28 @@ impl<'a> State<'a> {
|
||||
self.end()
|
||||
}
|
||||
hir::ItemKind::Ty(ref ty, ref generics) => {
|
||||
self.head(visibility_qualified(&item.vis, "type"));
|
||||
self.print_ident(item.ident);
|
||||
self.print_generic_params(&generics.params);
|
||||
self.end(); // end the inner ibox
|
||||
|
||||
self.print_where_clause(&generics.where_clause);
|
||||
self.s.space();
|
||||
self.word_space("=");
|
||||
self.print_type(&ty);
|
||||
self.s.word(";");
|
||||
self.end(); // end the outer ibox
|
||||
self.print_item_type(item, &generics, |state| {
|
||||
state.word_space("=");
|
||||
state.print_type(&ty);
|
||||
});
|
||||
}
|
||||
hir::ItemKind::Existential(ref exist) => {
|
||||
self.head(visibility_qualified(&item.vis, "existential type"));
|
||||
self.print_ident(item.ident);
|
||||
self.print_generic_params(&exist.generics.params);
|
||||
self.end(); // end the inner ibox
|
||||
|
||||
self.print_where_clause(&exist.generics.where_clause);
|
||||
self.s.space();
|
||||
let mut real_bounds = Vec::with_capacity(exist.bounds.len());
|
||||
for b in exist.bounds.iter() {
|
||||
if let GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
|
||||
self.s.space();
|
||||
self.word_space("for ?");
|
||||
self.print_trait_ref(&ptr.trait_ref);
|
||||
} else {
|
||||
real_bounds.push(b);
|
||||
hir::ItemKind::OpaqueTy(ref opaque_ty) => {
|
||||
self.print_item_type(item, &opaque_ty.generics, |state| {
|
||||
let mut real_bounds = Vec::with_capacity(opaque_ty.bounds.len());
|
||||
for b in opaque_ty.bounds.iter() {
|
||||
if let GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
|
||||
state.s.space();
|
||||
state.word_space("for ?");
|
||||
state.print_trait_ref(&ptr.trait_ref);
|
||||
} else {
|
||||
real_bounds.push(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
self.print_bounds(":", real_bounds);
|
||||
self.s.word(";");
|
||||
self.end(); // end the outer ibox
|
||||
state.print_bounds("= impl", real_bounds);
|
||||
});
|
||||
}
|
||||
hir::ItemKind::Enum(ref enum_definition, ref params) => {
|
||||
self.print_enum_def(enum_definition, params, item.ident.name, item.span,
|
||||
&item.vis);
|
||||
self.print_enum_def(enum_definition, params, item.ident.name, item.span, &item.vis);
|
||||
}
|
||||
hir::ItemKind::Struct(ref struct_def, ref generics) => {
|
||||
self.head(visibility_qualified(&item.vis, "struct"));
|
||||
@ -908,9 +911,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",
|
||||
}
|
||||
}
|
||||
|
@ -18,19 +18,19 @@ use syntax_pos::Span;
|
||||
|
||||
pub type OpaqueTypeMap<'tcx> = DefIdMap<OpaqueTypeDecl<'tcx>>;
|
||||
|
||||
/// Information about the opaque, abstract types whose values we
|
||||
/// Information about the opaque types whose values we
|
||||
/// are inferring in this function (these are the `impl Trait` that
|
||||
/// appear in the return type).
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct OpaqueTypeDecl<'tcx> {
|
||||
/// The substitutions that we apply to the abstract that this
|
||||
/// The substitutions that we apply to the opaque type that this
|
||||
/// `impl Trait` desugars to. e.g., if:
|
||||
///
|
||||
/// fn foo<'a, 'b, T>() -> impl Trait<'a>
|
||||
///
|
||||
/// winds up desugared to:
|
||||
///
|
||||
/// abstract type Foo<'x, X>: Trait<'x>
|
||||
/// type Foo<'x, X> = impl Trait<'x>
|
||||
/// fn foo<'a, 'b, T>() -> Foo<'a, T>
|
||||
///
|
||||
/// then `substs` would be `['a, T]`.
|
||||
@ -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!
|
||||
/// ```
|
||||
@ -50,7 +50,7 @@ pub struct OpaqueTypeDecl<'tcx> {
|
||||
/// over-approximated, but better than nothing.
|
||||
pub definition_span: Span,
|
||||
|
||||
/// The type variable that represents the value of the abstract type
|
||||
/// The type variable that represents the value of the opaque type
|
||||
/// that we require. In other words, after we compile this function,
|
||||
/// we will be created a constraint like:
|
||||
///
|
||||
@ -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
|
||||
@ -164,12 +164,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
/// Here, we have two `impl Trait` types whose values are being
|
||||
/// inferred (the `impl Bar<'a>` and the `impl
|
||||
/// Bar<'b>`). Conceptually, this is sugar for a setup where we
|
||||
/// define underlying abstract types (`Foo1`, `Foo2`) and then, in
|
||||
/// define underlying opaque types (`Foo1`, `Foo2`) and then, in
|
||||
/// the return type of `foo`, we *reference* those definitions:
|
||||
///
|
||||
/// ```text
|
||||
/// abstract type Foo1<'x>: Bar<'x>;
|
||||
/// abstract type Foo2<'x>: Bar<'x>;
|
||||
/// type Foo1<'x> = impl Bar<'x>;
|
||||
/// type Foo2<'x> = impl Bar<'x>;
|
||||
/// fn foo<'a, 'b>(..) -> (Foo1<'a>, Foo2<'b>) { .. }
|
||||
/// // ^^^^ ^^
|
||||
/// // | |
|
||||
@ -228,7 +228,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
///
|
||||
/// This is actually a bit of a tricky constraint in general. We
|
||||
/// want to say that each variable (e.g., `'0`) can only take on
|
||||
/// values that were supplied as arguments to the abstract type
|
||||
/// values that were supplied as arguments to the opaque type
|
||||
/// (e.g., `'a` for `Foo1<'a>`) or `'static`, which is always in
|
||||
/// scope. We don't have a constraint quite of this kind in the current
|
||||
/// region checker.
|
||||
@ -265,24 +265,24 @@ 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`.
|
||||
///
|
||||
/// # The `free_region_relations` parameter
|
||||
///
|
||||
/// The `free_region_relations` argument is used to find the
|
||||
/// "minimum" of the regions supplied to a given abstract type.
|
||||
/// "minimum" of the regions supplied to a given opaque type.
|
||||
/// It must be a relation that can answer whether `'a <= 'b`,
|
||||
/// where `'a` and `'b` are regions that appear in the "substs"
|
||||
/// for the abstract type references (the `<'a>` in `Foo1<'a>`).
|
||||
/// for the opaque type references (the `<'a>` in `Foo1<'a>`).
|
||||
///
|
||||
/// Note that we do not impose the constraints based on the
|
||||
/// generic regions from the `Foo1` definition (e.g., `'x`). This
|
||||
@ -298,7 +298,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
///
|
||||
/// Here, the fact that `'b: 'a` is known only because of the
|
||||
/// implied bounds from the `&'a &'b u32` parameter, and is not
|
||||
/// "inherent" to the abstract type definition.
|
||||
/// "inherent" to the opaque type definition.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
@ -361,7 +361,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
// There were no `required_region_bounds`,
|
||||
// so we have to search for a `least_region`.
|
||||
// Go through all the regions used as arguments to the
|
||||
// abstract type. These are the parameters to the abstract
|
||||
// opaque type. These are the parameters to the opaque
|
||||
// type; so in our example above, `substs` would contain
|
||||
// `['a]` for the first impl trait and `'b` for the
|
||||
// second.
|
||||
@ -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::TypeAlias => "impl Trait",
|
||||
hir::OpaqueTyOrigin::FnReturn => "impl Trait",
|
||||
};
|
||||
let msg = format!("ambiguous lifetime bound in `{}`", context_name);
|
||||
let mut err = self.tcx.sess.struct_span_err(span, &msg);
|
||||
@ -528,12 +528,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
|
||||
/// Given the fully resolved, instantiated type for an opaque
|
||||
/// type, i.e., the value of an inference variable like C1 or C2
|
||||
/// (*), computes the "definition type" for an abstract type
|
||||
/// (*), computes the "definition type" for an opaque type
|
||||
/// definition -- that is, the inferred value of `Foo1<'x>` or
|
||||
/// `Foo2<'x>` that we would conceptually use in its definition:
|
||||
///
|
||||
/// abstract type Foo1<'x>: Bar<'x> = AAA; <-- this type AAA
|
||||
/// abstract type Foo2<'x>: Bar<'x> = BBB; <-- or this type BBB
|
||||
/// type Foo1<'x> = impl Bar<'x> = AAA; <-- this type AAA
|
||||
/// type Foo2<'x> = impl Bar<'x> = BBB; <-- or this type BBB
|
||||
/// fn foo<'a, 'b>(..) -> (Foo1<'a>, Foo2<'b>) { .. }
|
||||
///
|
||||
/// Note that these values are defined in terms of a distinct set of
|
||||
@ -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();
|
||||
|
||||
@ -992,15 +994,15 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
|
||||
// value we are inferring. At present, this is
|
||||
// always true during the first phase of
|
||||
// type-check, but not always true later on during
|
||||
// NLL. Once we support named abstract types more fully,
|
||||
// NLL. Once we support named opaque types more fully,
|
||||
// this same scenario will be able to arise during all phases.
|
||||
//
|
||||
// Here is an example using `abstract type` that indicates
|
||||
// the distinction we are checking for:
|
||||
// Here is an example using type alias `impl Trait`
|
||||
// that indicates the distinction we are checking for:
|
||||
//
|
||||
// ```rust
|
||||
// mod a {
|
||||
// pub abstract type Foo: Iterator;
|
||||
// pub type Foo = impl Iterator;
|
||||
// pub fn make_foo() -> Foo { .. }
|
||||
// }
|
||||
//
|
||||
@ -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::OpaqueTy {
|
||||
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::OpaqueTy {
|
||||
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::TypeAlias)
|
||||
}
|
||||
},
|
||||
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::TypeAlias,
|
||||
),
|
||||
_ => (def_scope_default(), hir::ExistTyOrigin::ExistentialType),
|
||||
_ => {
|
||||
(def_scope_default(), hir::OpaqueTyOrigin::TypeAlias)
|
||||
}
|
||||
},
|
||||
_ => 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 {
|
||||
@ -1200,7 +1207,7 @@ pub fn may_define_existential_type(
|
||||
// Syntactically, we are allowed to define the concrete type if:
|
||||
let res = hir_id == scope;
|
||||
trace!(
|
||||
"may_define_existential_type(def={:?}, opaque_node={:?}) = {}",
|
||||
"may_define_opaque_type(def={:?}, opaque_node={:?}) = {}",
|
||||
tcx.hir().get(hir_id),
|
||||
tcx.hir().get(opaque_hir_id),
|
||||
res
|
||||
|
@ -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(_) => {}
|
||||
}
|
||||
}
|
||||
|
@ -268,17 +268,17 @@ enum Scope<'a> {
|
||||
track_lifetime_uses: bool,
|
||||
|
||||
/// Whether or not this binder would serve as the parent
|
||||
/// binder for abstract types introduced within. For example:
|
||||
/// binder for opaque types introduced within. For example:
|
||||
///
|
||||
/// fn foo<'a>() -> impl for<'b> Trait<Item = impl Trait2<'a>>
|
||||
///
|
||||
/// Here, the abstract types we create for the `impl Trait`
|
||||
/// Here, the opaque types we create for the `impl Trait`
|
||||
/// and `impl Trait2` references will both have the `foo` item
|
||||
/// as their parent. When we get to `impl Trait2`, we find
|
||||
/// that it is nested within the `for<>` binder -- this flag
|
||||
/// allows us to skip that when looking for the parent binder
|
||||
/// of the resulting abstract type.
|
||||
abstract_type_parent: bool,
|
||||
/// of the resulting opaque type.
|
||||
opaque_type_parent: bool,
|
||||
|
||||
s: ScopeRef<'a>,
|
||||
},
|
||||
@ -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::OpaqueTy {
|
||||
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::OpaqueTy {
|
||||
impl_trait_fn: None,
|
||||
ref generics,
|
||||
..
|
||||
@ -526,7 +526,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
let scope = Scope::Binder {
|
||||
lifetimes,
|
||||
next_early_index: index + non_lifetime_count,
|
||||
abstract_type_parent: true,
|
||||
opaque_type_parent: true,
|
||||
track_lifetime_uses,
|
||||
s: ROOT_SCOPE,
|
||||
};
|
||||
@ -574,7 +574,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
s: self.scope,
|
||||
next_early_index,
|
||||
track_lifetime_uses: true,
|
||||
abstract_type_parent: false,
|
||||
opaque_type_parent: false,
|
||||
};
|
||||
self.with(scope, |old_scope, this| {
|
||||
// a bare fn has no bounds, so everything
|
||||
@ -622,14 +622,14 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
hir::TyKind::Def(item_id, ref lifetimes) => {
|
||||
// Resolve the lifetimes in the bounds to the lifetime defs in the generics.
|
||||
// `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
|
||||
// `abstract type MyAnonTy<'b>: MyTrait<'b>;`
|
||||
// ^ ^ this gets resolved in the scope of
|
||||
// the exist_ty generics
|
||||
// `type MyAnonTy<'b> = impl MyTrait<'b>;`
|
||||
// ^ ^ this gets resolved in the scope of
|
||||
// the opaque_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::OpaqueTy {
|
||||
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::OpaqueTy {
|
||||
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> { ... }`
|
||||
@ -687,7 +687,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
|
||||
// We want to start our early-bound indices at the end of the parent scope,
|
||||
// not including any parent `impl Trait`s.
|
||||
let mut index = self.next_early_index_for_abstract_type();
|
||||
let mut index = self.next_early_index_for_opaque_type();
|
||||
debug!("visit_ty: index = {}", index);
|
||||
|
||||
let mut elision = None;
|
||||
@ -728,7 +728,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
next_early_index,
|
||||
s: this.scope,
|
||||
track_lifetime_uses: true,
|
||||
abstract_type_parent: false,
|
||||
opaque_type_parent: false,
|
||||
};
|
||||
this.with(scope, |_old_scope, this| {
|
||||
this.visit_generics(generics);
|
||||
@ -743,7 +743,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
next_early_index,
|
||||
s: self.scope,
|
||||
track_lifetime_uses: true,
|
||||
abstract_type_parent: false,
|
||||
opaque_type_parent: false,
|
||||
};
|
||||
self.with(scope, |_old_scope, this| {
|
||||
this.visit_generics(generics);
|
||||
@ -796,7 +796,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
next_early_index: index + non_lifetime_count,
|
||||
s: self.scope,
|
||||
track_lifetime_uses: true,
|
||||
abstract_type_parent: true,
|
||||
opaque_type_parent: true,
|
||||
};
|
||||
self.with(scope, |_old_scope, this| {
|
||||
this.visit_generics(generics);
|
||||
@ -848,14 +848,14 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
next_early_index: index + non_lifetime_count,
|
||||
s: self.scope,
|
||||
track_lifetime_uses: true,
|
||||
abstract_type_parent: true,
|
||||
opaque_type_parent: true,
|
||||
};
|
||||
self.with(scope, |_old_scope, this| {
|
||||
this.visit_generics(generics);
|
||||
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;
|
||||
@ -879,7 +879,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
next_early_index,
|
||||
s: self.scope,
|
||||
track_lifetime_uses: true,
|
||||
abstract_type_parent: true,
|
||||
opaque_type_parent: true,
|
||||
};
|
||||
self.with(scope, |_old_scope, this| {
|
||||
this.visit_generics(generics);
|
||||
@ -967,7 +967,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
s: self.scope,
|
||||
next_early_index,
|
||||
track_lifetime_uses: true,
|
||||
abstract_type_parent: false,
|
||||
opaque_type_parent: false,
|
||||
};
|
||||
let result = self.with(scope, |old_scope, this| {
|
||||
this.check_lifetime_params(old_scope, &bound_generic_params);
|
||||
@ -1037,7 +1037,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
s: self.scope,
|
||||
next_early_index,
|
||||
track_lifetime_uses: true,
|
||||
abstract_type_parent: false,
|
||||
opaque_type_parent: false,
|
||||
};
|
||||
self.with(scope, |old_scope, this| {
|
||||
this.check_lifetime_params(old_scope, &trait_ref.bound_generic_params);
|
||||
@ -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::OpaqueTy {
|
||||
ref generics,
|
||||
impl_trait_fn: None,
|
||||
..
|
||||
@ -1753,7 +1753,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
lifetimes,
|
||||
next_early_index,
|
||||
s: self.scope,
|
||||
abstract_type_parent: true,
|
||||
opaque_type_parent: true,
|
||||
track_lifetime_uses: false,
|
||||
};
|
||||
self.with(scope, move |old_scope, this| {
|
||||
@ -1762,7 +1762,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
});
|
||||
}
|
||||
|
||||
fn next_early_index_helper(&self, only_abstract_type_parent: bool) -> u32 {
|
||||
fn next_early_index_helper(&self, only_opaque_type_parent: bool) -> u32 {
|
||||
let mut scope = self.scope;
|
||||
loop {
|
||||
match *scope {
|
||||
@ -1770,9 +1770,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
|
||||
Scope::Binder {
|
||||
next_early_index,
|
||||
abstract_type_parent,
|
||||
opaque_type_parent,
|
||||
..
|
||||
} if (!only_abstract_type_parent || abstract_type_parent) =>
|
||||
} if (!only_opaque_type_parent || opaque_type_parent) =>
|
||||
{
|
||||
return next_early_index
|
||||
}
|
||||
@ -1792,10 +1792,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
/// Returns the next index one would use for an `impl Trait` that
|
||||
/// is being converted into an `abstract type`. This will be the
|
||||
/// is being converted into an opaque type alias `impl Trait`. This will be the
|
||||
/// next early index from the enclosing item, for the most
|
||||
/// part. See the `abstract_type_parent` field for more info.
|
||||
fn next_early_index_for_abstract_type(&self) -> u32 {
|
||||
/// part. See the `opaque_type_parent` field for more info.
|
||||
fn next_early_index_for_opaque_type(&self) -> u32 {
|
||||
self.next_early_index_helper(false)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
/// by this function
|
||||
pub concrete_existential_types: FxHashMap<DefId, ResolvedOpaqueTy<'tcx>>,
|
||||
/// All the opaque types that are restricted to concrete types
|
||||
/// by this function.
|
||||
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(type_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,8 +3214,8 @@ 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 {
|
||||
return exist_ty.impl_trait_fn;
|
||||
if let hir::ItemKind::OpaqueTy(ref opaque_ty) = item.node {
|
||||
return opaque_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,18 +438,6 @@ impl Sig for ast::Item {
|
||||
refs: vec![],
|
||||
})
|
||||
}
|
||||
ast::ItemKind::Existential(ref bounds, ref generics) => {
|
||||
let text = "existential 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(&pprust::bounds_to_string(bounds));
|
||||
}
|
||||
sig.text.push(';');
|
||||
|
||||
Ok(sig)
|
||||
}
|
||||
ast::ItemKind::Ty(ref ty, ref generics) => {
|
||||
let text = "type ".to_owned();
|
||||
let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?;
|
||||
@ -461,6 +449,16 @@ impl Sig for ast::Item {
|
||||
|
||||
Ok(merge_sigs(sig.text.clone(), vec![sig, ty]))
|
||||
}
|
||||
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)?;
|
||||
|
||||
sig.text.push_str(" = impl ");
|
||||
sig.text.push_str(&pprust::bounds_to_string(bounds));
|
||||
sig.text.push(';');
|
||||
|
||||
Ok(sig)
|
||||
}
|
||||
ast::ItemKind::Enum(_, ref generics) => {
|
||||
let text = "enum ".to_owned();
|
||||
let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?;
|
||||
|
@ -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::OpaqueTy{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(OpaqueTy {
|
||||
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::OpaqueTy {
|
||||
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::OpaqueTy { 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::OpaqueTy { 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::OpaqueTy {
|
||||
impl_trait_fn: None,
|
||||
..
|
||||
}) => find_existential_constraints(tcx, def_id),
|
||||
// Existential types desugared from `impl Trait`.
|
||||
ItemKind::Existential(hir::ExistTy {
|
||||
}) => find_opaque_ty_constraints(tcx, def_id),
|
||||
// Opaque types desugared from `impl Trait`.
|
||||
ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||
impl_trait_fn: Some(owner),
|
||||
..
|
||||
}) => {
|
||||
tcx.typeck_tables_of(owner)
|
||||
.concrete_existential_types
|
||||
.concrete_opaque_types
|
||||
.get(&def_id)
|
||||
.map(|opaque| opaque.concrete_type)
|
||||
.unwrap_or_else(|| {
|
||||
// This can occur if some error in the
|
||||
// owner fn prevented us from populating
|
||||
// the `concrete_existential_types` table.
|
||||
// the `concrete_opaque_types` table.
|
||||
tcx.sess.delay_span_bug(
|
||||
DUMMY_SP,
|
||||
&format!(
|
||||
"owner {:?} has no existential type for {:?} in its tables",
|
||||
"owner {:?} has no opaque type for {:?} in its tables",
|
||||
owner, def_id,
|
||||
),
|
||||
);
|
||||
@ -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
|
||||
@ -1713,7 +1713,7 @@ fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
// For example, this code:
|
||||
// ```
|
||||
// fn foo() {
|
||||
// existential type Blah: Debug;
|
||||
// type Blah = impl Debug;
|
||||
// let my_closure = || -> Blah { true };
|
||||
// }
|
||||
// ```
|
||||
@ -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(OpaqueTy {
|
||||
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,
|
||||
|
@ -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,9 +3663,9 @@ impl Clean<Item> for doctree::Existential<'_> {
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: self.stab.clean(cx),
|
||||
deprecation: self.depr.clean(cx),
|
||||
inner: ExistentialItem(Existential {
|
||||
bounds: self.exist_ty.bounds.clean(cx),
|
||||
generics: self.exist_ty.generics.clean(cx),
|
||||
inner: OpaqueTyItem(OpaqueTy {
|
||||
bounds: self.opaque_ty.bounds.clean(cx),
|
||||
generics: self.opaque_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,
|
||||
|
||||
|
@ -1886,7 +1886,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>,
|
||||
@ -1907,7 +1907,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),
|
||||
@ -1932,7 +1932,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)),
|
||||
@ -1982,7 +1982,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")
|
||||
}
|
||||
@ -2480,7 +2480,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.
|
||||
@ -2519,7 +2519,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.
|
||||
@ -4390,15 +4390,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 },
|
||||
@ -4986,7 +4986,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,9 +472,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
};
|
||||
om.typedefs.push(t);
|
||||
},
|
||||
hir::ItemKind::Existential(ref exist_ty) => {
|
||||
let t = Existential {
|
||||
exist_ty,
|
||||
hir::ItemKind::OpaqueTy(ref opaque_ty) => {
|
||||
let t = OpaqueTy {
|
||||
opaque_ty,
|
||||
name: ident.name,
|
||||
id: item.hir_id,
|
||||
attrs: &item.attrs,
|
||||
@ -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 {
|
||||
|
@ -1488,6 +1488,7 @@ pub enum TraitItemKind {
|
||||
Macro(Mac),
|
||||
}
|
||||
|
||||
/// Represents anything within an `impl` block.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct ImplItem {
|
||||
pub id: NodeId,
|
||||
@ -1502,12 +1503,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),
|
||||
}
|
||||
|
||||
@ -1710,7 +1712,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>),
|
||||
@ -2334,10 +2336,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> }`.
|
||||
@ -2391,7 +2393,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",
|
||||
|
@ -453,9 +453,6 @@ declare_features! (
|
||||
// Allows `#[doc(alias = "...")]`.
|
||||
(active, doc_alias, "1.27.0", Some(50146), None),
|
||||
|
||||
// Allows defining `existential type`s.
|
||||
(active, existential_type, "1.28.0", Some(63063), None),
|
||||
|
||||
// Allows inconsistent bounds in where clauses.
|
||||
(active, trivial_bounds, "1.28.0", Some(48214), None),
|
||||
|
||||
@ -560,6 +557,9 @@ declare_features! (
|
||||
// Allows `[x; N]` where `x` is a constant (RFC 2203).
|
||||
(active, const_in_array_repeat_expressions, "1.37.0", Some(49147), None),
|
||||
|
||||
// Allows `impl Trait` to be used inside type aliases (RFC 2515).
|
||||
(active, type_alias_impl_trait, "1.38.0", Some(63063), None),
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// feature-group-end: actual feature gates
|
||||
// -------------------------------------------------------------------------
|
||||
@ -625,6 +625,9 @@ declare_features! (
|
||||
(removed, dropck_parametricity, "1.38.0", Some(28498), None, None),
|
||||
(removed, await_macro, "1.38.0", Some(50547), None,
|
||||
Some("subsumed by `.await` syntax")),
|
||||
// Allows defining `existential type`s.
|
||||
(removed, existential_type, "1.38.0", Some(63063), None,
|
||||
Some("removed in favor of `#![feature(type_alias_impl_trait)]`")),
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// feature-group-end: removed features
|
||||
@ -2014,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,
|
||||
existential_type,
|
||||
type_alias_impl_trait,
|
||||
i.span,
|
||||
"existential types are unstable"
|
||||
"`impl Trait` in type aliases is unstable"
|
||||
);
|
||||
}
|
||||
|
||||
@ -2243,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,
|
||||
existential_type,
|
||||
type_alias_impl_trait,
|
||||
ii.span,
|
||||
"existential types are unstable"
|
||||
"`impl Trait` in type aliases is unstable"
|
||||
);
|
||||
}
|
||||
ast::ImplItemKind::Type(_) => {
|
||||
|
@ -851,7 +851,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);
|
||||
}
|
||||
@ -934,7 +934,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! {
|
||||
@ -4273,11 +4273,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) &&
|
||||
@ -4375,7 +4370,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)?;
|
||||
@ -5694,7 +5688,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() {
|
||||
@ -6813,40 +6807,29 @@ impl<'a> Parser<'a> {
|
||||
Ok(self.mk_item(lo.to(prev_span), invalid, ItemKind::ForeignMod(m), visibility, attrs))
|
||||
}
|
||||
|
||||
/// Parses `type Foo = Bar;`
|
||||
/// or
|
||||
/// `existential type Foo: Bar;`
|
||||
/// or
|
||||
/// `return `None``
|
||||
/// Parses `type Foo = Bar;` or returns `None`
|
||||
/// without modifying the parser state.
|
||||
fn eat_type(&mut self) -> Option<PResult<'a, (Ident, AliasKind, ast::Generics)>> {
|
||||
// This parses the grammar:
|
||||
// Ident ["<"...">"] ["where" ...] ("=" | ":") Ty ";"
|
||||
if self.check_keyword(kw::Type) ||
|
||||
self.check_keyword(kw::Existential) &&
|
||||
self.is_keyword_ahead(1, &[kw::Type]) {
|
||||
let existential = self.eat_keyword(kw::Existential);
|
||||
assert!(self.eat_keyword(kw::Type));
|
||||
Some(self.parse_existential_or_alias(existential))
|
||||
if self.eat_keyword(kw::Type) {
|
||||
Some(self.parse_type_alias())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses a type alias or existential type.
|
||||
fn parse_existential_or_alias(
|
||||
&mut self,
|
||||
existential: bool,
|
||||
) -> PResult<'a, (Ident, AliasKind, ast::Generics)> {
|
||||
/// 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()?;
|
||||
tps.where_clause = self.parse_where_clause()?;
|
||||
let alias = if existential {
|
||||
self.expect(&token::Colon)?;
|
||||
self.expect(&token::Eq)?;
|
||||
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 {
|
||||
self.expect(&token::Eq)?;
|
||||
let ty = self.parse_ty()?;
|
||||
AliasKind::Weak(ty)
|
||||
};
|
||||
@ -7268,7 +7251,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),
|
||||
|
@ -1221,9 +1221,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
|
||||
|
||||
@ -1581,9 +1582,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",
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +98,6 @@ symbols! {
|
||||
Auto: "auto",
|
||||
Catch: "catch",
|
||||
Default: "default",
|
||||
Existential: "existential",
|
||||
Union: "union",
|
||||
}
|
||||
|
||||
@ -680,6 +679,7 @@ symbols! {
|
||||
tuple_indexing,
|
||||
Ty,
|
||||
ty,
|
||||
type_alias_impl_trait,
|
||||
TyCtxt,
|
||||
TyKind,
|
||||
type_alias_enum_variants,
|
||||
|
@ -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 opaque 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; }
|
||||
|
@ -3,7 +3,7 @@
|
||||
// error-pattern:could not find defining uses
|
||||
|
||||
#![feature(associated_type_bounds)]
|
||||
#![feature(existential_type)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
#![feature(impl_trait_in_bindings)]
|
||||
#![feature(untagged_unions)]
|
||||
|
||||
@ -107,17 +107,17 @@ type TAW2<T> where T: Iterator<Item: Copy, Item: Copy> = T;
|
||||
type TAW3<T> where T: Iterator<Item: 'static, Item: 'static> = T;
|
||||
//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719]
|
||||
|
||||
existential type ETAI1<T: Iterator<Item: Copy, Item: Send>>: Copy;
|
||||
type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
|
||||
//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719]
|
||||
existential type ETAI2<T: Iterator<Item: Copy, Item: Copy>>: Copy;
|
||||
type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
|
||||
//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719]
|
||||
existential type ETAI3<T: Iterator<Item: 'static, Item: 'static>>: Copy;
|
||||
type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
|
||||
//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719]
|
||||
existential type ETAI4: Iterator<Item: Copy, Item: Send>;
|
||||
type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
|
||||
//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719]
|
||||
existential type ETAI5: Iterator<Item: Copy, Item: Copy>;
|
||||
type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
|
||||
//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719]
|
||||
existential type ETAI6: Iterator<Item: 'static, Item: 'static>;
|
||||
type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
|
||||
//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719]
|
||||
|
||||
trait TRI1<T: Iterator<Item: Copy, Item: Send>> {}
|
||||
|
@ -369,86 +369,86 @@ LL | type TAW3<T> where T: Iterator<Item: 'static, Item: 'static> = T;
|
||||
error: could not find defining uses
|
||||
--> $DIR/duplicate.rs:110:1
|
||||
|
|
||||
LL | existential type ETAI1<T: Iterator<Item: Copy, Item: Send>>: Copy;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
|
||||
--> $DIR/duplicate.rs:110:48
|
||||
--> $DIR/duplicate.rs:110:36
|
||||
|
|
||||
LL | existential type ETAI1<T: Iterator<Item: Copy, Item: Send>>: Copy;
|
||||
| ---------- ^^^^^^^^^^ re-bound here
|
||||
| |
|
||||
| `Item` bound here first
|
||||
LL | type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
|
||||
| ---------- ^^^^^^^^^^ re-bound here
|
||||
| |
|
||||
| `Item` bound here first
|
||||
|
||||
error: could not find defining uses
|
||||
--> $DIR/duplicate.rs:112:1
|
||||
|
|
||||
LL | existential type ETAI2<T: Iterator<Item: Copy, Item: Copy>>: Copy;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
|
||||
--> $DIR/duplicate.rs:112:48
|
||||
--> $DIR/duplicate.rs:112:36
|
||||
|
|
||||
LL | existential type ETAI2<T: Iterator<Item: Copy, Item: Copy>>: Copy;
|
||||
| ---------- ^^^^^^^^^^ re-bound here
|
||||
| |
|
||||
| `Item` bound here first
|
||||
LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
|
||||
| ---------- ^^^^^^^^^^ re-bound here
|
||||
| |
|
||||
| `Item` bound here first
|
||||
|
||||
error: could not find defining uses
|
||||
--> $DIR/duplicate.rs:114:1
|
||||
|
|
||||
LL | existential type ETAI3<T: Iterator<Item: 'static, Item: 'static>>: Copy;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
|
||||
--> $DIR/duplicate.rs:114:51
|
||||
--> $DIR/duplicate.rs:114:39
|
||||
|
|
||||
LL | existential type ETAI3<T: Iterator<Item: 'static, Item: 'static>>: Copy;
|
||||
| ------------- ^^^^^^^^^^^^^ re-bound here
|
||||
| |
|
||||
| `Item` bound here first
|
||||
LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
|
||||
| ------------- ^^^^^^^^^^^^^ re-bound here
|
||||
| |
|
||||
| `Item` bound here first
|
||||
|
||||
error: could not find defining uses
|
||||
--> $DIR/duplicate.rs:116:1
|
||||
|
|
||||
LL | existential type ETAI4: Iterator<Item: Copy, Item: Send>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
|
||||
--> $DIR/duplicate.rs:116:46
|
||||
--> $DIR/duplicate.rs:116:40
|
||||
|
|
||||
LL | existential type ETAI4: Iterator<Item: Copy, Item: Send>;
|
||||
| ---------- ^^^^^^^^^^ re-bound here
|
||||
| |
|
||||
| `Item` bound here first
|
||||
LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
|
||||
| ---------- ^^^^^^^^^^ re-bound here
|
||||
| |
|
||||
| `Item` bound here first
|
||||
|
||||
error: could not find defining uses
|
||||
--> $DIR/duplicate.rs:118:1
|
||||
|
|
||||
LL | existential type ETAI5: Iterator<Item: Copy, Item: Copy>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
|
||||
--> $DIR/duplicate.rs:118:46
|
||||
--> $DIR/duplicate.rs:118:40
|
||||
|
|
||||
LL | existential type ETAI5: Iterator<Item: Copy, Item: Copy>;
|
||||
| ---------- ^^^^^^^^^^ re-bound here
|
||||
| |
|
||||
| `Item` bound here first
|
||||
LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
|
||||
| ---------- ^^^^^^^^^^ re-bound here
|
||||
| |
|
||||
| `Item` bound here first
|
||||
|
||||
error: could not find defining uses
|
||||
--> $DIR/duplicate.rs:120:1
|
||||
|
|
||||
LL | existential type ETAI6: Iterator<Item: 'static, Item: 'static>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
|
||||
--> $DIR/duplicate.rs:120:49
|
||||
--> $DIR/duplicate.rs:120:43
|
||||
|
|
||||
LL | existential type ETAI6: Iterator<Item: 'static, Item: 'static>;
|
||||
| ------------- ^^^^^^^^^^^^^ re-bound here
|
||||
| |
|
||||
| `Item` bound here first
|
||||
LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
|
||||
| ------------- ^^^^^^^^^^^^^ re-bound here
|
||||
| |
|
||||
| `Item` bound here first
|
||||
|
||||
error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
|
||||
--> $DIR/duplicate.rs:123:36
|
||||
|
@ -1,7 +1,6 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(associated_type_bounds)]
|
||||
#![feature(existential_type)]
|
||||
|
||||
use std::ops::Add;
|
||||
|
@ -1,7 +1,7 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(associated_type_bounds)]
|
||||
#![feature(existential_type)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
use std::ops::Add;
|
||||
|
||||
@ -17,15 +17,15 @@ struct S1;
|
||||
struct S2;
|
||||
impl Tr1 for S1 { type As1 = S2; fn mk(self) -> Self::As1 { S2 } }
|
||||
|
||||
existential type Et1: Tr1<As1: Copy>;
|
||||
type Et1 = impl Tr1<As1: Copy>;
|
||||
fn def_et1() -> Et1 { S1 }
|
||||
pub fn use_et1() { assert_copy(def_et1().mk()); }
|
||||
|
||||
existential type Et2: Tr1<As1: 'static>;
|
||||
type Et2 = impl Tr1<As1: 'static>;
|
||||
fn def_et2() -> Et2 { S1 }
|
||||
pub fn use_et2() { assert_static(def_et2().mk()); }
|
||||
|
||||
existential type Et3: Tr1<As1: Clone + Iterator<Item: Add<u8, Output: Into<u8>>>>;
|
||||
type Et3 = impl Tr1<As1: Clone + Iterator<Item: Add<u8, Output: Into<u8>>>>;
|
||||
fn def_et3() -> Et3 {
|
||||
struct A;
|
||||
impl Tr1 for A {
|
||||
@ -44,7 +44,7 @@ pub fn use_et3() {
|
||||
assert_eq!(s, (0..10).map(|x| x + 1).sum());
|
||||
}
|
||||
|
||||
existential type Et4: Tr1<As1: for<'a> Tr2<'a>>;
|
||||
type Et4 = impl Tr1<As1: for<'a> Tr2<'a>>;
|
||||
fn def_et4() -> Et4 {
|
||||
#[derive(Copy, Clone)]
|
||||
struct A;
|
@ -99,12 +99,10 @@ 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
|
||||
async fn async_fn_multiple_args(x: &u8, _y: &u8) -> u8 {
|
||||
await!(wake_and_yield_once());
|
||||
wake_and_yield_once().await;
|
||||
*x
|
||||
}
|
||||
*/
|
||||
|
||||
async fn async_fn_multiple_args_named_lifetime<'a>(x: &'a u8, _y: &'a u8) -> u8 {
|
||||
wake_and_yield_once().await;
|
||||
|
@ -1,13 +1,14 @@
|
||||
// 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
|
||||
|
||||
#![feature(async_await, existential_type)]
|
||||
#![feature(async_await)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
use std::future::Future;
|
||||
|
||||
pub existential type Func: Sized;
|
||||
pub type Func = impl Sized;
|
||||
|
||||
// Late bound region should be allowed to escape the function, since it's bound
|
||||
// in the type.
|
||||
@ -17,7 +18,7 @@ fn null_function_ptr() -> Func {
|
||||
|
||||
async fn async_nop(_: &u8) {}
|
||||
|
||||
pub existential type ServeFut: Future<Output=()>;
|
||||
pub type ServeFut = impl Future<Output=()>;
|
||||
|
||||
// Late bound regions occur in the generator witness type here.
|
||||
fn serve() -> ServeFut {
|
||||
|
@ -1,12 +0,0 @@
|
||||
// Checks to ensure that we properly detect when a closure constrains an existential type
|
||||
#![feature(existential_type)]
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
fn main() {
|
||||
existential type Existential: Debug;
|
||||
fn _unused() -> Existential { String::new() }
|
||||
//~^ ERROR: concrete type differs from previous defining existential type use
|
||||
let null = || -> Existential { 0 };
|
||||
println!("{:?}", null());
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
error: concrete type differs from previous defining existential type use
|
||||
--> $DIR/issue-52843-closure-constrain.rs:8:5
|
||||
|
|
||||
LL | fn _unused() -> Existential { String::new() }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, got `std::string::String`
|
||||
|
|
||||
note: previous use here
|
||||
--> $DIR/issue-52843-closure-constrain.rs:6:1
|
||||
|
|
||||
LL | / fn main() {
|
||||
LL | | existential type Existential: Debug;
|
||||
LL | | fn _unused() -> Existential { String::new() }
|
||||
LL | |
|
||||
LL | | let null = || -> Existential { 0 };
|
||||
LL | | println!("{:?}", null());
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -1,11 +0,0 @@
|
||||
// Crate that exports an existential type. Used for testing cross-crate.
|
||||
|
||||
#![crate_type="rlib"]
|
||||
|
||||
#![feature(existential_type)]
|
||||
|
||||
pub existential type Foo: std::fmt::Debug;
|
||||
|
||||
pub fn foo() -> Foo {
|
||||
5
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
#![feature(existential_type)]
|
||||
|
||||
fn main() {}
|
||||
|
||||
// declared but never defined
|
||||
existential type Bar: std::fmt::Debug; //~ ERROR could not find defining uses
|
@ -1,12 +0,0 @@
|
||||
#![feature(existential_type)]
|
||||
|
||||
fn main() {}
|
||||
|
||||
mod boo {
|
||||
// declared in module but not defined inside of it
|
||||
pub existential type Boo: ::std::fmt::Debug; //~ ERROR could not find defining uses
|
||||
}
|
||||
|
||||
fn bomp() -> boo::Boo {
|
||||
""
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
error: could not find defining uses
|
||||
--> $DIR/existential-types-with-cycle-error.rs:3:1
|
||||
|
|
||||
LL | existential type Foo: Fn() -> Foo;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -1,8 +0,0 @@
|
||||
error: could not find defining uses
|
||||
--> $DIR/existential-types-with-cycle-error2.rs:7:1
|
||||
|
|
||||
LL | existential type Foo: Bar<Foo, Item = Foo>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -1,9 +0,0 @@
|
||||
#![feature(existential_type)]
|
||||
|
||||
fn main() {}
|
||||
|
||||
existential type Two<'a, 'b>: std::fmt::Debug;
|
||||
|
||||
fn one<'a>(t: &'a ()) -> Two<'a, 'a> { //~ ERROR non-defining existential type use
|
||||
t
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
error: at least one trait must be specified
|
||||
--> $DIR/unused_generic_param.rs:6:39
|
||||
|
|
||||
LL | existential type PartiallyDefined<T>: 'static;
|
||||
| ^^^^^^^
|
||||
|
||||
error: at least one trait must be specified
|
||||
--> $DIR/unused_generic_param.rs:13:40
|
||||
|
|
||||
LL | existential type PartiallyDefined2<T>: 'static;
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -1,17 +0,0 @@
|
||||
// Check that existential types must be ungated to use the `existential` keyword
|
||||
|
||||
existential type Foo: std::fmt::Debug; //~ ERROR existential types are unstable
|
||||
|
||||
trait Bar {
|
||||
type Baa: std::fmt::Debug;
|
||||
fn define() -> Self::Baa;
|
||||
}
|
||||
|
||||
impl Bar for () {
|
||||
existential type Baa: std::fmt::Debug; //~ ERROR existential types are unstable
|
||||
fn define() -> Self::Baa { 0 }
|
||||
}
|
||||
|
||||
fn define() -> Foo { 0 }
|
||||
|
||||
fn main() {}
|
@ -1,21 +0,0 @@
|
||||
error[E0658]: existential types are unstable
|
||||
--> $DIR/feature-gate-existential-type.rs:3:1
|
||||
|
|
||||
LL | existential type Foo: std::fmt::Debug;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/63063
|
||||
= help: add `#![feature(existential_type)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: existential types are unstable
|
||||
--> $DIR/feature-gate-existential-type.rs:11:5
|
||||
|
|
||||
LL | existential type Baa: std::fmt::Debug;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/63063
|
||||
= help: add `#![feature(existential_type)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
@ -0,0 +1,15 @@
|
||||
type Foo = impl std::fmt::Debug; //~ ERROR `impl Trait` in type aliases is unstable
|
||||
|
||||
trait Bar {
|
||||
type Baa: std::fmt::Debug;
|
||||
fn define() -> Self::Baa;
|
||||
}
|
||||
|
||||
impl Bar for () {
|
||||
type Baa = impl std::fmt::Debug; //~ ERROR `impl Trait` in type aliases is unstable
|
||||
fn define() -> Self::Baa { 0 }
|
||||
}
|
||||
|
||||
fn define() -> Foo { 0 }
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,21 @@
|
||||
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;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= 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]: `impl Trait` in type aliases is unstable
|
||||
--> $DIR/feature-gate-type_alias_impl_trait.rs:9:5
|
||||
|
|
||||
LL | type Baa = 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: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
@ -1,4 +1,4 @@
|
||||
#![feature(existential_type)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
// build-pass (FIXME(62277): could be check-pass?)
|
||||
|
||||
trait Bar {}
|
||||
@ -11,7 +11,7 @@ trait Foo<T> {
|
||||
}
|
||||
|
||||
impl<W> Foo<W> for i32 {
|
||||
existential type Assoc: Bar;
|
||||
type Assoc = impl Bar;
|
||||
fn foo(w: W) -> Self::Assoc {
|
||||
Dummy(w)
|
||||
}
|
||||
@ -21,7 +21,7 @@ struct NonGeneric;
|
||||
impl Bar for NonGeneric {}
|
||||
|
||||
impl<W> Foo<W> for u32 {
|
||||
existential type Assoc: Bar;
|
||||
type Assoc = impl Bar;
|
||||
fn foo(_: W) -> Self::Assoc {
|
||||
NonGeneric
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
#![feature(existential_type)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
// build-pass (FIXME(62277): could be check-pass?)
|
||||
|
||||
trait Bar {}
|
||||
@ -11,7 +11,7 @@ trait Foo {
|
||||
}
|
||||
|
||||
impl Foo for i32 {
|
||||
existential type Assoc: Bar;
|
||||
type Assoc = impl Bar;
|
||||
fn foo() -> Self::Assoc {
|
||||
Dummy
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
#![feature(existential_type)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
// build-pass (FIXME(62277): could be check-pass?)
|
||||
|
||||
trait Bar {}
|
||||
@ -12,7 +12,7 @@ trait Foo {
|
||||
}
|
||||
|
||||
impl Foo for i32 {
|
||||
existential type Assoc: Bar;
|
||||
type Assoc = impl Bar;
|
||||
fn foo() -> Self::Assoc {
|
||||
Dummy
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
// edition:2018
|
||||
|
||||
#![feature(async_await)]
|
||||
#![feature(existential_type)]
|
||||
#![feature(impl_trait_in_bindings)]
|
||||
//~^ WARNING the feature `impl_trait_in_bindings` is incomplete
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
|
||||
--> $DIR/bound-normalization-fail.rs:6:12
|
||||
--> $DIR/bound-normalization-fail.rs:5:12
|
||||
|
|
||||
LL | #![feature(impl_trait_in_bindings)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -7,7 +7,7 @@ LL | #![feature(impl_trait_in_bindings)]
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc`
|
||||
--> $DIR/bound-normalization-fail.rs:30:32
|
||||
--> $DIR/bound-normalization-fail.rs:29:32
|
||||
|
|
||||
LL | fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found associated type
|
||||
@ -17,7 +17,7 @@ LL | fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> {
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
||||
error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc`
|
||||
--> $DIR/bound-normalization-fail.rs:47:41
|
||||
--> $DIR/bound-normalization-fail.rs:46:41
|
||||
|
|
||||
LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found associated type
|
||||
|
@ -2,7 +2,7 @@
|
||||
// edition:2018
|
||||
|
||||
#![feature(async_await)]
|
||||
#![feature(existential_type)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
#![feature(impl_trait_in_bindings)]
|
||||
//~^ WARNING the feature `impl_trait_in_bindings` is incomplete
|
||||
|
||||
@ -81,9 +81,9 @@ mod impl_trait_in_bindings {
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// The same applied to `existential type`s
|
||||
// The same applied to `type Foo = impl Bar`s
|
||||
|
||||
mod existential_types {
|
||||
mod opaque_types {
|
||||
trait Implemented {
|
||||
type Assoc;
|
||||
}
|
||||
@ -99,7 +99,7 @@ mod existential_types {
|
||||
type Out = u8;
|
||||
}
|
||||
|
||||
existential type Ex: Trait<Out = <() as Implemented>::Assoc>;
|
||||
type Ex = impl Trait<Out = <() as Implemented>::Assoc>;
|
||||
|
||||
fn define() -> Ex {
|
||||
()
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ignore-tidy-linelength
|
||||
#![feature(existential_type)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
pub trait Bar
|
||||
{
|
||||
@ -9,12 +9,12 @@ pub trait Bar
|
||||
}
|
||||
|
||||
impl<S: Default> Bar for S {
|
||||
existential type E: Copy;
|
||||
type E = impl Copy;
|
||||
//~^ ERROR the trait bound `S: std::marker::Copy` is not satisfied in `(S, T)` [E0277]
|
||||
//~^^ ERROR the trait bound `T: std::marker::Copy` is not satisfied in `(S, T)` [E0277]
|
||||
|
||||
fn foo<T: Default>() -> Self::E {
|
||||
//~^ 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())
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
error[E0277]: the trait bound `S: std::marker::Copy` is not satisfied in `(S, T)`
|
||||
--> $DIR/issue-55872-1.rs:12:5
|
||||
|
|
||||
LL | existential type E: Copy;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ within `(S, T)`, the trait `std::marker::Copy` is not implemented for `S`
|
||||
LL | type E = impl Copy;
|
||||
| ^^^^^^^^^^^^^^^^^^^ within `(S, T)`, the trait `std::marker::Copy` is not implemented for `S`
|
||||
|
|
||||
= help: consider adding a `where S: std::marker::Copy` bound
|
||||
= note: required because it appears within the type `(S, T)`
|
||||
@ -11,14 +11,14 @@ LL | existential type E: Copy;
|
||||
error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied in `(S, T)`
|
||||
--> $DIR/issue-55872-1.rs:12:5
|
||||
|
|
||||
LL | existential type E: Copy;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ within `(S, T)`, the trait `std::marker::Copy` is not implemented for `T`
|
||||
LL | type E = impl Copy;
|
||||
| ^^^^^^^^^^^^^^^^^^^ within `(S, T)`, the trait `std::marker::Copy` is not implemented for `T`
|
||||
|
|
||||
= help: consider adding a `where T: std::marker::Copy` bound
|
||||
= 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 {
|
||||
|
@ -1,6 +1,6 @@
|
||||
// edition:2018
|
||||
// ignore-tidy-linelength
|
||||
#![feature(async_await, existential_type)]
|
||||
#![feature(async_await, type_alias_impl_trait)]
|
||||
|
||||
pub trait Bar {
|
||||
type E: Copy;
|
||||
@ -9,10 +9,10 @@ pub trait Bar {
|
||||
}
|
||||
|
||||
impl<S> Bar for S {
|
||||
existential type E: Copy;
|
||||
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 {}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
error[E0277]: the trait bound `impl std::future::Future: std::marker::Copy` is not satisfied
|
||||
--> $DIR/issue-55872-2.rs:12:5
|
||||
|
|
||||
LL | existential type E: Copy;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `impl std::future::Future`
|
||||
LL | type E = impl Copy;
|
||||
| ^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `impl std::future::Future`
|
||||
|
|
||||
= 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 {
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ignore-tidy-linelength
|
||||
#![feature(existential_type)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
pub trait Bar {
|
||||
type E: Copy;
|
||||
@ -8,10 +8,10 @@ pub trait Bar {
|
||||
}
|
||||
|
||||
impl<S> Bar for S {
|
||||
existential type E: Copy;
|
||||
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 {
|
||||
|
@ -1,8 +1,8 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(existential_type)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
existential type X: Clone;
|
||||
type X = impl Clone;
|
||||
|
||||
fn bar<F: Fn(&i32) + Clone>(f: F) -> F {
|
||||
f
|
||||
|
@ -1,14 +1,14 @@
|
||||
// compile-flags:-Zborrowck=mir
|
||||
|
||||
#![feature(member_constraints)]
|
||||
#![feature(existential_type)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
#[derive(Clone)]
|
||||
struct CopyIfEq<T, U>(T, U);
|
||||
|
||||
impl<T: Copy> Copy for CopyIfEq<T, T> {}
|
||||
|
||||
existential type E<'a, 'b>: Sized;
|
||||
type E<'a, 'b> = impl Sized;
|
||||
|
||||
fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> {
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
|
@ -5,7 +5,7 @@ LL | fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> {
|
||||
| -- lifetime `'a` defined here ^^^^^^^^^ opaque type requires that `'a` must outlive `'static`
|
||||
help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a constraint
|
||||
|
|
||||
LL | existential type E<'a, 'b>: Sized; + 'a
|
||||
LL | type E<'a, 'b> = impl Sized; + 'a
|
||||
|
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -4,7 +4,7 @@
|
||||
//[mir]compile-flags: -Z borrowck=mir
|
||||
|
||||
#![feature(member_constraints)]
|
||||
#![feature(existential_type)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
trait Trait<'a, 'b> { }
|
||||
impl<T> Trait<'_, '_> for T { }
|
||||
@ -12,7 +12,7 @@ impl<T> Trait<'_, '_> for T { }
|
||||
// Here we wind up selecting `'a` and `'b` in the hidden type because
|
||||
// those are the types that appear in the original values.
|
||||
|
||||
existential type Foo<'a, 'b>: Trait<'a, 'b>;
|
||||
type Foo<'a, 'b> = impl Trait<'a, 'b>;
|
||||
|
||||
fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> Foo<'a, 'b> {
|
||||
// In this simple case, you have a hidden type `(&'0 u8, &'1 u8)` and constraints like
|
@ -1,11 +1,11 @@
|
||||
// build-pass (FIXME(62277): could be check-pass?)
|
||||
|
||||
#![feature(existential_type)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
fn main() {
|
||||
existential type Existential: Debug;
|
||||
type Existential = impl Debug;
|
||||
|
||||
fn f() -> Existential {}
|
||||
println!("{:?}", f());
|
@ -120,7 +120,8 @@ trait DummyTrait {
|
||||
}
|
||||
impl DummyTrait for () {
|
||||
type Out = impl Debug;
|
||||
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
|
||||
//~^ ERROR `impl Trait` in type aliases is unstable
|
||||
//~^^ ERROR could not find defining uses
|
||||
|
||||
fn in_trait_impl_parameter(_: impl Debug) { }
|
||||
// Allowed
|
||||
@ -155,7 +156,8 @@ extern "C" fn in_extern_fn_return() -> impl Debug {
|
||||
}
|
||||
|
||||
type InTypeAlias<R> = impl Debug;
|
||||
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
|
||||
//~^ ERROR `impl Trait` in type aliases is unstable
|
||||
//~^^ ERROR could not find defining uses
|
||||
|
||||
type InReturnInTypeAlias<R> = fn() -> impl Debug;
|
||||
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
|
||||
|
@ -16,6 +16,24 @@ LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic
|
||||
| | nested `impl Trait` here
|
||||
| outer `impl Trait`
|
||||
|
||||
error[E0658]: `impl Trait` in type aliases is unstable
|
||||
--> $DIR/where-allowed.rs:122:5
|
||||
|
|
||||
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]: `impl Trait` in type aliases is unstable
|
||||
--> $DIR/where-allowed.rs:158:1
|
||||
|
|
||||
LL | type InTypeAlias<R> = 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[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:18:40
|
||||
|
|
||||
@ -137,97 +155,85 @@ LL | fn in_return() -> impl Debug;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:122:16
|
||||
|
|
||||
LL | type Out = impl Debug;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:128:34
|
||||
--> $DIR/where-allowed.rs:129:34
|
||||
|
|
||||
LL | fn in_trait_impl_return() -> impl Debug { () }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:141:33
|
||||
--> $DIR/where-allowed.rs:142:33
|
||||
|
|
||||
LL | fn in_foreign_parameters(_: impl Debug);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:144:31
|
||||
--> $DIR/where-allowed.rs:145:31
|
||||
|
|
||||
LL | fn in_foreign_return() -> impl Debug;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:157:23
|
||||
|
|
||||
LL | type InTypeAlias<R> = impl Debug;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:160:39
|
||||
--> $DIR/where-allowed.rs:162:39
|
||||
|
|
||||
LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:164:16
|
||||
--> $DIR/where-allowed.rs:166:16
|
||||
|
|
||||
LL | impl PartialEq<impl Debug> for () {
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:169:24
|
||||
--> $DIR/where-allowed.rs:171:24
|
||||
|
|
||||
LL | impl PartialEq<()> for impl Debug {
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:174:6
|
||||
--> $DIR/where-allowed.rs:176:6
|
||||
|
|
||||
LL | impl impl Debug {
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:180:24
|
||||
--> $DIR/where-allowed.rs:182:24
|
||||
|
|
||||
LL | impl InInherentImplAdt<impl Debug> {
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:186:11
|
||||
--> $DIR/where-allowed.rs:188:11
|
||||
|
|
||||
LL | where impl Debug: Debug
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:193:15
|
||||
--> $DIR/where-allowed.rs:195:15
|
||||
|
|
||||
LL | where Vec<impl Debug>: Debug
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:200:24
|
||||
--> $DIR/where-allowed.rs:202:24
|
||||
|
|
||||
LL | where T: PartialEq<impl Debug>
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:207:17
|
||||
--> $DIR/where-allowed.rs:209:17
|
||||
|
|
||||
LL | where T: Fn(impl Debug)
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:214:22
|
||||
--> $DIR/where-allowed.rs:216:22
|
||||
|
|
||||
LL | where T: Fn() -> impl Debug
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:220:29
|
||||
--> $DIR/where-allowed.rs:222:29
|
||||
|
|
||||
LL | let _in_local_variable: impl Fn() = || {};
|
||||
| ^^^^^^^^^
|
||||
@ -235,11 +241,24 @@ LL | let _in_local_variable: impl Fn() = || {};
|
||||
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
|
||||
|
||||
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
|
||||
--> $DIR/where-allowed.rs:222:46
|
||||
--> $DIR/where-allowed.rs:224:46
|
||||
|
|
||||
LL | let _in_return_in_local_variable = || -> impl Fn() { || {} };
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: aborting due to 39 previous errors
|
||||
error: could not find defining uses
|
||||
--> $DIR/where-allowed.rs:158:1
|
||||
|
|
||||
LL | type InTypeAlias<R> = impl Debug;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
For more information about this error, try `rustc --explain E0562`.
|
||||
error: could not find defining uses
|
||||
--> $DIR/where-allowed.rs:122:5
|
||||
|
|
||||
LL | type Out = impl Debug;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 41 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0562, E0658.
|
||||
For more information about an error, try `rustc --explain E0562`.
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,6 @@ impl Howness for () {
|
||||
Empty
|
||||
}
|
||||
}
|
||||
//~^ ERROR expected one of `async`, `const`, `crate`, `default`, `existential`, `extern`, `fn`,
|
||||
//~^ ERROR expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`,
|
||||
|
||||
fn main() {}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user