Skip to content

Commit 983899b

Browse files
authored
Rollup merge of rust-lang#58353 - matthewjasper:typeck-pattern-constants, r=arielb1
Check the Self-type of inherent associated constants r? @arielb1
2 parents a62a203 + 283ffcf commit 983899b

7 files changed

+74
-30
lines changed

src/librustc_typeck/check/mod.rs

+16-10
Original file line numberDiff line numberDiff line change
@@ -2237,7 +2237,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
22372237
hir_id, def_id, substs, user_self_ty, self.tag(),
22382238
);
22392239

2240-
if !substs.is_noop() {
2240+
if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
22412241
let canonicalized = self.infcx.canonicalize_user_type_annotation(
22422242
&UserType::TypeOf(def_id, UserSubsts {
22432243
substs,
@@ -2432,15 +2432,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
24322432
let ty = self.to_ty(ast_ty);
24332433
debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
24342434

2435-
// If the type given by the user has free regions, save it for
2436-
// later, since NLL would like to enforce those. Also pass in
2437-
// types that involve projections, since those can resolve to
2438-
// `'static` bounds (modulo #54940, which hopefully will be
2439-
// fixed by the time you see this comment, dear reader,
2440-
// although I have my doubts). Also pass in types with inference
2441-
// types, because they may be repeated. Other sorts of things
2442-
// are already sufficiently enforced with erased regions. =)
2443-
if ty.has_free_regions() || ty.has_projections() || ty.has_infer_types() {
2435+
if Self::can_contain_user_lifetime_bounds(ty) {
24442436
let c_ty = self.infcx.canonicalize_response(&UserType::Ty(ty));
24452437
debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
24462438
self.tables.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
@@ -2449,6 +2441,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
24492441
ty
24502442
}
24512443

2444+
// If the type given by the user has free regions, save it for later, since
2445+
// NLL would like to enforce those. Also pass in types that involve
2446+
// projections, since those can resolve to `'static` bounds (modulo #54940,
2447+
// which hopefully will be fixed by the time you see this comment, dear
2448+
// reader, although I have my doubts). Also pass in types with inference
2449+
// types, because they may be repeated. Other sorts of things are already
2450+
// sufficiently enforced with erased regions. =)
2451+
fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
2452+
where
2453+
T: TypeFoldable<'tcx>
2454+
{
2455+
t.has_free_regions() || t.has_projections() || t.has_infer_types()
2456+
}
2457+
24522458
pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
24532459
match self.tables.borrow().node_types().get(id) {
24542460
Some(&t) => t,

src/test/ui/nll/user-annotations/dump-adt-brace-struct.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,7 @@ fn main() {
1515

1616
SomeStruct::<_> { t: 22 }; // Nothing interesting given, no annotation.
1717

18-
SomeStruct::<u32> { t: 22 }; //~ ERROR [u32]
18+
SomeStruct::<u32> { t: 22 }; // No lifetime bounds given.
19+
20+
SomeStruct::<&'static u32> { t: &22 }; //~ ERROR [&ReStatic u32]
1921
}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: user substs: UserSubsts { substs: [u32], user_self_ty: None }
2-
--> $DIR/dump-adt-brace-struct.rs:18:5
1+
error: user substs: UserSubsts { substs: [&ReStatic u32], user_self_ty: None }
2+
--> $DIR/dump-adt-brace-struct.rs:20:5
33
|
4-
LL | SomeStruct::<u32> { t: 22 }; //~ ERROR [u32]
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
4+
LL | SomeStruct::<&'static u32> { t: &22 }; //~ ERROR [&ReStatic u32]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66

77
error: aborting due to previous error
88

src/test/ui/nll/user-annotations/dump-fn-method.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ trait Bazoom<T> {
1111
fn method<U>(&self, arg: T, arg2: U) { }
1212
}
1313

14-
impl<T, U> Bazoom<U> for T {
14+
impl<S, T> Bazoom<T> for S {
1515
}
1616

1717
fn foo<'a, T>(_: T) { }
@@ -22,20 +22,29 @@ fn main() {
2222
let x = foo;
2323
x(22);
2424

25-
// Here: `u32` is given.
26-
let x = foo::<u32>; //~ ERROR [u32]
25+
// Here: `u32` is given, which doesn't contain any lifetimes, so we don't
26+
// have any annotation.
27+
let x = foo::<u32>;
2728
x(22);
2829

30+
let x = foo::<&'static u32>; //~ ERROR [&ReStatic u32]
31+
x(&22);
32+
2933
// Here: we only want the `T` to be given, the rest should be variables.
3034
//
3135
// (`T` refers to the declaration of `Bazoom`)
3236
let x = <_ as Bazoom<u32>>::method::<_>; //~ ERROR [^0, u32, ^1]
3337
x(&22, 44, 66);
3438

35-
// Here: all are given
36-
let x = <u8 as Bazoom<u16>>::method::<u32>; //~ ERROR [u8, u16, u32]
39+
// Here: all are given and definitely contain no lifetimes, so we
40+
// don't have any annotation.
41+
let x = <u8 as Bazoom<u16>>::method::<u32>;
3742
x(&22, 44, 66);
3843

44+
// Here: all are given and we have a lifetime.
45+
let x = <u8 as Bazoom<&'static u16>>::method::<u32>; //~ ERROR [u8, &ReStatic u16, u32]
46+
x(&22, &44, 66);
47+
3948
// Here: we want in particular that *only* the method `U`
4049
// annotation is given, the rest are variables.
4150
//

src/test/ui/nll/user-annotations/dump-fn-method.stderr

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
1-
error: user substs: UserSubsts { substs: [u32], user_self_ty: None }
2-
--> $DIR/dump-fn-method.rs:26:13
1+
error: user substs: UserSubsts { substs: [&ReStatic u32], user_self_ty: None }
2+
--> $DIR/dump-fn-method.rs:30:13
33
|
4-
LL | let x = foo::<u32>; //~ ERROR [u32]
5-
| ^^^^^^^^^^
4+
LL | let x = foo::<&'static u32>; //~ ERROR [&ReStatic u32]
5+
| ^^^^^^^^^^^^^^^^^^^
66

77
error: user substs: UserSubsts { substs: [^0, u32, ^1], user_self_ty: None }
8-
--> $DIR/dump-fn-method.rs:32:13
8+
--> $DIR/dump-fn-method.rs:36:13
99
|
1010
LL | let x = <_ as Bazoom<u32>>::method::<_>; //~ ERROR [^0, u32, ^1]
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1212

13-
error: user substs: UserSubsts { substs: [u8, u16, u32], user_self_ty: None }
14-
--> $DIR/dump-fn-method.rs:36:13
13+
error: user substs: UserSubsts { substs: [u8, &ReStatic u16, u32], user_self_ty: None }
14+
--> $DIR/dump-fn-method.rs:45:13
1515
|
16-
LL | let x = <u8 as Bazoom<u16>>::method::<u32>; //~ ERROR [u8, u16, u32]
17-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
16+
LL | let x = <u8 as Bazoom<&'static u16>>::method::<u32>; //~ ERROR [u8, &ReStatic u16, u32]
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1818

1919
error: user substs: UserSubsts { substs: [^0, ^1, u32], user_self_ty: None }
20-
--> $DIR/dump-fn-method.rs:44:5
20+
--> $DIR/dump-fn-method.rs:53:5
2121
|
2222
LL | y.method::<u32>(44, 66); //~ ERROR [^0, ^1, u32]
2323
| ^^^^^^^^^^^^^^^^^^^^^^^
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#![feature(nll)]
2+
3+
struct A<'a>(&'a ());
4+
5+
impl A<'static> {
6+
const IC: i32 = 10;
7+
}
8+
9+
fn non_wf_associated_const<'a>(x: i32) {
10+
A::<'a>::IC; //~ ERROR lifetime may not live long enough
11+
}
12+
13+
fn wf_associated_const<'a>(x: i32) {
14+
A::<'static>::IC;
15+
}
16+
17+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: lifetime may not live long enough
2+
--> $DIR/inherent-associated-constants.rs:10:5
3+
|
4+
LL | fn non_wf_associated_const<'a>(x: i32) {
5+
| -- lifetime `'a` defined here
6+
LL | A::<'a>::IC; //~ ERROR lifetime may not live long enough
7+
| ^^^^^^^^^^^ requires that `'a` must outlive `'static`
8+
9+
error: aborting due to previous error
10+

0 commit comments

Comments
 (0)