Skip to content

Commit

Permalink
Move in_trait into OpaqueTyOrigin
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Oct 3, 2024
1 parent cb7e369 commit ecbd707
Show file tree
Hide file tree
Showing 19 changed files with 100 additions and 123 deletions.
2 changes: 0 additions & 2 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
parent: this.local_def_id(id),
in_assoc_ty: false,
},
fn_kind: None,
}),
},
);
Expand Down Expand Up @@ -983,7 +982,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
parent: this.local_def_id(i.id),
in_assoc_ty: true,
},
fn_kind: None,
});
hir::ImplItemKind::Type(ty)
}
Expand Down
70 changes: 27 additions & 43 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,12 +288,7 @@ enum ImplTraitContext {
/// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
/// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.
///
OpaqueTy {
origin: hir::OpaqueTyOrigin,
/// Only used to change the lifetime capture rules, since
/// RPITIT captures all in scope, RPIT does not.
fn_kind: Option<FnDeclKind>,
},
OpaqueTy { origin: hir::OpaqueTyOrigin },
/// `impl Trait` is unstably accepted in this position.
FeatureGated(ImplTraitPosition, Symbol),
/// `impl Trait` is not accepted in this position.
Expand Down Expand Up @@ -1404,14 +1399,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
TyKind::ImplTrait(def_node_id, bounds) => {
let span = t.span;
match itctx {
ImplTraitContext::OpaqueTy { origin, fn_kind } => self.lower_opaque_impl_trait(
span,
origin,
*def_node_id,
bounds,
fn_kind,
itctx,
),
ImplTraitContext::OpaqueTy { origin } => {
self.lower_opaque_impl_trait(span, origin, *def_node_id, bounds, itctx)
}
ImplTraitContext::Universal => {
if let Some(span) = bounds.iter().find_map(|bound| match *bound {
ast::GenericBound::Use(_, span) => Some(span),
Expand Down Expand Up @@ -1513,7 +1503,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
origin: hir::OpaqueTyOrigin,
opaque_ty_node_id: NodeId,
bounds: &GenericBounds,
fn_kind: Option<FnDeclKind>,
itctx: ImplTraitContext,
) -> hir::TyKind<'hir> {
// Make sure we know that some funky desugaring has been going on here.
Expand Down Expand Up @@ -1555,11 +1544,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
.map(|(ident, id, _)| Lifetime { id, ident })
.collect()
}
hir::OpaqueTyOrigin::FnReturn { .. } => {
if matches!(
fn_kind.expect("expected RPITs to be lowered with a FnKind"),
FnDeclKind::Impl | FnDeclKind::Trait
) || self.tcx.features().lifetime_capture_rules_2024
hir::OpaqueTyOrigin::FnReturn { in_trait, .. } => {
if in_trait
|| self.tcx.features().lifetime_capture_rules_2024
|| span.at_least_rust_2024()
{
// return-position impl trait in trait was decided to capture all
Expand All @@ -1583,30 +1570,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
};
debug!(?captured_lifetimes_to_duplicate);

match fn_kind {
// Deny `use<>` on RPITIT in trait/trait-impl for now.
Some(FnDeclKind::Trait | FnDeclKind::Impl) => {
// Feature gate for RPITIT + use<..>
match origin {
rustc_hir::OpaqueTyOrigin::FnReturn { in_trait: true, .. } => {
if let Some(span) = bounds.iter().find_map(|bound| match *bound {
ast::GenericBound::Use(_, span) => Some(span),
_ => None,
}) {
self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnRpitit { span });
}
}
None
| Some(
FnDeclKind::Fn
| FnDeclKind::Inherent
| FnDeclKind::ExternFn
| FnDeclKind::Closure
| FnDeclKind::Pointer,
) => {}
_ => {}
}

self.lower_opaque_inner(
opaque_ty_node_id,
origin,
matches!(fn_kind, Some(FnDeclKind::Trait)),
captured_lifetimes_to_duplicate,
span,
opaque_ty_span,
Expand All @@ -1618,7 +1597,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&mut self,
opaque_ty_node_id: NodeId,
origin: hir::OpaqueTyOrigin,
in_trait: bool,
captured_lifetimes_to_duplicate: FxIndexSet<Lifetime>,
span: Span,
opaque_ty_span: Span,
Expand Down Expand Up @@ -1747,7 +1725,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
bounds,
origin,
lifetime_mapping,
in_trait,
};

// Generate an `type Foo = impl Trait;` declaration.
Expand Down Expand Up @@ -1863,14 +1840,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
None => match &decl.output {
FnRetTy::Ty(ty) => {
let itctx = match kind {
FnDeclKind::Fn
| FnDeclKind::Inherent
| FnDeclKind::Trait
| FnDeclKind::Impl => ImplTraitContext::OpaqueTy {
FnDeclKind::Fn | FnDeclKind::Inherent => ImplTraitContext::OpaqueTy {
origin: hir::OpaqueTyOrigin::FnReturn {
parent: self.local_def_id(fn_node_id),
in_trait: false,
},
},
FnDeclKind::Trait | FnDeclKind::Impl => ImplTraitContext::OpaqueTy {
origin: hir::OpaqueTyOrigin::FnReturn {
parent: self.local_def_id(fn_node_id),
in_trait: true,
},
fn_kind: Some(kind),
},
FnDeclKind::ExternFn => {
ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
Expand Down Expand Up @@ -1952,10 +1932,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
.map(|(ident, id, _)| Lifetime { id, ident })
.collect();

let in_trait = match fn_kind {
FnDeclKind::Trait | FnDeclKind::Impl => true,
FnDeclKind::Fn | FnDeclKind::Inherent => false,
FnDeclKind::ExternFn | FnDeclKind::Closure | FnDeclKind::Pointer => unreachable!(),
};

let opaque_ty_ref = self.lower_opaque_inner(
opaque_ty_node_id,
hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id },
matches!(fn_kind, FnDeclKind::Trait),
hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait },
captured_lifetimes,
span,
opaque_ty_span,
Expand All @@ -1965,8 +1950,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
coro,
opaque_ty_span,
ImplTraitContext::OpaqueTy {
origin: hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id },
fn_kind: Some(fn_kind),
origin: hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, in_trait },
},
);
arena_vec![this; bound]
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/region_infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,8 +503,8 @@ impl<'tcx> LazyOpaqueTyEnv<'tcx> {
let &Self { tcx, def_id, .. } = self;
let origin = tcx.opaque_type_origin(def_id);
let parent = 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(parent);
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2762,10 +2762,6 @@ pub struct OpaqueTy<'hir> {
/// This mapping associated a captured lifetime (first parameter) with the new
/// early-bound lifetime that was generated for the opaque.
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)]
Expand Down Expand Up @@ -2809,11 +2805,15 @@ pub enum OpaqueTyOrigin {
FnReturn {
/// The defining function.
parent: LocalDefId,
// Whether this is an RPITIT (return position impl trait in trait)
in_trait: bool,
},
/// `async fn`
AsyncFn {
/// The defining function.
parent: LocalDefId,
// Whether this is an AFIT (async fn in trait)
in_trait: bool,
},
/// type aliases: `type Foo = impl Trait;`
TyAlias {
Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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,
)
Expand Down Expand Up @@ -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()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
)
}) {
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_hir_analysis/src/collect/generics_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,8 @@ 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 }
| hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait },
..
}) => {
if in_trait {
Expand Down
58 changes: 27 additions & 31 deletions compiler/rustc_hir_analysis/src/collect/item_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,39 +370,35 @@ 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: true }
| rustc_hir::OpaqueTyOrigin::AsyncFn { parent, in_trait: true } => {
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: false }
| rustc_hir::OpaqueTyOrigin::AsyncFn { parent: _, in_trait: false }
| 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),
};
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
..
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -618,9 +618,8 @@ 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 }
| hir::OpaqueTyOrigin::AsyncFn { parent: owner, in_trait },
..
}) => {
if in_trait && !tcx.defaultness(owner).has_value() {
Expand Down
23 changes: 16 additions & 7 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2091,17 +2091,26 @@ 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: true, .. }
| hir::OpaqueTyOrigin::AsyncFn { in_trait: true, .. } => 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: false, .. }
| hir::OpaqueTyOrigin::AsyncFn { in_trait: false, .. }
| 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),
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.map(|(k, _)| (k.def_id, k.args))?,
_ => 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)
else {
return None;
Expand Down
Loading

0 comments on commit ecbd707

Please sign in to comment.