Skip to content

Commit 0027216

Browse files
committed
Auto merge of #116219 - compiler-errors:relate-alias-ty-with-variance, r=<try>
Relate alias ty with variance In the new solver, turns out that the subst-relate branch of the alias-relate predicate was relating args invariantly even for opaques, which have variance 💀. This change is a bit more invasive, but I'd rather not special-case it [here](https://github.com/rust-lang/rust/blob/aeaa5c30e5c9041264a2e8314b68ad84c2dc3169/compiler/rustc_trait_selection/src/solve/alias_relate.rs#L171-L190) and then have it break elsewhere. I'm doing a perf run to see if the extra call to `def_kind` is that expensive, if it is, I'll reconsider. r? `@lcnr`
2 parents 4910642 + be29d22 commit 0027216

File tree

4 files changed

+40
-43
lines changed

4 files changed

+40
-43
lines changed

compiler/rustc_infer/src/infer/equate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
5656
// performing trait matching (which then performs equality
5757
// unification).
5858

59-
relate::relate_args(self, a_arg, b_arg)
59+
relate::relate_args_invariantly(self, a_arg, b_arg)
6060
}
6161

6262
fn relate_with_variance<T: Relate<'tcx>>(

compiler/rustc_infer/src/infer/generalize.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ where
183183
// Avoid fetching the variance if we are in an invariant
184184
// context; no need, and it can induce dependency cycles
185185
// (e.g., #41849).
186-
relate::relate_args(self, a_subst, b_subst)
186+
relate::relate_args_invariantly(self, a_subst, b_subst)
187187
} else {
188188
let tcx = self.tcx();
189189
let opt_variances = tcx.variances_of(item_def_id);

compiler/rustc_middle/src/ty/relate.rs

+24-41
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::ty::error::{ExpectedFound, TypeError};
88
use crate::ty::{self, Expr, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable};
99
use crate::ty::{GenericArg, GenericArgKind, GenericArgsRef};
1010
use rustc_hir as hir;
11+
use rustc_hir::def::DefKind;
1112
use rustc_hir::def_id::DefId;
1213
use rustc_target::spec::abi;
1314
use std::iter;
@@ -134,7 +135,7 @@ pub fn relate_type_and_mut<'tcx, R: TypeRelation<'tcx>>(
134135
}
135136

136137
#[inline]
137-
pub fn relate_args<'tcx, R: TypeRelation<'tcx>>(
138+
pub fn relate_args_invariantly<'tcx, R: TypeRelation<'tcx>>(
138139
relation: &mut R,
139140
a_arg: GenericArgsRef<'tcx>,
140141
b_arg: GenericArgsRef<'tcx>,
@@ -273,7 +274,20 @@ impl<'tcx> Relate<'tcx> for ty::AliasTy<'tcx> {
273274
if a.def_id != b.def_id {
274275
Err(TypeError::ProjectionMismatched(expected_found(relation, a.def_id, b.def_id)))
275276
} else {
276-
let args = relation.relate(a.args, b.args)?;
277+
let args = match relation.tcx().def_kind(a.def_id) {
278+
DefKind::OpaqueTy => relate_args_with_variances(
279+
relation,
280+
a.def_id,
281+
relation.tcx().variances_of(a.def_id),
282+
a.args,
283+
b.args,
284+
false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
285+
)?,
286+
DefKind::AssocTy | DefKind::AssocConst | DefKind::TyAlias => {
287+
relate_args_invariantly(relation, a.args, b.args)?
288+
}
289+
def => bug!("unknown alias DefKind: {def:?}"),
290+
};
277291
Ok(relation.tcx().mk_alias_ty(a.def_id, args))
278292
}
279293
}
@@ -315,7 +329,7 @@ impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> {
315329
if a.def_id != b.def_id {
316330
Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id)))
317331
} else {
318-
let args = relate_args(relation, a.args, b.args)?;
332+
let args = relate_args_invariantly(relation, a.args, b.args)?;
319333
Ok(ty::TraitRef::new(relation.tcx(), a.def_id, args))
320334
}
321335
}
@@ -331,7 +345,7 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> {
331345
if a.def_id != b.def_id {
332346
Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id)))
333347
} else {
334-
let args = relate_args(relation, a.args, b.args)?;
348+
let args = relate_args_invariantly(relation, a.args, b.args)?;
335349
Ok(ty::ExistentialTraitRef { def_id: a.def_id, args })
336350
}
337351
}
@@ -449,7 +463,7 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
449463
// All Generator types with the same id represent
450464
// the (anonymous) type of the same generator expression. So
451465
// all of their regions should be equated.
452-
let args = relation.relate(a_args, b_args)?;
466+
let args = relate_args_invariantly(relation, a_args, b_args)?;
453467
Ok(Ty::new_generator(tcx, a_id, args, movability))
454468
}
455469

@@ -459,15 +473,15 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
459473
// All GeneratorWitness types with the same id represent
460474
// the (anonymous) type of the same generator expression. So
461475
// all of their regions should be equated.
462-
let args = relation.relate(a_args, b_args)?;
476+
let args = relate_args_invariantly(relation, a_args, b_args)?;
463477
Ok(Ty::new_generator_witness(tcx, a_id, args))
464478
}
465479

466480
(&ty::Closure(a_id, a_args), &ty::Closure(b_id, b_args)) if a_id == b_id => {
467481
// All Closure types with the same id represent
468482
// the (anonymous) type of the same closure expression. So
469483
// all of their regions should be equated.
470-
let args = relation.relate(a_args, b_args)?;
484+
let args = relate_args_invariantly(relation, a_args, b_args)?;
471485
Ok(Ty::new_closure(tcx, a_id, &args))
472486
}
473487

@@ -536,24 +550,6 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
536550
Ok(Ty::new_fn_ptr(tcx, fty))
537551
}
538552

539-
// The args of opaque types may not all be invariant, so we have
540-
// to treat them separately from other aliases.
541-
(
542-
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, args: a_args, .. }),
543-
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, args: b_args, .. }),
544-
) if a_def_id == b_def_id => {
545-
let opt_variances = tcx.variances_of(a_def_id);
546-
let args = relate_args_with_variances(
547-
relation,
548-
a_def_id,
549-
opt_variances,
550-
a_args,
551-
b_args,
552-
false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
553-
)?;
554-
Ok(Ty::new_opaque(tcx, a_def_id, args))
555-
}
556-
557553
// Alias tend to mostly already be handled downstream due to normalization.
558554
(&ty::Alias(a_kind, a_data), &ty::Alias(b_kind, b_data)) => {
559555
let alias_ty = relation.relate(a_data, b_data)?;
@@ -709,7 +705,7 @@ impl<'tcx> Relate<'tcx> for ty::ClosureArgs<'tcx> {
709705
a: ty::ClosureArgs<'tcx>,
710706
b: ty::ClosureArgs<'tcx>,
711707
) -> RelateResult<'tcx, ty::ClosureArgs<'tcx>> {
712-
let args = relate_args(relation, a.args, b.args)?;
708+
let args = relate_args_invariantly(relation, a.args, b.args)?;
713709
Ok(ty::ClosureArgs { args })
714710
}
715711
}
@@ -720,7 +716,7 @@ impl<'tcx> Relate<'tcx> for ty::GeneratorArgs<'tcx> {
720716
a: ty::GeneratorArgs<'tcx>,
721717
b: ty::GeneratorArgs<'tcx>,
722718
) -> RelateResult<'tcx, ty::GeneratorArgs<'tcx>> {
723-
let args = relate_args(relation, a.args, b.args)?;
719+
let args = relate_args_invariantly(relation, a.args, b.args)?;
724720
Ok(ty::GeneratorArgs { args })
725721
}
726722
}
@@ -731,7 +727,7 @@ impl<'tcx> Relate<'tcx> for GenericArgsRef<'tcx> {
731727
a: GenericArgsRef<'tcx>,
732728
b: GenericArgsRef<'tcx>,
733729
) -> RelateResult<'tcx, GenericArgsRef<'tcx>> {
734-
relate_args(relation, a, b)
730+
relate_args_invariantly(relation, a, b)
735731
}
736732
}
737733

@@ -835,19 +831,6 @@ impl<'tcx> Relate<'tcx> for Term<'tcx> {
835831
}
836832
}
837833

838-
impl<'tcx> Relate<'tcx> for ty::ProjectionPredicate<'tcx> {
839-
fn relate<R: TypeRelation<'tcx>>(
840-
relation: &mut R,
841-
a: ty::ProjectionPredicate<'tcx>,
842-
b: ty::ProjectionPredicate<'tcx>,
843-
) -> RelateResult<'tcx, ty::ProjectionPredicate<'tcx>> {
844-
Ok(ty::ProjectionPredicate {
845-
projection_ty: relation.relate(a.projection_ty, b.projection_ty)?,
846-
term: relation.relate(a.term, b.term)?,
847-
})
848-
}
849-
}
850-
851834
///////////////////////////////////////////////////////////////////////////
852835
// Error handling
853836

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// check-pass
2+
// compile-flags: -Ztrait-solver=next
3+
4+
fn foo<'a: 'a>(x: &'a Vec<i32>) -> impl Sized {
5+
()
6+
}
7+
8+
fn main() {
9+
// in NLL, we want to make sure that the `'a` subst of `foo` does not get
10+
// related between `x` and the RHS of the assignment. That would require
11+
// that the temp is live for the lifetime of the variable `x`, which of
12+
// course is not necessary since `'a` is not captured by the RPIT.
13+
let x = foo(&Vec::new());
14+
}

0 commit comments

Comments
 (0)