Skip to content

Commit 5087bb1

Browse files
Relate AliasTy considering variance
1 parent 4910642 commit 5087bb1

File tree

2 files changed

+29
-19
lines changed

2 files changed

+29
-19
lines changed

compiler/rustc_middle/src/ty/relate.rs

Lines changed: 15 additions & 19 deletions
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;
@@ -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+
relation.relate(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
}
@@ -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)?;
Lines changed: 14 additions & 0 deletions
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)