Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
6edd86d
tests: add test for #105111
davidtwco Sep 11, 2024
207bc77
codegen_ssa: consolidate tied feature checking
davidtwco Sep 11, 2024
461b49d
stabilize `{slice,array}::from_mut`
ultrabear Sep 19, 2024
becf664
Match std RUSTFLAGS for host and target for `mir-opt` test
jieyouxu Oct 9, 2024
62b24ea
Compiler: Replace remaining occurrences of "object safe" with "dyn co…
fmease Oct 9, 2024
2e7a52b
Rename feature object_safe_for_dispatch to dyn_compatible_for_dispatch
fmease Oct 9, 2024
20cebae
UI tests: Rename "object safe" to "dyn compatible"
fmease Oct 9, 2024
b12dc20
add config to explicitely test rustc with autodiff/enzyme disabled
ZuseZ4 Oct 10, 2024
1edff46
Avoid redundant additions to PATH when linking
madsmtm Oct 10, 2024
2900c58
stdarch: Bump stdarch submodule
mrkajetanp Sep 19, 2024
335f67b
rustc_target: Add sme-b16b16 as an explicit aarch64 target feature
mrkajetanp Sep 3, 2024
b7297ac
Add gate for precise capturing in traits
compiler-errors Sep 29, 2024
a7dc987
Add variances to RPITITs
compiler-errors Sep 29, 2024
36076ec
Clarify implicit captures for RPITIT
compiler-errors Sep 29, 2024
322c4bd
Don't fire refinement lint if there are errors
compiler-errors Sep 29, 2024
82433ee
Update .mailmap
P1n3appl3 Oct 10, 2024
13976f1
Rollup merge of #130308 - davidtwco:tied-target-consolidation, r=wesl…
matthiaskrgr Oct 10, 2024
9237937
Rollup merge of #130538 - ultrabear:ultrabear_const_from_ref, r=worki…
matthiaskrgr Oct 10, 2024
edb6693
Rollup merge of #130741 - mrkajetanp:detect-b16b16, r=Amanieu
matthiaskrgr Oct 10, 2024
4f2af12
Rollup merge of #131033 - compiler-errors:precise-capturing-in-traits…
matthiaskrgr Oct 10, 2024
28bc5a2
Rollup merge of #131442 - jieyouxu:mir-opt-rebuild, r=onur-ozkan
matthiaskrgr Oct 10, 2024
75ccd9f
Rollup merge of #131470 - EnzymeAD:enzyme-testinfra2, r=jieyouxu
matthiaskrgr Oct 10, 2024
fa3dff3
Rollup merge of #131475 - fmease:compiler-mv-obj-safe-dyn-compat-2, r…
matthiaskrgr Oct 10, 2024
e88cc51
Rollup merge of #131493 - madsmtm:avoid-redundant-linker-path, r=jiey…
matthiaskrgr Oct 10, 2024
8ddd327
Rollup merge of #131509 - P1n3appl3:patch-1, r=aDotInTheVoid
matthiaskrgr Oct 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add variances to RPITITs
  • Loading branch information
compiler-errors authored and workingjubilee committed Oct 10, 2024
commit a7dc98733da8b84cfc21a538541a41803c4529a0
49 changes: 44 additions & 5 deletions compiler/rustc_hir_analysis/src/variance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

use itertools::Itertools;
use rustc_arena::DroplessArena;
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::query::Providers;
Expand Down Expand Up @@ -63,8 +64,29 @@ 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(),
ForceCaptureTraitArgs::Yes,
);
}
None | Some(ty::ImplTraitInTraitData::Impl { .. }) => {}
},
DefKind::OpaqueTy => {
return variance_of_opaque(tcx, item_def_id);
let force_capture_trait_args = if let hir::OpaqueTyOrigin::FnReturn {
parent: _,
in_trait_or_impl: Some(hir::RpitContext::Trait),
} =
tcx.hir_node_by_def_id(item_def_id).expect_opaque_ty().origin
{
ForceCaptureTraitArgs::Yes
} else {
ForceCaptureTraitArgs::No
};

return variance_of_opaque(tcx, item_def_id, force_capture_trait_args);
}
_ => {}
}
Expand All @@ -73,8 +95,18 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
span_bug!(tcx.def_span(item_def_id), "asked to compute variance for wrong kind of item");
}

#[derive(Debug, Copy, Clone)]
enum ForceCaptureTraitArgs {
Yes,
No,
}

#[instrument(level = "trace", skip(tcx), ret)]
fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
fn variance_of_opaque(
tcx: TyCtxt<'_>,
item_def_id: LocalDefId,
force_capture_trait_args: ForceCaptureTraitArgs,
) -> &[ty::Variance] {
let generics = tcx.generics_of(item_def_id);

// Opaque types may only use regions that are bound. So for
Expand Down Expand Up @@ -115,9 +147,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
#[instrument(level = "trace", skip(self), ret)]
fn visit_ty(&mut self, t: Ty<'tcx>) {
match t.kind() {
ty::Alias(_, ty::AliasTy { def_id, args, .. })
if matches!(self.tcx.def_kind(*def_id), DefKind::OpaqueTy) =>
{
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
self.visit_opaque(*def_id, args);
}
_ => t.super_visit_with(self),
Expand All @@ -135,6 +165,15 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
let mut generics = generics;
while let Some(def_id) = generics.parent {
generics = tcx.generics_of(def_id);

// Don't mark trait params generic if we're in an RPITIT.
if matches!(force_capture_trait_args, ForceCaptureTraitArgs::Yes)
&& generics.parent.is_none()
{
debug_assert_eq!(tcx.def_kind(def_id), DefKind::Trait);
break;
}

for param in &generics.own_params {
match param.kind {
ty::GenericParamDefKind::Lifetime => {
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 @@ -1100,9 +1100,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
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
self.trait_def(trait_def_id).implement_via_object
}

fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
self.is_impl_trait_in_trait(def_id)
}

fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed {
self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string())
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_type_ir/src/interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ pub trait Interner:

fn trait_may_be_implemented_via_object(self, trait_def_id: Self::DefId) -> bool;

fn is_impl_trait_in_trait(self, def_id: Self::DefId) -> bool;

fn delay_bug(self, msg: impl ToString) -> Self::ErrorGuaranteed;

fn is_general_coroutine(self, coroutine_def_id: Self::DefId) -> bool;
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_type_ir/src/relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,16 @@ impl<I: Interner> Relate<I> for ty::AliasTy<I> {
b.args,
false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
)?,
ty::Projection if relation.cx().is_impl_trait_in_trait(a.def_id) => {
relate_args_with_variances(
relation,
a.def_id,
relation.cx().variances_of(a.def_id),
a.args,
b.args,
false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
)?
}
ty::Projection | ty::Weak | ty::Inherent => {
relate_args_invariantly(relation, a.args, b.args)?
}
Expand Down
23 changes: 13 additions & 10 deletions tests/ui/impl-trait/in-trait/variance.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
#![feature(rustc_attrs)]
#![feature(rustc_attrs, precise_capturing_in_traits)]
#![allow(internal_features)]
#![rustc_variance_of_opaques]

trait Captures<'a> {}
impl<T> Captures<'_> for T {}

trait Foo<'i> {
fn implicit_capture_early<'a: 'a>() -> impl Sized {}
//~^ [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
//~^ [Self: o, 'i: o, 'a: *, 'a: o, 'i: o]

fn explicit_capture_early<'a: 'a>() -> impl Sized + use<'i, 'a, Self> {}
//~^ [Self: o, 'i: o, 'a: *, 'i: o, 'a: o]

fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {}
//~^ [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
fn not_captured_early<'a: 'a>() -> impl Sized + use<'i, Self> {}
//~^ [Self: o, 'i: o, 'a: *, 'i: o]

fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {}
//~^ [Self: o, 'i: *, 'a: o, 'i: o]
//~^ [Self: o, 'i: o, 'a: o, 'i: o]

fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + use<'i, 'a, Self> {}
//~^ [Self: o, 'i: o, 'i: o, 'a: o]

fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
//~^ [Self: o, 'i: *, 'a: o, 'i: o]
fn not_cpatured_late<'a>(_: &'a ()) -> impl Sized + use<'i, Self> {}
//~^ [Self: o, 'i: o, 'i: o]
}

fn main() {}
34 changes: 23 additions & 11 deletions tests/ui/impl-trait/in-trait/variance.stderr
Original file line number Diff line number Diff line change
@@ -1,26 +1,38 @@
error: [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:9:44
error: [Self: o, 'i: o, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:6:44
|
LL | fn implicit_capture_early<'a: 'a>() -> impl Sized {}
| ^^^^^^^^^^

error: [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:12:44
error: [Self: o, 'i: o, 'a: *, 'i: o, 'a: o]
--> $DIR/variance.rs:9:44
|
LL | fn explicit_capture_early<'a: 'a>() -> impl Sized + use<'i, 'a, Self> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: [Self: o, 'i: o, 'a: *, 'i: o]
--> $DIR/variance.rs:12:40
|
LL | fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
LL | fn not_captured_early<'a: 'a>() -> impl Sized + use<'i, Self> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^

error: [Self: o, 'i: *, 'a: o, 'i: o]
error: [Self: o, 'i: o, 'a: o, 'i: o]
--> $DIR/variance.rs:15:48
|
LL | fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {}
| ^^^^^^^^^^

error: [Self: o, 'i: *, 'a: o, 'i: o]
error: [Self: o, 'i: o, 'i: o, 'a: o]
--> $DIR/variance.rs:18:48
|
LL | fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
LL | fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + use<'i, 'a, Self> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: [Self: o, 'i: o, 'i: o]
--> $DIR/variance.rs:21:44
|
LL | fn not_cpatured_late<'a>(_: &'a ()) -> impl Sized + use<'i, Self> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 4 previous errors
error: aborting due to 6 previous errors

Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#![feature(precise_capturing_in_traits)]

fn type_param<T>() -> impl Sized + use<> {}
//~^ ERROR `impl Trait` must mention all type parameters in scope

trait Foo {
fn bar() -> impl Sized + use<>;
//~^ ERROR `impl Trait` must mention the `Self` type of the trait
//~| ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
--> $DIR/forgot-to-capture-type.rs:5:30
|
LL | fn bar() -> impl Sized + use<>;
| ^^^^^
|
= note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
= note: see issue #130044 <https://github.com/rust-lang/rust/issues/130044> for more information
= help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error: `impl Trait` must mention all type parameters in scope in `use<...>`
--> $DIR/forgot-to-capture-type.rs:1:23
--> $DIR/forgot-to-capture-type.rs:3:23
|
LL | fn type_param<T>() -> impl Sized + use<> {}
| - ^^^^^^^^^^^^^^^^^^
Expand All @@ -20,7 +9,7 @@ LL | fn type_param<T>() -> impl Sized + use<> {}
= note: currently, all type parameters are required to be mentioned in the precise captures list

error: `impl Trait` must mention the `Self` type of the trait in `use<...>`
--> $DIR/forgot-to-capture-type.rs:5:17
--> $DIR/forgot-to-capture-type.rs:7:17
|
LL | trait Foo {
| --------- `Self` type parameter is implicitly captured by this `impl Trait`
Expand All @@ -29,5 +18,5 @@ LL | fn bar() -> impl Sized + use<>;
|
= note: currently, all type parameters are required to be mentioned in the precise captures list

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

20 changes: 0 additions & 20 deletions tests/ui/impl-trait/precise-capturing/redundant.normal.stderr

This file was deleted.

24 changes: 0 additions & 24 deletions tests/ui/impl-trait/precise-capturing/redundant.rpitit.stderr

This file was deleted.

15 changes: 7 additions & 8 deletions tests/ui/impl-trait/precise-capturing/redundant.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
//@ compile-flags: -Zunstable-options --edition=2024
//@ revisions: normal rpitit
//@[normal] check-pass
//@ check-pass

#![feature(precise_capturing_in_traits)]

fn hello<'a>() -> impl Sized + use<'a> {}
//[normal]~^ WARN all possible in-scope parameters are already captured
//~^ WARN all possible in-scope parameters are already captured

struct Inherent;
impl Inherent {
fn inherent(&self) -> impl Sized + use<'_> {}
//[normal]~^ WARN all possible in-scope parameters are already captured
//~^ WARN all possible in-scope parameters are already captured
}

#[cfg(rpitit)]
trait Test<'a> {
fn in_trait() -> impl Sized + use<'a, Self>;
//[rpitit]~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
//~^ WARN all possible in-scope parameters are already captured
}
#[cfg(rpitit)]
impl<'a> Test<'a> for () {
fn in_trait() -> impl Sized + use<'a> {}
//[rpitit]~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
//~^ WARN all possible in-scope parameters are already captured
}

fn main() {}
36 changes: 36 additions & 0 deletions tests/ui/impl-trait/precise-capturing/redundant.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
--> $DIR/redundant.rs:6:19
|
LL | fn hello<'a>() -> impl Sized + use<'a> {}
| ^^^^^^^^^^^^^-------
| |
| help: remove the `use<...>` syntax
|
= note: `#[warn(impl_trait_redundant_captures)]` on by default

warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
--> $DIR/redundant.rs:11:27
|
LL | fn inherent(&self) -> impl Sized + use<'_> {}
| ^^^^^^^^^^^^^-------
| |
| help: remove the `use<...>` syntax

warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
--> $DIR/redundant.rs:16:22
|
LL | fn in_trait() -> impl Sized + use<'a, Self>;
| ^^^^^^^^^^^^^-------------
| |
| help: remove the `use<...>` syntax

warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
--> $DIR/redundant.rs:20:22
|
LL | fn in_trait() -> impl Sized + use<'a> {}
| ^^^^^^^^^^^^^-------
| |
| help: remove the `use<...>` syntax

warning: 4 warnings emitted

Loading