Move in_trait into OpaqueTyOrigin
This commit is contained in:
parent
cb7e3695e8
commit
7cd466a036
19 changed files with 146 additions and 125 deletions
|
@ -336,8 +336,8 @@ fn check_opaque_meets_bounds<'tcx>(
|
|||
origin: &hir::OpaqueTyOrigin,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let defining_use_anchor = match *origin {
|
||||
hir::OpaqueTyOrigin::FnReturn { parent }
|
||||
| hir::OpaqueTyOrigin::AsyncFn { parent }
|
||||
hir::OpaqueTyOrigin::FnReturn { parent, .. }
|
||||
| hir::OpaqueTyOrigin::AsyncFn { parent, .. }
|
||||
| hir::OpaqueTyOrigin::TyAlias { parent, .. } => parent,
|
||||
};
|
||||
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 args = match *origin {
|
||||
hir::OpaqueTyOrigin::FnReturn { parent }
|
||||
| hir::OpaqueTyOrigin::AsyncFn { parent }
|
||||
hir::OpaqueTyOrigin::FnReturn { parent, .. }
|
||||
| hir::OpaqueTyOrigin::AsyncFn { parent, .. }
|
||||
| hir::OpaqueTyOrigin::TyAlias { parent, .. } => GenericArgs::identity_for_item(
|
||||
tcx, parent,
|
||||
)
|
||||
|
@ -736,8 +736,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
check_opaque_precise_captures(tcx, def_id);
|
||||
|
||||
let origin = tcx.opaque_type_origin(def_id);
|
||||
if let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id }
|
||||
| hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id } = origin
|
||||
if let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. }
|
||||
| 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::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| {
|
||||
matches!(
|
||||
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()
|
||||
)
|
||||
}) {
|
||||
|
|
|
@ -210,12 +210,11 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
|||
Node::Item(item) => match item.kind {
|
||||
ItemKind::OpaqueTy(&hir::OpaqueTy {
|
||||
origin:
|
||||
hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id }
|
||||
| hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id },
|
||||
in_trait,
|
||||
hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, in_trait_or_impl }
|
||||
| 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);
|
||||
} else {
|
||||
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),
|
||||
hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait: false, .. }),
|
||||
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, origin, .. }),
|
||||
span,
|
||||
..
|
||||
}) => {
|
||||
let args = GenericArgs::identity_for_item(tcx, def_id);
|
||||
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);
|
||||
assert_only_contains_predicates_from(filter, bounds, item_ty);
|
||||
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
|
||||
}
|
||||
}) => 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 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);
|
||||
assert_only_contains_predicates_from(filter, bounds, item_ty);
|
||||
bounds
|
||||
}
|
||||
},
|
||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[],
|
||||
_ => 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 {
|
||||
origin:
|
||||
hir::OpaqueTyOrigin::FnReturn { parent }
|
||||
| hir::OpaqueTyOrigin::AsyncFn { parent }
|
||||
hir::OpaqueTyOrigin::FnReturn { parent, .. }
|
||||
| hir::OpaqueTyOrigin::AsyncFn { parent, .. }
|
||||
| hir::OpaqueTyOrigin::TyAlias { parent, .. },
|
||||
generics,
|
||||
..
|
||||
|
|
|
@ -618,12 +618,13 @@ pub(super) fn type_of_opaque(
|
|||
// Opaque types desugared from `impl Trait`.
|
||||
ItemKind::OpaqueTy(&OpaqueTy {
|
||||
origin:
|
||||
hir::OpaqueTyOrigin::FnReturn { parent: owner }
|
||||
| hir::OpaqueTyOrigin::AsyncFn { parent: owner },
|
||||
in_trait,
|
||||
hir::OpaqueTyOrigin::FnReturn { parent: owner, in_trait_or_impl }
|
||||
| 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!(
|
||||
tcx.def_span(def_id),
|
||||
"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);
|
||||
|
||||
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;
|
||||
// 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
|
||||
// type a projection.
|
||||
let def_id = if in_trait {
|
||||
tcx.associated_type_for_impl_trait_in_trait(local_def_id).to_def_id()
|
||||
} else {
|
||||
local_def_id.to_def_id()
|
||||
};
|
||||
self.lower_opaque_ty(def_id, lifetimes, in_trait)
|
||||
match origin {
|
||||
hir::OpaqueTyOrigin::FnReturn {
|
||||
in_trait_or_impl: Some(hir::RpitContext::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),
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue