Skip to content

Commit 5698a58

Browse files
committed
Auto merge of #118247 - spastorino:type-equality-subtyping, r=<try>
Fix for TypeId exposes equality-by-subtyping vs normal-form-syntactic-equality unsoundness Fixes #97156 This PR revives #97427 idea, it sits on top of #118118 because the idea uncovered some problems with IATs. r? `@lcnr` This is ICEing yet for `tests/ui/traits/new-solver/escaping-bound-vars-in-writeback-normalization.rs` using the new trait solver. After #118118 and this ICE is fixed, we would need a rebase and a crater run. Opening as a WIP for now.
2 parents 42ae1a7 + 3679fde commit 5698a58

File tree

63 files changed

+373
-387
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+373
-387
lines changed

compiler/rustc_hir_analysis/src/check/intrinsic.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
138138
let name_str = intrinsic_name.as_str();
139139

140140
let bound_vars = tcx.mk_bound_variable_kinds(&[
141+
ty::BoundVariableKind::Region(ty::BrAnon),
141142
ty::BoundVariableKind::Region(ty::BrAnon),
142143
ty::BoundVariableKind::Region(ty::BrEnv),
143144
]);
@@ -151,7 +152,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
151152
let env_region = ty::Region::new_bound(
152153
tcx,
153154
ty::INNERMOST,
154-
ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrEnv },
155+
ty::BoundRegion { var: ty::BoundVar::from_u32(2), kind: ty::BrEnv },
155156
);
156157
let va_list_ty = tcx.type_of(did).instantiate(tcx, &[region.into()]);
157158
(Ty::new_ref(tcx, env_region, ty::TypeAndMut { ty: va_list_ty, mutbl }), va_list_ty)
@@ -446,9 +447,12 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
446447

447448
sym::raw_eq => {
448449
let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon };
449-
let param_ty =
450+
let param_ty_lhs =
451+
Ty::new_imm_ref(tcx, ty::Region::new_bound(tcx, ty::INNERMOST, br), param(0));
452+
let br = ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrAnon };
453+
let param_ty_rhs =
450454
Ty::new_imm_ref(tcx, ty::Region::new_bound(tcx, ty::INNERMOST, br), param(0));
451-
(1, vec![param_ty; 2], tcx.types.bool)
455+
(1, vec![param_ty_lhs, param_ty_rhs], tcx.types.bool)
452456
}
453457

454458
sym::black_box => (1, vec![param(0)], param(0)),

compiler/rustc_infer/src/infer/equate.rs

+12-7
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ use crate::traits::PredicateObligations;
44
use super::combine::{CombineFields, ObligationEmittingRelation};
55
use super::Subtype;
66

7+
use rustc_middle::ty::error::TypeError;
78
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
89
use rustc_middle::ty::GenericArgsRef;
910
use rustc_middle::ty::TyVar;
10-
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
11+
use rustc_middle::ty::{self, Ty, TyCtxt};
1112

1213
use rustc_hir::def_id::DefId;
1314

@@ -164,14 +165,18 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
164165
return Ok(a);
165166
}
166167

167-
if a.skip_binder().has_escaping_bound_vars() || b.skip_binder().has_escaping_bound_vars() {
168-
self.fields.higher_ranked_sub(a, b, self.a_is_expected)?;
169-
self.fields.higher_ranked_sub(b, a, self.a_is_expected)?;
168+
let a = self.tcx().anonymize_bound_vars(a);
169+
let b = self.tcx().anonymize_bound_vars(b);
170+
171+
if a.bound_vars() == b.bound_vars() {
172+
let (a, b) = self
173+
.fields
174+
.infcx
175+
.instantiate_binder_with_placeholders(a.map_bound(|a| (a, b.skip_binder())));
176+
Ok(ty::Binder::dummy(self.relate(a, b)?))
170177
} else {
171-
// Fast path for the common case.
172-
self.relate(a.skip_binder(), b.skip_binder())?;
178+
Err(TypeError::Mismatch)
173179
}
174-
Ok(a)
175180
}
176181
}
177182

tests/ui/associated-inherent-types/issue-109789.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ impl Other for u32 {}
1616
// `try_report_trait_placeholder_mismatch`.
1717

1818
fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {}
19-
//~^ ERROR mismatched types
20-
//~| ERROR mismatched types
19+
//~^ ERROR associated type `Assoc` not found for `Foo<for<'a> fn(&'a ())>` in the current scope [E0220]
2120

2221
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,15 @@
1-
error[E0308]: mismatched types
2-
--> $DIR/issue-109789.rs:18:11
1+
error[E0220]: associated type `Assoc` not found for `Foo<for<'a> fn(&'a ())>` in the current scope
2+
--> $DIR/issue-109789.rs:18:36
33
|
4+
LL | struct Foo<T>(T);
5+
| ------------- associated item `Assoc` not found for this struct
6+
...
47
LL | fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {}
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
8+
| ^^^^^ associated item not found in `Foo<for<'a> fn(&'a ())>`
69
|
7-
= note: expected struct `Foo<fn(&'static ())>`
8-
found struct `Foo<for<'a> fn(&'a ())>`
10+
= note: the associated type was found for
11+
- `Foo<fn(&'static ())>`
912

10-
error[E0308]: mismatched types
11-
--> $DIR/issue-109789.rs:18:11
12-
|
13-
LL | fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {}
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
15-
|
16-
= note: expected struct `Foo<fn(&'static ())>`
17-
found struct `Foo<for<'a> fn(&'a ())>`
18-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
19-
20-
error: aborting due to 2 previous errors
13+
error: aborting due to previous error
2114

22-
For more information about this error, try `rustc --explain E0308`.
15+
For more information about this error, try `rustc --explain E0220`.
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,33 @@
1+
error[E0220]: associated type `Assoc` not found for `Foo<for<'b> fn(&'b ())>` in the current scope
2+
--> $DIR/issue-111404-1.rs:10:55
3+
|
4+
LL | struct Foo<T>(T);
5+
| ------------- associated item `Assoc` not found for this struct
6+
...
7+
LL | fn bar(_: fn(Foo<for<'b> fn(Foo<fn(&'b ())>::Assoc)>::Assoc)) {}
8+
<<<<<<< HEAD
9+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
10+
11+
error: aborting due to previous error
12+
||||||| parent of 9bb25a65025 (Make type equality != bidirectional subtyping)
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14+
115
error: higher-ranked subtype error
216
--> $DIR/issue-111404-1.rs:10:1
317
|
418
LL | fn bar(_: fn(Foo<for<'b> fn(Foo<fn(&'b ())>::Assoc)>::Assoc)) {}
519
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
20+
|
21+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
22+
23+
error: aborting due to 2 previous errors
24+
=======
25+
| ^^^^^ associated item not found in `Foo<for<'b> fn(&'b ())>`
26+
|
27+
= note: the associated type was found for
28+
- `Foo<fn(&'a ())>`
629

730
error: aborting due to previous error
31+
>>>>>>> 9bb25a65025 (Make type equality != bidirectional subtyping)
832

33+
For more information about this error, try `rustc --explain E0220`.

tests/ui/closure-expected-type/expect-fn-supply-fn.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ fn expect_free_supply_free_from_fn<'x>(x: &'x u32) {
1414
// Here, the type given for `'x` "obscures" a region from the
1515
// expected signature that is bound at closure level.
1616
with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {});
17-
//~^ ERROR lifetime may not live long enough
18-
//~| ERROR lifetime may not live long enough
1917
}
2018

2119
fn expect_free_supply_free_from_closure() {
@@ -30,14 +28,14 @@ fn expect_free_supply_bound() {
3028
// Here, we are given a function whose region is bound at closure level,
3129
// but we expect one bound in the argument. Error results.
3230
with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
33-
//~^ ERROR mismatched types
31+
//~^ ERROR type mismatch in closure arguments
3432
}
3533

3634
fn expect_bound_supply_free_from_fn<'x>(x: &'x u32) {
3735
// Here, we are given a `fn(&u32)` but we expect a `fn(&'x
3836
// u32)`. In principle, this could be ok, but we demand equality.
3937
with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
40-
//~^ ERROR mismatched types
38+
//~^ ERROR type mismatch in closure arguments
4139
}
4240

4341
fn expect_bound_supply_free_from_closure() {
@@ -46,7 +44,7 @@ fn expect_bound_supply_free_from_closure() {
4644
// the argument level.
4745
type Foo<'a> = fn(&'a u32);
4846
with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
49-
//~^ ERROR mismatched types
47+
//~^ ERROR type mismatch in closure arguments
5048
});
5149
}
5250

Original file line numberDiff line numberDiff line change
@@ -1,51 +1,72 @@
1-
error: lifetime may not live long enough
2-
--> $DIR/expect-fn-supply-fn.rs:16:49
3-
|
4-
LL | fn expect_free_supply_free_from_fn<'x>(x: &'x u32) {
5-
| -- lifetime `'x` defined here
6-
...
7-
LL | with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {});
8-
| ^
9-
| |
10-
| has type `fn(&'1 u32)`
11-
| requires that `'1` must outlive `'x`
12-
13-
error: lifetime may not live long enough
14-
--> $DIR/expect-fn-supply-fn.rs:16:49
15-
|
16-
LL | fn expect_free_supply_free_from_fn<'x>(x: &'x u32) {
17-
| -- lifetime `'x` defined here
18-
...
19-
LL | with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {});
20-
| ^ requires that `'x` must outlive `'static`
21-
22-
error[E0308]: mismatched types
23-
--> $DIR/expect-fn-supply-fn.rs:32:49
1+
error[E0631]: type mismatch in closure arguments
2+
--> $DIR/expect-fn-supply-fn.rs:30:5
243
|
254
LL | with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
26-
| ^ one type is more general than the other
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------- found signature defined here
6+
| |
7+
| expected due to this
8+
|
9+
= note: expected closure signature `for<'a, 'b> fn(for<'a> fn(&'a u32), &'b i32) -> _`
10+
found closure signature `fn(for<'a> fn(&'a u32), _) -> _`
11+
note: required by a bound in `with_closure_expecting_fn_with_free_region`
12+
--> $DIR/expect-fn-supply-fn.rs:3:8
13+
|
14+
LL | fn with_closure_expecting_fn_with_free_region<F>(_: F)
15+
| ------------------------------------------ required by a bound in this function
16+
LL | where
17+
LL | F: for<'a> FnOnce(fn(&'a u32), &i32),
18+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `with_closure_expecting_fn_with_free_region`
19+
help: consider adjusting the signature so it borrows its argument
2720
|
28-
= note: expected fn pointer `fn(&u32)`
29-
found fn pointer `for<'a> fn(&'a u32)`
21+
LL | with_closure_expecting_fn_with_free_region(|x: fn(&u32), &y| {});
22+
| +
3023

31-
error[E0308]: mismatched types
32-
--> $DIR/expect-fn-supply-fn.rs:39:50
24+
error[E0631]: type mismatch in closure arguments
25+
--> $DIR/expect-fn-supply-fn.rs:37:5
3326
|
3427
LL | with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
35-
| ^ one type is more general than the other
28+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------- found signature defined here
29+
| |
30+
| expected due to this
3631
|
37-
= note: expected fn pointer `for<'a> fn(&'a u32)`
38-
found fn pointer `fn(&u32)`
32+
= note: expected closure signature `for<'a> fn(for<'a> fn(&'a u32), &'a i32) -> _`
33+
found closure signature `fn(fn(&'x u32), _) -> _`
34+
note: required by a bound in `with_closure_expecting_fn_with_bound_region`
35+
--> $DIR/expect-fn-supply-fn.rs:9:8
36+
|
37+
LL | fn with_closure_expecting_fn_with_bound_region<F>(_: F)
38+
| ------------------------------------------- required by a bound in this function
39+
LL | where
40+
LL | F: FnOnce(fn(&u32), &i32),
41+
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `with_closure_expecting_fn_with_bound_region`
42+
help: consider adjusting the signature so it borrows its argument
43+
|
44+
LL | with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), &y| {});
45+
| +
3946

40-
error[E0308]: mismatched types
41-
--> $DIR/expect-fn-supply-fn.rs:48:50
47+
error[E0631]: type mismatch in closure arguments
48+
--> $DIR/expect-fn-supply-fn.rs:46:5
4249
|
4350
LL | with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
44-
| ^ one type is more general than the other
51+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- found signature defined here
52+
| |
53+
| expected due to this
54+
|
55+
= note: expected closure signature `for<'a> fn(for<'a> fn(&'a u32), &'a i32) -> _`
56+
found closure signature `for<'a> fn(for<'a> fn(&'a u32), _) -> _`
57+
note: required by a bound in `with_closure_expecting_fn_with_bound_region`
58+
--> $DIR/expect-fn-supply-fn.rs:9:8
59+
|
60+
LL | fn with_closure_expecting_fn_with_bound_region<F>(_: F)
61+
| ------------------------------------------- required by a bound in this function
62+
LL | where
63+
LL | F: FnOnce(fn(&u32), &i32),
64+
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `with_closure_expecting_fn_with_bound_region`
65+
help: consider adjusting the signature so it borrows its argument
4566
|
46-
= note: expected fn pointer `for<'a> fn(&'a u32)`
47-
found fn pointer `fn(&u32)`
67+
LL | with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, &y| {
68+
| +
4869

49-
error: aborting due to 5 previous errors
70+
error: aborting due to 3 previous errors
5071

51-
For more information about this error, try `rustc --explain E0308`.
72+
For more information about this error, try `rustc --explain E0631`.

tests/ui/coherence/coherence-fn-covariant-bound-vs-static.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@
1010
// * true if `exists<'r> { 'r: 'static }` (obviously true)
1111
// * `fn(fn(&'static u32)) <: for<'r> fn(fn(&'r u32))`
1212
// * true if `forall<'r> { 'static: 'r }` (also true)
13+
//
14+
// check-pass
15+
1316

1417
trait Trait {}
1518

1619
impl Trait for for<'r> fn(fn(&'r ())) {}
1720
impl<'a> Trait for fn(fn(&'a ())) {}
18-
//~^ ERROR conflicting implementations
1921
//
2022
// Note in particular that we do NOT get a future-compatibility warning
2123
// here. This is because the new leak-check proposed in [MCP 295] does not

tests/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr

-13
This file was deleted.

tests/ui/coherence/coherence-fn-implied-bounds.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,12 @@
1111
// Note that while we would like to make this a hard error, we also
1212
// give the same warning for `coherence-wasm-bindgen.rs`, which ought
1313
// to be accepted.
14-
15-
#![deny(coherence_leak_check)]
16-
14+
//
15+
// check-pass
1716
trait Trait {}
1817

1918
impl Trait for for<'a, 'b> fn(&'a &'b u32, &'b &'a u32) -> &'b u32 {}
2019

21-
impl Trait for for<'c> fn(&'c &'c u32, &'c &'c u32) -> &'c u32 {
22-
//~^ ERROR conflicting implementations
23-
//~| WARNING this was previously accepted by the compiler
24-
}
20+
impl Trait for for<'c> fn(&'c &'c u32, &'c &'c u32) -> &'c u32 {}
2521

2622
fn main() {}

tests/ui/coherence/coherence-fn-implied-bounds.stderr

-20
This file was deleted.

tests/ui/coherence/coherence-fn-inputs.rs

+3-9
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,11 @@
99
//
1010
// * `'c` can be the intersection of `'a` and `'b` (and there is always an intersection)
1111
// * `'a` and `'b` can both be equal to `'c`
12+
//
13+
// check-pass
1214

1315
trait Trait {}
1416
impl Trait for for<'a, 'b> fn(&'a u32, &'b u32) {}
15-
impl Trait for for<'c> fn(&'c u32, &'c u32) {
16-
//~^ ERROR conflicting implementations
17-
//
18-
// Note in particular that we do NOT get a future-compatibility warning
19-
// here. This is because the new leak-check proposed in [MCP 295] does not
20-
// "error" when these two types are equated.
21-
//
22-
// [MCP 295]: https://github.com/rust-lang/compiler-team/issues/295
23-
}
17+
impl Trait for for<'c> fn(&'c u32, &'c u32) {}
2418

2519
fn main() {}

tests/ui/coherence/coherence-fn-inputs.stderr

-13
This file was deleted.

0 commit comments

Comments
 (0)