mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Move in_trait into OpaqueTyOrigin
This commit is contained in:
parent
cb7e3695e8
commit
7cd466a036
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
@ -1583,9 +1570,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
};
|
};
|
||||||
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.
|
||||||
@ -1863,14 +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
|
|
||||||
| FnDeclKind::Trait
|
|
||||||
| FnDeclKind::Impl => ImplTraitContext::OpaqueTy {
|
|
||||||
origin: hir::OpaqueTyOrigin::FnReturn {
|
origin: hir::OpaqueTyOrigin::FnReturn {
|
||||||
parent: self.local_def_id(fn_node_id),
|
parent: self.local_def_id(fn_node_id),
|
||||||
|
in_trait_or_impl: None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
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),
|
||||||
},
|
},
|
||||||
fn_kind: Some(kind),
|
|
||||||
},
|
},
|
||||||
FnDeclKind::ExternFn => {
|
FnDeclKind::ExternFn => {
|
||||||
ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
|
ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
|
||||||
@ -1952,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 { parent: 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,
|
||||||
@ -1965,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 { parent: 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]
|
||||||
|
@ -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);
|
||||||
|
@ -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,6 +2798,12 @@ 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 {
|
||||||
@ -2809,11 +2811,15 @@ pub enum OpaqueTyOrigin {
|
|||||||
FnReturn {
|
FnReturn {
|
||||||
/// The defining function.
|
/// The defining function.
|
||||||
parent: LocalDefId,
|
parent: LocalDefId,
|
||||||
|
// Whether this is an RPITIT (return position impl trait in trait)
|
||||||
|
in_trait_or_impl: Option<RpitContext>,
|
||||||
},
|
},
|
||||||
/// `async fn`
|
/// `async fn`
|
||||||
AsyncFn {
|
AsyncFn {
|
||||||
/// The defining function.
|
/// The defining function.
|
||||||
parent: LocalDefId,
|
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 {
|
||||||
|
@ -336,8 +336,8 @@ 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 { 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(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,
|
||||||
)
|
)
|
||||||
@ -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 { parent: fn_def_id }
|
if let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. }
|
||||||
| hir::OpaqueTyOrigin::AsyncFn { parent: 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()
|
||||||
{
|
{
|
||||||
|
@ -94,7 +94,7 @@ 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 { parent } | hir::OpaqueTyOrigin::FnReturn { parent }
|
hir::OpaqueTyOrigin::AsyncFn { parent, .. } | hir::OpaqueTyOrigin::FnReturn { parent, .. }
|
||||||
if parent == impl_m.def_id.expect_local()
|
if parent == impl_m.def_id.expect_local()
|
||||||
)
|
)
|
||||||
}) {
|
}) {
|
||||||
|
@ -210,12 +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 { parent: fn_def_id }
|
hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, in_trait_or_impl }
|
||||||
| hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id },
|
| hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
|
||||||
in_trait,
|
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
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);
|
||||||
|
@ -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 { parent: fn_def_id }
|
|
||||||
| hir::OpaqueTyOrigin::AsyncFn { parent: 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),
|
||||||
};
|
};
|
||||||
|
@ -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,
|
||||||
..
|
..
|
||||||
|
@ -618,12 +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 { parent: owner }
|
hir::OpaqueTyOrigin::FnReturn { parent: owner, in_trait_or_impl }
|
||||||
| hir::OpaqueTyOrigin::AsyncFn { parent: owner },
|
| hir::OpaqueTyOrigin::AsyncFn { parent: owner, in_trait_or_impl },
|
||||||
in_trait,
|
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
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"
|
||||||
|
@ -2091,17 +2091,37 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||||||
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 { in_trait, .. }) => {
|
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),
|
||||||
}
|
}
|
||||||
|
@ -602,7 +602,7 @@ 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: parent_def_id } =
|
let hir::OpaqueTyOrigin::FnReturn { parent: parent_def_id, .. } =
|
||||||
self.tcx.opaque_type_origin(def_id)
|
self.tcx.opaque_type_origin(def_id)
|
||||||
else {
|
else {
|
||||||
return None;
|
return None;
|
||||||
|
@ -259,7 +259,7 @@ 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 } = opaque.origin
|
&& let hir::OpaqueTyOrigin::FnReturn { parent, .. } = opaque.origin
|
||||||
&& parent == 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);
|
||||||
|
@ -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 { parent: 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()
|
||||||
{
|
{
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -1186,8 +1186,8 @@ 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 { parent }
|
if let hir::OpaqueTyOrigin::FnReturn { parent, .. }
|
||||||
| hir::OpaqueTyOrigin::AsyncFn { parent } = origin
|
| hir::OpaqueTyOrigin::AsyncFn { parent, .. } = origin
|
||||||
&& let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(parent)
|
&& 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()
|
||||||
{
|
{
|
||||||
|
@ -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",
|
||||||
|
@ -636,8 +636,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
|
|||||||
impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
|
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(..) = item.kind
|
||||||
&& !opaque.in_trait
|
|
||||||
{
|
{
|
||||||
// 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
|
||||||
|
@ -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 { parent: fn_def_id } = *origin else {
|
let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. } = *origin else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -379,8 +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 { parent: fn_def_id }
|
let (hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. }
|
||||||
| hir::OpaqueTyOrigin::AsyncFn { 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:?}");
|
||||||
|
Loading…
Reference in New Issue
Block a user