Handle generic parameters.
This commit is contained in:
parent
cdf78073c5
commit
05812df603
25 changed files with 171 additions and 224 deletions
|
@ -252,11 +252,10 @@ enum ImplTraitContext {
|
||||||
ReturnPositionOpaqueTy {
|
ReturnPositionOpaqueTy {
|
||||||
/// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
|
/// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
|
||||||
origin: hir::OpaqueTyOrigin,
|
origin: hir::OpaqueTyOrigin,
|
||||||
|
in_trait: bool,
|
||||||
},
|
},
|
||||||
/// Impl trait in type aliases.
|
/// Impl trait in type aliases.
|
||||||
TypeAliasesOpaqueTy,
|
TypeAliasesOpaqueTy,
|
||||||
/// Return-position `impl Trait` in trait definition
|
|
||||||
InTrait,
|
|
||||||
/// `impl Trait` is not accepted in this position.
|
/// `impl Trait` is not accepted in this position.
|
||||||
Disallowed(ImplTraitPosition),
|
Disallowed(ImplTraitPosition),
|
||||||
}
|
}
|
||||||
|
@ -1343,9 +1342,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
TyKind::ImplTrait(def_node_id, ref bounds) => {
|
TyKind::ImplTrait(def_node_id, ref bounds) => {
|
||||||
let span = t.span;
|
let span = t.span;
|
||||||
match itctx {
|
match itctx {
|
||||||
ImplTraitContext::ReturnPositionOpaqueTy { origin } => {
|
ImplTraitContext::ReturnPositionOpaqueTy { origin, in_trait } => self
|
||||||
self.lower_opaque_impl_trait(span, *origin, def_node_id, bounds, itctx)
|
.lower_opaque_impl_trait(
|
||||||
}
|
span,
|
||||||
|
*origin,
|
||||||
|
def_node_id,
|
||||||
|
bounds,
|
||||||
|
*in_trait,
|
||||||
|
itctx,
|
||||||
|
),
|
||||||
ImplTraitContext::TypeAliasesOpaqueTy => {
|
ImplTraitContext::TypeAliasesOpaqueTy => {
|
||||||
let mut nested_itctx = ImplTraitContext::TypeAliasesOpaqueTy;
|
let mut nested_itctx = ImplTraitContext::TypeAliasesOpaqueTy;
|
||||||
self.lower_opaque_impl_trait(
|
self.lower_opaque_impl_trait(
|
||||||
|
@ -1353,14 +1358,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
hir::OpaqueTyOrigin::TyAlias,
|
hir::OpaqueTyOrigin::TyAlias,
|
||||||
def_node_id,
|
def_node_id,
|
||||||
bounds,
|
bounds,
|
||||||
&mut nested_itctx,
|
false,
|
||||||
|
nested_itctx,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ImplTraitContext::InTrait => {
|
|
||||||
self.lower_impl_trait_in_trait(span, def_node_id, |lctx| {
|
|
||||||
lctx.lower_param_bounds(bounds, ImplTraitContext::InTrait)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
ImplTraitContext::Universal => {
|
ImplTraitContext::Universal => {
|
||||||
let span = t.span;
|
let span = t.span;
|
||||||
let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span);
|
let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span);
|
||||||
|
@ -1430,6 +1431,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
origin: hir::OpaqueTyOrigin,
|
origin: hir::OpaqueTyOrigin,
|
||||||
opaque_ty_node_id: NodeId,
|
opaque_ty_node_id: NodeId,
|
||||||
bounds: &GenericBounds,
|
bounds: &GenericBounds,
|
||||||
|
in_trait: bool,
|
||||||
itctx: &mut ImplTraitContext,
|
itctx: &mut ImplTraitContext,
|
||||||
) -> hir::TyKind<'hir> {
|
) -> hir::TyKind<'hir> {
|
||||||
// Make sure we know that some funky desugaring has been going on here.
|
// Make sure we know that some funky desugaring has been going on here.
|
||||||
|
@ -1518,6 +1520,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
}),
|
}),
|
||||||
bounds: hir_bounds,
|
bounds: hir_bounds,
|
||||||
origin,
|
origin,
|
||||||
|
in_trait,
|
||||||
};
|
};
|
||||||
debug!(?opaque_ty_item);
|
debug!(?opaque_ty_item);
|
||||||
|
|
||||||
|
@ -1544,30 +1547,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
debug!(?lifetimes);
|
debug!(?lifetimes);
|
||||||
|
|
||||||
// `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
|
// `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
|
||||||
hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, lifetimes)
|
hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, lifetimes, in_trait)
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self, lower_bounds))]
|
|
||||||
fn lower_impl_trait_in_trait(
|
|
||||||
&mut self,
|
|
||||||
span: Span,
|
|
||||||
opaque_ty_node_id: NodeId,
|
|
||||||
lower_bounds: impl FnOnce(&mut Self) -> hir::GenericBounds<'hir>,
|
|
||||||
) -> hir::TyKind<'hir> {
|
|
||||||
let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
|
|
||||||
self.with_hir_id_owner(opaque_ty_node_id, |lctx| {
|
|
||||||
let hir_bounds = lower_bounds(lctx);
|
|
||||||
let rpitit_placeholder = hir::ImplTraitPlaceholder { bounds: hir_bounds };
|
|
||||||
let rpitit_item = hir::Item {
|
|
||||||
def_id: opaque_ty_def_id,
|
|
||||||
ident: Ident::empty(),
|
|
||||||
kind: hir::ItemKind::ImplTraitPlaceholder(rpitit_placeholder),
|
|
||||||
span: lctx.lower_span(span),
|
|
||||||
vis_span: lctx.lower_span(span.shrink_to_lo()),
|
|
||||||
};
|
|
||||||
hir::OwnerNode::Item(lctx.arena.alloc(rpitit_item))
|
|
||||||
});
|
|
||||||
hir::TyKind::ImplTraitInTrait(hir::ItemId { def_id: opaque_ty_def_id })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Registers a new opaque type with the proper `NodeId`s and
|
/// Registers a new opaque type with the proper `NodeId`s and
|
||||||
|
@ -1728,15 +1708,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
self.lower_async_fn_ret_ty_in_trait(
|
self.lower_async_fn_ret_ty(
|
||||||
&decl.output,
|
&decl.output,
|
||||||
fn_node_id.expect("`make_ret_async` but no `fn_def_id`"),
|
fn_node_id.expect("`make_ret_async` but no `fn_def_id`"),
|
||||||
ret_id,
|
ret_id,
|
||||||
|
true,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if !kind.impl_trait_return_allowed(self.tcx) {
|
if !kind.impl_trait_return_allowed(self.tcx) {
|
||||||
if kind == FnDeclKind::Impl {
|
|
||||||
self.tcx
|
self.tcx
|
||||||
.sess
|
.sess
|
||||||
.create_feature_err(
|
.create_feature_err(
|
||||||
|
@ -1744,14 +1724,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
sym::return_position_impl_trait_in_trait,
|
sym::return_position_impl_trait_in_trait,
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
} else {
|
|
||||||
self.tcx.sess.emit_err(TraitFnAsync { fn_span, span });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
self.lower_async_fn_ret_ty(
|
self.lower_async_fn_ret_ty(
|
||||||
&decl.output,
|
&decl.output,
|
||||||
fn_node_id.expect("`make_ret_async` but no `fn_def_id`"),
|
fn_node_id.expect("`make_ret_async` but no `fn_def_id`"),
|
||||||
ret_id,
|
ret_id,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1763,10 +1741,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
let fn_def_id = self.local_def_id(fn_node_id);
|
let fn_def_id = self.local_def_id(fn_node_id);
|
||||||
ImplTraitContext::ReturnPositionOpaqueTy {
|
ImplTraitContext::ReturnPositionOpaqueTy {
|
||||||
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
|
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
|
||||||
|
in_trait: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(_) if kind.impl_trait_in_trait_allowed(self.tcx) => {
|
Some(fn_node_id) if kind.impl_trait_in_trait_allowed(self.tcx) => {
|
||||||
ImplTraitContext::InTrait
|
let fn_def_id = self.local_def_id(fn_node_id);
|
||||||
|
ImplTraitContext::ReturnPositionOpaqueTy {
|
||||||
|
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
|
||||||
|
in_trait: true,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => ImplTraitContext::Disallowed(match kind {
|
_ => ImplTraitContext::Disallowed(match kind {
|
||||||
FnDeclKind::Fn | FnDeclKind::Inherent => {
|
FnDeclKind::Fn | FnDeclKind::Inherent => {
|
||||||
|
@ -1829,6 +1812,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
output: &FnRetTy,
|
output: &FnRetTy,
|
||||||
fn_node_id: NodeId,
|
fn_node_id: NodeId,
|
||||||
opaque_ty_node_id: NodeId,
|
opaque_ty_node_id: NodeId,
|
||||||
|
in_trait: bool,
|
||||||
) -> hir::FnRetTy<'hir> {
|
) -> hir::FnRetTy<'hir> {
|
||||||
let span = output.span();
|
let span = output.span();
|
||||||
|
|
||||||
|
@ -1960,6 +1944,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
span,
|
span,
|
||||||
ImplTraitContext::ReturnPositionOpaqueTy {
|
ImplTraitContext::ReturnPositionOpaqueTy {
|
||||||
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
|
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
|
||||||
|
in_trait,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1999,6 +1984,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
}),
|
}),
|
||||||
bounds: arena_vec![this; future_bound],
|
bounds: arena_vec![this; future_bound],
|
||||||
origin: hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
|
origin: hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
|
||||||
|
in_trait,
|
||||||
};
|
};
|
||||||
|
|
||||||
trace!("exist ty from async fn def id: {:#?}", opaque_ty_def_id);
|
trace!("exist ty from async fn def id: {:#?}", opaque_ty_def_id);
|
||||||
|
@ -2043,38 +2029,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
// Foo = impl Trait` is, internally, created as a child of the
|
// Foo = impl Trait` is, internally, created as a child of the
|
||||||
// async fn, so the *type parameters* are inherited. It's
|
// async fn, so the *type parameters* are inherited. It's
|
||||||
// only the lifetime parameters that we must supply.
|
// only the lifetime parameters that we must supply.
|
||||||
let opaque_ty_ref =
|
let opaque_ty_ref = hir::TyKind::OpaqueDef(
|
||||||
hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, generic_args);
|
hir::ItemId { def_id: opaque_ty_def_id },
|
||||||
let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
|
generic_args,
|
||||||
hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
|
in_trait,
|
||||||
}
|
|
||||||
|
|
||||||
// Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`
|
|
||||||
// combined with the following definition of `OpaqueTy`:
|
|
||||||
//
|
|
||||||
// type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;
|
|
||||||
//
|
|
||||||
// `output`: unlowered output type (`T` in `-> T`)
|
|
||||||
// `fn_def_id`: `DefId` of the parent function (used to create child impl trait definition)
|
|
||||||
// `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
|
||||||
fn lower_async_fn_ret_ty_in_trait(
|
|
||||||
&mut self,
|
|
||||||
output: &FnRetTy,
|
|
||||||
fn_node_id: NodeId,
|
|
||||||
opaque_ty_node_id: NodeId,
|
|
||||||
) -> hir::FnRetTy<'hir> {
|
|
||||||
let kind = self.lower_impl_trait_in_trait(output.span(), opaque_ty_node_id, |lctx| {
|
|
||||||
let bound = lctx.lower_async_fn_output_type_to_future_bound(
|
|
||||||
output,
|
|
||||||
output.span(),
|
|
||||||
ImplTraitContext::InTrait,
|
|
||||||
);
|
);
|
||||||
arena_vec![lctx; bound]
|
let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
|
||||||
});
|
|
||||||
|
|
||||||
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, output.span(), None);
|
|
||||||
let opaque_ty = self.ty(opaque_ty_span, kind);
|
|
||||||
hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
|
hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -772,7 +772,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||||
fn get_future_inner_return_ty(&self, hir_ty: &'tcx hir::Ty<'tcx>) -> &'tcx hir::Ty<'tcx> {
|
fn get_future_inner_return_ty(&self, hir_ty: &'tcx hir::Ty<'tcx>) -> &'tcx hir::Ty<'tcx> {
|
||||||
let hir = self.infcx.tcx.hir();
|
let hir = self.infcx.tcx.hir();
|
||||||
|
|
||||||
let hir::TyKind::OpaqueDef(id, _) = hir_ty.kind else {
|
let hir::TyKind::OpaqueDef(id, _, _) = hir_ty.kind else {
|
||||||
span_bug!(
|
span_bug!(
|
||||||
hir_ty.span,
|
hir_ty.span,
|
||||||
"lowered return type of async fn is not OpaqueDef: {:?}",
|
"lowered return type of async fn is not OpaqueDef: {:?}",
|
||||||
|
|
|
@ -2505,6 +2505,7 @@ pub struct OpaqueTy<'hir> {
|
||||||
pub generics: &'hir Generics<'hir>,
|
pub generics: &'hir Generics<'hir>,
|
||||||
pub bounds: GenericBounds<'hir>,
|
pub bounds: GenericBounds<'hir>,
|
||||||
pub origin: OpaqueTyOrigin,
|
pub origin: OpaqueTyOrigin,
|
||||||
|
pub in_trait: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// From whence the opaque type came.
|
/// From whence the opaque type came.
|
||||||
|
@ -2518,12 +2519,6 @@ pub enum OpaqueTyOrigin {
|
||||||
TyAlias,
|
TyAlias,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Placeholder representation of an `impl Trait` in a trait. Since this never gets lowered into a `ty::Opaque` of its own, we just keep this as
|
|
||||||
#[derive(Debug, HashStable_Generic)]
|
|
||||||
pub struct ImplTraitPlaceholder<'hir> {
|
|
||||||
pub bounds: GenericBounds<'hir>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The various kinds of types recognized by the compiler.
|
/// The various kinds of types recognized by the compiler.
|
||||||
#[derive(Debug, HashStable_Generic)]
|
#[derive(Debug, HashStable_Generic)]
|
||||||
pub enum TyKind<'hir> {
|
pub enum TyKind<'hir> {
|
||||||
|
@ -2550,12 +2545,9 @@ pub enum TyKind<'hir> {
|
||||||
///
|
///
|
||||||
/// The generic argument list contains the lifetimes (and in the future
|
/// The generic argument list contains the lifetimes (and in the future
|
||||||
/// possibly parameters) that are actually bound on the `impl Trait`.
|
/// possibly parameters) that are actually bound on the `impl Trait`.
|
||||||
OpaqueDef(ItemId, &'hir [GenericArg<'hir>]),
|
///
|
||||||
/// A type that represents an `impl Trait` in a trait function. This is
|
/// The last parameter specifies whether this opaque appears in a trait definition.
|
||||||
/// not an opaque type, since it acts more like an associated type than
|
OpaqueDef(ItemId, &'hir [GenericArg<'hir>], bool),
|
||||||
/// an opaque, and since it needs no generics since it inherits those
|
|
||||||
/// from the item's parent.
|
|
||||||
ImplTraitInTrait(ItemId),
|
|
||||||
/// A trait object type `Bound1 + Bound2 + Bound3`
|
/// A trait object type `Bound1 + Bound2 + Bound3`
|
||||||
/// where `Bound` is a trait or a lifetime.
|
/// where `Bound` is a trait or a lifetime.
|
||||||
TraitObject(&'hir [PolyTraitRef<'hir>], &'hir Lifetime, TraitObjectSyntax),
|
TraitObject(&'hir [PolyTraitRef<'hir>], &'hir Lifetime, TraitObjectSyntax),
|
||||||
|
@ -3011,8 +3003,6 @@ pub enum ItemKind<'hir> {
|
||||||
TyAlias(&'hir Ty<'hir>, &'hir Generics<'hir>),
|
TyAlias(&'hir Ty<'hir>, &'hir Generics<'hir>),
|
||||||
/// An opaque `impl Trait` type alias, e.g., `type Foo = impl Bar;`.
|
/// An opaque `impl Trait` type alias, e.g., `type Foo = impl Bar;`.
|
||||||
OpaqueTy(OpaqueTy<'hir>),
|
OpaqueTy(OpaqueTy<'hir>),
|
||||||
/// An `impl Trait` in a trait
|
|
||||||
ImplTraitPlaceholder(ImplTraitPlaceholder<'hir>),
|
|
||||||
/// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`.
|
/// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`.
|
||||||
Enum(EnumDef<'hir>, &'hir Generics<'hir>),
|
Enum(EnumDef<'hir>, &'hir Generics<'hir>),
|
||||||
/// A struct definition, e.g., `struct Foo<A> {x: A}`.
|
/// A struct definition, e.g., `struct Foo<A> {x: A}`.
|
||||||
|
@ -3081,7 +3071,6 @@ impl ItemKind<'_> {
|
||||||
ItemKind::Trait(..) => "trait",
|
ItemKind::Trait(..) => "trait",
|
||||||
ItemKind::TraitAlias(..) => "trait alias",
|
ItemKind::TraitAlias(..) => "trait alias",
|
||||||
ItemKind::Impl(..) => "implementation",
|
ItemKind::Impl(..) => "implementation",
|
||||||
ItemKind::ImplTraitPlaceholder(..) => "opaque type in trait",
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -562,10 +562,6 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
|
||||||
walk_generics(visitor, generics);
|
walk_generics(visitor, generics);
|
||||||
walk_list!(visitor, visit_param_bound, bounds);
|
walk_list!(visitor, visit_param_bound, bounds);
|
||||||
}
|
}
|
||||||
ItemKind::ImplTraitPlaceholder(ImplTraitPlaceholder { bounds }) => {
|
|
||||||
visitor.visit_id(item.hir_id());
|
|
||||||
walk_list!(visitor, visit_param_bound, bounds);
|
|
||||||
}
|
|
||||||
ItemKind::Enum(ref enum_definition, ref generics) => {
|
ItemKind::Enum(ref enum_definition, ref generics) => {
|
||||||
visitor.visit_generics(generics);
|
visitor.visit_generics(generics);
|
||||||
// `visit_enum_def()` takes care of visiting the `Item`'s `HirId`.
|
// `visit_enum_def()` takes care of visiting the `Item`'s `HirId`.
|
||||||
|
@ -674,13 +670,10 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) {
|
||||||
TyKind::Path(ref qpath) => {
|
TyKind::Path(ref qpath) => {
|
||||||
visitor.visit_qpath(qpath, typ.hir_id, typ.span);
|
visitor.visit_qpath(qpath, typ.hir_id, typ.span);
|
||||||
}
|
}
|
||||||
TyKind::OpaqueDef(item_id, lifetimes) => {
|
TyKind::OpaqueDef(item_id, lifetimes, _in_trait) => {
|
||||||
visitor.visit_nested_item(item_id);
|
visitor.visit_nested_item(item_id);
|
||||||
walk_list!(visitor, visit_generic_arg, lifetimes);
|
walk_list!(visitor, visit_generic_arg, lifetimes);
|
||||||
}
|
}
|
||||||
TyKind::ImplTraitInTrait(item_id) => {
|
|
||||||
visitor.visit_nested_item(item_id);
|
|
||||||
}
|
|
||||||
TyKind::Array(ref ty, ref length) => {
|
TyKind::Array(ref ty, ref length) => {
|
||||||
visitor.visit_ty(ty);
|
visitor.visit_ty(ty);
|
||||||
visitor.visit_array_length(length)
|
visitor.visit_array_length(length)
|
||||||
|
|
|
@ -80,8 +80,13 @@ impl Target {
|
||||||
ItemKind::ForeignMod { .. } => Target::ForeignMod,
|
ItemKind::ForeignMod { .. } => Target::ForeignMod,
|
||||||
ItemKind::GlobalAsm(..) => Target::GlobalAsm,
|
ItemKind::GlobalAsm(..) => Target::GlobalAsm,
|
||||||
ItemKind::TyAlias(..) => Target::TyAlias,
|
ItemKind::TyAlias(..) => Target::TyAlias,
|
||||||
ItemKind::OpaqueTy(..) => Target::OpaqueTy,
|
ItemKind::OpaqueTy(ref opaque) => {
|
||||||
ItemKind::ImplTraitPlaceholder(..) => Target::ImplTraitPlaceholder,
|
if opaque.in_trait {
|
||||||
|
Target::ImplTraitPlaceholder
|
||||||
|
} else {
|
||||||
|
Target::OpaqueTy
|
||||||
|
}
|
||||||
|
}
|
||||||
ItemKind::Enum(..) => Target::Enum,
|
ItemKind::Enum(..) => Target::Enum,
|
||||||
ItemKind::Struct(..) => Target::Struct,
|
ItemKind::Struct(..) => Target::Struct,
|
||||||
ItemKind::Union(..) => Target::Union,
|
ItemKind::Union(..) => Target::Union,
|
||||||
|
|
|
@ -327,7 +327,6 @@ impl<'a> State<'a> {
|
||||||
self.print_ty_fn(f.abi, f.unsafety, f.decl, None, f.generic_params, f.param_names);
|
self.print_ty_fn(f.abi, f.unsafety, f.decl, None, f.generic_params, f.param_names);
|
||||||
}
|
}
|
||||||
hir::TyKind::OpaqueDef(..) => self.word("/*impl Trait*/"),
|
hir::TyKind::OpaqueDef(..) => self.word("/*impl Trait*/"),
|
||||||
hir::TyKind::ImplTraitInTrait(..) => self.word("/*impl Trait*/"),
|
|
||||||
hir::TyKind::Path(ref qpath) => self.print_qpath(qpath, false),
|
hir::TyKind::Path(ref qpath) => self.print_qpath(qpath, false),
|
||||||
hir::TyKind::TraitObject(bounds, ref lifetime, syntax) => {
|
hir::TyKind::TraitObject(bounds, ref lifetime, syntax) => {
|
||||||
if syntax == ast::TraitObjectSyntax::Dyn {
|
if syntax == ast::TraitObjectSyntax::Dyn {
|
||||||
|
@ -609,9 +608,6 @@ impl<'a> State<'a> {
|
||||||
state.print_bounds("= impl", real_bounds);
|
state.print_bounds("= impl", real_bounds);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
hir::ItemKind::ImplTraitPlaceholder(..) => {
|
|
||||||
unreachable!("FIXME(RPITIT): I don't think this ever gets called here...");
|
|
||||||
}
|
|
||||||
hir::ItemKind::Enum(ref enum_definition, params) => {
|
hir::ItemKind::Enum(ref enum_definition, params) => {
|
||||||
self.print_enum_def(enum_definition, params, item.ident.name, item.span);
|
self.print_enum_def(enum_definition, params, item.ident.name, item.span);
|
||||||
}
|
}
|
||||||
|
|
|
@ -300,7 +300,7 @@ pub fn suggest_new_region_bound(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
match fn_return.kind {
|
match fn_return.kind {
|
||||||
TyKind::OpaqueDef(item_id, _) => {
|
TyKind::OpaqueDef(item_id, _, _) => {
|
||||||
let item = tcx.hir().item(item_id);
|
let item = tcx.hir().item(item_id);
|
||||||
let ItemKind::OpaqueTy(opaque) = &item.kind else {
|
let ItemKind::OpaqueTy(opaque) = &item.kind else {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1500,9 +1500,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
hir::ItemKind::OpaqueTy(..) => {
|
hir::ItemKind::OpaqueTy(..) => {
|
||||||
self.encode_explicit_item_bounds(def_id);
|
self.encode_explicit_item_bounds(def_id);
|
||||||
}
|
}
|
||||||
hir::ItemKind::ImplTraitPlaceholder(..) => {
|
|
||||||
self.encode_explicit_item_bounds(def_id);
|
|
||||||
}
|
|
||||||
hir::ItemKind::Enum(..) => {
|
hir::ItemKind::Enum(..) => {
|
||||||
let adt_def = self.tcx.adt_def(def_id);
|
let adt_def = self.tcx.adt_def(def_id);
|
||||||
record!(self.tables.repr_options[def_id] <- adt_def.repr());
|
record!(self.tables.repr_options[def_id] <- adt_def.repr());
|
||||||
|
|
|
@ -212,8 +212,13 @@ impl<'hir> Map<'hir> {
|
||||||
ItemKind::Fn(..) => DefKind::Fn,
|
ItemKind::Fn(..) => DefKind::Fn,
|
||||||
ItemKind::Macro(_, macro_kind) => DefKind::Macro(macro_kind),
|
ItemKind::Macro(_, macro_kind) => DefKind::Macro(macro_kind),
|
||||||
ItemKind::Mod(..) => DefKind::Mod,
|
ItemKind::Mod(..) => DefKind::Mod,
|
||||||
ItemKind::OpaqueTy(..) => DefKind::OpaqueTy,
|
ItemKind::OpaqueTy(ref opaque) => {
|
||||||
ItemKind::ImplTraitPlaceholder(..) => DefKind::ImplTraitPlaceholder,
|
if opaque.in_trait {
|
||||||
|
DefKind::ImplTraitPlaceholder
|
||||||
|
} else {
|
||||||
|
DefKind::OpaqueTy
|
||||||
|
}
|
||||||
|
}
|
||||||
ItemKind::TyAlias(..) => DefKind::TyAlias,
|
ItemKind::TyAlias(..) => DefKind::TyAlias,
|
||||||
ItemKind::Enum(..) => DefKind::Enum,
|
ItemKind::Enum(..) => DefKind::Enum,
|
||||||
ItemKind::Struct(..) => DefKind::Struct,
|
ItemKind::Struct(..) => DefKind::Struct,
|
||||||
|
@ -1188,8 +1193,13 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
|
||||||
ItemKind::ForeignMod { .. } => "foreign mod",
|
ItemKind::ForeignMod { .. } => "foreign mod",
|
||||||
ItemKind::GlobalAsm(..) => "global asm",
|
ItemKind::GlobalAsm(..) => "global asm",
|
||||||
ItemKind::TyAlias(..) => "ty",
|
ItemKind::TyAlias(..) => "ty",
|
||||||
ItemKind::OpaqueTy(..) => "opaque type",
|
ItemKind::OpaqueTy(ref opaque) => {
|
||||||
ItemKind::ImplTraitPlaceholder(..) => "opaque type in trait",
|
if opaque.in_trait {
|
||||||
|
"opaque type in trait"
|
||||||
|
} else {
|
||||||
|
"opaque type"
|
||||||
|
}
|
||||||
|
}
|
||||||
ItemKind::Enum(..) => "enum",
|
ItemKind::Enum(..) => "enum",
|
||||||
ItemKind::Struct(..) => "struct",
|
ItemKind::Struct(..) => "struct",
|
||||||
ItemKind::Union(..) => "union",
|
ItemKind::Union(..) => "union",
|
||||||
|
|
|
@ -408,7 +408,7 @@ impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
|
||||||
) => {
|
) => {
|
||||||
self.0.push(ty);
|
self.0.push(ty);
|
||||||
}
|
}
|
||||||
hir::TyKind::OpaqueDef(item_id, _) => {
|
hir::TyKind::OpaqueDef(item_id, _, _) => {
|
||||||
self.0.push(ty);
|
self.0.push(ty);
|
||||||
let item = self.1.item(item_id);
|
let item = self.1.item(item_id);
|
||||||
hir::intravisit::walk_item(self, item);
|
hir::intravisit::walk_item(self, item);
|
||||||
|
|
|
@ -447,7 +447,7 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
|
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
|
||||||
if let TyKind::OpaqueDef(item_id, _) = ty.kind {
|
if let TyKind::OpaqueDef(item_id, _, _) = ty.kind {
|
||||||
let item = self.tcx.hir().item(item_id);
|
let item = self.tcx.hir().item(item_id);
|
||||||
intravisit::walk_item(self, item);
|
intravisit::walk_item(self, item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -235,7 +235,6 @@ impl<'tcx> ReachableContext<'tcx> {
|
||||||
hir::ItemKind::ExternCrate(_)
|
hir::ItemKind::ExternCrate(_)
|
||||||
| hir::ItemKind::Use(..)
|
| hir::ItemKind::Use(..)
|
||||||
| hir::ItemKind::OpaqueTy(..)
|
| hir::ItemKind::OpaqueTy(..)
|
||||||
| hir::ItemKind::ImplTraitPlaceholder(..)
|
|
||||||
| hir::ItemKind::TyAlias(..)
|
| hir::ItemKind::TyAlias(..)
|
||||||
| hir::ItemKind::Macro(..)
|
| hir::ItemKind::Macro(..)
|
||||||
| hir::ItemKind::Mod(..)
|
| hir::ItemKind::Mod(..)
|
||||||
|
|
|
@ -686,7 +686,6 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ItemKind::OpaqueTy(..)
|
hir::ItemKind::OpaqueTy(..)
|
||||||
| hir::ItemKind::ImplTraitPlaceholder(..)
|
|
||||||
| hir::ItemKind::Use(..)
|
| hir::ItemKind::Use(..)
|
||||||
| hir::ItemKind::Static(..)
|
| hir::ItemKind::Static(..)
|
||||||
| hir::ItemKind::Const(..)
|
| hir::ItemKind::Const(..)
|
||||||
|
@ -708,12 +707,12 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
|
||||||
hir::ItemKind::Use(..) => {}
|
hir::ItemKind::Use(..) => {}
|
||||||
// The interface is empty.
|
// The interface is empty.
|
||||||
hir::ItemKind::GlobalAsm(..) => {}
|
hir::ItemKind::GlobalAsm(..) => {}
|
||||||
hir::ItemKind::OpaqueTy(..) => {
|
hir::ItemKind::OpaqueTy(ref opaque) => {
|
||||||
// HACK(jynelson): trying to infer the type of `impl trait` breaks `async-std` (and `pub async fn` in general)
|
// HACK(jynelson): trying to infer the type of `impl trait` breaks `async-std` (and `pub async fn` in general)
|
||||||
// Since rustdoc never needs to do codegen and doesn't care about link-time reachability,
|
// Since rustdoc never needs to do codegen and doesn't care about link-time reachability,
|
||||||
// mark this as unreachable.
|
// mark this as unreachable.
|
||||||
// See https://github.com/rust-lang/rust/issues/75100
|
// See https://github.com/rust-lang/rust/issues/75100
|
||||||
if !self.tcx.sess.opts.actually_rustdoc {
|
if !opaque.in_trait && !self.tcx.sess.opts.actually_rustdoc {
|
||||||
// FIXME: This is some serious pessimization intended to workaround deficiencies
|
// FIXME: This is some serious pessimization intended to workaround deficiencies
|
||||||
// in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
|
// in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
|
||||||
// reachable if they are returned via `impl Trait`, even from private functions.
|
// reachable if they are returned via `impl Trait`, even from private functions.
|
||||||
|
@ -722,9 +721,6 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
|
||||||
self.reach(item.def_id, exist_level).generics().predicates().ty();
|
self.reach(item.def_id, exist_level).generics().predicates().ty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::ItemKind::ImplTraitPlaceholder(..) => {
|
|
||||||
// FIXME(RPITIT): Do we need to do anything here?
|
|
||||||
}
|
|
||||||
// Visit everything.
|
// Visit everything.
|
||||||
hir::ItemKind::Const(..)
|
hir::ItemKind::Const(..)
|
||||||
| hir::ItemKind::Static(..)
|
| hir::ItemKind::Static(..)
|
||||||
|
@ -2039,8 +2035,7 @@ fn local_visibility(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Visibility {
|
||||||
// query failing on some items, we provide it for opaque types as well.
|
// query failing on some items, we provide it for opaque types as well.
|
||||||
| Node::Item(hir::Item {
|
| Node::Item(hir::Item {
|
||||||
kind: hir::ItemKind::Use(_, hir::UseKind::ListStem)
|
kind: hir::ItemKind::Use(_, hir::UseKind::ListStem)
|
||||||
| hir::ItemKind::OpaqueTy(..)
|
| hir::ItemKind::OpaqueTy(..),
|
||||||
| hir::ItemKind::ImplTraitPlaceholder(..),
|
|
||||||
..
|
..
|
||||||
}) => ty::Visibility::Restricted(tcx.parent_module(hir_id)),
|
}) => ty::Visibility::Restricted(tcx.parent_module(hir_id)),
|
||||||
// Visibilities of trait impl items are inherited from their traits
|
// Visibilities of trait impl items are inherited from their traits
|
||||||
|
|
|
@ -596,10 +596,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::ItemKind::ImplTraitPlaceholder(..) => {
|
|
||||||
// FIXME(RPITIT): We don't need to do anything special here, right?
|
|
||||||
intravisit::walk_item(self, item);
|
|
||||||
}
|
|
||||||
hir::ItemKind::TyAlias(_, ref generics)
|
hir::ItemKind::TyAlias(_, ref generics)
|
||||||
| hir::ItemKind::Enum(_, ref generics)
|
| hir::ItemKind::Enum(_, ref generics)
|
||||||
| hir::ItemKind::Struct(_, ref generics)
|
| hir::ItemKind::Struct(_, ref generics)
|
||||||
|
@ -719,7 +715,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
self.with(scope, |this| this.visit_ty(&mt.ty));
|
self.with(scope, |this| this.visit_ty(&mt.ty));
|
||||||
}
|
}
|
||||||
hir::TyKind::OpaqueDef(item_id, lifetimes) => {
|
hir::TyKind::OpaqueDef(item_id, lifetimes, _in_trait) => {
|
||||||
// Resolve the lifetimes in the bounds to the lifetime defs in the generics.
|
// Resolve the lifetimes in the bounds to the lifetime defs in the generics.
|
||||||
// `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
|
// `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
|
||||||
// `type MyAnonTy<'b> = impl MyTrait<'b>;`
|
// `type MyAnonTy<'b> = impl MyTrait<'b>;`
|
||||||
|
|
|
@ -1321,7 +1321,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::TyKind::OpaqueDef(item_id, _) => {
|
hir::TyKind::OpaqueDef(item_id, _, _) => {
|
||||||
let item = self.tcx.hir().item(item_id);
|
let item = self.tcx.hir().item(item_id);
|
||||||
self.nest_typeck_results(item_id.def_id, |v| v.visit_item(item));
|
self.nest_typeck_results(item_id.def_id, |v| v.visit_item(item));
|
||||||
}
|
}
|
||||||
|
|
|
@ -316,11 +316,7 @@ impl<'hir> Sig for hir::Ty<'hir> {
|
||||||
let text = format!("[{}; {}]", nested_ty.text, expr);
|
let text = format!("[{}; {}]", nested_ty.text, expr);
|
||||||
Ok(replace_text(nested_ty, text))
|
Ok(replace_text(nested_ty, text))
|
||||||
}
|
}
|
||||||
hir::TyKind::OpaqueDef(item_id, _) => {
|
hir::TyKind::OpaqueDef(item_id, _, _) => {
|
||||||
let item = scx.tcx.hir().item(item_id);
|
|
||||||
item.make(offset, Some(item_id.hir_id()), scx)
|
|
||||||
}
|
|
||||||
hir::TyKind::ImplTraitInTrait(item_id) => {
|
|
||||||
let item = scx.tcx.hir().item(item_id);
|
let item = scx.tcx.hir().item(item_id);
|
||||||
item.make(offset, Some(item_id.hir_id()), scx)
|
item.make(offset, Some(item_id.hir_id()), scx)
|
||||||
}
|
}
|
||||||
|
@ -565,8 +561,13 @@ impl<'hir> Sig for hir::Item<'hir> {
|
||||||
hir::ItemKind::ForeignMod { .. } => Err("extern mod"),
|
hir::ItemKind::ForeignMod { .. } => Err("extern mod"),
|
||||||
hir::ItemKind::GlobalAsm(_) => Err("global asm"),
|
hir::ItemKind::GlobalAsm(_) => Err("global asm"),
|
||||||
hir::ItemKind::ExternCrate(_) => Err("extern crate"),
|
hir::ItemKind::ExternCrate(_) => Err("extern crate"),
|
||||||
hir::ItemKind::OpaqueTy(..) => Err("opaque type"),
|
hir::ItemKind::OpaqueTy(ref opaque) => {
|
||||||
hir::ItemKind::ImplTraitPlaceholder(..) => Err("opaque type in trait"),
|
if opaque.in_trait {
|
||||||
|
Err("opaque type in trait")
|
||||||
|
} else {
|
||||||
|
Err("opaque type")
|
||||||
|
}
|
||||||
|
}
|
||||||
// FIXME should implement this (e.g., pub use).
|
// FIXME should implement this (e.g., pub use).
|
||||||
hir::ItemKind::Use(..) => Err("import"),
|
hir::ItemKind::Use(..) => Err("import"),
|
||||||
}
|
}
|
||||||
|
|
|
@ -2165,7 +2165,7 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
|
||||||
let tcx = selcx.tcx();
|
let tcx = selcx.tcx();
|
||||||
let mut obligations = data.nested;
|
let mut obligations = data.nested;
|
||||||
|
|
||||||
let trait_fn_def_id = tcx.parent(obligation.predicate.item_def_id);
|
let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.item_def_id);
|
||||||
let Ok(leaf_def) = assoc_def(selcx, data.impl_def_id, trait_fn_def_id) else {
|
let Ok(leaf_def) = assoc_def(selcx, data.impl_def_id, trait_fn_def_id) else {
|
||||||
return Progress { term: tcx.ty_error().into(), obligations };
|
return Progress { term: tcx.ty_error().into(), obligations };
|
||||||
};
|
};
|
||||||
|
|
|
@ -2360,7 +2360,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
|
|
||||||
let span = path.span;
|
let span = path.span;
|
||||||
match path.res {
|
match path.res {
|
||||||
Res::Def(DefKind::OpaqueTy, did) => {
|
Res::Def(DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder, did) => {
|
||||||
// Check for desugared `impl Trait`.
|
// Check for desugared `impl Trait`.
|
||||||
assert!(ty::is_impl_trait_defn(tcx, did).is_none());
|
assert!(ty::is_impl_trait_defn(tcx, did).is_none());
|
||||||
let item_segment = path.segments.split_last().unwrap();
|
let item_segment = path.segments.split_last().unwrap();
|
||||||
|
@ -2627,21 +2627,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
let opt_self_ty = maybe_qself.as_ref().map(|qself| self.ast_ty_to_ty(qself));
|
let opt_self_ty = maybe_qself.as_ref().map(|qself| self.ast_ty_to_ty(qself));
|
||||||
self.res_to_ty(opt_self_ty, path, false)
|
self.res_to_ty(opt_self_ty, path, false)
|
||||||
}
|
}
|
||||||
hir::TyKind::OpaqueDef(item_id, lifetimes) => {
|
hir::TyKind::OpaqueDef(item_id, lifetimes, in_trait) => {
|
||||||
let opaque_ty = tcx.hir().item(item_id);
|
let opaque_ty = tcx.hir().item(item_id);
|
||||||
let def_id = item_id.def_id.to_def_id();
|
let def_id = item_id.def_id.to_def_id();
|
||||||
|
|
||||||
match opaque_ty.kind {
|
match opaque_ty.kind {
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
|
hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
|
||||||
self.impl_trait_ty_to_ty(def_id, lifetimes, origin)
|
self.impl_trait_ty_to_ty(def_id, lifetimes, origin, in_trait)
|
||||||
}
|
}
|
||||||
ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
|
ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::TyKind::ImplTraitInTrait(item_id) => {
|
|
||||||
let def_id = item_id.def_id.to_def_id();
|
|
||||||
tcx.mk_projection(def_id, InternalSubsts::identity_for_item(tcx, def_id))
|
|
||||||
}
|
|
||||||
hir::TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => {
|
hir::TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => {
|
||||||
debug!(?qself, ?segment);
|
debug!(?qself, ?segment);
|
||||||
let ty = self.ast_ty_to_ty_inner(qself, false, true);
|
let ty = self.ast_ty_to_ty_inner(qself, false, true);
|
||||||
|
@ -2707,6 +2703,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
lifetimes: &[hir::GenericArg<'_>],
|
lifetimes: &[hir::GenericArg<'_>],
|
||||||
origin: OpaqueTyOrigin,
|
origin: OpaqueTyOrigin,
|
||||||
|
in_trait: bool,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
debug!("impl_trait_ty_to_ty(def_id={:?}, lifetimes={:?})", def_id, lifetimes);
|
debug!("impl_trait_ty_to_ty(def_id={:?}, lifetimes={:?})", def_id, lifetimes);
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
@ -2750,7 +2747,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
});
|
});
|
||||||
debug!("impl_trait_ty_to_ty: substs={:?}", substs);
|
debug!("impl_trait_ty_to_ty: substs={:?}", substs);
|
||||||
|
|
||||||
tcx.mk_opaque(def_id, substs)
|
if in_trait { tcx.mk_projection(def_id, substs) } else { tcx.mk_opaque(def_id, substs) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ty_of_arg(&self, ty: &hir::Ty<'_>, expected_ty: Option<Ty<'tcx>>) -> Ty<'tcx> {
|
pub fn ty_of_arg(&self, ty: &hir::Ty<'_>, expected_ty: Option<Ty<'tcx>>) -> Ty<'tcx> {
|
||||||
|
|
|
@ -423,9 +423,28 @@ pub(super) fn compare_predicates_and_trait_impl_trait_tys<'tcx>(
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut collected_tys = FxHashMap::default();
|
let mut collected_tys = FxHashMap::default();
|
||||||
for (def_id, ty) in collector.types {
|
for (def_id, (ty, substs)) in collector.types {
|
||||||
match infcx.fully_resolve(ty) {
|
match infcx.fully_resolve(ty) {
|
||||||
Ok(ty) => {
|
Ok(ty) => {
|
||||||
|
// `ty` contains free regions that we created earlier while liberating the
|
||||||
|
// trait fn signature. However, projection normalization expects `ty` to
|
||||||
|
// contains `def_id`'s early-bound regions.
|
||||||
|
let id_substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||||
|
debug!(?id_substs, ?substs);
|
||||||
|
let map: FxHashMap<ty::GenericArg<'tcx>, ty::GenericArg<'tcx>> = substs
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(index, arg)| (arg, id_substs[index]))
|
||||||
|
.collect();
|
||||||
|
debug!(?map);
|
||||||
|
|
||||||
|
let ty = tcx.fold_regions(ty, |region, _| {
|
||||||
|
if let ty::ReFree(_) = region.kind() {
|
||||||
|
map[®ion.into()].expect_region()
|
||||||
|
} else {
|
||||||
|
region
|
||||||
|
}
|
||||||
|
});
|
||||||
collected_tys.insert(def_id, ty);
|
collected_tys.insert(def_id, ty);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -444,7 +463,7 @@ pub(super) fn compare_predicates_and_trait_impl_trait_tys<'tcx>(
|
||||||
|
|
||||||
struct ImplTraitInTraitCollector<'a, 'tcx> {
|
struct ImplTraitInTraitCollector<'a, 'tcx> {
|
||||||
ocx: &'a ObligationCtxt<'a, 'tcx>,
|
ocx: &'a ObligationCtxt<'a, 'tcx>,
|
||||||
types: FxHashMap<DefId, Ty<'tcx>>,
|
types: FxHashMap<DefId, (Ty<'tcx>, ty::SubstsRef<'tcx>)>,
|
||||||
span: Span,
|
span: Span,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
body_id: hir::HirId,
|
body_id: hir::HirId,
|
||||||
|
@ -470,7 +489,7 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
|
||||||
if let ty::Projection(proj) = ty.kind()
|
if let ty::Projection(proj) = ty.kind()
|
||||||
&& self.tcx().def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
|
&& self.tcx().def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
|
||||||
{
|
{
|
||||||
if let Some(ty) = self.types.get(&proj.item_def_id) {
|
if let Some((ty, _)) = self.types.get(&proj.item_def_id) {
|
||||||
return *ty;
|
return *ty;
|
||||||
}
|
}
|
||||||
//FIXME(RPITIT): Deny nested RPITIT in substs too
|
//FIXME(RPITIT): Deny nested RPITIT in substs too
|
||||||
|
@ -482,7 +501,7 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
|
||||||
span: self.span,
|
span: self.span,
|
||||||
kind: TypeVariableOriginKind::MiscVariable,
|
kind: TypeVariableOriginKind::MiscVariable,
|
||||||
});
|
});
|
||||||
self.types.insert(proj.item_def_id, infer_ty);
|
self.types.insert(proj.item_def_id, (infer_ty, proj.substs));
|
||||||
// Recurse into bounds
|
// Recurse into bounds
|
||||||
for pred in self.tcx().bound_explicit_item_bounds(proj.item_def_id).transpose_iter() {
|
for pred in self.tcx().bound_explicit_item_bounds(proj.item_def_id).transpose_iter() {
|
||||||
let pred_span = pred.0.1;
|
let pred_span = pred.0.1;
|
||||||
|
|
|
@ -815,11 +815,6 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
|
||||||
tcx.ensure().predicates_of(def_id);
|
tcx.ensure().predicates_of(def_id);
|
||||||
tcx.ensure().explicit_item_bounds(def_id);
|
tcx.ensure().explicit_item_bounds(def_id);
|
||||||
}
|
}
|
||||||
hir::ItemKind::ImplTraitPlaceholder(..) => {
|
|
||||||
tcx.ensure().generics_of(def_id);
|
|
||||||
tcx.ensure().predicates_of(def_id);
|
|
||||||
tcx.ensure().explicit_item_bounds(def_id);
|
|
||||||
}
|
|
||||||
hir::ItemKind::TyAlias(..)
|
hir::ItemKind::TyAlias(..)
|
||||||
| hir::ItemKind::Static(..)
|
| hir::ItemKind::Static(..)
|
||||||
| hir::ItemKind::Const(..)
|
| hir::ItemKind::Const(..)
|
||||||
|
@ -1590,8 +1585,16 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
|
||||||
ItemKind::OpaqueTy(hir::OpaqueTy {
|
ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
origin:
|
origin:
|
||||||
hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
|
hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
|
||||||
|
in_trait,
|
||||||
..
|
..
|
||||||
}) => Some(fn_def_id.to_def_id()),
|
}) => {
|
||||||
|
if in_trait {
|
||||||
|
assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn))
|
||||||
|
} else {
|
||||||
|
assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn))
|
||||||
|
}
|
||||||
|
Some(fn_def_id.to_def_id())
|
||||||
|
}
|
||||||
ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => {
|
ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => {
|
||||||
let parent_id = tcx.hir().get_parent_item(hir_id);
|
let parent_id = tcx.hir().get_parent_item(hir_id);
|
||||||
assert_ne!(parent_id, CRATE_DEF_ID);
|
assert_ne!(parent_id, CRATE_DEF_ID);
|
||||||
|
@ -1600,14 +1603,6 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
|
||||||
// inherit the generics of the item.
|
// inherit the generics of the item.
|
||||||
Some(parent_id.to_def_id())
|
Some(parent_id.to_def_id())
|
||||||
}
|
}
|
||||||
ItemKind::ImplTraitPlaceholder(_) => {
|
|
||||||
let parent_id = tcx.hir().get_parent_item(hir_id).to_def_id();
|
|
||||||
assert!(matches!(
|
|
||||||
tcx.def_kind(parent_id),
|
|
||||||
DefKind::AssocFn | DefKind::ImplTraitPlaceholder
|
|
||||||
));
|
|
||||||
Some(parent_id)
|
|
||||||
}
|
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -1800,7 +1795,7 @@ fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool {
|
||||||
}
|
}
|
||||||
Tup(tys) => tys.iter().any(is_suggestable_infer_ty),
|
Tup(tys) => tys.iter().any(is_suggestable_infer_ty),
|
||||||
Ptr(mut_ty) | Rptr(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty),
|
Ptr(mut_ty) | Rptr(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty),
|
||||||
OpaqueDef(_, generic_args) => are_suggestable_generic_args(generic_args),
|
OpaqueDef(_, generic_args, _) => are_suggestable_generic_args(generic_args),
|
||||||
Path(hir::QPath::TypeRelative(ty, segment)) => {
|
Path(hir::QPath::TypeRelative(ty, segment)) => {
|
||||||
is_suggestable_infer_ty(ty) || are_suggestable_generic_args(segment.args().args)
|
is_suggestable_infer_ty(ty) || are_suggestable_generic_args(segment.args().args)
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,10 +59,15 @@ fn opaque_type_bounds<'tcx>(
|
||||||
opaque_def_id: DefId,
|
opaque_def_id: DefId,
|
||||||
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
|
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
|
||||||
span: Span,
|
span: Span,
|
||||||
|
in_trait: bool,
|
||||||
) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
|
) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
|
||||||
ty::print::with_no_queries!({
|
ty::print::with_no_queries!({
|
||||||
let item_ty =
|
let substs = InternalSubsts::identity_for_item(tcx, opaque_def_id);
|
||||||
tcx.mk_opaque(opaque_def_id, InternalSubsts::identity_for_item(tcx, opaque_def_id));
|
let item_ty = if in_trait {
|
||||||
|
tcx.mk_projection(opaque_def_id, substs)
|
||||||
|
} else {
|
||||||
|
tcx.mk_opaque(opaque_def_id, substs)
|
||||||
|
};
|
||||||
|
|
||||||
let icx = ItemCtxt::new(tcx, opaque_def_id);
|
let icx = ItemCtxt::new(tcx, opaque_def_id);
|
||||||
let mut bounds = <dyn AstConv<'_>>::compute_bounds(&icx, item_ty, ast_bounds);
|
let mut bounds = <dyn AstConv<'_>>::compute_bounds(&icx, item_ty, ast_bounds);
|
||||||
|
@ -74,29 +79,6 @@ fn opaque_type_bounds<'tcx>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Opaque types don't inherit bounds from their parent: for return position
|
|
||||||
/// impl trait it isn't possible to write a suitable predicate on the
|
|
||||||
/// containing function and for type-alias impl trait we don't have a backwards
|
|
||||||
/// compatibility issue.
|
|
||||||
fn impl_trait_in_trait_item_bounds<'tcx>(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
opaque_def_id: DefId,
|
|
||||||
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
|
|
||||||
span: Span,
|
|
||||||
) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
|
|
||||||
ty::print::with_no_queries!({
|
|
||||||
// FIXME(RPITIT): DRY-er code please
|
|
||||||
let item_ty =
|
|
||||||
tcx.mk_projection(opaque_def_id, InternalSubsts::identity_for_item(tcx, opaque_def_id));
|
|
||||||
|
|
||||||
let icx = ItemCtxt::new(tcx, opaque_def_id);
|
|
||||||
let mut bounds = <dyn AstConv<'_>>::compute_bounds(&icx, item_ty, ast_bounds);
|
|
||||||
// RPITITs are implicitly sized unless a `?Sized` bound is found
|
|
||||||
<dyn AstConv<'_>>::add_implicitly_sized(&icx, &mut bounds, ast_bounds, None, span);
|
|
||||||
tcx.arena.alloc_from_iter(bounds.predicates(tcx, item_ty))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn explicit_item_bounds(
|
pub(super) fn explicit_item_bounds(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
|
@ -109,15 +91,10 @@ pub(super) fn explicit_item_bounds(
|
||||||
..
|
..
|
||||||
}) => associated_type_bounds(tcx, def_id, bounds, *span),
|
}) => associated_type_bounds(tcx, def_id, bounds, *span),
|
||||||
hir::Node::Item(hir::Item {
|
hir::Node::Item(hir::Item {
|
||||||
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, .. }),
|
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait, .. }),
|
||||||
span,
|
span,
|
||||||
..
|
..
|
||||||
}) => opaque_type_bounds(tcx, def_id, bounds, *span),
|
}) => opaque_type_bounds(tcx, def_id, bounds, *span, *in_trait),
|
||||||
hir::Node::Item(hir::Item {
|
|
||||||
kind: hir::ItemKind::ImplTraitPlaceholder(hir::ImplTraitPlaceholder { bounds }),
|
|
||||||
span,
|
|
||||||
..
|
|
||||||
}) => impl_trait_in_trait_item_bounds(tcx, def_id, bounds, *span),
|
|
||||||
_ => bug!("item_bounds called on {:?}", def_id),
|
_ => bug!("item_bounds called on {:?}", def_id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -333,11 +333,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||||
find_opaque_ty_constraints_for_tait(tcx, def_id)
|
find_opaque_ty_constraints_for_tait(tcx, def_id)
|
||||||
}
|
}
|
||||||
// Opaque types desugared from `impl Trait`.
|
// Opaque types desugared from `impl Trait`.
|
||||||
ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner), .. }) => {
|
ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner), in_trait, .. }) => {
|
||||||
|
if in_trait {
|
||||||
|
span_bug!(item.span, "impl-trait in trait has no default")
|
||||||
|
} else {
|
||||||
find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
|
find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
|
||||||
}
|
}
|
||||||
ItemKind::ImplTraitPlaceholder(..) => {
|
|
||||||
span_bug!(item.span, "not yet implemented")
|
|
||||||
}
|
}
|
||||||
ItemKind::Trait(..)
|
ItemKind::Trait(..)
|
||||||
| ItemKind::TraitAlias(..)
|
| ItemKind::TraitAlias(..)
|
||||||
|
|
|
@ -1492,7 +1492,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
|
||||||
Array(Box::new(clean_ty(ty, cx)), length)
|
Array(Box::new(clean_ty(ty, cx)), length)
|
||||||
}
|
}
|
||||||
TyKind::Tup(tys) => Tuple(tys.iter().map(|ty| clean_ty(ty, cx)).collect()),
|
TyKind::Tup(tys) => Tuple(tys.iter().map(|ty| clean_ty(ty, cx)).collect()),
|
||||||
TyKind::OpaqueDef(item_id, _) => {
|
TyKind::OpaqueDef(item_id, _, _) => {
|
||||||
let item = cx.tcx.hir().item(item_id);
|
let item = cx.tcx.hir().item(item_id);
|
||||||
if let hir::ItemKind::OpaqueTy(ref ty) = item.kind {
|
if let hir::ItemKind::OpaqueTy(ref ty) = item.kind {
|
||||||
ImplTrait(ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect())
|
ImplTrait(ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect())
|
||||||
|
@ -1500,16 +1500,6 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TyKind::ImplTraitInTrait(item_id) => {
|
|
||||||
let item = cx.tcx.hir().item(item_id);
|
|
||||||
if let hir::ItemKind::ImplTraitPlaceholder(hir::ImplTraitPlaceholder { bounds }) =
|
|
||||||
item.kind
|
|
||||||
{
|
|
||||||
ImplTrait(bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect())
|
|
||||||
} else {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TyKind::Path(_) => clean_qpath(ty, cx),
|
TyKind::Path(_) => clean_qpath(ty, cx),
|
||||||
TyKind::TraitObject(bounds, ref lifetime, _) => {
|
TyKind::TraitObject(bounds, ref lifetime, _) => {
|
||||||
let bounds = bounds.iter().map(|bound| clean_poly_trait_ref(bound, cx)).collect();
|
let bounds = bounds.iter().map(|bound| clean_poly_trait_ref(bound, cx)).collect();
|
||||||
|
|
|
@ -362,7 +362,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
| hir::ItemKind::Union(..)
|
| hir::ItemKind::Union(..)
|
||||||
| hir::ItemKind::TyAlias(..)
|
| hir::ItemKind::TyAlias(..)
|
||||||
| hir::ItemKind::OpaqueTy(..)
|
| hir::ItemKind::OpaqueTy(..)
|
||||||
| hir::ItemKind::ImplTraitPlaceholder(..)
|
|
||||||
| hir::ItemKind::Static(..)
|
| hir::ItemKind::Static(..)
|
||||||
| hir::ItemKind::Trait(..)
|
| hir::ItemKind::Trait(..)
|
||||||
| hir::ItemKind::TraitAlias(..) => om.items.push((item, renamed)),
|
| hir::ItemKind::TraitAlias(..) => om.items.push((item, renamed)),
|
||||||
|
|
|
@ -3,18 +3,46 @@
|
||||||
#![feature(return_position_impl_trait_in_trait)]
|
#![feature(return_position_impl_trait_in_trait)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
use std::fmt::Display;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
trait Foo {
|
trait Foo {
|
||||||
fn bar(&self) -> impl Display;
|
fn foo(&self) -> impl Debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Foo for () {
|
impl Foo for () {
|
||||||
fn bar(&self) -> impl Display {
|
fn foo(&self) -> impl Debug {
|
||||||
"Hello, world"
|
"Hello, world"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
impl<T: Default + Debug> Foo for std::marker::PhantomData<T> {
|
||||||
println!("{}", ().bar());
|
fn foo(&self) -> impl Debug {
|
||||||
|
T::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Bar {
|
||||||
|
fn bar<T>(&self) -> impl Debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Bar for () {
|
||||||
|
fn bar<T>(&self) -> impl Debug {
|
||||||
|
format!("Hello with generic {}", std::any::type_name::<T>())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Baz {
|
||||||
|
fn baz(&self) -> impl Debug + '_;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Baz for String {
|
||||||
|
fn baz(&self) -> impl Debug + '_ {
|
||||||
|
(self,)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("{:?}", ().foo());
|
||||||
|
println!("{:?}", ().bar::<u64>());
|
||||||
|
println!("{:?}", "hi".to_string().baz());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue