1
Fork 0

Rollup merge of #131183 - compiler-errors:opaque-ty-origin, r=estebank

Refactoring to `OpaqueTyOrigin`

Pulled out of a larger PR that uses these changes to do cross-crate encoding of opaque origin, so we can use them for edition 2024 migrations. These changes should be self-explanatory on their own, tho 😄
This commit is contained in:
Matthias Krüger 2024-10-03 21:52:46 +02:00 committed by GitHub
commit da81f64d84
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 223 additions and 163 deletions

View file

@ -286,7 +286,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
parent: this.local_def_id(id), parent: this.local_def_id(id),
in_assoc_ty: false, in_assoc_ty: false,
}, },
fn_kind: None,
}), }),
}, },
); );
@ -983,7 +982,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
parent: this.local_def_id(i.id), parent: this.local_def_id(i.id),
in_assoc_ty: true, in_assoc_ty: true,
}, },
fn_kind: None,
}); });
hir::ImplItemKind::Type(ty) hir::ImplItemKind::Type(ty)
} }

View file

@ -288,12 +288,7 @@ enum ImplTraitContext {
/// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
/// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`. /// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.
/// ///
OpaqueTy { OpaqueTy { origin: hir::OpaqueTyOrigin },
origin: hir::OpaqueTyOrigin,
/// Only used to change the lifetime capture rules, since
/// RPITIT captures all in scope, RPIT does not.
fn_kind: Option<FnDeclKind>,
},
/// `impl Trait` is unstably accepted in this position. /// `impl Trait` is unstably accepted in this position.
FeatureGated(ImplTraitPosition, Symbol), FeatureGated(ImplTraitPosition, Symbol),
/// `impl Trait` is not accepted in this position. /// `impl Trait` is not accepted in this position.
@ -1404,14 +1399,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
TyKind::ImplTrait(def_node_id, bounds) => { TyKind::ImplTrait(def_node_id, bounds) => {
let span = t.span; let span = t.span;
match itctx { match itctx {
ImplTraitContext::OpaqueTy { origin, fn_kind } => self.lower_opaque_impl_trait( ImplTraitContext::OpaqueTy { origin } => {
span, self.lower_opaque_impl_trait(span, origin, *def_node_id, bounds, itctx)
origin, }
*def_node_id,
bounds,
fn_kind,
itctx,
),
ImplTraitContext::Universal => { ImplTraitContext::Universal => {
if let Some(span) = bounds.iter().find_map(|bound| match *bound { if let Some(span) = bounds.iter().find_map(|bound| match *bound {
ast::GenericBound::Use(_, span) => Some(span), ast::GenericBound::Use(_, span) => Some(span),
@ -1513,7 +1503,6 @@ 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,
fn_kind: Option<FnDeclKind>,
itctx: ImplTraitContext, itctx: 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.
@ -1555,11 +1544,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
.map(|(ident, id, _)| Lifetime { id, ident }) .map(|(ident, id, _)| Lifetime { id, ident })
.collect() .collect()
} }
hir::OpaqueTyOrigin::FnReturn(..) => { hir::OpaqueTyOrigin::FnReturn { in_trait_or_impl, .. } => {
if matches!( if in_trait_or_impl.is_some()
fn_kind.expect("expected RPITs to be lowered with a FnKind"), || self.tcx.features().lifetime_capture_rules_2024
FnDeclKind::Impl | FnDeclKind::Trait
) || self.tcx.features().lifetime_capture_rules_2024
|| span.at_least_rust_2024() || span.at_least_rust_2024()
{ {
// return-position impl trait in trait was decided to capture all // return-position impl trait in trait was decided to capture all
@ -1576,16 +1563,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
lifetime_collector::lifetimes_in_bounds(self.resolver, bounds) lifetime_collector::lifetimes_in_bounds(self.resolver, bounds)
} }
} }
hir::OpaqueTyOrigin::AsyncFn(..) => { hir::OpaqueTyOrigin::AsyncFn { .. } => {
unreachable!("should be using `lower_async_fn_ret_ty`") unreachable!("should be using `lower_async_fn_ret_ty`")
} }
} }
}; };
debug!(?captured_lifetimes_to_duplicate); debug!(?captured_lifetimes_to_duplicate);
match fn_kind { // Feature gate for RPITIT + use<..>
// Deny `use<>` on RPITIT in trait/trait-impl for now. match origin {
Some(FnDeclKind::Trait | FnDeclKind::Impl) => { rustc_hir::OpaqueTyOrigin::FnReturn { in_trait_or_impl: Some(_), .. } => {
if let Some(span) = bounds.iter().find_map(|bound| match *bound { if let Some(span) = bounds.iter().find_map(|bound| match *bound {
ast::GenericBound::Use(_, span) => Some(span), ast::GenericBound::Use(_, span) => Some(span),
_ => None, _ => None,
@ -1593,20 +1580,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnRpitit { span }); self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnRpitit { span });
} }
} }
None _ => {}
| Some(
FnDeclKind::Fn
| FnDeclKind::Inherent
| FnDeclKind::ExternFn
| FnDeclKind::Closure
| FnDeclKind::Pointer,
) => {}
} }
self.lower_opaque_inner( self.lower_opaque_inner(
opaque_ty_node_id, opaque_ty_node_id,
origin, origin,
matches!(fn_kind, Some(FnDeclKind::Trait)),
captured_lifetimes_to_duplicate, captured_lifetimes_to_duplicate,
span, span,
opaque_ty_span, opaque_ty_span,
@ -1618,7 +1597,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&mut self, &mut self,
opaque_ty_node_id: NodeId, opaque_ty_node_id: NodeId,
origin: hir::OpaqueTyOrigin, origin: hir::OpaqueTyOrigin,
in_trait: bool,
captured_lifetimes_to_duplicate: FxIndexSet<Lifetime>, captured_lifetimes_to_duplicate: FxIndexSet<Lifetime>,
span: Span, span: Span,
opaque_ty_span: Span, opaque_ty_span: Span,
@ -1747,7 +1725,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
bounds, bounds,
origin, origin,
lifetime_mapping, lifetime_mapping,
in_trait,
}; };
// Generate an `type Foo = impl Trait;` declaration. // Generate an `type Foo = impl Trait;` declaration.
@ -1776,7 +1753,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::TyKind::OpaqueDef( hir::TyKind::OpaqueDef(
hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } }, hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } },
generic_args, generic_args,
in_trait,
) )
} }
@ -1864,12 +1840,23 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
None => match &decl.output { None => match &decl.output {
FnRetTy::Ty(ty) => { FnRetTy::Ty(ty) => {
let itctx = match kind { let itctx = match kind {
FnDeclKind::Fn FnDeclKind::Fn | FnDeclKind::Inherent => ImplTraitContext::OpaqueTy {
| FnDeclKind::Inherent origin: hir::OpaqueTyOrigin::FnReturn {
| FnDeclKind::Trait parent: self.local_def_id(fn_node_id),
| FnDeclKind::Impl => ImplTraitContext::OpaqueTy { in_trait_or_impl: None,
origin: hir::OpaqueTyOrigin::FnReturn(self.local_def_id(fn_node_id)), },
fn_kind: Some(kind), },
FnDeclKind::Trait => ImplTraitContext::OpaqueTy {
origin: hir::OpaqueTyOrigin::FnReturn {
parent: self.local_def_id(fn_node_id),
in_trait_or_impl: Some(hir::RpitContext::Trait),
},
},
FnDeclKind::Impl => ImplTraitContext::OpaqueTy {
origin: hir::OpaqueTyOrigin::FnReturn {
parent: self.local_def_id(fn_node_id),
in_trait_or_impl: Some(hir::RpitContext::TraitImpl),
},
}, },
FnDeclKind::ExternFn => { FnDeclKind::ExternFn => {
ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn) ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
@ -1951,10 +1938,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
.map(|(ident, id, _)| Lifetime { id, ident }) .map(|(ident, id, _)| Lifetime { id, ident })
.collect(); .collect();
let in_trait_or_impl = match fn_kind {
FnDeclKind::Trait => Some(hir::RpitContext::Trait),
FnDeclKind::Impl => Some(hir::RpitContext::TraitImpl),
FnDeclKind::Fn | FnDeclKind::Inherent => None,
FnDeclKind::ExternFn | FnDeclKind::Closure | FnDeclKind::Pointer => unreachable!(),
};
let opaque_ty_ref = self.lower_opaque_inner( let opaque_ty_ref = self.lower_opaque_inner(
opaque_ty_node_id, opaque_ty_node_id,
hir::OpaqueTyOrigin::AsyncFn(fn_def_id), hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
matches!(fn_kind, FnDeclKind::Trait),
captured_lifetimes, captured_lifetimes,
span, span,
opaque_ty_span, opaque_ty_span,
@ -1964,8 +1957,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
coro, coro,
opaque_ty_span, opaque_ty_span,
ImplTraitContext::OpaqueTy { ImplTraitContext::OpaqueTy {
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), origin: hir::OpaqueTyOrigin::FnReturn {
fn_kind: Some(fn_kind), parent: fn_def_id,
in_trait_or_impl,
},
}, },
); );
arena_vec![this; bound] arena_vec![this; bound]

View file

@ -832,7 +832,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: {:?}",

View file

@ -503,8 +503,8 @@ impl<'tcx> LazyOpaqueTyEnv<'tcx> {
let &Self { tcx, def_id, .. } = self; let &Self { tcx, def_id, .. } = self;
let origin = tcx.opaque_type_origin(def_id); let origin = tcx.opaque_type_origin(def_id);
let parent = match origin { let parent = match origin {
hir::OpaqueTyOrigin::FnReturn(parent) hir::OpaqueTyOrigin::FnReturn { parent, .. }
| hir::OpaqueTyOrigin::AsyncFn(parent) | hir::OpaqueTyOrigin::AsyncFn { parent, .. }
| hir::OpaqueTyOrigin::TyAlias { parent, .. } => parent, | hir::OpaqueTyOrigin::TyAlias { parent, .. } => parent,
}; };
let param_env = tcx.param_env(parent); let param_env = tcx.param_env(parent);

View file

@ -2632,7 +2632,7 @@ impl<'hir> Ty<'hir> {
} }
TyKind::Tup(tys) => tys.iter().any(Self::is_suggestable_infer_ty), TyKind::Tup(tys) => tys.iter().any(Self::is_suggestable_infer_ty),
TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty) => mut_ty.ty.is_suggestable_infer_ty(), TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty) => mut_ty.ty.is_suggestable_infer_ty(),
TyKind::OpaqueDef(_, generic_args, _) => are_suggestable_generic_args(generic_args), TyKind::OpaqueDef(_, generic_args) => are_suggestable_generic_args(generic_args),
TyKind::Path(QPath::TypeRelative(ty, segment)) => { TyKind::Path(QPath::TypeRelative(ty, segment)) => {
ty.is_suggestable_infer_ty() || are_suggestable_generic_args(segment.args().args) ty.is_suggestable_infer_ty() || are_suggestable_generic_args(segment.args().args)
} }
@ -2762,10 +2762,6 @@ pub struct OpaqueTy<'hir> {
/// This mapping associated a captured lifetime (first parameter) with the new /// This mapping associated a captured lifetime (first parameter) with the new
/// early-bound lifetime that was generated for the opaque. /// early-bound lifetime that was generated for the opaque.
pub lifetime_mapping: &'hir [(&'hir Lifetime, LocalDefId)], pub lifetime_mapping: &'hir [(&'hir Lifetime, LocalDefId)],
/// Whether the opaque is a return-position impl trait (or async future)
/// originating from a trait method. This makes it so that the opaque is
/// lowered as an associated type.
pub in_trait: bool,
} }
#[derive(Debug, Clone, Copy, HashStable_Generic)] #[derive(Debug, Clone, Copy, HashStable_Generic)]
@ -2802,13 +2798,29 @@ pub struct PreciseCapturingNonLifetimeArg {
pub res: Res, pub res: Res,
} }
#[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)]
pub enum RpitContext {
Trait,
TraitImpl,
}
/// From whence the opaque type came. /// From whence the opaque type came.
#[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)] #[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)]
pub enum OpaqueTyOrigin { pub enum OpaqueTyOrigin {
/// `-> impl Trait` /// `-> impl Trait`
FnReturn(LocalDefId), FnReturn {
/// The defining function.
parent: LocalDefId,
// Whether this is an RPITIT (return position impl trait in trait)
in_trait_or_impl: Option<RpitContext>,
},
/// `async fn` /// `async fn`
AsyncFn(LocalDefId), AsyncFn {
/// The defining function.
parent: LocalDefId,
// Whether this is an AFIT (async fn in trait)
in_trait_or_impl: Option<RpitContext>,
},
/// type aliases: `type Foo = impl Trait;` /// type aliases: `type Foo = impl Trait;`
TyAlias { TyAlias {
/// The type alias or associated type parent of the TAIT/ATPIT /// The type alias or associated type parent of the TAIT/ATPIT
@ -2856,7 +2868,7 @@ pub enum TyKind<'hir> {
/// possibly parameters) that are actually bound on the `impl Trait`. /// possibly parameters) that are actually bound on the `impl Trait`.
/// ///
/// The last parameter specifies whether this opaque appears in a trait definition. /// The last parameter specifies whether this opaque appears in a trait definition.
OpaqueDef(ItemId, &'hir [GenericArg<'hir>], bool), OpaqueDef(ItemId, &'hir [GenericArg<'hir>]),
/// 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( TraitObject(

View file

@ -894,7 +894,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul
TyKind::Path(ref qpath) => { TyKind::Path(ref qpath) => {
try_visit!(visitor.visit_qpath(qpath, typ.hir_id, typ.span)); try_visit!(visitor.visit_qpath(qpath, typ.hir_id, typ.span));
} }
TyKind::OpaqueDef(item_id, lifetimes, _in_trait) => { TyKind::OpaqueDef(item_id, lifetimes) => {
try_visit!(visitor.visit_nested_item(item_id)); try_visit!(visitor.visit_nested_item(item_id));
walk_list!(visitor, visit_generic_arg, lifetimes); walk_list!(visitor, visit_generic_arg, lifetimes);
} }

View file

@ -336,9 +336,9 @@ fn check_opaque_meets_bounds<'tcx>(
origin: &hir::OpaqueTyOrigin, origin: &hir::OpaqueTyOrigin,
) -> Result<(), ErrorGuaranteed> { ) -> Result<(), ErrorGuaranteed> {
let defining_use_anchor = match *origin { let defining_use_anchor = match *origin {
hir::OpaqueTyOrigin::FnReturn(did) hir::OpaqueTyOrigin::FnReturn { parent, .. }
| hir::OpaqueTyOrigin::AsyncFn(did) | hir::OpaqueTyOrigin::AsyncFn { parent, .. }
| hir::OpaqueTyOrigin::TyAlias { parent: did, .. } => did, | hir::OpaqueTyOrigin::TyAlias { parent, .. } => parent,
}; };
let param_env = tcx.param_env(defining_use_anchor); let param_env = tcx.param_env(defining_use_anchor);
@ -346,8 +346,8 @@ fn check_opaque_meets_bounds<'tcx>(
let ocx = ObligationCtxt::new_with_diagnostics(&infcx); let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
let args = match *origin { let args = match *origin {
hir::OpaqueTyOrigin::FnReturn(parent) hir::OpaqueTyOrigin::FnReturn { parent, .. }
| hir::OpaqueTyOrigin::AsyncFn(parent) | hir::OpaqueTyOrigin::AsyncFn { parent, .. }
| hir::OpaqueTyOrigin::TyAlias { parent, .. } => GenericArgs::identity_for_item( | hir::OpaqueTyOrigin::TyAlias { parent, .. } => GenericArgs::identity_for_item(
tcx, parent, tcx, parent,
) )
@ -409,7 +409,7 @@ fn check_opaque_meets_bounds<'tcx>(
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env)?; ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env)?;
if let hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) = origin { if let hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. } = origin {
// HACK: this should also fall through to the hidden type check below, but the original // HACK: this should also fall through to the hidden type check below, but the original
// implementation had a bug where equivalent lifetimes are not identical. This caused us // implementation had a bug where equivalent lifetimes are not identical. This caused us
// to reject existing stable code that is otherwise completely fine. The real fix is to // to reject existing stable code that is otherwise completely fine. The real fix is to
@ -736,8 +736,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
check_opaque_precise_captures(tcx, def_id); check_opaque_precise_captures(tcx, def_id);
let origin = tcx.opaque_type_origin(def_id); let origin = tcx.opaque_type_origin(def_id);
if let hir::OpaqueTyOrigin::FnReturn(fn_def_id) if let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. }
| hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, .. } = origin
&& let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id) && let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id)
&& let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn() && let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
{ {

View file

@ -94,8 +94,8 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
if !tcx.hir().get_if_local(impl_opaque.def_id).is_some_and(|node| { if !tcx.hir().get_if_local(impl_opaque.def_id).is_some_and(|node| {
matches!( matches!(
node.expect_item().expect_opaque_ty().origin, node.expect_item().expect_opaque_ty().origin,
hir::OpaqueTyOrigin::AsyncFn(def_id) | hir::OpaqueTyOrigin::FnReturn(def_id) hir::OpaqueTyOrigin::AsyncFn { parent, .. } | hir::OpaqueTyOrigin::FnReturn { parent, .. }
if def_id == impl_m.def_id.expect_local() if parent == impl_m.def_id.expect_local()
) )
}) { }) {
report_mismatched_rpitit_signature( report_mismatched_rpitit_signature(

View file

@ -210,11 +210,11 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
Node::Item(item) => match item.kind { Node::Item(item) => match item.kind {
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 { parent: fn_def_id, in_trait_or_impl }
in_trait, | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
.. ..
}) => { }) => {
if in_trait { if in_trait_or_impl.is_some() {
assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn); assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn);
} else { } else {
assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn); assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn);

View file

@ -370,39 +370,47 @@ pub(super) fn explicit_item_bounds_with_filter(
.. ..
}) => associated_type_bounds(tcx, def_id, bounds, *span, filter), }) => associated_type_bounds(tcx, def_id, bounds, *span, filter),
hir::Node::Item(hir::Item { hir::Node::Item(hir::Item {
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait: false, .. }), kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, origin, .. }),
span, span,
.. ..
}) => { }) => match origin {
// Since RPITITs are lowered as projections in `<dyn HirTyLowerer>::lower_ty`,
// when we're asking for the item bounds of the *opaques* in a trait's default
// method signature, we need to map these projections back to opaques.
rustc_hir::OpaqueTyOrigin::FnReturn {
parent,
in_trait_or_impl: Some(hir::RpitContext::Trait),
}
| rustc_hir::OpaqueTyOrigin::AsyncFn {
parent,
in_trait_or_impl: Some(hir::RpitContext::Trait),
} => {
let args = GenericArgs::identity_for_item(tcx, def_id);
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
let bounds = &*tcx.arena.alloc_slice(
&opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter)
.to_vec()
.fold_with(&mut AssocTyToOpaque { tcx, fn_def_id: parent.to_def_id() }),
);
assert_only_contains_predicates_from(filter, bounds, item_ty);
bounds
}
rustc_hir::OpaqueTyOrigin::FnReturn {
parent: _,
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
}
| rustc_hir::OpaqueTyOrigin::AsyncFn {
parent: _,
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
}
| rustc_hir::OpaqueTyOrigin::TyAlias { parent: _, .. } => {
let args = GenericArgs::identity_for_item(tcx, def_id); let args = GenericArgs::identity_for_item(tcx, def_id);
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args); let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
let bounds = opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter); let bounds = opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter);
assert_only_contains_predicates_from(filter, bounds, item_ty); assert_only_contains_predicates_from(filter, bounds, item_ty);
bounds bounds
} }
// Since RPITITs are lowered as projections in `<dyn HirTyLowerer>::lower_ty`, when we're },
// asking for the item bounds of the *opaques* in a trait's default method signature, we
// need to map these projections back to opaques.
hir::Node::Item(hir::Item {
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait: true, origin, .. }),
span,
..
}) => {
let (hir::OpaqueTyOrigin::FnReturn(fn_def_id)
| hir::OpaqueTyOrigin::AsyncFn(fn_def_id)) = *origin
else {
span_bug!(*span, "RPITIT cannot be a TAIT, but got origin {origin:?}");
};
let args = GenericArgs::identity_for_item(tcx, def_id);
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
let bounds = &*tcx.arena.alloc_slice(
&opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter)
.to_vec()
.fold_with(&mut AssocTyToOpaque { tcx, fn_def_id: fn_def_id.to_def_id() }),
);
assert_only_contains_predicates_from(filter, bounds, item_ty);
bounds
}
hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[], hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[],
_ => bug!("item_bounds called on {:?}", def_id), _ => bug!("item_bounds called on {:?}", def_id),
}; };

View file

@ -332,7 +332,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
// and the duplicated parameter, to ensure that they do not get out of sync. // and the duplicated parameter, to ensure that they do not get out of sync.
if let Node::Item(&Item { kind: ItemKind::OpaqueTy(..), .. }) = node { if let Node::Item(&Item { kind: ItemKind::OpaqueTy(..), .. }) = node {
let opaque_ty_node = tcx.parent_hir_node(hir_id); let opaque_ty_node = tcx.parent_hir_node(hir_id);
let Node::Ty(&hir::Ty { kind: TyKind::OpaqueDef(_, lifetimes, _), .. }) = opaque_ty_node let Node::Ty(&hir::Ty { kind: TyKind::OpaqueDef(_, lifetimes), .. }) = opaque_ty_node
else { else {
bug!("unexpected {opaque_ty_node:?}") bug!("unexpected {opaque_ty_node:?}")
}; };

View file

@ -515,8 +515,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
} }
hir::ItemKind::OpaqueTy(&hir::OpaqueTy { hir::ItemKind::OpaqueTy(&hir::OpaqueTy {
origin: origin:
hir::OpaqueTyOrigin::FnReturn(parent) hir::OpaqueTyOrigin::FnReturn { parent, .. }
| hir::OpaqueTyOrigin::AsyncFn(parent) | hir::OpaqueTyOrigin::AsyncFn { parent, .. }
| hir::OpaqueTyOrigin::TyAlias { parent, .. }, | hir::OpaqueTyOrigin::TyAlias { parent, .. },
generics, generics,
.. ..
@ -689,7 +689,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'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, _in_trait) => { hir::TyKind::OpaqueDef(item_id, lifetimes) => {
// 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>;`

View file

@ -618,11 +618,13 @@ pub(super) fn type_of_opaque(
// Opaque types desugared from `impl Trait`. // Opaque types desugared from `impl Trait`.
ItemKind::OpaqueTy(&OpaqueTy { ItemKind::OpaqueTy(&OpaqueTy {
origin: origin:
hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner), hir::OpaqueTyOrigin::FnReturn { parent: owner, in_trait_or_impl }
in_trait, | hir::OpaqueTyOrigin::AsyncFn { parent: owner, in_trait_or_impl },
.. ..
}) => { }) => {
if in_trait && !tcx.defaultness(owner).has_value() { if in_trait_or_impl == Some(hir::RpitContext::Trait)
&& !tcx.defaultness(owner).has_value()
{
span_bug!( span_bug!(
tcx.def_span(def_id), tcx.def_span(def_id),
"tried to get type of this RPITIT with no definition" "tried to get type of this RPITIT with no definition"

View file

@ -2087,21 +2087,41 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself)); let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
self.lower_path(opt_self_ty, path, hir_ty.hir_id, false) self.lower_path(opt_self_ty, path, hir_ty.hir_id, false)
} }
&hir::TyKind::OpaqueDef(item_id, lifetimes, in_trait) => { &hir::TyKind::OpaqueDef(item_id, lifetimes) => {
let opaque_ty = tcx.hir().item(item_id); let opaque_ty = tcx.hir().item(item_id);
match opaque_ty.kind { match opaque_ty.kind {
hir::ItemKind::OpaqueTy(&hir::OpaqueTy { .. }) => { hir::ItemKind::OpaqueTy(&hir::OpaqueTy { origin, .. }) => {
let local_def_id = item_id.owner_id.def_id; let local_def_id = item_id.owner_id.def_id;
// If this is an RPITIT and we are using the new RPITIT lowering scheme, we // If this is an RPITIT and we are using the new RPITIT lowering scheme, we
// generate the def_id of an associated type for the trait and return as // generate the def_id of an associated type for the trait and return as
// type a projection. // type a projection.
let def_id = if in_trait { match origin {
tcx.associated_type_for_impl_trait_in_trait(local_def_id).to_def_id() hir::OpaqueTyOrigin::FnReturn {
} else { in_trait_or_impl: Some(hir::RpitContext::Trait),
local_def_id.to_def_id() ..
}; }
self.lower_opaque_ty(def_id, lifetimes, in_trait) | hir::OpaqueTyOrigin::AsyncFn {
in_trait_or_impl: Some(hir::RpitContext::Trait),
..
} => self.lower_opaque_ty(
tcx.associated_type_for_impl_trait_in_trait(local_def_id)
.to_def_id(),
lifetimes,
true,
),
hir::OpaqueTyOrigin::FnReturn {
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
..
}
| hir::OpaqueTyOrigin::AsyncFn {
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
..
}
| hir::OpaqueTyOrigin::TyAlias { .. } => {
self.lower_opaque_ty(local_def_id.to_def_id(), lifetimes, false)
}
}
} }
ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i), ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
} }

View file

@ -602,7 +602,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.map(|(k, _)| (k.def_id, k.args))?, .map(|(k, _)| (k.def_id, k.args))?,
_ => return None, _ => return None,
}; };
let hir::OpaqueTyOrigin::FnReturn(parent_def_id) = self.tcx.opaque_type_origin(def_id) let hir::OpaqueTyOrigin::FnReturn { parent: parent_def_id, .. } =
self.tcx.opaque_type_origin(def_id)
else { else {
return None; return None;
}; };

View file

@ -259,8 +259,8 @@ where
// If it's owned by this function // If it's owned by this function
&& let opaque = && let opaque =
self.tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty() self.tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty()
&& let hir::OpaqueTyOrigin::FnReturn(parent_def_id) = opaque.origin && let hir::OpaqueTyOrigin::FnReturn { parent, .. } = opaque.origin
&& parent_def_id == self.parent_def_id && parent == self.parent_def_id
{ {
let opaque_span = self.tcx.def_span(opaque_def_id); let opaque_span = self.tcx.def_span(opaque_def_id);
let new_capture_rules = let new_capture_rules =

View file

@ -77,7 +77,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
// That's because although we may have an opaque type on the function, // That's because although we may have an opaque type on the function,
// it won't have a hidden type, so proving predicates about it is // it won't have a hidden type, so proving predicates about it is
// not really meaningful. // not really meaningful.
if let hir::OpaqueTyOrigin::FnReturn(method_def_id) = opaque.origin if let hir::OpaqueTyOrigin::FnReturn { parent: method_def_id, .. } = opaque.origin
&& let hir::Node::TraitItem(trait_item) = cx.tcx.hir_node_by_def_id(method_def_id) && let hir::Node::TraitItem(trait_item) = cx.tcx.hir_node_by_def_id(method_def_id)
&& !trait_item.defaultness.has_value() && !trait_item.defaultness.has_value()
{ {
@ -103,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
&& cx.tcx.parent(opaque_ty.def_id) == def_id && cx.tcx.parent(opaque_ty.def_id) == def_id
&& matches!( && matches!(
opaque.origin, opaque.origin,
hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_) hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. }
) )
{ {
return; return;
@ -114,8 +114,10 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
// return type is well-formed in traits even when `Self` isn't sized. // return type is well-formed in traits even when `Self` isn't sized.
if let ty::Param(param_ty) = *proj_term.kind() if let ty::Param(param_ty) = *proj_term.kind()
&& param_ty.name == kw::SelfUpper && param_ty.name == kw::SelfUpper
&& matches!(opaque.origin, hir::OpaqueTyOrigin::AsyncFn(_)) && matches!(opaque.origin, hir::OpaqueTyOrigin::AsyncFn {
&& opaque.in_trait in_trait_or_impl: Some(hir::RpitContext::Trait),
..
})
{ {
return; return;
} }

View file

@ -1186,9 +1186,9 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
DefKind::OpaqueTy => { DefKind::OpaqueTy => {
let origin = tcx.opaque_type_origin(def_id); let origin = tcx.opaque_type_origin(def_id);
if let hir::OpaqueTyOrigin::FnReturn(fn_def_id) if let hir::OpaqueTyOrigin::FnReturn { parent, .. }
| hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin | hir::OpaqueTyOrigin::AsyncFn { parent, .. } = origin
&& let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id) && let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(parent)
&& let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn() && let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
{ {
false false

View file

@ -1139,13 +1139,7 @@ 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) => { ItemKind::OpaqueTy(..) => "opaque type",
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",

View file

@ -510,7 +510,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);

View file

@ -656,7 +656,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);
} }

View file

@ -637,8 +637,34 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
if self.impl_trait_pass if self.impl_trait_pass
&& let hir::ItemKind::OpaqueTy(opaque) = item.kind && let hir::ItemKind::OpaqueTy(opaque) = item.kind
&& !opaque.in_trait
{ {
let should_visit = match opaque.origin {
hir::OpaqueTyOrigin::FnReturn {
parent,
in_trait_or_impl: Some(hir::RpitContext::Trait),
}
| hir::OpaqueTyOrigin::AsyncFn {
parent,
in_trait_or_impl: Some(hir::RpitContext::Trait),
} => match self.tcx.hir_node_by_def_id(parent).expect_trait_item().expect_fn().1 {
hir::TraitFn::Required(_) => false,
hir::TraitFn::Provided(..) => true,
},
// Always visit RPITs in functions that have definitions,
// and all TAITs.
hir::OpaqueTyOrigin::FnReturn {
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
..
}
| hir::OpaqueTyOrigin::AsyncFn {
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
..
}
| hir::OpaqueTyOrigin::TyAlias { .. } => true,
};
if should_visit {
// 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.
@ -649,6 +675,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
.ty(); .ty();
return; return;
} }
}
// Update levels of nested things and mark all items // Update levels of nested things and mark all items
// in interfaces of reachable items as reachable. // in interfaces of reachable items as reachable.

View file

@ -284,7 +284,7 @@ pub fn suggest_new_region_bound(
} }
match fn_return.kind { match fn_return.kind {
// FIXME(precise_captures): Suggest adding to `use<...>` list instead. // FIXME(precise_captures): Suggest adding to `use<...>` list instead.
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;

View file

@ -857,7 +857,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
} }
fn visit_ty(&mut self, ty: &'hir hir::Ty<'hir>) { fn visit_ty(&mut self, ty: &'hir hir::Ty<'hir>) {
let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind else { let hir::TyKind::OpaqueDef(item_id, _) = ty.kind else {
return hir::intravisit::walk_ty(self, ty); return hir::intravisit::walk_ty(self, ty);
}; };
let opaque_ty = self.tcx.hir().item(item_id).expect_opaque_ty(); let opaque_ty = self.tcx.hir().item(item_id).expect_opaque_ty();
@ -1271,7 +1271,7 @@ fn suggest_precise_capturing<'tcx>(
let hir::OpaqueTy { bounds, origin, .. } = let hir::OpaqueTy { bounds, origin, .. } =
tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty(); tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty();
let hir::OpaqueTyOrigin::FnReturn(fn_def_id) = *origin else { let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. } = *origin else {
return; return;
}; };

View file

@ -2640,7 +2640,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
def_id: DefId, def_id: DefId,
) -> ErrorGuaranteed { ) -> ErrorGuaranteed {
let name = match self.tcx.opaque_type_origin(def_id.expect_local()) { let name = match self.tcx.opaque_type_origin(def_id.expect_local()) {
hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_) => { hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. } => {
"opaque type".to_string() "opaque type".to_string()
} }
hir::OpaqueTyOrigin::TyAlias { .. } => { hir::OpaqueTyOrigin::TyAlias { .. } => {

View file

@ -323,7 +323,7 @@ fn associated_types_for_impl_traits_in_associated_fn(
impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> { impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> {
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind if let hir::TyKind::OpaqueDef(item_id, _) = ty.kind
&& self.rpits.insert(item_id.owner_id.def_id) && self.rpits.insert(item_id.owner_id.def_id)
{ {
let opaque_item = let opaque_item =
@ -379,7 +379,8 @@ fn associated_type_for_impl_trait_in_trait(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
opaque_ty_def_id: LocalDefId, opaque_ty_def_id: LocalDefId,
) -> LocalDefId { ) -> LocalDefId {
let (hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id)) = let (hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. }
| hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, .. }) =
tcx.opaque_type_origin(opaque_ty_def_id) tcx.opaque_type_origin(opaque_ty_def_id)
else { else {
bug!("expected opaque for {opaque_ty_def_id:?}"); bug!("expected opaque for {opaque_ty_def_id:?}");

View file

@ -141,7 +141,8 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
let origin = self.tcx.opaque_type_origin(alias_ty.def_id.expect_local()); let origin = self.tcx.opaque_type_origin(alias_ty.def_id.expect_local());
trace!(?origin); trace!(?origin);
match origin { match origin {
rustc_hir::OpaqueTyOrigin::FnReturn(_) | rustc_hir::OpaqueTyOrigin::AsyncFn(_) => {} rustc_hir::OpaqueTyOrigin::FnReturn { .. }
| rustc_hir::OpaqueTyOrigin::AsyncFn { .. } => {}
rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => { rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => {
if !in_assoc_ty && !self.check_tait_defining_scope(alias_ty.def_id.expect_local()) { if !in_assoc_ty && !self.check_tait_defining_scope(alias_ty.def_id.expect_local()) {
return; return;

View file

@ -1828,7 +1828,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
Array(Box::new(clean_ty(ty, cx)), length.into()) Array(Box::new(clean_ty(ty, cx)), length.into())
} }
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(ty) = item.kind { if let hir::ItemKind::OpaqueTy(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())

View file

@ -515,7 +515,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
self.add_to_current_mod(item, renamed, import_id); self.add_to_current_mod(item, renamed, import_id);
} }
hir::ItemKind::OpaqueTy(hir::OpaqueTy { hir::ItemKind::OpaqueTy(hir::OpaqueTy {
origin: hir::OpaqueTyOrigin::AsyncFn(_) | hir::OpaqueTyOrigin::FnReturn(_), origin: hir::OpaqueTyOrigin::AsyncFn { .. } | hir::OpaqueTyOrigin::FnReturn { .. },
.. ..
}) => { }) => {
// return-position impl traits are never nameable, and should never be documented. // return-position impl traits are never nameable, and should never be documented.

View file

@ -199,7 +199,7 @@ impl<'tcx> Visitor<'tcx> for TypeWalker<'_, 'tcx> {
fn visit_ty(&mut self, t: &'tcx Ty<'tcx>) { fn visit_ty(&mut self, t: &'tcx Ty<'tcx>) {
if let Some((def_id, _)) = t.peel_refs().as_generic_param() { if let Some((def_id, _)) = t.peel_refs().as_generic_param() {
self.ty_params.remove(&def_id); self.ty_params.remove(&def_id);
} else if let TyKind::OpaqueDef(id, _, _) = t.kind { } else if let TyKind::OpaqueDef(id, _) = t.kind {
// Explicitly walk OpaqueDef. Normally `walk_ty` would do the job, but it calls // Explicitly walk OpaqueDef. Normally `walk_ty` would do the job, but it calls
// `visit_nested_item`, which checks that `Self::NestedFilter::INTER` is set. We're // `visit_nested_item`, which checks that `Self::NestedFilter::INTER` is set. We're
// using `OnlyBodies`, so the check ends up failing and the type isn't fully walked. // using `OnlyBodies`, so the check ends up failing and the type isn't fully walked.

View file

@ -313,7 +313,7 @@ fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&
kind: ItemKind::OpaqueTy(opaque), kind: ItemKind::OpaqueTy(opaque),
.. ..
} = item } = item
&& let OpaqueTyOrigin::AsyncFn(_) = opaque.origin && let OpaqueTyOrigin::AsyncFn { .. } = opaque.origin
&& let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds && let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds
&& let Some(segment) = trait_ref.trait_ref.path.segments.last() && let Some(segment) = trait_ref.trait_ref.path.segments.last()
&& let Some(generic_args) = segment.args && let Some(generic_args) = segment.args

View file

@ -420,7 +420,7 @@ impl<'tcx> Visitor<'tcx> for RefVisitor<'_, 'tcx> {
fn visit_ty(&mut self, ty: &'tcx Ty<'_>) { fn visit_ty(&mut self, ty: &'tcx Ty<'_>) {
match ty.kind { match ty.kind {
TyKind::OpaqueDef(item, bounds, _) => { TyKind::OpaqueDef(item, bounds) => {
let map = self.cx.tcx.hir(); let map = self.cx.tcx.hir();
let item = map.item(item); let item = map.item(item);
let len = self.lts.len(); let len = self.lts.len();

View file

@ -105,7 +105,7 @@ fn future_trait_ref<'tcx>(
cx: &LateContext<'tcx>, cx: &LateContext<'tcx>,
ty: &'tcx Ty<'tcx>, ty: &'tcx Ty<'tcx>,
) -> Option<(&'tcx TraitRef<'tcx>, Vec<LifetimeName>)> { ) -> Option<(&'tcx TraitRef<'tcx>, Vec<LifetimeName>)> {
if let TyKind::OpaqueDef(item_id, bounds, false) = ty.kind if let TyKind::OpaqueDef(item_id, bounds) = ty.kind
&& let item = cx.tcx.hir().item(item_id) && let item = cx.tcx.hir().item(item_id)
&& let ItemKind::OpaqueTy(opaque) = &item.kind && let ItemKind::OpaqueTy(opaque) = &item.kind
&& let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| { && let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| {

View file

@ -1126,9 +1126,8 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
} }
}, },
TyKind::Path(ref qpath) => self.hash_qpath(qpath), TyKind::Path(ref qpath) => self.hash_qpath(qpath),
TyKind::OpaqueDef(_, arg_list, in_trait) => { TyKind::OpaqueDef(_, arg_list) => {
self.hash_generic_args(arg_list); self.hash_generic_args(arg_list);
in_trait.hash(&mut self.s);
}, },
TyKind::TraitObject(_, lifetime, _) => { TyKind::TraitObject(_, lifetime, _) => {
self.hash_lifetime(lifetime); self.hash_lifetime(lifetime);