Introduce GeneratorWitnessMIR.

This commit is contained in:
Camille GILLOT 2022-10-01 14:56:24 +02:00
parent 03618d6afd
commit 1974b6b68d
52 changed files with 265 additions and 72 deletions

View File

@ -414,6 +414,7 @@ fn push_debuginfo_type_name<'tcx>(
| ty::Placeholder(..)
| ty::Alias(..)
| ty::Bound(..)
| ty::GeneratorWitnessMIR(..)
| ty::GeneratorWitness(..) => {
bug!(
"debuginfo: Trying to create type name for \

View File

@ -151,7 +151,7 @@ pub(crate) fn const_to_valtree_inner<'tcx>(
// FIXME(oli-obk): we can probably encode closures just like structs
| ty::Closure(..)
| ty::Generator(..)
| ty::GeneratorWitness(..) => Err(ValTreeCreationError::NonSupportedType),
| ty::GeneratorWitness(..) |ty::GeneratorWitnessMIR(..)=> Err(ValTreeCreationError::NonSupportedType),
}
}
@ -314,6 +314,7 @@ pub fn valtree_to_const_value<'tcx>(
| ty::Closure(..)
| ty::Generator(..)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::FnPtr(_)
| ty::RawPtr(_)
| ty::Str

View File

@ -101,6 +101,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
| ty::Closure(_, _)
| ty::Generator(_, _, _)
| ty::GeneratorWitness(_)
| ty::GeneratorWitnessMIR(_, _)
| ty::Never
| ty::Tuple(_)
| ty::Error(_) => ConstValue::from_machine_usize(0u64, &tcx),

View File

@ -602,6 +602,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
| ty::Bound(..)
| ty::Param(..)
| ty::Alias(..)
| ty::GeneratorWitnessMIR(..)
| ty::GeneratorWitness(..) => bug!("Encountered invalid type {:?}", ty),
}
}

View File

@ -64,6 +64,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
ty::Foreign(def_id) => self.print_def_path(def_id, &[]),
ty::GeneratorWitness(_) => bug!("type_name: unexpected `GeneratorWitness`"),
ty::GeneratorWitnessMIR(..) => bug!("type_name: unexpected `GeneratorWitnessMIR`"),
}
}

View File

@ -240,6 +240,7 @@ impl<'tcx> InherentCollect<'tcx> {
| ty::Closure(..)
| ty::Generator(..)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::Bound(..)
| ty::Placeholder(_)
| ty::Infer(_) => {

View File

@ -295,12 +295,12 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
// types, where we use Error as the Self type
}
ty::Placeholder(..) | ty::GeneratorWitness(..) | ty::Bound(..) | ty::Infer(..) => {
bug!(
"unexpected type encountered in \
variance inference: {}",
ty
);
ty::Placeholder(..)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::Bound(..)
| ty::Infer(..) => {
bug!("unexpected type encountered in variance inference: {}", ty);
}
}
}

View File

@ -130,6 +130,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
| ty::Float(_)
| ty::Array(..)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::RawPtr(_)
| ty::Ref(..)
| ty::FnDef(..)

View File

@ -435,6 +435,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
ty::Closure(..)
| ty::Generator(..)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::Bool
| ty::Char
| ty::Int(..)

View File

@ -209,6 +209,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
| ty::Foreign(..)
| ty::Param(..)
| ty::Closure(..)
| ty::GeneratorWitnessMIR(..)
| ty::GeneratorWitness(..) => t.super_fold_with(self),
ty::Placeholder(..) | ty::Bound(..) => bug!("unexpected type {:?}", t),

View File

@ -112,7 +112,7 @@ fn compute_components<'tcx>(
}
// All regions are bound inside a witness
ty::GeneratorWitness(..) => (),
ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => (),
// OutlivesTypeParameterEnv -- the actual checking that `X:'a`
// is implied by the environment is done in regionck.

View File

@ -1107,6 +1107,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
| ty::Closure(..)
| ty::Generator(..)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::Placeholder(..)
| ty::FnDef(..) => bug!("unexpected type in foreign function: {:?}", ty),
}

View File

@ -1306,6 +1306,7 @@ impl<'tcx> TyCtxt<'tcx> {
Placeholder,
Generator,
GeneratorWitness,
GeneratorWitnessMIR,
Dynamic,
Closure,
Tuple,
@ -1815,6 +1816,11 @@ impl<'tcx> TyCtxt<'tcx> {
self.mk_mut_ref(self.lifetimes.re_erased, context_ty)
}
#[inline]
pub fn mk_generator_witness_mir(self, id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
self.mk_ty(GeneratorWitnessMIR(id, substs))
}
#[inline]
pub fn mk_ty_var(self, v: TyVid) -> Ty<'tcx> {
self.mk_ty_infer(TyVar(v))

View File

@ -325,7 +325,8 @@ impl<'tcx> Ty<'tcx> {
ty::Dynamic(..) => "trait object".into(),
ty::Closure(..) => "closure".into(),
ty::Generator(def_id, ..) => tcx.generator_kind(def_id).unwrap().descr().into(),
ty::GeneratorWitness(..) => "generator witness".into(),
ty::GeneratorWitness(..) |
ty::GeneratorWitnessMIR(..) => "generator witness".into(),
ty::Tuple(..) => "tuple".into(),
ty::Infer(ty::TyVar(_)) => "inferred type".into(),
ty::Infer(ty::IntVar(_)) => "integer".into(),
@ -373,7 +374,7 @@ impl<'tcx> Ty<'tcx> {
ty::Dynamic(..) => "trait object".into(),
ty::Closure(..) => "closure".into(),
ty::Generator(def_id, ..) => tcx.generator_kind(def_id).unwrap().descr().into(),
ty::GeneratorWitness(..) => "generator witness".into(),
ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => "generator witness".into(),
ty::Tuple(..) => "tuple".into(),
ty::Placeholder(..) => "higher-ranked type".into(),
ty::Bound(..) => "bound type variable".into(),

View File

@ -32,6 +32,7 @@ pub enum SimplifiedType {
ClosureSimplifiedType(DefId),
GeneratorSimplifiedType(DefId),
GeneratorWitnessSimplifiedType(usize),
GeneratorWitnessMIRSimplifiedType(DefId),
FunctionSimplifiedType(usize),
PlaceholderSimplifiedType,
}
@ -108,6 +109,7 @@ pub fn simplify_type<'tcx>(
ty::FnDef(def_id, _) | ty::Closure(def_id, _) => Some(ClosureSimplifiedType(def_id)),
ty::Generator(def_id, _, _) => Some(GeneratorSimplifiedType(def_id)),
ty::GeneratorWitness(tys) => Some(GeneratorWitnessSimplifiedType(tys.skip_binder().len())),
ty::GeneratorWitnessMIR(def_id, _) => Some(GeneratorWitnessMIRSimplifiedType(def_id)),
ty::Never => Some(NeverSimplifiedType),
ty::Tuple(tys) => Some(TupleSimplifiedType(tys.len())),
ty::FnPtr(f) => Some(FunctionSimplifiedType(f.skip_binder().inputs().len())),
@ -139,7 +141,8 @@ impl SimplifiedType {
| ForeignSimplifiedType(d)
| TraitSimplifiedType(d)
| ClosureSimplifiedType(d)
| GeneratorSimplifiedType(d) => Some(d),
| GeneratorSimplifiedType(d)
| GeneratorWitnessMIRSimplifiedType(d) => Some(d),
_ => None,
}
}
@ -208,6 +211,7 @@ impl DeepRejectCtxt {
| ty::Closure(..)
| ty::Generator(..)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::Placeholder(..)
| ty::Bound(..)
| ty::Infer(_) => bug!("unexpected impl_ty: {impl_ty}"),
@ -306,7 +310,7 @@ impl DeepRejectCtxt {
ty::Error(_) => true,
ty::GeneratorWitness(..) | ty::Bound(..) => {
ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) | ty::Bound(..) => {
bug!("unexpected obligation type: {:?}", obligation_ty)
}
}

View File

@ -125,6 +125,16 @@ impl FlagComputation {
self.bound_computation(ts, |flags, ts| flags.add_tys(ts));
}
&ty::GeneratorWitnessMIR(_, ref substs) => {
let should_remove_further_specializable =
!self.flags.contains(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
self.add_substs(substs);
if should_remove_further_specializable {
self.flags -= TypeFlags::STILL_FURTHER_SPECIALIZABLE;
}
self.add_flags(TypeFlags::HAS_TY_GENERATOR);
}
&ty::Closure(_, substs) => {
let substs = substs.as_closure();
let should_remove_further_specializable =

View File

@ -645,6 +645,7 @@ where
| ty::Never
| ty::FnDef(..)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::Foreign(..)
| ty::Dynamic(_, _, ty::Dyn) => {
bug!("TyAndLayout::field({:?}): not applicable", this)

View File

@ -3,6 +3,7 @@ use crate::ty::fold::{TypeFolder, TypeSuperFoldable};
use crate::ty::subst::{GenericArg, GenericArgKind};
use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc_data_structures::fx::FxHashMap;
use rustc_span::def_id::DefId;
use rustc_span::Span;
/// Converts generic params of a TypeFoldable from one
@ -47,6 +48,47 @@ impl<'tcx> ReverseMapper<'tcx> {
assert!(!self.do_not_error);
kind.fold_with(self)
}
fn fold_closure_substs(
&mut self,
def_id: DefId,
substs: ty::SubstsRef<'tcx>,
) -> ty::SubstsRef<'tcx> {
// I am a horrible monster and I pray for death. When
// we encounter a closure here, it is always a closure
// from within the function that we are currently
// type-checking -- one that is now being encapsulated
// in an opaque type. Ideally, we would
// go through the types/lifetimes that it references
// and treat them just like we would any other type,
// which means we would error out if we find any
// reference to a type/region that is not in the
// "reverse map".
//
// **However,** in the case of closures, there is a
// somewhat subtle (read: hacky) consideration. The
// problem is that our closure types currently include
// all the lifetime parameters declared on the
// enclosing function, even if they are unused by the
// closure itself. We can't readily filter them out,
// so here we replace those values with `'empty`. This
// can't really make a difference to the rest of the
// compiler; those regions are ignored for the
// outlives relation, and hence don't affect trait
// selection or auto traits, and they are erased
// during codegen.
let generics = self.tcx.generics_of(def_id);
self.tcx.mk_substs(substs.iter().enumerate().map(|(index, kind)| {
if index < generics.parent_count {
// Accommodate missing regions in the parent kinds...
self.fold_kind_no_missing_regions_error(kind)
} else {
// ...but not elsewhere.
self.fold_kind_normally(kind)
}
}))
}
}
impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
@ -104,59 +146,20 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
match *ty.kind() {
ty::Closure(def_id, substs) => {
// I am a horrible monster and I pray for death. When
// we encounter a closure here, it is always a closure
// from within the function that we are currently
// type-checking -- one that is now being encapsulated
// in an opaque type. Ideally, we would
// go through the types/lifetimes that it references
// and treat them just like we would any other type,
// which means we would error out if we find any
// reference to a type/region that is not in the
// "reverse map".
//
// **However,** in the case of closures, there is a
// somewhat subtle (read: hacky) consideration. The
// problem is that our closure types currently include
// all the lifetime parameters declared on the
// enclosing function, even if they are unused by the
// closure itself. We can't readily filter them out,
// so here we replace those values with `'empty`. This
// can't really make a difference to the rest of the
// compiler; those regions are ignored for the
// outlives relation, and hence don't affect trait
// selection or auto traits, and they are erased
// during codegen.
let generics = self.tcx.generics_of(def_id);
let substs = self.tcx.mk_substs(substs.iter().enumerate().map(|(index, kind)| {
if index < generics.parent_count {
// Accommodate missing regions in the parent kinds...
self.fold_kind_no_missing_regions_error(kind)
} else {
// ...but not elsewhere.
self.fold_kind_normally(kind)
}
}));
let substs = self.fold_closure_substs(def_id, substs);
self.tcx.mk_closure(def_id, substs)
}
ty::Generator(def_id, substs, movability) => {
let generics = self.tcx.generics_of(def_id);
let substs = self.tcx.mk_substs(substs.iter().enumerate().map(|(index, kind)| {
if index < generics.parent_count {
// Accommodate missing regions in the parent kinds...
self.fold_kind_no_missing_regions_error(kind)
} else {
// ...but not elsewhere.
self.fold_kind_normally(kind)
}
}));
let substs = self.fold_closure_substs(def_id, substs);
self.tcx.mk_generator(def_id, substs, movability)
}
ty::GeneratorWitnessMIR(def_id, substs) => {
let substs = self.fold_closure_substs(def_id, substs);
self.tcx.mk_generator_witness_mir(def_id, substs)
}
ty::Param(param) => {
// Look it up in the substitution list.
match self.map.get(&ty.into()).map(|k| k.unpack()) {

View File

@ -265,6 +265,7 @@ fn characteristic_def_id_of_type_cached<'a>(
ty::FnDef(def_id, _)
| ty::Closure(def_id, _)
| ty::Generator(def_id, _, _)
| ty::GeneratorWitnessMIR(def_id, _)
| ty::Foreign(def_id) => Some(def_id),
ty::Bool

View File

@ -811,6 +811,28 @@ pub trait PrettyPrinter<'tcx>:
ty::GeneratorWitness(types) => {
p!(in_binder(&types));
}
ty::GeneratorWitnessMIR(did, substs) => {
p!(write("["));
if !self.tcx().sess.verbose() {
p!("generator witness");
// FIXME(eddyb) should use `def_span`.
if let Some(did) = did.as_local() {
let span = self.tcx().def_span(did);
p!(write(
"@{}",
// This may end up in stderr diagnostics but it may also be emitted
// into MIR. Hence we use the remapped path if available
self.tcx().sess.source_map().span_to_embeddable_string(span)
));
} else {
p!(write("@"), print_def_path(did, substs));
}
} else {
p!(print_def_path(did, substs));
}
p!("]")
}
ty::Closure(did, substs) => {
p!(write("["));
if !self.should_print_verbose() {

View File

@ -473,6 +473,16 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
Ok(tcx.mk_generator_witness(types))
}
(&ty::GeneratorWitnessMIR(a_id, a_substs), &ty::GeneratorWitnessMIR(b_id, b_substs))
if a_id == b_id =>
{
// All GeneratorWitness types with the same id represent
// the (anonymous) type of the same generator expression. So
// all of their regions should be equated.
let substs = relation.relate(a_substs, b_substs)?;
Ok(tcx.mk_generator_witness_mir(a_id, substs))
}
(&ty::Closure(a_id, a_substs), &ty::Closure(b_id, b_substs)) if a_id == b_id => {
// All Closure types with the same id represent
// the (anonymous) type of the same closure expression. So

View File

@ -656,6 +656,9 @@ impl<'tcx> TypeSuperFoldable<'tcx> for Ty<'tcx> {
ty::Generator(did, substs.try_fold_with(folder)?, movability)
}
ty::GeneratorWitness(types) => ty::GeneratorWitness(types.try_fold_with(folder)?),
ty::GeneratorWitnessMIR(did, substs) => {
ty::GeneratorWitnessMIR(did, substs.try_fold_with(folder)?)
}
ty::Closure(did, substs) => ty::Closure(did, substs.try_fold_with(folder)?),
ty::Alias(kind, data) => ty::Alias(kind, data.try_fold_with(folder)?),
@ -701,6 +704,7 @@ impl<'tcx> TypeSuperVisitable<'tcx> for Ty<'tcx> {
}
ty::Generator(_did, ref substs, _) => substs.visit_with(visitor),
ty::GeneratorWitness(ref types) => types.visit_with(visitor),
ty::GeneratorWitnessMIR(_did, ref substs) => substs.visit_with(visitor),
ty::Closure(_did, ref substs) => substs.visit_with(visitor),
ty::Alias(_, ref data) => data.visit_with(visitor),

View File

@ -2175,6 +2175,7 @@ impl<'tcx> Ty<'tcx> {
| ty::Dynamic(..)
| ty::Closure(..)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::Never
| ty::Tuple(_)
| ty::Error(_)
@ -2210,6 +2211,7 @@ impl<'tcx> Ty<'tcx> {
| ty::Ref(..)
| ty::Generator(..)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::Array(..)
| ty::Closure(..)
| ty::Never
@ -2296,6 +2298,7 @@ impl<'tcx> Ty<'tcx> {
| ty::Ref(..)
| ty::Generator(..)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::Array(..)
| ty::Closure(..)
| ty::Never
@ -2360,7 +2363,7 @@ impl<'tcx> Ty<'tcx> {
// anything with custom metadata it might be more complicated.
ty::Ref(_, _, hir::Mutability::Not) | ty::RawPtr(..) => false,
ty::Generator(..) | ty::GeneratorWitness(..) => false,
ty::Generator(..) | ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => false,
// Might be, but not "trivial" so just giving the safe answer.
ty::Adt(..) | ty::Closure(..) => false,

View File

@ -896,6 +896,7 @@ impl<'tcx> Ty<'tcx> {
| ty::Foreign(_)
| ty::Generator(..)
| ty::GeneratorWitness(_)
| ty::GeneratorWitnessMIR(..)
| ty::Infer(_)
| ty::Alias(..)
| ty::Param(_)
@ -935,6 +936,7 @@ impl<'tcx> Ty<'tcx> {
| ty::Foreign(_)
| ty::Generator(..)
| ty::GeneratorWitness(_)
| ty::GeneratorWitnessMIR(..)
| ty::Infer(_)
| ty::Alias(..)
| ty::Param(_)
@ -1062,7 +1064,10 @@ impl<'tcx> Ty<'tcx> {
false
}
ty::Foreign(_) | ty::GeneratorWitness(..) | ty::Error(_) => false,
ty::Foreign(_)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::Error(_) => false,
}
}
@ -1158,6 +1163,7 @@ pub fn needs_drop_components<'tcx>(
| ty::FnPtr(_)
| ty::Char
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::RawPtr(_)
| ty::Ref(..)
| ty::Str => Ok(SmallVec::new()),
@ -1228,7 +1234,11 @@ pub fn is_trivially_const_drop(ty: Ty<'_>) -> bool {
// Not trivial because they have components, and instead of looking inside,
// we'll just perform trait selection.
ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(_) | ty::Adt(..) => false,
ty::Closure(..)
| ty::Generator(..)
| ty::GeneratorWitness(_)
| ty::GeneratorWitnessMIR(..)
| ty::Adt(..) => false,
ty::Array(ty, _) | ty::Slice(ty) => is_trivially_const_drop(ty),

View File

@ -100,6 +100,9 @@ pub trait TypeVisitable<'tcx>: fmt::Debug + Clone {
fn has_opaque_types(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_OPAQUE)
}
fn has_generators(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_GENERATOR)
}
fn references_error(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_ERROR)
}

View File

@ -190,6 +190,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
ty::Adt(_, substs)
| ty::Closure(_, substs)
| ty::Generator(_, substs, _)
| ty::GeneratorWitnessMIR(_, substs)
| ty::FnDef(_, substs) => {
stack.extend(substs.iter().rev());
}

View File

@ -271,7 +271,8 @@ where
| ty::FnPtr(..)
| ty::Param(..)
| ty::Error(_)
| ty::GeneratorWitness(..) => {}
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..) => {}
ty::Bound(..) | ty::Placeholder(..) | ty::Infer(..) => {
bug!("unexpected type: {:?}", ty)
}

View File

@ -640,6 +640,7 @@ fn encode_ty<'tcx>(
ty::Bound(..)
| ty::Error(..)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::Infer(..)
| ty::Alias(..)
| ty::Param(..)
@ -793,6 +794,7 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
ty::Bound(..)
| ty::Error(..)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::Infer(..)
| ty::Alias(..)
| ty::Param(..)

View File

@ -490,6 +490,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
}
ty::GeneratorWitness(_) => bug!("symbol_names: unexpected `GeneratorWitness`"),
ty::GeneratorWitnessMIR(..) => bug!("symbol_names: unexpected `GeneratorWitnessMIR`"),
}
// Only cache types that do not refer to an enclosing

View File

@ -331,6 +331,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
| ty::Closure(..)
| ty::Generator(..)
| ty::GeneratorWitness(_)
| ty::GeneratorWitnessMIR(..)
| ty::Never
| ty::Tuple(_)
| ty::Param(_)
@ -382,6 +383,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
| ty::Closure(..)
| ty::Generator(..)
| ty::GeneratorWitness(_)
| ty::GeneratorWitnessMIR(..)
| ty::Never
| ty::Tuple(_)
| ty::Param(_)

View File

@ -414,6 +414,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
| ty::Infer(ty::IntVar(..) | ty::FloatVar(..))
| ty::Generator(..)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::Never
| ty::Foreign(..) => tcx.types.unit,

View File

@ -57,6 +57,8 @@ pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
Ok(infcx.replace_bound_vars_with_placeholders(types).to_vec())
}
ty::GeneratorWitnessMIR(..) => todo!(),
// For `PhantomData<T>`, we pass `T`.
ty::Adt(def, substs) if def.is_phantom_data() => Ok(vec![substs.type_at(0)]),
@ -88,6 +90,7 @@ pub(super) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
| ty::Ref(..)
| ty::Generator(..)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::Array(..)
| ty::Closure(..)
| ty::Never
@ -173,6 +176,8 @@ pub(super) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
ty::GeneratorWitness(types) => {
Ok(infcx.replace_bound_vars_with_placeholders(types).to_vec())
}
ty::GeneratorWitnessMIR(..) => todo!(),
}
}
@ -215,6 +220,7 @@ pub(crate) fn extract_tupled_inputs_and_output_from_callable<'tcx>(
| ty::Dynamic(_, _, _)
| ty::Generator(_, _, _)
| ty::GeneratorWitness(_)
| ty::GeneratorWitnessMIR(..)
| ty::Never
| ty::Tuple(_)
| ty::Alias(_, _)

View File

@ -696,7 +696,9 @@ impl<'tcx> TypeVisitor<'tcx> for OrphanChecker<'tcx> {
// This should only be created when checking whether we have to check whether some
// auto trait impl applies. There will never be multiple impls, so we can just
// act as if it were a local type here.
ty::GeneratorWitness(_) => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)),
ty::GeneratorWitness(_) | ty::GeneratorWitnessMIR(..) => {
ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty))
}
ty::Alias(ty::Opaque, ..) => {
// This merits some explanation.
// Normally, opaque types are not involved when performing

View File

@ -1919,6 +1919,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
ty::Generator(..) => Some(16),
ty::Foreign(..) => Some(17),
ty::GeneratorWitness(..) => Some(18),
ty::GeneratorWitnessMIR(..) => Some(19),
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error(_) => None,
}
}

View File

@ -1605,6 +1605,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
| ty::Closure(..)
| ty::Generator(..)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::Never
| ty::Tuple(..)
// Integers and floats always have `u8` as their discriminant.
@ -1654,6 +1655,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
| ty::Closure(..)
| ty::Generator(..)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::Never
// Extern types have unit metadata, according to RFC 2850
| ty::Foreign(_)

View File

@ -31,6 +31,7 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
| ty::FnPtr(_)
| ty::Char
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::RawPtr(_)
| ty::Ref(..)
| ty::Str

View File

@ -765,7 +765,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| ty::Closure(..)
| ty::Generator(..)
| ty::Tuple(_)
| ty::GeneratorWitness(_) => {
| ty::GeneratorWitness(_)
| ty::GeneratorWitnessMIR(..) => {
// These are built-in, and cannot have a custom `impl const Destruct`.
candidates.vec.push(ConstDestructCandidate(None));
}
@ -826,6 +827,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| ty::Closure(_, _)
| ty::Generator(_, _, _)
| ty::GeneratorWitness(_)
| ty::GeneratorWitnessMIR(..)
| ty::Never
| ty::Alias(..)
| ty::Param(_)

View File

@ -1285,6 +1285,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty::GeneratorWitness(tys) => {
stack.extend(tcx.erase_late_bound_regions(tys).to_vec());
}
ty::GeneratorWitnessMIR(..) => {
todo!()
}
// If we have a projection type, make sure to normalize it so we replace it
// with a fresh infer variable

View File

@ -2066,6 +2066,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| ty::Ref(..)
| ty::Generator(..)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::Array(..)
| ty::Closure(..)
| ty::Never
@ -2182,6 +2183,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
Where(ty::Binder::bind_with_vars(witness_tys.to_vec(), all_vars))
}
ty::GeneratorWitnessMIR(..) => {
todo!()
}
ty::Closure(_, substs) => {
// (*) binder moved here
let ty = self.infcx.shallow_resolve(substs.as_closure().tupled_upvars_ty());
@ -2279,6 +2284,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
types.map_bound(|types| types.to_vec())
}
ty::GeneratorWitnessMIR(..) => {
todo!()
}
// For `PhantomData<T>`, we pass `T`.
ty::Adt(def, substs) if def.is_phantom_data() => t.rebind(substs.types().collect()),

View File

@ -101,7 +101,7 @@ impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> {
ty::Closure(..) => {
return ControlFlow::Break(ty);
}
ty::Generator(..) | ty::GeneratorWitness(..) => {
ty::Generator(..) | ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => {
return ControlFlow::Break(ty);
}
ty::FnDef(..) => {

View File

@ -551,6 +551,7 @@ impl<'tcx> WfPredicates<'tcx> {
| ty::Error(_)
| ty::Str
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::Never
| ty::Param(_)
| ty::Bound(..)

View File

@ -343,6 +343,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
substs.lower_into(interner),
),
ty::GeneratorWitness(_) => unimplemented!(),
ty::GeneratorWitnessMIR(..) => unimplemented!(),
ty::Never => chalk_ir::TyKind::Never,
ty::Tuple(types) => {
chalk_ir::TyKind::Tuple(types.len(), types.as_substs().lower_into(interner))

View File

@ -164,7 +164,8 @@ fn dtorck_constraint_for_ty<'tcx>(
| ty::Ref(..)
| ty::FnDef(..)
| ty::FnPtr(_)
| ty::GeneratorWitness(..) => {
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..) => {
// these types never have a destructor
}

View File

@ -470,7 +470,10 @@ fn layout_of_uncached<'tcx>(
return Err(LayoutError::Unknown(ty));
}
ty::Placeholder(..) | ty::GeneratorWitness(..) | ty::Infer(_) => {
ty::Placeholder(..)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::Infer(_) => {
bug!("Layout::compute: unexpected type `{}`", ty)
}

View File

@ -16,7 +16,13 @@ fn sized_constraint_for_ty<'tcx>(
Bool | Char | Int(..) | Uint(..) | Float(..) | RawPtr(..) | Ref(..) | FnDef(..)
| FnPtr(_) | Array(..) | Closure(..) | Generator(..) | Never => vec![],
Str | Dynamic(..) | Slice(_) | Foreign(..) | Error(_) | GeneratorWitness(..) => {
Str
| Dynamic(..)
| Slice(_)
| Foreign(..)
| Error(_)
| GeneratorWitness(..)
| GeneratorWitnessMIR(..) => {
// these are never sized - return the target type
vec![ty]
}

View File

@ -265,6 +265,9 @@ bitflags! {
/// Does this value have `InferConst::Fresh`?
const HAS_CT_FRESH = 1 << 21;
/// Does this have `Generator` or `GeneratorWitness`?
const HAS_TY_GENERATOR = 1 << 22;
}
}

View File

@ -160,6 +160,32 @@ pub enum TyKind<I: Interner> {
/// ```
GeneratorWitness(I::BinderListTy),
/// A type representing the types stored inside a generator.
/// This should only appear as part of the `GeneratorSubsts`.
///
/// Unlike upvars, the witness can reference lifetimes from
/// inside of the generator itself. To deal with them in
/// the type of the generator, we convert them to higher ranked
/// lifetimes bound by the witness itself.
///
/// This variant is only using when `drop_tracking_mir` is set.
/// This contains the `DefId` and the `SubstRef` of the generator.
/// The actual witness types are computed on MIR by the `mir_generator_info` query.
///
/// Looking at the following example, the witness for this generator
/// may end up as something like `for<'a> [Vec<i32>, &'a Vec<i32>]`:
///
/// ```ignore UNSOLVED (ask @compiler-errors, should this error? can we just swap the yields?)
/// #![feature(generators)]
/// |a| {
/// let x = &vec![3];
/// yield a;
/// yield x[0];
/// }
/// # ;
/// ```
GeneratorWitnessMIR(I::DefId, I::SubstsRef),
/// The never type `!`.
Never,
@ -241,6 +267,7 @@ const fn tykind_discriminant<I: Interner>(value: &TyKind<I>) -> usize {
Placeholder(_) => 23,
Infer(_) => 24,
Error(_) => 25,
GeneratorWitnessMIR(_, _) => 26,
}
}
@ -266,6 +293,7 @@ impl<I: Interner> Clone for TyKind<I> {
Closure(d, s) => Closure(d.clone(), s.clone()),
Generator(d, s, m) => Generator(d.clone(), s.clone(), m.clone()),
GeneratorWitness(g) => GeneratorWitness(g.clone()),
GeneratorWitnessMIR(d, s) => GeneratorWitnessMIR(d.clone(), s.clone()),
Never => Never,
Tuple(t) => Tuple(t.clone()),
Alias(k, p) => Alias(*k, p.clone()),
@ -303,6 +331,10 @@ impl<I: Interner> PartialEq for TyKind<I> {
a_d == b_d && a_s == b_s && a_m == b_m
}
(GeneratorWitness(a_g), GeneratorWitness(b_g)) => a_g == b_g,
(
&GeneratorWitnessMIR(ref a_d, ref a_s),
&GeneratorWitnessMIR(ref b_d, ref b_s),
) => a_d == b_d && a_s == b_s,
(Tuple(a_t), Tuple(b_t)) => a_t == b_t,
(Alias(a_i, a_p), Alias(b_i, b_p)) => a_i == b_i && a_p == b_p,
(Param(a_p), Param(b_p)) => a_p == b_p,
@ -360,6 +392,13 @@ impl<I: Interner> Ord for TyKind<I> {
a_d.cmp(b_d).then_with(|| a_s.cmp(b_s).then_with(|| a_m.cmp(b_m)))
}
(GeneratorWitness(a_g), GeneratorWitness(b_g)) => a_g.cmp(b_g),
(
&GeneratorWitnessMIR(ref a_d, ref a_s),
&GeneratorWitnessMIR(ref b_d, ref b_s),
) => match Ord::cmp(a_d, b_d) {
Ordering::Equal => Ord::cmp(a_s, b_s),
cmp => cmp,
},
(Tuple(a_t), Tuple(b_t)) => a_t.cmp(b_t),
(Alias(a_i, a_p), Alias(b_i, b_p)) => a_i.cmp(b_i).then_with(|| a_p.cmp(b_p)),
(Param(a_p), Param(b_p)) => a_p.cmp(b_p),
@ -421,6 +460,10 @@ impl<I: Interner> hash::Hash for TyKind<I> {
m.hash(state)
}
GeneratorWitness(g) => g.hash(state),
GeneratorWitnessMIR(d, s) => {
d.hash(state);
s.hash(state);
}
Tuple(t) => t.hash(state),
Alias(i, p) => {
i.hash(state);
@ -461,6 +504,7 @@ impl<I: Interner> fmt::Debug for TyKind<I> {
Closure(d, s) => f.debug_tuple_field2_finish("Closure", d, s),
Generator(d, s, m) => f.debug_tuple_field3_finish("Generator", d, s, m),
GeneratorWitness(g) => f.debug_tuple_field1_finish("GeneratorWitness", g),
GeneratorWitnessMIR(d, s) => f.debug_tuple_field2_finish("GeneratorWitnessMIR", d, s),
Never => f.write_str("Never"),
Tuple(t) => f.debug_tuple_field1_finish("Tuple", t),
Alias(i, a) => f.debug_tuple_field2_finish("Alias", i, a),
@ -559,6 +603,10 @@ where
GeneratorWitness(b) => e.emit_enum_variant(disc, |e| {
b.encode(e);
}),
GeneratorWitnessMIR(def_id, substs) => e.emit_enum_variant(disc, |e| {
def_id.encode(e);
substs.encode(e);
}),
Never => e.emit_enum_variant(disc, |_| {}),
Tuple(substs) => e.emit_enum_variant(disc, |e| {
substs.encode(e);
@ -641,6 +689,7 @@ where
23 => Placeholder(Decodable::decode(d)),
24 => Infer(Decodable::decode(d)),
25 => Error(Decodable::decode(d)),
26 => GeneratorWitnessMIR(Decodable::decode(d), Decodable::decode(d)),
_ => panic!(
"{}",
format!(
@ -742,6 +791,10 @@ where
GeneratorWitness(b) => {
b.hash_stable(__hcx, __hasher);
}
GeneratorWitnessMIR(def_id, substs) => {
def_id.hash_stable(__hcx, __hasher);
substs.hash_stable(__hcx, __hasher);
}
Never => {}
Tuple(substs) => {
substs.hash_stable(__hcx, __hasher);

View File

@ -1855,6 +1855,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
ty::Bound(..) => panic!("Bound"),
ty::Placeholder(..) => panic!("Placeholder"),
ty::GeneratorWitness(..) => panic!("GeneratorWitness"),
ty::GeneratorWitnessMIR(..) => panic!("GeneratorWitnessMIR"),
ty::Infer(..) => panic!("Infer"),
ty::Error(_) => rustc_errors::FatalError.raise(),
}

View File

@ -542,6 +542,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
| ty::Closure(..)
| ty::Generator(..)
| ty::GeneratorWitness(_)
| ty::GeneratorWitnessMIR(..)
| ty::Dynamic(..)
| ty::Param(_)
| ty::Bound(..)

View File

@ -1419,6 +1419,7 @@ fn ty_auto_deref_stability<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, precedenc
| ty::FnDef(..)
| ty::Generator(..)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::Closure(..)
| ty::Never
| ty::Tuple(_)

View File

@ -1,10 +1,10 @@
error: symbol-name(_ZN5basic4main17hcbad207c0eeb0b3bE)
error: symbol-name(_ZN5basic4main17he9f658e438f1cac0E)
--> $DIR/basic.rs:8:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: demangling(basic::main::hcbad207c0eeb0b3b)
error: demangling(basic::main::he9f658e438f1cac0)
--> $DIR/basic.rs:8:1
|
LL | #[rustc_symbol_name]

View File

@ -1,10 +1,10 @@
error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17h2f2efcf580c9b1eeE)
error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17h13209029be24b923E)
--> $DIR/issue-60925.rs:21:9
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: demangling(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo::h2f2efcf580c9b1ee)
error: demangling(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo::h13209029be24b923)
--> $DIR/issue-60925.rs:21:9
|
LL | #[rustc_symbol_name]