Skip to content

Commit 957db6d

Browse files
committed
Auto merge of #124029 - compiler-errors:rpitit-variances, r=<try>
Give RPITITs variances, so they can (not) capture lifetimes This is needed for edition 2021 and the `precise_captures` feature, so we can specify that we *don't* want to capture a lifetime implicitly for an RPITIT. I'll elaborate this further and try to motivate its soundness once perf comes back. r? `@ghost`
2 parents 1dea922 + 8ba97b6 commit 957db6d

File tree

8 files changed

+96
-2
lines changed

8 files changed

+96
-2
lines changed

compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use rustc_infer::infer::{outlives::env::OutlivesEnvironment, TyCtxtInferExt};
55
use rustc_lint_defs::builtin::{REFINING_IMPL_TRAIT_INTERNAL, REFINING_IMPL_TRAIT_REACHABLE};
66
use rustc_middle::traits::{ObligationCause, Reveal};
77
use rustc_middle::ty::{
8-
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable, TypeVisitor,
8+
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable,
9+
TypeVisitableExt, TypeVisitor,
910
};
1011
use rustc_span::Span;
1112
use rustc_trait_selection::regions::InferCtxtRegionExt;
@@ -62,6 +63,10 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
6263
return;
6364
};
6465

66+
if hidden_tys.items().any(|(_, &ty)| ty.skip_binder().references_error()) {
67+
return;
68+
}
69+
6570
let mut collector = ImplTraitInTraitCollector { tcx, types: FxIndexSet::default() };
6671
trait_m_sig.visit_with(&mut collector);
6772

compiler/rustc_hir_analysis/src/variance/mod.rs

+7
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

+4-1
Original file line numberDiff line numberDiff line change
@@ -1086,9 +1086,12 @@ fn should_encode_variances<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, def_kind: Def
10861086
| DefKind::Fn
10871087
| DefKind::Ctor(..)
10881088
| DefKind::AssocFn => true,
1089+
DefKind::AssocTy => {
1090+
// Only encode variances for RPITITs (for traits)
1091+
matches!(tcx.opt_rpitit_info(def_id), Some(ty::ImplTraitInTraitData::Trait { .. }))
1092+
}
10891093
DefKind::Mod
10901094
| DefKind::Field
1091-
| DefKind::AssocTy
10921095
| DefKind::AssocConst
10931096
| DefKind::TyParam
10941097
| DefKind::ConstParam

compiler/rustc_middle/src/ty/relate.rs

+10
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,16 @@ impl<'tcx> Relate<'tcx> for ty::AliasTy<'tcx> {
233233
b.args,
234234
false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
235235
)?,
236+
DefKind::AssocTy if relation.tcx().is_impl_trait_in_trait(a.def_id) => {
237+
relate_args_with_variances(
238+
relation,
239+
a.def_id,
240+
relation.tcx().variances_of(a.def_id),
241+
a.args,
242+
b.args,
243+
false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
244+
)?
245+
}
236246
DefKind::AssocTy | DefKind::AssocConst | DefKind::TyAlias => {
237247
relate_args_invariantly(relation, a.args, b.args)?
238248
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![feature(precise_capturing)]
2+
//~^ WARN the feature `precise_capturing` is incomplete
3+
4+
struct Invariant<'a>(&'a mut &'a mut ());
5+
6+
trait Trait {
7+
fn hello(self_: Invariant<'_>) -> impl use<Self> Sized;
8+
}
9+
10+
impl Trait for () {
11+
fn hello(self_: Invariant<'_>) -> impl use<'_> Sized {}
12+
//~^ return type captures more lifetimes than trait definition
13+
}
14+
15+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/rpitit-impl-captures-too-much.rs:1:12
3+
|
4+
LL | #![feature(precise_capturing)]
5+
| ^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
error: return type captures more lifetimes than trait definition
11+
--> $DIR/rpitit-impl-captures-too-much.rs:11:39
12+
|
13+
LL | fn hello(self_: Invariant<'_>) -> impl use<'_> Sized {}
14+
| -- ^^^^^^^^^^^^^^^^^^
15+
| |
16+
| this lifetime was captured
17+
|
18+
note: hidden type must only reference lifetimes captured by this impl trait
19+
--> $DIR/rpitit-impl-captures-too-much.rs:7:39
20+
|
21+
LL | fn hello(self_: Invariant<'_>) -> impl use<Self> Sized;
22+
| ^^^^^^^^^^^^^^^^^^^^
23+
= note: hidden type inferred to be `impl Sized`
24+
25+
error: aborting due to 1 previous error; 1 warning emitted
26+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//@ check-pass
2+
3+
#![feature(precise_capturing)]
4+
//~^ WARN the feature `precise_capturing` is incomplete
5+
6+
struct Invariant<'a>(&'a mut &'a mut ());
7+
8+
trait Trait {
9+
fn hello(self_: Invariant<'_>) -> impl use<Self> Sized;
10+
}
11+
12+
fn eq<'a, 'b, T: Trait>(x: Invariant<'a>, y: Invariant<'b>) {
13+
let mut out = T::hello(x);
14+
out = T::hello(y);
15+
}
16+
17+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/rpitit.rs:3:12
3+
|
4+
LL | #![feature(precise_capturing)]
5+
| ^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
warning: 1 warning emitted
11+

0 commit comments

Comments
 (0)