summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_ty_utils/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
commitef24de24a82fe681581cc130f342363c47c0969a (patch)
tree0d494f7e1a38b95c92426f58fe6eaa877303a86c /compiler/rustc_ty_utils/src
parentReleasing progress-linux version 1.74.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-ef24de24a82fe681581cc130f342363c47c0969a.tar.xz
rustc-ef24de24a82fe681581cc130f342363c47c0969a.zip
Merging upstream version 1.75.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_ty_utils/src')
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs20
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs3
-rw-r--r--compiler/rustc_ty_utils/src/consts.rs2
-rw-r--r--compiler/rustc_ty_utils/src/implied_bounds.rs131
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs40
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs116
-rw-r--r--compiler/rustc_ty_utils/src/layout_sanity_check.rs3
-rw-r--r--compiler/rustc_ty_utils/src/lib.rs5
-rw-r--r--compiler/rustc_ty_utils/src/needs_drop.rs12
-rw-r--r--compiler/rustc_ty_utils/src/opaque_types.rs86
-rw-r--r--compiler/rustc_ty_utils/src/sig_types.rs112
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs45
12 files changed, 355 insertions, 220 deletions
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index 16183403d..fcf6626bb 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -97,8 +97,8 @@ fn fn_sig_for_fn_abi<'tcx>(
bound_vars,
)
}
- ty::Generator(did, args, _) => {
- let sig = args.as_generator().poly_sig();
+ ty::Coroutine(did, args, _) => {
+ let sig = args.as_coroutine().poly_sig();
let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
sig.bound_vars().iter().chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))),
@@ -116,11 +116,11 @@ fn fn_sig_for_fn_abi<'tcx>(
let env_ty = Ty::new_adt(tcx, pin_adt_ref, pin_args);
let sig = sig.skip_binder();
- // The `FnSig` and the `ret_ty` here is for a generators main
- // `Generator::resume(...) -> GeneratorState` function in case we
- // have an ordinary generator, or the `Future::poll(...) -> Poll`
- // function in case this is a special generator backing an async construct.
- let (resume_ty, ret_ty) = if tcx.generator_is_async(did) {
+ // The `FnSig` and the `ret_ty` here is for a coroutines main
+ // `Coroutine::resume(...) -> CoroutineState` function in case we
+ // have an ordinary coroutine, or the `Future::poll(...) -> Poll`
+ // function in case this is a special coroutine backing an async construct.
+ let (resume_ty, ret_ty) = if tcx.coroutine_is_async(did) {
// The signature should be `Future::poll(_, &mut Context<'_>) -> Poll<Output>`
let poll_did = tcx.require_lang_item(LangItem::Poll, None);
let poll_adt_ref = tcx.adt_def(poll_did);
@@ -143,8 +143,8 @@ fn fn_sig_for_fn_abi<'tcx>(
(context_mut_ref, ret_ty)
} else {
- // The signature should be `Generator::resume(_, Resume) -> GeneratorState<Yield, Return>`
- let state_did = tcx.require_lang_item(LangItem::GeneratorState, None);
+ // The signature should be `Coroutine::resume(_, Resume) -> CoroutineState<Yield, Return>`
+ let state_did = tcx.require_lang_item(LangItem::CoroutineState, None);
let state_adt_ref = tcx.adt_def(state_did);
let state_args = tcx.mk_args(&[sig.yield_ty.into(), sig.return_ty.into()]);
let ret_ty = Ty::new_adt(tcx, state_adt_ref, state_args);
@@ -528,7 +528,7 @@ fn fn_abi_adjust_for_abi<'tcx>(
arg.make_indirect();
} else {
// We want to pass small aggregates as immediates, but using
- // a LLVM aggregate type for this leads to bad optimizations,
+ // an LLVM aggregate type for this leads to bad optimizations,
// so we pick an appropriately sized integer type instead.
arg.cast_to(Reg { kind: RegKind::Integer, size });
}
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index 780f7ea42..3e140793b 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -192,7 +192,8 @@ fn associated_types_for_impl_traits_in_associated_fn(
if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind
&& self.rpits.insert(item_id.owner_id.def_id)
{
- let opaque_item = self.tcx.hir().expect_item(item_id.owner_id.def_id).expect_opaque_ty();
+ let opaque_item =
+ self.tcx.hir().expect_item(item_id.owner_id.def_id).expect_opaque_ty();
for bound in opaque_item.bounds {
intravisit::walk_param_bound(self, bound);
}
diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs
index 383cc996b..35487d3b6 100644
--- a/compiler/rustc_ty_utils/src/consts.rs
+++ b/compiler/rustc_ty_utils/src/consts.rs
@@ -71,7 +71,7 @@ pub(crate) fn destructure_const<'tcx>(
_ => bug!("cannot destructure constant {:?}", const_),
};
- let fields = tcx.arena.alloc_from_iter(fields.into_iter());
+ let fields = tcx.arena.alloc_from_iter(fields);
ty::DestructuredConst { variant, fields }
}
diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs
index ec2e0daaf..5c34df1ed 100644
--- a/compiler/rustc_ty_utils/src/implied_bounds.rs
+++ b/compiler/rustc_ty_utils/src/implied_bounds.rs
@@ -50,73 +50,76 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
let mut impl_spans = impl_spans(tcx, def_id);
tcx.arena.alloc_from_iter(tys.into_iter().map(|ty| (ty, impl_spans.next().unwrap())))
}
- DefKind::AssocTy if let Some(data) = tcx.opt_rpitit_info(def_id.to_def_id()) => match data {
- ty::ImplTraitInTraitData::Trait { fn_def_id, .. } => {
- // We need to remap all of the late-bound lifetimes in theassumed wf types
- // of the fn (which are represented as ReFree) to the early-bound lifetimes
- // of the RPITIT (which are represented by ReEarlyBound owned by the opaque).
- // Luckily, this is very easy to do because we already have that mapping
- // stored in the HIR of this RPITIT.
- //
- // Side-note: We don't really need to do this remapping for early-bound
- // lifetimes because they're already "linked" by the bidirectional outlives
- // predicates we insert in the `explicit_predicates_of` query for RPITITs.
- let mut mapping = FxHashMap::default();
- let generics = tcx.generics_of(def_id);
+ DefKind::AssocTy if let Some(data) = tcx.opt_rpitit_info(def_id.to_def_id()) => {
+ match data {
+ ty::ImplTraitInTraitData::Trait { fn_def_id, .. } => {
+ // We need to remap all of the late-bound lifetimes in theassumed wf types
+ // of the fn (which are represented as ReFree) to the early-bound lifetimes
+ // of the RPITIT (which are represented by ReEarlyBound owned by the opaque).
+ // Luckily, this is very easy to do because we already have that mapping
+ // stored in the HIR of this RPITIT.
+ //
+ // Side-note: We don't really need to do this remapping for early-bound
+ // lifetimes because they're already "linked" by the bidirectional outlives
+ // predicates we insert in the `explicit_predicates_of` query for RPITITs.
+ let mut mapping = FxHashMap::default();
+ let generics = tcx.generics_of(def_id);
- // For each captured opaque lifetime, if it's late-bound (`ReFree` in this case,
- // since it has been liberated), map it back to the early-bound lifetime of
- // the GAT. Since RPITITs also have all of the fn's generics, we slice only
- // the end of the list corresponding to the opaque's generics.
- for param in &generics.params[tcx.generics_of(fn_def_id).params.len()..] {
- let orig_lt = tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local());
- if matches!(*orig_lt, ty::ReFree(..)) {
- mapping.insert(
- orig_lt,
- ty::Region::new_early_bound(
- tcx,
- ty::EarlyBoundRegion {
- def_id: param.def_id,
- index: param.index,
- name: param.name,
- },
- ),
- );
+ // For each captured opaque lifetime, if it's late-bound (`ReFree` in this case,
+ // since it has been liberated), map it back to the early-bound lifetime of
+ // the GAT. Since RPITITs also have all of the fn's generics, we slice only
+ // the end of the list corresponding to the opaque's generics.
+ for param in &generics.params[tcx.generics_of(fn_def_id).params.len()..] {
+ let orig_lt =
+ tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local());
+ if matches!(*orig_lt, ty::ReFree(..)) {
+ mapping.insert(
+ orig_lt,
+ ty::Region::new_early_bound(
+ tcx,
+ ty::EarlyBoundRegion {
+ def_id: param.def_id,
+ index: param.index,
+ name: param.name,
+ },
+ ),
+ );
+ }
}
+ // FIXME: This could use a real folder, I guess.
+ let remapped_wf_tys = tcx.fold_regions(
+ tcx.assumed_wf_types(fn_def_id.expect_local()).to_vec(),
+ |region, _| {
+ // If `region` is a `ReFree` that is captured by the
+ // opaque, remap it to its corresponding the early-
+ // bound region.
+ if let Some(remapped_region) = mapping.get(&region) {
+ *remapped_region
+ } else {
+ region
+ }
+ },
+ );
+ tcx.arena.alloc_from_iter(remapped_wf_tys)
+ }
+ // Assumed wf types for RPITITs in an impl just inherit (and instantiate)
+ // the assumed wf types of the trait's RPITIT GAT.
+ ty::ImplTraitInTraitData::Impl { .. } => {
+ let impl_def_id = tcx.local_parent(def_id);
+ let rpitit_def_id = tcx.associated_item(def_id).trait_item_def_id.unwrap();
+ let args = ty::GenericArgs::identity_for_item(tcx, def_id).rebase_onto(
+ tcx,
+ impl_def_id.to_def_id(),
+ tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity().args,
+ );
+ tcx.arena.alloc_from_iter(
+ ty::EarlyBinder::bind(tcx.assumed_wf_types_for_rpitit(rpitit_def_id))
+ .iter_instantiated_copied(tcx, args)
+ .chain(tcx.assumed_wf_types(impl_def_id).into_iter().copied()),
+ )
}
- // FIXME: This could use a real folder, I guess.
- let remapped_wf_tys = tcx.fold_regions(
- tcx.assumed_wf_types(fn_def_id.expect_local()).to_vec(),
- |region, _| {
- // If `region` is a `ReFree` that is captured by the
- // opaque, remap it to its corresponding the early-
- // bound region.
- if let Some(remapped_region) = mapping.get(&region) {
- *remapped_region
- } else {
- region
- }
- },
- );
- tcx.arena.alloc_from_iter(remapped_wf_tys)
- }
- // Assumed wf types for RPITITs in an impl just inherit (and instantiate)
- // the assumed wf types of the trait's RPITIT GAT.
- ty::ImplTraitInTraitData::Impl { .. } => {
- let impl_def_id = tcx.local_parent(def_id);
- let rpitit_def_id = tcx.associated_item(def_id).trait_item_def_id.unwrap();
- let args = ty::GenericArgs::identity_for_item(tcx, def_id).rebase_onto(
- tcx,
- impl_def_id.to_def_id(),
- tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity().args,
- );
- tcx.arena.alloc_from_iter(
- ty::EarlyBinder::bind(tcx.assumed_wf_types_for_rpitit(rpitit_def_id))
- .iter_instantiated_copied(tcx, args)
- .chain(tcx.assumed_wf_types(impl_def_id).into_iter().copied()),
- )
}
- },
+ }
DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.local_parent(def_id)),
DefKind::OpaqueTy => match tcx.def_kind(tcx.local_parent(def_id)) {
DefKind::TyAlias => ty::List::empty(),
@@ -154,7 +157,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
| DefKind::LifetimeParam
| DefKind::GlobalAsm
| DefKind::Closure
- | DefKind::Generator => ty::List::empty(),
+ | DefKind::Coroutine => ty::List::empty(),
}
}
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index 91f1c2131..1487f40fd 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -38,7 +38,7 @@ fn resolve_instance<'tcx>(
debug!(" => nontrivial drop glue");
match *ty.kind() {
ty::Closure(..)
- | ty::Generator(..)
+ | ty::Coroutine(..)
| ty::Tuple(..)
| ty::Adt(..)
| ty::Dynamic(..)
@@ -188,10 +188,7 @@ fn resolve_associated_item<'tcx>(
&& trait_item_id != leaf_def.item.def_id
&& let Some(leaf_def_item) = leaf_def.item.def_id.as_local()
{
- tcx.compare_impl_const((
- leaf_def_item,
- trait_item_id,
- ))?;
+ tcx.compare_impl_const((leaf_def_item, trait_item_id))?;
}
Some(ty::Instance::new(leaf_def.item.def_id, args))
@@ -215,8 +212,8 @@ fn resolve_associated_item<'tcx>(
let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env);
match self_ty.kind() {
_ if is_copy => (),
- ty::Generator(..)
- | ty::GeneratorWitness(..)
+ ty::Coroutine(..)
+ | ty::CoroutineWitness(..)
| ty::Closure(..)
| ty::Tuple(..) => {}
_ => return Ok(None),
@@ -249,34 +246,47 @@ fn resolve_associated_item<'tcx>(
})
}
} else if Some(trait_ref.def_id) == lang_items.future_trait() {
- let ty::Generator(generator_def_id, args, _) = *rcvr_args.type_at(0).kind() else {
+ let ty::Coroutine(coroutine_def_id, args, _) = *rcvr_args.type_at(0).kind() else {
bug!()
};
if Some(trait_item_id) == tcx.lang_items().future_poll_fn() {
// `Future::poll` is generated by the compiler.
- Some(Instance { def: ty::InstanceDef::Item(generator_def_id), args: args })
+ Some(Instance { def: ty::InstanceDef::Item(coroutine_def_id), args: args })
} else {
// All other methods are default methods of the `Future` trait.
// (this assumes that `ImplSource::Builtin` is only used for methods on `Future`)
debug_assert!(tcx.defaultness(trait_item_id).has_value());
Some(Instance::new(trait_item_id, rcvr_args))
}
- } else if Some(trait_ref.def_id) == lang_items.gen_trait() {
- let ty::Generator(generator_def_id, args, _) = *rcvr_args.type_at(0).kind() else {
+ } else if Some(trait_ref.def_id) == lang_items.iterator_trait() {
+ let ty::Coroutine(coroutine_def_id, args, _) = *rcvr_args.type_at(0).kind() else {
+ bug!()
+ };
+ if Some(trait_item_id) == tcx.lang_items().next_fn() {
+ // `Iterator::next` is generated by the compiler.
+ Some(Instance { def: ty::InstanceDef::Item(coroutine_def_id), args })
+ } else {
+ // All other methods are default methods of the `Iterator` trait.
+ // (this assumes that `ImplSource::Builtin` is only used for methods on `Iterator`)
+ debug_assert!(tcx.defaultness(trait_item_id).has_value());
+ Some(Instance::new(trait_item_id, rcvr_args))
+ }
+ } else if Some(trait_ref.def_id) == lang_items.coroutine_trait() {
+ let ty::Coroutine(coroutine_def_id, args, _) = *rcvr_args.type_at(0).kind() else {
bug!()
};
if cfg!(debug_assertions) && tcx.item_name(trait_item_id) != sym::resume {
- // For compiler developers who'd like to add new items to `Generator`,
+ // For compiler developers who'd like to add new items to `Coroutine`,
// you either need to generate a shim body, or perhaps return
// `InstanceDef::Item` pointing to a trait default method body if
// it is given a default implementation by the trait.
span_bug!(
- tcx.def_span(generator_def_id),
- "no definition for `{trait_ref}::{}` for built-in generator type",
+ tcx.def_span(coroutine_def_id),
+ "no definition for `{trait_ref}::{}` for built-in coroutine type",
tcx.item_name(trait_item_id)
)
}
- Some(Instance { def: ty::InstanceDef::Item(generator_def_id), args })
+ Some(Instance { def: ty::InstanceDef::Item(coroutine_def_id), args })
} else if tcx.fn_trait_kind_from_def_id(trait_ref.def_id).is_some() {
// FIXME: This doesn't check for malformed libcore that defines, e.g.,
// `trait Fn { fn call_once(&self) { .. } }`. This is mostly for extension
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 5bd68d7cc..283862b5e 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -2,7 +2,7 @@ use hir::def_id::DefId;
use rustc_hir as hir;
use rustc_index::bit_set::BitSet;
use rustc_index::{IndexSlice, IndexVec};
-use rustc_middle::mir::{GeneratorLayout, GeneratorSavedLocal};
+use rustc_middle::mir::{CoroutineLayout, CoroutineSavedLocal};
use rustc_middle::query::Providers;
use rustc_middle::ty::layout::{
IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, MAX_SIMD_LANES,
@@ -85,7 +85,7 @@ fn univariant_uninterned<'tcx>(
fields: &IndexSlice<FieldIdx, Layout<'_>>,
repr: &ReprOptions,
kind: StructKind,
-) -> Result<LayoutS, &'tcx LayoutError<'tcx>> {
+) -> Result<LayoutS<FieldIdx, VariantIdx>, &'tcx LayoutError<'tcx>> {
let dl = cx.data_layout();
let pack = repr.pack;
if pack.is_some() && repr.align.is_some() {
@@ -170,29 +170,27 @@ fn layout_of_uncached<'tcx>(
// fall back to structurally deducing metadata.
&& !pointee.references_error()
{
- let pointee_metadata = Ty::new_projection(tcx,metadata_def_id, [pointee]);
- let metadata_ty = match tcx.try_normalize_erasing_regions(
- param_env,
- pointee_metadata,
- ) {
- Ok(metadata_ty) => metadata_ty,
- Err(mut err) => {
- // Usually `<Ty as Pointee>::Metadata` can't be normalized because
- // its struct tail cannot be normalized either, so try to get a
- // more descriptive layout error here, which will lead to less confusing
- // diagnostics.
- match tcx.try_normalize_erasing_regions(
- param_env,
- tcx.struct_tail_without_normalization(pointee),
- ) {
- Ok(_) => {},
- Err(better_err) => {
- err = better_err;
+ let pointee_metadata = Ty::new_projection(tcx, metadata_def_id, [pointee]);
+ let metadata_ty =
+ match tcx.try_normalize_erasing_regions(param_env, pointee_metadata) {
+ Ok(metadata_ty) => metadata_ty,
+ Err(mut err) => {
+ // Usually `<Ty as Pointee>::Metadata` can't be normalized because
+ // its struct tail cannot be normalized either, so try to get a
+ // more descriptive layout error here, which will lead to less confusing
+ // diagnostics.
+ match tcx.try_normalize_erasing_regions(
+ param_env,
+ tcx.struct_tail_without_normalization(pointee),
+ ) {
+ Ok(_) => {}
+ Err(better_err) => {
+ err = better_err;
+ }
}
+ return Err(error(cx, LayoutError::NormalizationFailure(pointee, err)));
}
- return Err(error(cx, LayoutError::NormalizationFailure(pointee, err)));
- },
- };
+ };
let metadata_layout = cx.layout_of(metadata_ty)?;
// If the metadata is a 1-zst, then the pointer is thin.
@@ -316,7 +314,7 @@ fn layout_of_uncached<'tcx>(
tcx.mk_layout(unit)
}
- ty::Generator(def_id, args, _) => generator_layout(cx, ty, def_id, args)?,
+ ty::Coroutine(def_id, args, _) => coroutine_layout(cx, ty, def_id, args)?,
ty::Closure(_, ref args) => {
let tys = args.as_closure().upvar_tys();
@@ -577,7 +575,7 @@ fn layout_of_uncached<'tcx>(
return Err(error(cx, LayoutError::Unknown(ty)));
}
- ty::Bound(..) | ty::GeneratorWitness(..) | ty::Infer(_) | ty::Error(_) => {
+ ty::Bound(..) | ty::CoroutineWitness(..) | ty::Infer(_) | ty::Error(_) => {
bug!("Layout::compute: unexpected type `{}`", ty)
}
@@ -587,7 +585,7 @@ fn layout_of_uncached<'tcx>(
})
}
-/// Overlap eligibility and variant assignment for each GeneratorSavedLocal.
+/// Overlap eligibility and variant assignment for each CoroutineSavedLocal.
#[derive(Clone, Debug, PartialEq)]
enum SavedLocalEligibility {
Unassigned,
@@ -595,7 +593,7 @@ enum SavedLocalEligibility {
Ineligible(Option<FieldIdx>),
}
-// When laying out generators, we divide our saved local fields into two
+// When laying out coroutines, we divide our saved local fields into two
// categories: overlap-eligible and overlap-ineligible.
//
// Those fields which are ineligible for overlap go in a "prefix" at the
@@ -615,16 +613,16 @@ enum SavedLocalEligibility {
// of any variant.
/// Compute the eligibility and assignment of each local.
-fn generator_saved_local_eligibility(
- info: &GeneratorLayout<'_>,
-) -> (BitSet<GeneratorSavedLocal>, IndexVec<GeneratorSavedLocal, SavedLocalEligibility>) {
+fn coroutine_saved_local_eligibility(
+ info: &CoroutineLayout<'_>,
+) -> (BitSet<CoroutineSavedLocal>, IndexVec<CoroutineSavedLocal, SavedLocalEligibility>) {
use SavedLocalEligibility::*;
- let mut assignments: IndexVec<GeneratorSavedLocal, SavedLocalEligibility> =
+ let mut assignments: IndexVec<CoroutineSavedLocal, SavedLocalEligibility> =
IndexVec::from_elem(Unassigned, &info.field_tys);
// The saved locals not eligible for overlap. These will get
- // "promoted" to the prefix of our generator.
+ // "promoted" to the prefix of our coroutine.
let mut ineligible_locals = BitSet::new_empty(info.field_tys.len());
// Figure out which of our saved locals are fields in only
@@ -662,7 +660,7 @@ fn generator_saved_local_eligibility(
for local_b in info.storage_conflicts.iter(local_a) {
// local_a and local_b are storage live at the same time, therefore they
- // cannot overlap in the generator layout. The only way to guarantee
+ // cannot overlap in the coroutine layout. The only way to guarantee
// this is if they are in the same variant, or one is ineligible
// (which means it is stored in every variant).
if ineligible_locals.contains(local_b) || assignments[local_a] == assignments[local_b] {
@@ -707,13 +705,13 @@ fn generator_saved_local_eligibility(
assignments[local] = Ineligible(Some(FieldIdx::from_usize(idx)));
}
}
- debug!("generator saved local assignments: {:?}", assignments);
+ debug!("coroutine saved local assignments: {:?}", assignments);
(ineligible_locals, assignments)
}
-/// Compute the full generator layout.
-fn generator_layout<'tcx>(
+/// Compute the full coroutine layout.
+fn coroutine_layout<'tcx>(
cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
ty: Ty<'tcx>,
def_id: hir::def_id::DefId,
@@ -723,15 +721,15 @@ fn generator_layout<'tcx>(
let tcx = cx.tcx;
let subst_field = |ty: Ty<'tcx>| EarlyBinder::bind(ty).instantiate(tcx, args);
- let Some(info) = tcx.generator_layout(def_id) else {
+ let Some(info) = tcx.coroutine_layout(def_id) else {
return Err(error(cx, LayoutError::Unknown(ty)));
};
- let (ineligible_locals, assignments) = generator_saved_local_eligibility(&info);
+ let (ineligible_locals, assignments) = coroutine_saved_local_eligibility(&info);
// Build a prefix layout, including "promoting" all ineligible
// locals as part of the prefix. We compute the layout of all of
// these fields at once to get optimal packing.
- let tag_index = args.as_generator().prefix_tys().len();
+ let tag_index = args.as_coroutine().prefix_tys().len();
// `info.variant_fields` already accounts for the reserved variants, so no need to add them.
let max_discr = (info.variant_fields.len() - 1) as u128;
@@ -748,7 +746,7 @@ fn generator_layout<'tcx>(
.map(|ty| Ty::new_maybe_uninit(tcx, ty))
.map(|ty| Ok(cx.layout_of(ty)?.layout));
let prefix_layouts = args
- .as_generator()
+ .as_coroutine()
.prefix_tys()
.iter()
.map(|ty| Ok(cx.layout_of(ty)?.layout))
@@ -768,7 +766,7 @@ fn generator_layout<'tcx>(
// Split the prefix layout into the "outer" fields (upvars and
// discriminant) and the "promoted" fields. Promoted fields will
// get included in each variant that requested them in
- // GeneratorLayout.
+ // CoroutineLayout.
debug!("prefix = {:#?}", prefix);
let (outer_fields, promoted_offsets, promoted_memory_index) = match prefix.fields {
FieldsShape::Arbitrary { mut offsets, memory_index } => {
@@ -835,7 +833,7 @@ fn generator_layout<'tcx>(
};
// Now, stitch the promoted and variant-only fields back together in
- // the order they are mentioned by our GeneratorLayout.
+ // the order they are mentioned by our CoroutineLayout.
// Because we only use some subset (that can differ between variants)
// of the promoted fields, we can't just pick those elements of the
// `promoted_memory_index` (as we'd end up with gaps).
@@ -909,7 +907,7 @@ fn generator_layout<'tcx>(
max_repr_align: None,
unadjusted_abi_align: align.abi,
});
- debug!("generator layout ({:?}): {:#?}", ty, layout);
+ debug!("coroutine layout ({:?}): {:#?}", ty, layout);
Ok(layout)
}
@@ -958,12 +956,12 @@ fn record_layout_for_printing_outlined<'tcx>(
record(adt_kind.into(), adt_packed, opt_discr_size, variant_infos);
}
- ty::Generator(def_id, args, _) => {
- debug!("print-type-size t: `{:?}` record generator", layout.ty);
- // Generators always have a begin/poisoned/end state with additional suspend points
+ ty::Coroutine(def_id, args, _) => {
+ debug!("print-type-size t: `{:?}` record coroutine", layout.ty);
+ // Coroutines always have a begin/poisoned/end state with additional suspend points
let (variant_infos, opt_discr_size) =
- variant_info_for_generator(cx, layout, def_id, args);
- record(DataTypeKind::Generator, false, opt_discr_size, variant_infos);
+ variant_info_for_coroutine(cx, layout, def_id, args);
+ record(DataTypeKind::Coroutine, false, opt_discr_size, variant_infos);
}
ty::Closure(..) => {
@@ -1048,7 +1046,7 @@ fn variant_info_for_adt<'tcx>(
}
}
-fn variant_info_for_generator<'tcx>(
+fn variant_info_for_coroutine<'tcx>(
cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
layout: TyAndLayout<'tcx>,
def_id: DefId,
@@ -1058,12 +1056,12 @@ fn variant_info_for_generator<'tcx>(
return (vec![], None);
};
- let generator = cx.tcx.optimized_mir(def_id).generator_layout().unwrap();
+ let coroutine = cx.tcx.optimized_mir(def_id).coroutine_layout().unwrap();
let upvar_names = cx.tcx.closure_saved_names_of_captured_variables(def_id);
let mut upvars_size = Size::ZERO;
let upvar_fields: Vec<_> = args
- .as_generator()
+ .as_coroutine()
.upvar_tys()
.iter()
.zip(upvar_names)
@@ -1082,7 +1080,7 @@ fn variant_info_for_generator<'tcx>(
})
.collect();
- let mut variant_infos: Vec<_> = generator
+ let mut variant_infos: Vec<_> = coroutine
.variant_fields
.iter_enumerated()
.map(|(variant_idx, variant_def)| {
@@ -1097,9 +1095,9 @@ fn variant_info_for_generator<'tcx>(
// The struct is as large as the last field's end
variant_size = variant_size.max(offset + field_layout.size);
FieldInfo {
- kind: FieldKind::GeneratorLocal,
- name: generator.field_names[*local].unwrap_or(Symbol::intern(&format!(
- ".generator_field{}",
+ kind: FieldKind::CoroutineLocal,
+ name: coroutine.field_names[*local].unwrap_or(Symbol::intern(&format!(
+ ".coroutine_field{}",
local.as_usize()
))),
offset: offset.bytes(),
@@ -1117,8 +1115,8 @@ fn variant_info_for_generator<'tcx>(
// This `if` deserves some explanation.
//
- // The layout code has a choice of where to place the discriminant of this generator.
- // If the discriminant of the generator is placed early in the layout (before the
+ // The layout code has a choice of where to place the discriminant of this coroutine.
+ // If the discriminant of the coroutine is placed early in the layout (before the
// variant's own fields), then it'll implicitly be counted towards the size of the
// variant, since we use the maximum offset to calculate size.
// (side-note: I know this is a bit problematic given upvars placement, etc).
@@ -1138,7 +1136,7 @@ fn variant_info_for_generator<'tcx>(
}
VariantInfo {
- name: Some(Symbol::intern(&ty::GeneratorArgs::variant_name(variant_idx))),
+ name: Some(Symbol::intern(&ty::CoroutineArgs::variant_name(variant_idx))),
kind: SizeKind::Exact,
size: variant_size.bytes(),
align: variant_layout.align.abi.bytes(),
@@ -1149,7 +1147,7 @@ fn variant_info_for_generator<'tcx>(
// The first three variants are hardcoded to be `UNRESUMED`, `RETURNED` and `POISONED`.
// We will move the `RETURNED` and `POISONED` elements to the end so we
- // are left with a sorting order according to the generators yield points:
+ // are left with a sorting order according to the coroutines yield points:
// First `Unresumed`, then the `SuspendN` followed by `Returned` and `Panicked` (POISONED).
let end_states = variant_infos.drain(1..=2);
let end_states: Vec<_> = end_states.collect();
diff --git a/compiler/rustc_ty_utils/src/layout_sanity_check.rs b/compiler/rustc_ty_utils/src/layout_sanity_check.rs
index 863333438..6332c614a 100644
--- a/compiler/rustc_ty_utils/src/layout_sanity_check.rs
+++ b/compiler/rustc_ty_utils/src/layout_sanity_check.rs
@@ -19,6 +19,9 @@ pub(super) fn sanity_check_layout<'tcx>(
if layout.size.bytes() % layout.align.abi.bytes() != 0 {
bug!("size is not a multiple of align, in the following layout:\n{layout:#?}");
}
+ if layout.size.bytes() >= cx.tcx.data_layout.obj_size_bound() {
+ bug!("size is too large, in the following layout:\n{layout:#?}");
+ }
if !cfg!(debug_assertions) {
// Stop here, the rest is kind of expensive.
diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs
index 147b600f7..dabe25589 100644
--- a/compiler/rustc_ty_utils/src/lib.rs
+++ b/compiler/rustc_ty_utils/src/lib.rs
@@ -5,7 +5,11 @@
//! This API is completely unstable and subject to change.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
+#![cfg_attr(not(bootstrap), doc(rust_logo))]
+#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
+#![cfg_attr(not(bootstrap), allow(internal_features))]
#![feature(assert_matches)]
+#![feature(associated_type_defaults)]
#![feature(iterator_try_collect)]
#![feature(let_chains)]
#![feature(if_let_guard)]
@@ -36,6 +40,7 @@ mod layout_sanity_check;
mod needs_drop;
mod opaque_types;
pub mod representability;
+pub mod sig_types;
mod structural_match;
mod ty;
diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs
index 51a6d6235..67ccfe7e7 100644
--- a/compiler/rustc_ty_utils/src/needs_drop.rs
+++ b/compiler/rustc_ty_utils/src/needs_drop.rs
@@ -134,9 +134,9 @@ where
for component in components {
match *component.kind() {
- // The information required to determine whether a generator has drop is
+ // The information required to determine whether a coroutine has drop is
// computed on MIR, while this very method is used to build MIR.
- // To avoid cycles, we consider that generators always require drop.
+ // To avoid cycles, we consider that coroutines always require drop.
//
// HACK: Because we erase regions contained in the coroutine witness, we
// have to conservatively assume that every region captured by the
@@ -145,15 +145,15 @@ where
// for the coroutine witness and check whether any of the contained types
// need to be dropped, and only require the captured types to be live
// if they do.
- ty::Generator(_, args, _) => {
+ ty::Coroutine(_, args, _) => {
if self.reveal_coroutine_witnesses {
- queue_type(self, args.as_generator().witness());
+ queue_type(self, args.as_coroutine().witness());
} else {
return Some(Err(AlwaysRequiresDrop));
}
}
- ty::GeneratorWitness(def_id, args) => {
- if let Some(witness) = tcx.mir_generator_witnesses(def_id) {
+ ty::CoroutineWitness(def_id, args) => {
+ if let Some(witness) = tcx.mir_coroutine_witnesses(def_id) {
self.reveal_coroutine_witnesses = true;
for field_ty in &witness.field_tys {
queue_type(
diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs
index 06a30677d..9242a1a75 100644
--- a/compiler/rustc_ty_utils/src/opaque_types.rs
+++ b/compiler/rustc_ty_utils/src/opaque_types.rs
@@ -53,14 +53,10 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
fn parent(&self) -> Option<LocalDefId> {
match self.tcx.def_kind(self.item) {
- DefKind::AnonConst | DefKind::InlineConst | DefKind::Fn | DefKind::TyAlias => None,
DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => {
Some(self.tcx.local_parent(self.item))
}
- other => span_bug!(
- self.tcx.def_span(self.item),
- "unhandled item with opaque types: {other:?}"
- ),
+ _ => None,
}
}
@@ -98,14 +94,6 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
hir_id == scope
}
- fn collect_body_and_predicate_taits(&mut self) {
- // Look at all where bounds.
- self.tcx.predicates_of(self.item).instantiate_identity(self.tcx).visit_with(self);
- // An item is allowed to constrain opaques declared within its own body (but not nested within
- // nested functions).
- self.collect_taits_declared_in_body();
- }
-
#[instrument(level = "trace", skip(self))]
fn collect_taits_declared_in_body(&mut self) {
let body = self.tcx.hir().body(self.tcx.hir().body_owned_by(self.item)).value;
@@ -132,6 +120,14 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
}
}
+impl<'tcx> super::sig_types::SpannedTypeVisitor<'tcx> for OpaqueTypeCollector<'tcx> {
+ #[instrument(skip(self), ret, level = "trace")]
+ fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) -> ControlFlow<!> {
+ self.visit_spanned(span, value);
+ ControlFlow::Continue(())
+ }
+}
+
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
#[instrument(skip(self), ret, level = "trace")]
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<!> {
@@ -159,7 +155,14 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
self.opaques.push(alias_ty.def_id.expect_local());
- match self.tcx.uses_unique_generic_params(alias_ty.args, CheckRegions::Bound) {
+ let parent_count = self.tcx.generics_of(alias_ty.def_id).parent_count;
+ // Only check that the parent generics of the TAIT/RPIT are unique.
+ // the args owned by the opaque are going to always be duplicate
+ // lifetime params for RPITs, and empty for TAITs.
+ match self
+ .tcx
+ .uses_unique_generic_params(&alias_ty.args[..parent_count], CheckRegions::Bound)
+ {
Ok(()) => {
// FIXME: implement higher kinded lifetime bounds on nested opaque types. They are not
// supported at all, so this is sound to do, but once we want to support them, you'll
@@ -269,41 +272,27 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
}
}
-fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [LocalDefId] {
+fn opaque_types_defined_by<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ item: LocalDefId,
+) -> &'tcx ty::List<LocalDefId> {
let kind = tcx.def_kind(item);
trace!(?kind);
let mut collector = OpaqueTypeCollector::new(tcx, item);
+ super::sig_types::walk_types(tcx, item, &mut collector);
match kind {
- // Walk over the signature of the function-like to find the opaques.
- DefKind::AssocFn | DefKind::Fn => {
- let ty_sig = tcx.fn_sig(item).instantiate_identity();
- let hir_sig = tcx.hir().get_by_def_id(item).fn_sig().unwrap();
- // Walk over the inputs and outputs manually in order to get good spans for them.
- collector.visit_spanned(hir_sig.decl.output.span(), ty_sig.output());
- for (hir, ty) in hir_sig.decl.inputs.iter().zip(ty_sig.inputs().iter()) {
- collector.visit_spanned(hir.span, ty.map_bound(|x| *x));
- }
- collector.collect_body_and_predicate_taits();
- }
- // Walk over the type of the item to find opaques.
- DefKind::Static(_) | DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => {
- let span = match tcx.hir().get_by_def_id(item).ty() {
- Some(ty) => ty.span,
- _ => tcx.def_span(item),
- };
- collector.visit_spanned(span, tcx.type_of(item).instantiate_identity());
- collector.collect_body_and_predicate_taits();
- }
- // We're also doing this for `AssocTy` for the wf checks in `check_opaque_meets_bounds`
- DefKind::TyAlias | DefKind::AssocTy => {
- tcx.type_of(item).instantiate_identity().visit_with(&mut collector);
- }
- DefKind::OpaqueTy => {
- for (pred, span) in tcx.explicit_item_bounds(item).instantiate_identity_iter_copied() {
- collector.visit_spanned(span, pred);
- }
+ DefKind::AssocFn
+ | DefKind::Fn
+ | DefKind::Static(_)
+ | DefKind::Const
+ | DefKind::AssocConst
+ | DefKind::AnonConst => {
+ collector.collect_taits_declared_in_body();
}
- DefKind::Mod
+ DefKind::OpaqueTy
+ | DefKind::TyAlias
+ | DefKind::AssocTy
+ | DefKind::Mod
| DefKind::Struct
| DefKind::Union
| DefKind::Enum
@@ -322,12 +311,13 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [
| DefKind::LifetimeParam
| DefKind::GlobalAsm
| DefKind::Impl { .. } => {}
- // Closures and generators are type checked with their parent, so there is no difference here.
- DefKind::Closure | DefKind::Generator | DefKind::InlineConst => {
- return tcx.opaque_types_defined_by(tcx.local_parent(item));
+ // Closures and coroutines are type checked with their parent, so we need to allow all
+ // opaques from the closure signature *and* from the parent body.
+ DefKind::Closure | DefKind::Coroutine | DefKind::InlineConst => {
+ collector.opaques.extend(tcx.opaque_types_defined_by(tcx.local_parent(item)));
}
}
- tcx.arena.alloc_from_iter(collector.opaques)
+ tcx.mk_local_def_ids(&collector.opaques)
}
pub(super) fn provide(providers: &mut Providers) {
diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs
new file mode 100644
index 000000000..ccdc61201
--- /dev/null
+++ b/compiler/rustc_ty_utils/src/sig_types.rs
@@ -0,0 +1,112 @@
+//! This module contains helpers for walking all types of
+//! a signature, while preserving spans as much as possible
+
+use std::ops::ControlFlow;
+
+use rustc_hir::{def::DefKind, def_id::LocalDefId};
+use rustc_middle::ty::TyCtxt;
+use rustc_span::Span;
+use rustc_type_ir::visit::TypeVisitable;
+
+pub trait SpannedTypeVisitor<'tcx> {
+ type BreakTy = !;
+ fn visit(
+ &mut self,
+ span: Span,
+ value: impl TypeVisitable<TyCtxt<'tcx>>,
+ ) -> ControlFlow<Self::BreakTy>;
+}
+
+pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
+ tcx: TyCtxt<'tcx>,
+ item: LocalDefId,
+ visitor: &mut V,
+) -> ControlFlow<V::BreakTy> {
+ let kind = tcx.def_kind(item);
+ trace!(?kind);
+ match kind {
+ // Walk over the signature of the function
+ DefKind::AssocFn | DefKind::Fn => {
+ let ty_sig = tcx.fn_sig(item).instantiate_identity();
+ let hir_sig = tcx.hir().get_by_def_id(item).fn_decl().unwrap();
+ // Walk over the inputs and outputs manually in order to get good spans for them.
+ visitor.visit(hir_sig.output.span(), ty_sig.output());
+ for (hir, ty) in hir_sig.inputs.iter().zip(ty_sig.inputs().iter()) {
+ visitor.visit(hir.span, ty.map_bound(|x| *x))?;
+ }
+ for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
+ visitor.visit(span, pred)?;
+ }
+ }
+ // Walk over the type behind the alias
+ DefKind::TyAlias {..} | DefKind::AssocTy |
+ // Walk over the type of the item
+ DefKind::Static(_) | DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => {
+ let span = match tcx.hir().get_by_def_id(item).ty() {
+ Some(ty) => ty.span,
+ _ => tcx.def_span(item),
+ };
+ visitor.visit(span, tcx.type_of(item).instantiate_identity());
+ for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
+ visitor.visit(span, pred)?;
+ }
+ }
+ DefKind::OpaqueTy => {
+ for (pred, span) in tcx.explicit_item_bounds(item).instantiate_identity_iter_copied() {
+ visitor.visit(span, pred)?;
+ }
+ }
+ // Look at field types
+ DefKind::Struct | DefKind::Union | DefKind::Enum => {
+ let span = tcx.def_ident_span(item).unwrap();
+ visitor.visit(span, tcx.type_of(item).instantiate_identity());
+ for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
+ visitor.visit(span, pred)?;
+ }
+ }
+ // These are not part of a public API, they can only appear as hidden types, and there
+ // the interesting parts are solely in the signature of the containing item's opaque type
+ // or dyn type.
+ DefKind::InlineConst | DefKind::Closure | DefKind::Coroutine => {}
+ DefKind::Impl { of_trait } => {
+ if of_trait {
+ let span = tcx.hir().get_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().path.span;
+ let args = &tcx.impl_trait_ref(item).unwrap().instantiate_identity().args[1..];
+ visitor.visit(span, args)?;
+ }
+ let span = match tcx.hir().get_by_def_id(item).ty() {
+ Some(ty) => ty.span,
+ _ => tcx.def_span(item),
+ };
+ visitor.visit(span, tcx.type_of(item).instantiate_identity());
+ for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
+ visitor.visit(span, pred)?;
+ }
+ }
+ DefKind::TraitAlias | DefKind::Trait => {
+ for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
+ visitor.visit(span, pred)?;
+ }
+ }
+ | DefKind::Variant
+ | DefKind::ForeignTy
+ | DefKind::TyParam
+ | DefKind::ConstParam
+ | DefKind::Ctor(_, _)
+ | DefKind::Field
+ | DefKind::LifetimeParam => {
+ span_bug!(
+ tcx.def_span(item),
+ "{kind:?} has not seen any uses of `walk_types` yet, ping oli-obk if you'd like any help"
+ )
+ }
+ // These don't have any types.
+ | DefKind::ExternCrate
+ | DefKind::ForeignMod
+ | DefKind::Macro(_)
+ | DefKind::GlobalAsm
+ | DefKind::Mod
+ | DefKind::Use => {}
+ }
+ ControlFlow::Continue(())
+}
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 4234e69e8..abf3e108e 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -3,9 +3,8 @@ use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_index::bit_set::BitSet;
use rustc_middle::query::Providers;
-use rustc_middle::ty::{
- self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor,
-};
+use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt, TypeVisitor};
+use rustc_middle::ty::{ToPredicate, TypeSuperVisitable, TypeVisitable};
use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
use rustc_span::DUMMY_SP;
use rustc_trait_selection::traits;
@@ -15,13 +14,13 @@ fn sized_constraint_for_ty<'tcx>(
adtdef: ty::AdtDef<'tcx>,
ty: Ty<'tcx>,
) -> Vec<Ty<'tcx>> {
- use rustc_type_ir::sty::TyKind::*;
+ use rustc_type_ir::TyKind::*;
let result = match ty.kind() {
Bool | Char | Int(..) | Uint(..) | Float(..) | RawPtr(..) | Ref(..) | FnDef(..)
- | FnPtr(_) | Array(..) | Closure(..) | Generator(..) | Never => vec![],
+ | FnPtr(_) | Array(..) | Closure(..) | Coroutine(..) | Never => vec![],
- Str | Dynamic(..) | Slice(_) | Foreign(..) | Error(_) | GeneratorWitness(..) => {
+ Str | Dynamic(..) | Slice(_) | Foreign(..) | Error(_) | CoroutineWitness(..) => {
// these are never sized - return the target type
vec![ty]
}
@@ -185,9 +184,10 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow<Self::BreakTy> {
if let ty::Alias(ty::Projection, unshifted_alias_ty) = *ty.kind()
- && let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }
- | ty::ImplTraitInTraitData::Impl { fn_def_id, .. })
- = self.tcx.opt_rpitit_info(unshifted_alias_ty.def_id)
+ && let Some(
+ ty::ImplTraitInTraitData::Trait { fn_def_id, .. }
+ | ty::ImplTraitInTraitData::Impl { fn_def_id, .. },
+ ) = self.tcx.opt_rpitit_info(unshifted_alias_ty.def_id)
&& fn_def_id == self.fn_def_id
&& self.seen.insert(unshifted_alias_ty.def_id)
{
@@ -203,7 +203,11 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
"we shouldn't walk non-predicate binders with `impl Trait`...",
);
}
- ty::Region::new_late_bound(self.tcx, index.shifted_out_to_binder(self.depth), bv)
+ ty::Region::new_late_bound(
+ self.tcx,
+ index.shifted_out_to_binder(self.depth),
+ bv,
+ )
} else {
re
}
@@ -212,12 +216,21 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
// If we're lowering to associated item, install the opaque type which is just
// the `type_of` of the trait's associated item. If we're using the old lowering
// strategy, then just reinterpret the associated type like an opaque :^)
- let default_ty = self.tcx.type_of(shifted_alias_ty.def_id).instantiate(self.tcx, shifted_alias_ty.args);
-
- self.predicates.push(ty::Clause::from_projection_clause(self.tcx, ty::Binder::bind_with_vars(
- ty::ProjectionPredicate { projection_ty: shifted_alias_ty, term: default_ty.into() },
- self.bound_vars,
- )));
+ let default_ty = self
+ .tcx
+ .type_of(shifted_alias_ty.def_id)
+ .instantiate(self.tcx, shifted_alias_ty.args);
+
+ self.predicates.push(
+ ty::Binder::bind_with_vars(
+ ty::ProjectionPredicate {
+ projection_ty: shifted_alias_ty,
+ term: default_ty.into(),
+ },
+ self.bound_vars,
+ )
+ .to_predicate(self.tcx),
+ );
// We walk the *un-shifted* alias ty, because we're tracking the de bruijn
// binder depth, and if we were to walk `shifted_alias_ty` instead, we'd