Skip to content

Commit b56a74f

Browse files
Give RPITITs variance for precise capturing
1 parent 99f77a2 commit b56a74f

File tree

5 files changed

+33
-1
lines changed

5 files changed

+33
-1
lines changed

compiler/rustc_hir_analysis/src/variance/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
6161
let crate_map = tcx.crate_variances(());
6262
return crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]);
6363
}
64+
DefKind::AssocTy => match tcx.opt_rpitit_info(item_def_id.to_def_id()) {
65+
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
66+
return variance_of_opaque(tcx, opaque_def_id.expect_local());
67+
}
68+
None => {}
69+
Some(ty::ImplTraitInTraitData::Impl { .. }) => {}
70+
},
6471
DefKind::OpaqueTy => {
6572
return variance_of_opaque(tcx, item_def_id);
6673
}

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1089,9 +1089,12 @@ fn should_encode_variances<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, def_kind: Def
10891089
| DefKind::Fn
10901090
| DefKind::Ctor(..)
10911091
| DefKind::AssocFn => true,
1092+
DefKind::AssocTy => {
1093+
// Only encode variances for RPITITs (for traits)
1094+
matches!(tcx.opt_rpitit_info(def_id), Some(ty::ImplTraitInTraitData::Trait { .. }))
1095+
}
10921096
DefKind::Mod
10931097
| DefKind::Field
1094-
| DefKind::AssocTy
10951098
| DefKind::AssocConst
10961099
| DefKind::TyParam
10971100
| DefKind::ConstParam

compiler/rustc_middle/src/ty/context.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,13 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
579579
) -> Ty<'tcx> {
580580
placeholder.find_const_ty_from_env(param_env)
581581
}
582+
583+
fn is_impl_trait_in_trait(
584+
self,
585+
def_id: DefId,
586+
) -> bool {
587+
self.is_impl_trait_in_trait(def_id)
588+
}
582589
}
583590

584591
fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem {

compiler/rustc_type_ir/src/interner.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,11 @@ pub trait Interner:
277277
param_env: Self::ParamEnv,
278278
placeholder: Self::PlaceholderConst,
279279
) -> Self::Ty;
280+
281+
fn is_impl_trait_in_trait(
282+
self,
283+
def_id: Self::DefId,
284+
) -> bool;
280285
}
281286

282287
/// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter`

compiler/rustc_type_ir/src/relate.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,16 @@ impl<I: Interner> Relate<I> for ty::AliasTy<I> {
254254
b.args,
255255
false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
256256
)?,
257+
ty::Projection if relation.tcx().is_impl_trait_in_trait(a.def_id) => {
258+
relate_args_with_variances(
259+
relation,
260+
a.def_id,
261+
relation.tcx().variances_of(a.def_id),
262+
a.args,
263+
b.args,
264+
false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
265+
)?
266+
}
257267
ty::Projection | ty::Weak | ty::Inherent => {
258268
relate_args_invariantly(relation, a.args, b.args)?
259269
}

0 commit comments

Comments
 (0)