Skip to content

Commit

Permalink
Auto merge of rust-lang#124029 - compiler-errors:rpitit-variances, r=…
Browse files Browse the repository at this point in the history
…<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`
  • Loading branch information
bors committed Apr 16, 2024
2 parents 1dea922 + 8ba97b6 commit 957db6d
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use rustc_infer::infer::{outlives::env::OutlivesEnvironment, TyCtxtInferExt};
use rustc_lint_defs::builtin::{REFINING_IMPL_TRAIT_INTERNAL, REFINING_IMPL_TRAIT_REACHABLE};
use rustc_middle::traits::{ObligationCause, Reveal};
use rustc_middle::ty::{
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable, TypeVisitor,
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable,
TypeVisitableExt, TypeVisitor,
};
use rustc_span::Span;
use rustc_trait_selection::regions::InferCtxtRegionExt;
Expand Down Expand Up @@ -62,6 +63,10 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
return;
};

if hidden_tys.items().any(|(_, &ty)| ty.skip_binder().references_error()) {
return;
}

let mut collector = ImplTraitInTraitCollector { tcx, types: FxIndexSet::default() };
trait_m_sig.visit_with(&mut collector);

Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_hir_analysis/src/variance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
let crate_map = tcx.crate_variances(());
return crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]);
}
DefKind::AssocTy => match tcx.opt_rpitit_info(item_def_id.to_def_id()) {
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
return variance_of_opaque(tcx, opaque_def_id.expect_local());
}
None => {}
Some(ty::ImplTraitInTraitData::Impl { .. }) => {}
},
DefKind::OpaqueTy => {
return variance_of_opaque(tcx, item_def_id);
}
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1086,9 +1086,12 @@ fn should_encode_variances<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, def_kind: Def
| DefKind::Fn
| DefKind::Ctor(..)
| DefKind::AssocFn => true,
DefKind::AssocTy => {
// Only encode variances for RPITITs (for traits)
matches!(tcx.opt_rpitit_info(def_id), Some(ty::ImplTraitInTraitData::Trait { .. }))
}
DefKind::Mod
| DefKind::Field
| DefKind::AssocTy
| DefKind::AssocConst
| DefKind::TyParam
| DefKind::ConstParam
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_middle/src/ty/relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,16 @@ impl<'tcx> Relate<'tcx> for ty::AliasTy<'tcx> {
b.args,
false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
)?,
DefKind::AssocTy if relation.tcx().is_impl_trait_in_trait(a.def_id) => {
relate_args_with_variances(
relation,
a.def_id,
relation.tcx().variances_of(a.def_id),
a.args,
b.args,
false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
)?
}
DefKind::AssocTy | DefKind::AssocConst | DefKind::TyAlias => {
relate_args_invariantly(relation, a.args, b.args)?
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#![feature(precise_capturing)]
//~^ WARN the feature `precise_capturing` is incomplete

struct Invariant<'a>(&'a mut &'a mut ());

trait Trait {
fn hello(self_: Invariant<'_>) -> impl use<Self> Sized;
}

impl Trait for () {
fn hello(self_: Invariant<'_>) -> impl use<'_> Sized {}
//~^ return type captures more lifetimes than trait definition
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/rpitit-impl-captures-too-much.rs:1:12
|
LL | #![feature(precise_capturing)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
= note: `#[warn(incomplete_features)]` on by default

error: return type captures more lifetimes than trait definition
--> $DIR/rpitit-impl-captures-too-much.rs:11:39
|
LL | fn hello(self_: Invariant<'_>) -> impl use<'_> Sized {}
| -- ^^^^^^^^^^^^^^^^^^
| |
| this lifetime was captured
|
note: hidden type must only reference lifetimes captured by this impl trait
--> $DIR/rpitit-impl-captures-too-much.rs:7:39
|
LL | fn hello(self_: Invariant<'_>) -> impl use<Self> Sized;
| ^^^^^^^^^^^^^^^^^^^^
= note: hidden type inferred to be `impl Sized`

error: aborting due to 1 previous error; 1 warning emitted

17 changes: 17 additions & 0 deletions tests/ui/impl-trait/precise-capturing/rpitit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//@ check-pass

#![feature(precise_capturing)]
//~^ WARN the feature `precise_capturing` is incomplete

struct Invariant<'a>(&'a mut &'a mut ());

trait Trait {
fn hello(self_: Invariant<'_>) -> impl use<Self> Sized;
}

fn eq<'a, 'b, T: Trait>(x: Invariant<'a>, y: Invariant<'b>) {
let mut out = T::hello(x);
out = T::hello(y);
}

fn main() {}
11 changes: 11 additions & 0 deletions tests/ui/impl-trait/precise-capturing/rpitit.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/rpitit.rs:3:12
|
LL | #![feature(precise_capturing)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
= note: `#[warn(incomplete_features)]` on by default

warning: 1 warning emitted

0 comments on commit 957db6d

Please sign in to comment.