Skip to content

Commit cdb1f13

Browse files
Fix projection types when checking generator auto-traits
1 parent 427eba2 commit cdb1f13

File tree

18 files changed

+353
-140
lines changed

18 files changed

+353
-140
lines changed

compiler/rustc_middle/src/ty/codec.rs

+12
Original file line numberDiff line numberDiff line change
@@ -381,9 +381,19 @@ impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<ty::BoundVaria
381381
}
382382
}
383383

384+
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<ty::ProjectionPredicate<'tcx>> {
385+
fn decode(decoder: &mut D) -> &'tcx Self {
386+
let len = decoder.read_usize();
387+
decoder.tcx().mk_projection_predicates(
388+
(0..len).map::<ty::ProjectionPredicate<'tcx>, _>(|_| Decodable::decode(decoder)),
389+
)
390+
}
391+
}
392+
384393
impl_decodable_via_ref! {
385394
&'tcx ty::TypeckResults<'tcx>,
386395
&'tcx ty::List<Ty<'tcx>>,
396+
&'tcx ty::List<ty::ProjectionPredicate<'tcx>>,
387397
&'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
388398
&'tcx Allocation,
389399
&'tcx mir::Body<'tcx>,
@@ -504,6 +514,8 @@ macro_rules! impl_binder_encode_decode {
504514

505515
impl_binder_encode_decode! {
506516
&'tcx ty::List<Ty<'tcx>>,
517+
&'tcx ty::List<ty::ProjectionPredicate<'tcx>>,
518+
ty::GeneratorWitnessInner<'tcx>,
507519
ty::FnSig<'tcx>,
508520
ty::ExistentialPredicate<'tcx>,
509521
ty::TraitRef<'tcx>,

compiler/rustc_middle/src/ty/context.rs

+33-5
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ use crate::ty::TyKind::*;
1717
use crate::ty::{
1818
self, AdtDef, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
1919
ClosureSizeProfileData, Const, ConstVid, DefIdTree, ExistentialPredicate, FloatTy, FloatVar,
20-
FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List, ParamConst,
21-
ParamTy, PolyFnSig, Predicate, PredicateInner, PredicateKind, ProjectionTy, Region, RegionKind,
22-
ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
20+
FloatVid, GeneratorWitnessInner, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar,
21+
IntVid, List, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateInner, PredicateKind,
22+
ProjectionPredicate, ProjectionTy, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty,
23+
TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
2324
};
2425
use rustc_ast as ast;
2526
use rustc_attr as attr;
@@ -102,6 +103,7 @@ pub struct CtxtInterners<'tcx> {
102103
substs: InternedSet<'tcx, InternalSubsts<'tcx>>,
103104
canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>,
104105
region: InternedSet<'tcx, RegionKind>,
106+
projection_predicates: InternedSet<'tcx, List<ProjectionPredicate<'tcx>>>,
105107
poly_existential_predicates:
106108
InternedSet<'tcx, List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>>,
107109
predicate: InternedSet<'tcx, PredicateInner<'tcx>>,
@@ -129,6 +131,7 @@ impl<'tcx> CtxtInterners<'tcx> {
129131
type_list: Default::default(),
130132
substs: Default::default(),
131133
region: Default::default(),
134+
projection_predicates: Default::default(),
132135
poly_existential_predicates: Default::default(),
133136
canonical_var_infos: Default::default(),
134137
predicate: Default::default(),
@@ -1654,6 +1657,7 @@ nop_lift! {const_allocation; &'a Allocation => &'tcx Allocation}
16541657
nop_lift! {predicate; &'a PredicateInner<'a> => &'tcx PredicateInner<'tcx>}
16551658

16561659
nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>}
1660+
nop_list_lift! {projection_predicates; ProjectionPredicate<'a> => ProjectionPredicate<'tcx>}
16571661
nop_list_lift! {poly_existential_predicates; ty::Binder<'a, ExistentialPredicate<'a>> => ty::Binder<'tcx, ExistentialPredicate<'tcx>>}
16581662
nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>}
16591663
nop_list_lift! {canonical_var_infos; CanonicalVarInfo<'a> => CanonicalVarInfo<'tcx>}
@@ -2115,6 +2119,7 @@ slice_interners!(
21152119
type_list: _intern_type_list(Ty<'tcx>),
21162120
substs: _intern_substs(GenericArg<'tcx>),
21172121
canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo<'tcx>),
2122+
projection_predicates: _intern_projection_predicates(ProjectionPredicate<'tcx>),
21182123
poly_existential_predicates:
21192124
_intern_poly_existential_predicates(ty::Binder<'tcx, ExistentialPredicate<'tcx>>),
21202125
predicates: _intern_predicates(Predicate<'tcx>),
@@ -2406,8 +2411,11 @@ impl<'tcx> TyCtxt<'tcx> {
24062411
}
24072412

24082413
#[inline]
2409-
pub fn mk_generator_witness(self, types: ty::Binder<'tcx, &'tcx List<Ty<'tcx>>>) -> Ty<'tcx> {
2410-
self.mk_ty(GeneratorWitness(types))
2414+
pub fn mk_generator_witness(
2415+
self,
2416+
inner: ty::Binder<'tcx, GeneratorWitnessInner<'tcx>>,
2417+
) -> Ty<'tcx> {
2418+
self.mk_ty(GeneratorWitness(inner))
24112419
}
24122420

24132421
#[inline]
@@ -2509,6 +2517,17 @@ impl<'tcx> TyCtxt<'tcx> {
25092517
Place { local: place.local, projection: self.intern_place_elems(&projection) }
25102518
}
25112519

2520+
pub fn intern_projection_predicates(
2521+
self,
2522+
predicates: &[ProjectionPredicate<'tcx>],
2523+
) -> &'tcx List<ProjectionPredicate<'tcx>> {
2524+
if predicates.is_empty() {
2525+
List::empty()
2526+
} else {
2527+
self._intern_projection_predicates(predicates)
2528+
}
2529+
}
2530+
25122531
pub fn intern_poly_existential_predicates(
25132532
self,
25142533
eps: &[ty::Binder<'tcx, ExistentialPredicate<'tcx>>],
@@ -2583,6 +2602,15 @@ impl<'tcx> TyCtxt<'tcx> {
25832602
})
25842603
}
25852604

2605+
pub fn mk_projection_predicates<
2606+
I: InternAs<[ProjectionPredicate<'tcx>], &'tcx List<ProjectionPredicate<'tcx>>>,
2607+
>(
2608+
self,
2609+
iter: I,
2610+
) -> I::Output {
2611+
iter.intern_with(|xs| self.intern_projection_predicates(xs))
2612+
}
2613+
25862614
pub fn mk_poly_existential_predicates<
25872615
I: InternAs<
25882616
[ty::Binder<'tcx, ExistentialPredicate<'tcx>>],

compiler/rustc_middle/src/ty/fast_reject.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ pub fn simplify_type(
118118
}
119119
ty::FnDef(def_id, _) | ty::Closure(def_id, _) => Some(ClosureSimplifiedType(def_id)),
120120
ty::Generator(def_id, _, _) => Some(GeneratorSimplifiedType(def_id)),
121-
ty::GeneratorWitness(ref tys) => {
122-
Some(GeneratorWitnessSimplifiedType(tys.skip_binder().len()))
121+
ty::GeneratorWitness(ref inner, ..) => {
122+
Some(GeneratorWitnessSimplifiedType(inner.as_ref().skip_binder().tys.len()))
123123
}
124124
ty::Never => Some(NeverSimplifiedType),
125125
ty::Tuple(ref tys) => Some(TupleSimplifiedType(tys.len())),

compiler/rustc_middle/src/ty/flags.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,13 @@ impl FlagComputation {
117117
self.add_ty(substs.tupled_upvars_ty());
118118
}
119119

120-
&ty::GeneratorWitness(ts) => {
121-
self.bound_computation(ts, |flags, ts| flags.add_tys(ts));
120+
&ty::GeneratorWitness(inner) => {
121+
self.bound_computation(inner, |computation, inner| {
122+
computation.add_tys(&inner.tys);
123+
for predicate in inner.structural_predicates {
124+
computation.add_predicate_atom(ty::PredicateKind::Projection(predicate));
125+
}
126+
});
122127
}
123128

124129
&ty::Closure(_, substs) => {

compiler/rustc_middle/src/ty/mod.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,10 @@ pub use self::sty::{
7575
Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVar, BoundVariableKind,
7676
CanonicalPolyFnSig, ClosureSubsts, ClosureSubstsParts, ConstVid, EarlyBoundRegion,
7777
ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FnSig, FreeRegion, GenSig,
78-
GeneratorSubsts, GeneratorSubstsParts, InlineConstSubsts, InlineConstSubstsParts, ParamConst,
79-
ParamTy, PolyExistentialProjection, PolyExistentialTraitRef, PolyFnSig, PolyGenSig,
80-
PolyTraitRef, ProjectionTy, Region, RegionKind, RegionVid, TraitRef, TyKind, TypeAndMut,
81-
UpvarSubsts, VarianceDiagInfo,
78+
GeneratorSubsts, GeneratorSubstsParts, GeneratorWitnessInner, InlineConstSubsts,
79+
InlineConstSubstsParts, ParamConst, ParamTy, PolyExistentialProjection,
80+
PolyExistentialTraitRef, PolyFnSig, PolyGenSig, PolyTraitRef, ProjectionTy, Region, RegionKind,
81+
RegionVid, TraitRef, TyKind, TypeAndMut, UpvarSubsts, VarianceDiagInfo,
8282
};
8383
pub use self::trait_def::TraitDef;
8484

@@ -871,7 +871,7 @@ impl<'tcx> Term<'tcx> {
871871
/// equality between arbitrary types. Processing an instance of
872872
/// Form #2 eventually yields one of these `ProjectionPredicate`
873873
/// instances to normalize the LHS.
874-
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
874+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
875875
#[derive(HashStable, TypeFoldable)]
876876
pub struct ProjectionPredicate<'tcx> {
877877
pub projection_ty: ProjectionTy<'tcx>,

compiler/rustc_middle/src/ty/print/pretty.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -698,8 +698,8 @@ pub trait PrettyPrinter<'tcx>:
698698

699699
p!("]")
700700
}
701-
ty::GeneratorWitness(types) => {
702-
p!(in_binder(&types));
701+
ty::GeneratorWitness(inner, ..) => {
702+
p!(in_binder(&inner.map_bound(|inner| inner.tys)));
703703
}
704704
ty::Closure(did, substs) => {
705705
p!(write("["));

compiler/rustc_middle/src/ty/relate.rs

+19-19
Original file line numberDiff line numberDiff line change
@@ -340,19 +340,25 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> {
340340
}
341341
}
342342

343-
#[derive(Copy, Debug, Clone, TypeFoldable)]
344-
struct GeneratorWitness<'tcx>(&'tcx ty::List<Ty<'tcx>>);
345-
346-
impl<'tcx> Relate<'tcx> for GeneratorWitness<'tcx> {
343+
impl<'tcx> Relate<'tcx> for ty::GeneratorWitnessInner<'tcx> {
347344
fn relate<R: TypeRelation<'tcx>>(
348345
relation: &mut R,
349-
a: GeneratorWitness<'tcx>,
350-
b: GeneratorWitness<'tcx>,
351-
) -> RelateResult<'tcx, GeneratorWitness<'tcx>> {
352-
assert_eq!(a.0.len(), b.0.len());
353-
let tcx = relation.tcx();
354-
let types = tcx.mk_type_list(iter::zip(a.0, b.0).map(|(a, b)| relation.relate(a, b)))?;
355-
Ok(GeneratorWitness(types))
346+
a: ty::GeneratorWitnessInner<'tcx>,
347+
b: ty::GeneratorWitnessInner<'tcx>,
348+
) -> RelateResult<'tcx, ty::GeneratorWitnessInner<'tcx>> {
349+
assert_eq!(a.tys.len(), b.tys.len());
350+
assert_eq!(a.structural_predicates.len(), b.structural_predicates.len());
351+
Ok(ty::GeneratorWitnessInner {
352+
tys: relation
353+
.tcx()
354+
.mk_type_list(a.tys.iter().zip(b.tys).map(|(a, b)| relation.relate(a, b)))?,
355+
structural_predicates: relation.tcx().mk_projection_predicates(
356+
a.structural_predicates
357+
.iter()
358+
.zip(b.structural_predicates)
359+
.map(|(a, b)| relation.relate(a, b)),
360+
)?,
361+
})
356362
}
357363
}
358364

@@ -434,14 +440,8 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
434440
Ok(tcx.mk_generator(a_id, substs, movability))
435441
}
436442

437-
(&ty::GeneratorWitness(a_types), &ty::GeneratorWitness(b_types)) => {
438-
// Wrap our types with a temporary GeneratorWitness struct
439-
// inside the binder so we can related them
440-
let a_types = a_types.map_bound(GeneratorWitness);
441-
let b_types = b_types.map_bound(GeneratorWitness);
442-
// Then remove the GeneratorWitness for the result
443-
let types = relation.relate(a_types, b_types)?.map_bound(|witness| witness.0);
444-
Ok(tcx.mk_generator_witness(types))
443+
(&ty::GeneratorWitness(a_interior), &ty::GeneratorWitness(b_interior)) => {
444+
Ok(tcx.mk_generator_witness(relation.relate(a_interior, b_interior)?))
445445
}
446446

447447
(&ty::Closure(a_id, a_substs), &ty::Closure(b_id, b_substs)) if a_id == b_id => {

compiler/rustc_middle/src/ty/structural_impls.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,19 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
908908
}
909909
}
910910

911+
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::ProjectionPredicate<'tcx>> {
912+
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
913+
self,
914+
folder: &mut F,
915+
) -> Result<Self, F::Error> {
916+
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projection_predicates(v))
917+
}
918+
919+
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
920+
self.iter().try_for_each(|t| t.visit_with(visitor))
921+
}
922+
}
923+
911924
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> {
912925
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
913926
self,
@@ -1007,7 +1020,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
10071020
ty::Generator(did, substs, movability) => {
10081021
ty::Generator(did, substs.try_fold_with(folder)?, movability)
10091022
}
1010-
ty::GeneratorWitness(types) => ty::GeneratorWitness(types.try_fold_with(folder)?),
1023+
ty::GeneratorWitness(inner) => ty::GeneratorWitness(inner.try_fold_with(folder)?),
10111024
ty::Closure(did, substs) => ty::Closure(did, substs.try_fold_with(folder)?),
10121025
ty::Projection(data) => ty::Projection(data.try_fold_with(folder)?),
10131026
ty::Opaque(did, substs) => ty::Opaque(did, substs.try_fold_with(folder)?),
@@ -1055,7 +1068,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
10551068
ty.visit_with(visitor)
10561069
}
10571070
ty::Generator(_did, ref substs, _) => substs.visit_with(visitor),
1058-
ty::GeneratorWitness(ref types) => types.visit_with(visitor),
1071+
ty::GeneratorWitness(ref inner, ..) => inner.visit_with(visitor),
10591072
ty::Closure(_did, ref substs) => substs.visit_with(visitor),
10601073
ty::Projection(ref data) => data.visit_with(visitor),
10611074
ty::Opaque(_, ref substs) => substs.visit_with(visitor),

compiler/rustc_middle/src/ty/sty.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,8 @@ pub enum TyKind<'tcx> {
159159
Generator(DefId, SubstsRef<'tcx>, hir::Movability),
160160

161161
/// A type representing the types stored inside a generator.
162-
/// This should only appear in GeneratorInteriors.
163-
GeneratorWitness(Binder<'tcx, &'tcx List<Ty<'tcx>>>),
162+
/// This should only appear inside of a generator's interior types.
163+
GeneratorWitness(Binder<'tcx, GeneratorWitnessInner<'tcx>>),
164164

165165
/// The never type `!`.
166166
Never,
@@ -2308,3 +2308,10 @@ impl<'tcx> VarianceDiagInfo<'tcx> {
23082308
}
23092309
}
23102310
}
2311+
2312+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2313+
#[derive(TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable)]
2314+
pub struct GeneratorWitnessInner<'tcx> {
2315+
pub tys: &'tcx List<Ty<'tcx>>,
2316+
pub structural_predicates: &'tcx List<ty::ProjectionPredicate<'tcx>>,
2317+
}

compiler/rustc_middle/src/ty/walk.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,8 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
179179
| ty::FnDef(_, substs) => {
180180
stack.extend(substs.iter().rev());
181181
}
182-
ty::GeneratorWitness(ts) => {
183-
stack.extend(ts.skip_binder().iter().rev().map(|ty| ty.into()));
182+
ty::GeneratorWitness(inner) => {
183+
stack.extend(inner.skip_binder().tys.iter().rev().map(|ty| ty.into()));
184184
}
185185
ty::FnPtr(sig) => {
186186
stack.push(sig.skip_binder().output().into());

compiler/rustc_mir_transform/src/generator.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -730,9 +730,10 @@ fn sanitize_witness<'tcx>(
730730

731731
let allowed_upvars = tcx.normalize_erasing_regions(param_env, upvars);
732732
let allowed = match witness.kind() {
733-
&ty::GeneratorWitness(interior_tys) => {
734-
tcx.normalize_erasing_late_bound_regions(param_env, interior_tys)
735-
}
733+
&ty::GeneratorWitness(interior) => tcx.normalize_erasing_late_bound_regions(
734+
param_env,
735+
interior.map_bound(|interior| interior.tys),
736+
),
736737
_ => {
737738
tcx.sess.delay_span_bug(
738739
body.span,

compiler/rustc_trait_selection/src/traits/auto_trait.rs

-21
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use super::*;
55

66
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
77
use crate::infer::InferCtxt;
8-
use rustc_middle::ty::fold::TypeFolder;
98
use rustc_middle::ty::{Region, RegionVid, Term};
109

1110
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -867,23 +866,3 @@ impl<'tcx> AutoTraitFinder<'tcx> {
867866
infcx.freshen(p)
868867
}
869868
}
870-
871-
// Replaces all ReVars in a type with ty::Region's, using the provided map
872-
pub struct RegionReplacer<'a, 'tcx> {
873-
vid_to_region: &'a FxHashMap<ty::RegionVid, ty::Region<'tcx>>,
874-
tcx: TyCtxt<'tcx>,
875-
}
876-
877-
impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx> {
878-
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
879-
self.tcx
880-
}
881-
882-
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
883-
(match r {
884-
ty::ReVar(vid) => self.vid_to_region.get(vid).cloned(),
885-
_ => None,
886-
})
887-
.unwrap_or_else(|| r.super_fold_with(self))
888-
}
889-
}

0 commit comments

Comments
 (0)