Skip to content

Commit 124673b

Browse files
committed
hr type equality != bidirectional subtyping
1 parent 4f68efa commit 124673b

File tree

62 files changed

+398
-454
lines changed

Some content is hidden

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

62 files changed

+398
-454
lines changed

compiler/rustc_infer/src/infer/combine.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -749,9 +749,7 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
749749
}
750750
}
751751
}
752-
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted })
753-
if self.tcx().lazy_normalization() =>
754-
{
752+
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
755753
assert_eq!(promoted, None);
756754
let substs = self.relate_with_variance(
757755
ty::Variance::Invariant,
@@ -980,9 +978,7 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
980978
}
981979
}
982980
}
983-
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted })
984-
if self.tcx().lazy_normalization() =>
985-
{
981+
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
986982
assert_eq!(promoted, None);
987983
let substs = self.relate_with_variance(
988984
ty::Variance::Invariant,

compiler/rustc_infer/src/infer/equate.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::combine::{CombineFields, ConstEquateRelation, RelationDir};
22
use super::Subtype;
33

4+
use rustc_middle::ty::error::TypeError;
45
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
56
use rustc_middle::ty::subst::SubstsRef;
67
use rustc_middle::ty::TyVar;
@@ -151,13 +152,16 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
151152
where
152153
T: Relate<'tcx>,
153154
{
154-
if a.skip_binder().has_escaping_bound_vars() || b.skip_binder().has_escaping_bound_vars() {
155-
self.fields.higher_ranked_sub(a, b, self.a_is_expected)?;
156-
self.fields.higher_ranked_sub(b, a, self.a_is_expected)
155+
let a = self.tcx().anonymize_late_bound_regions(a);
156+
let b = self.tcx().anonymize_late_bound_regions(b);
157+
if a.bound_vars() == b.bound_vars() {
158+
let (a, b) = self
159+
.fields
160+
.infcx
161+
.replace_bound_vars_with_placeholders(a.map_bound(|a| (a, b.skip_binder())));
162+
Ok(ty::Binder::dummy(self.relate(a, b)?))
157163
} else {
158-
// Fast path for the common case.
159-
self.relate(a.skip_binder(), b.skip_binder())?;
160-
Ok(a)
164+
Err(TypeError::Mismatch)
161165
}
162166
}
163167
}

compiler/rustc_trait_selection/src/traits/wf.rs

+16-13
Original file line numberDiff line numberDiff line change
@@ -432,19 +432,22 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
432432
GenericArgKind::Const(constant) => {
433433
match constant.val() {
434434
ty::ConstKind::Unevaluated(uv) => {
435-
let obligations = self.nominal_obligations(uv.def.did, uv.substs);
436-
self.out.extend(obligations);
437-
438-
let predicate =
439-
ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv.shrink()))
440-
.to_predicate(self.tcx());
441-
let cause = self.cause(traits::MiscObligation);
442-
self.out.push(traits::Obligation::with_depth(
443-
cause,
444-
self.recursion_depth,
445-
self.param_env,
446-
predicate,
447-
));
435+
if !uv.has_escaping_bound_vars() {
436+
let obligations = self.nominal_obligations(uv.def.did, uv.substs);
437+
self.out.extend(obligations);
438+
439+
let predicate = ty::Binder::dummy(
440+
ty::PredicateKind::ConstEvaluatable(uv.shrink()),
441+
)
442+
.to_predicate(self.tcx());
443+
let cause = self.cause(traits::MiscObligation);
444+
self.out.push(traits::Obligation::with_depth(
445+
cause,
446+
self.recursion_depth,
447+
self.param_env,
448+
predicate,
449+
));
450+
}
448451
}
449452
ty::ConstKind::Infer(infer) => {
450453
let resolved = self.infcx.shallow_resolve(infer);

compiler/rustc_typeck/src/check/intrinsic.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,13 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
115115
let name_str = intrinsic_name.as_str();
116116

117117
let bound_vars = tcx.mk_bound_variable_kinds(
118-
[ty::BoundVariableKind::Region(ty::BrAnon(0)), ty::BoundVariableKind::Region(ty::BrEnv)]
119-
.iter()
120-
.copied(),
118+
[
119+
ty::BoundVariableKind::Region(ty::BrAnon(0)),
120+
ty::BoundVariableKind::Region(ty::BrAnon(1)),
121+
ty::BoundVariableKind::Region(ty::BrEnv),
122+
]
123+
.iter()
124+
.copied(),
121125
);
122126
let mk_va_list_ty = |mutbl| {
123127
tcx.lang_items().va_list().map(|did| {
@@ -127,7 +131,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
127131
));
128132
let env_region = tcx.mk_region(ty::ReLateBound(
129133
ty::INNERMOST,
130-
ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrEnv },
134+
ty::BoundRegion { var: ty::BoundVar::from_u32(2), kind: ty::BrEnv },
131135
));
132136
let va_list_ty = tcx.bound_type_of(did).subst(tcx, &[region.into()]);
133137
(tcx.mk_ref(env_region, ty::TypeAndMut { ty: va_list_ty, mutbl }), va_list_ty)
@@ -391,9 +395,12 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
391395

392396
sym::raw_eq => {
393397
let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0) };
394-
let param_ty =
398+
let param_ty_lhs =
395399
tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)), param(0));
396-
(1, vec![param_ty; 2], tcx.types.bool)
400+
let br = ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrAnon(1) };
401+
let param_ty_rhs =
402+
tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)), param(0));
403+
(1, vec![param_ty_lhs, param_ty_rhs], tcx.types.bool)
397404
}
398405

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

src/test/ui/closure-expected-type/expect-fn-supply-fn.base.stderr

+41-16
Original file line numberDiff line numberDiff line change
@@ -36,33 +36,58 @@ note: ...does not necessarily outlive the anonymous lifetime #1 defined here
3636
LL | with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {});
3737
| ^^^^^^^^^^^^^^^^^^^^^^
3838

39-
error[E0308]: mismatched types
40-
--> $DIR/expect-fn-supply-fn.rs:38:52
39+
error[E0631]: type mismatch in closure arguments
40+
--> $DIR/expect-fn-supply-fn.rs:36:5
4141
|
4242
LL | with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
43-
| ^^^^^^^^ one type is more general than the other
43+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------- found signature of `fn(for<'r> fn(&'r u32), _) -> _`
44+
| |
45+
| expected signature of `for<'a, 'r> fn(for<'a> fn(&'a u32), &'r i32) -> _`
4446
|
45-
= note: expected fn pointer `fn(&u32)`
46-
found fn pointer `for<'r> fn(&'r u32)`
47+
note: required by a bound in `with_closure_expecting_fn_with_free_region`
48+
--> $DIR/expect-fn-supply-fn.rs:7:8
49+
|
50+
LL | fn with_closure_expecting_fn_with_free_region<F>(_: F)
51+
| ------------------------------------------ required by a bound in this
52+
LL | where
53+
LL | F: for<'a> FnOnce(fn(&'a u32), &i32),
54+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `with_closure_expecting_fn_with_free_region`
4755

48-
error[E0308]: mismatched types
49-
--> $DIR/expect-fn-supply-fn.rs:45:53
56+
error[E0631]: type mismatch in closure arguments
57+
--> $DIR/expect-fn-supply-fn.rs:43:5
5058
|
5159
LL | with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
52-
| ^^^^^^^^^^^ one type is more general than the other
60+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------- found signature of `fn(fn(&'x u32), _) -> _`
61+
| |
62+
| expected signature of `for<'r> fn(for<'s> fn(&'s u32), &'r i32) -> _`
5363
|
54-
= note: expected fn pointer `for<'r> fn(&'r u32)`
55-
found fn pointer `fn(&'x u32)`
64+
note: required by a bound in `with_closure_expecting_fn_with_bound_region`
65+
--> $DIR/expect-fn-supply-fn.rs:13:8
66+
|
67+
LL | fn with_closure_expecting_fn_with_bound_region<F>(_: F)
68+
| ------------------------------------------- required by a bound in this
69+
LL | where
70+
LL | F: FnOnce(fn(&u32), &i32),
71+
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `with_closure_expecting_fn_with_bound_region`
5672

57-
error[E0308]: mismatched types
58-
--> $DIR/expect-fn-supply-fn.rs:54:53
73+
error[E0631]: type mismatch in closure arguments
74+
--> $DIR/expect-fn-supply-fn.rs:52:5
5975
|
6076
LL | with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
61-
| ^^^^^^^ one type is more general than the other
77+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- found signature of `for<'r> fn(for<'r> fn(&'r u32), _) -> _`
78+
| |
79+
| expected signature of `for<'r> fn(for<'s> fn(&'s u32), &'r i32) -> _`
80+
|
81+
note: required by a bound in `with_closure_expecting_fn_with_bound_region`
82+
--> $DIR/expect-fn-supply-fn.rs:13:8
6283
|
63-
= note: expected fn pointer `for<'r> fn(&'r u32)`
64-
found fn pointer `fn(&u32)`
84+
LL | fn with_closure_expecting_fn_with_bound_region<F>(_: F)
85+
| ------------------------------------------- required by a bound in this
86+
LL | where
87+
LL | F: FnOnce(fn(&u32), &i32),
88+
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `with_closure_expecting_fn_with_bound_region`
6589

6690
error: aborting due to 5 previous errors
6791

68-
For more information about this error, try `rustc --explain E0308`.
92+
Some errors have detailed explanations: E0308, E0631.
93+
For more information about an error, try `rustc --explain E0308`.
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,54 @@
1-
error: lifetime may not live long enough
2-
--> $DIR/expect-fn-supply-fn.rs:20: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:20: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:38:49
1+
error[E0631]: type mismatch in closure arguments
2+
--> $DIR/expect-fn-supply-fn.rs:36:5
243
|
254
LL | with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
26-
| ^ one type is more general than the other
27-
|
28-
= note: expected fn pointer `for<'r> fn(&'r u32)`
29-
found fn pointer `fn(&u32)`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------- found signature of `fn(for<'r> fn(&'r u32), _) -> _`
6+
| |
7+
| expected signature of `for<'a, 'r> fn(for<'a> fn(&'a u32), &'r i32) -> _`
8+
|
9+
note: required by a bound in `with_closure_expecting_fn_with_free_region`
10+
--> $DIR/expect-fn-supply-fn.rs:7:8
11+
|
12+
LL | fn with_closure_expecting_fn_with_free_region<F>(_: F)
13+
| ------------------------------------------ required by a bound in this
14+
LL | where
15+
LL | F: for<'a> FnOnce(fn(&'a u32), &i32),
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `with_closure_expecting_fn_with_free_region`
3017

31-
error[E0308]: mismatched types
32-
--> $DIR/expect-fn-supply-fn.rs:45:50
18+
error[E0631]: type mismatch in closure arguments
19+
--> $DIR/expect-fn-supply-fn.rs:43:5
3320
|
3421
LL | with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
35-
| ^ one type is more general than the other
36-
|
37-
= note: expected fn pointer `fn(&'x u32)`
38-
found fn pointer `for<'r> fn(&'r u32)`
22+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------- found signature of `fn(fn(&'x u32), _) -> _`
23+
| |
24+
| expected signature of `for<'r> fn(for<'s> fn(&'s u32), &'r i32) -> _`
25+
|
26+
note: required by a bound in `with_closure_expecting_fn_with_bound_region`
27+
--> $DIR/expect-fn-supply-fn.rs:13:8
28+
|
29+
LL | fn with_closure_expecting_fn_with_bound_region<F>(_: F)
30+
| ------------------------------------------- required by a bound in this
31+
LL | where
32+
LL | F: FnOnce(fn(&u32), &i32),
33+
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `with_closure_expecting_fn_with_bound_region`
3934

40-
error[E0308]: mismatched types
41-
--> $DIR/expect-fn-supply-fn.rs:54:50
35+
error[E0631]: type mismatch in closure arguments
36+
--> $DIR/expect-fn-supply-fn.rs:52:5
4237
|
4338
LL | with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
44-
| ^ one type is more general than the other
45-
|
46-
= note: expected fn pointer `fn(&u32)`
47-
found fn pointer `for<'r> fn(&'r u32)`
39+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- found signature of `for<'r> fn(for<'r> fn(&'r u32), _) -> _`
40+
| |
41+
| expected signature of `for<'r> fn(for<'s> fn(&'s u32), &'r i32) -> _`
42+
|
43+
note: required by a bound in `with_closure_expecting_fn_with_bound_region`
44+
--> $DIR/expect-fn-supply-fn.rs:13:8
45+
|
46+
LL | fn with_closure_expecting_fn_with_bound_region<F>(_: F)
47+
| ------------------------------------------- required by a bound in this
48+
LL | where
49+
LL | F: FnOnce(fn(&u32), &i32),
50+
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `with_closure_expecting_fn_with_bound_region`
4851

49-
error: aborting due to 5 previous errors
52+
error: aborting due to 3 previous errors
5053

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

src/test/ui/closure-expected-type/expect-fn-supply-fn.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ fn expect_free_supply_free_from_fn<'x>(x: &'x u32) {
2020
with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {});
2121
//[base]~^ ERROR mismatched types
2222
//[base]~| ERROR mismatched types
23-
//[nll]~^^^ ERROR lifetime may not live long enough
24-
//[nll]~| ERROR lifetime may not live long enough
2523
}
2624

2725
fn expect_free_supply_free_from_closure() {
@@ -36,14 +34,14 @@ fn expect_free_supply_bound() {
3634
// Here, we are given a function whose region is bound at closure level,
3735
// but we expect one bound in the argument. Error results.
3836
with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
39-
//~^ ERROR mismatched types
37+
//~^ ERROR type mismatch in closure arguments
4038
}
4139

4240
fn expect_bound_supply_free_from_fn<'x>(x: &'x u32) {
4341
// Here, we are given a `fn(&u32)` but we expect a `fn(&'x
4442
// u32)`. In principle, this could be ok, but we demand equality.
4543
with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
46-
//~^ ERROR mismatched types
44+
//~^ ERROR type mismatch in closure arguments
4745
}
4846

4947
fn expect_bound_supply_free_from_closure() {
@@ -52,7 +50,7 @@ fn expect_bound_supply_free_from_closure() {
5250
// the argument level.
5351
type Foo<'a> = fn(&'a u32);
5452
with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
55-
//~^ ERROR mismatched types
53+
//~^ ERROR type mismatch in closure arguments
5654
});
5755
}
5856

src/test/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

src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr

-13
This file was deleted.

src/test/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() {}

0 commit comments

Comments
 (0)