Skip to content

Commit

Permalink
Rollup merge of rust-lang#58353 - matthewjasper:typeck-pattern-consta…
Browse files Browse the repository at this point in the history
…nts, r=arielb1

Check the Self-type of inherent associated constants

r? @arielb1
  • Loading branch information
Centril authored Feb 14, 2019
2 parents a62a203 + 283ffcf commit 983899b
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 30 deletions.
26 changes: 16 additions & 10 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2237,7 +2237,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
hir_id, def_id, substs, user_self_ty, self.tag(),
);

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

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

// If the type given by the user has free regions, save it for later, since
// NLL would like to enforce those. Also pass in types that involve
// projections, since those can resolve to `'static` bounds (modulo #54940,
// which hopefully will be fixed by the time you see this comment, dear
// reader, although I have my doubts). Also pass in types with inference
// types, because they may be repeated. Other sorts of things are already
// sufficiently enforced with erased regions. =)
fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
where
T: TypeFoldable<'tcx>
{
t.has_free_regions() || t.has_projections() || t.has_infer_types()
}

pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
match self.tables.borrow().node_types().get(id) {
Some(&t) => t,
Expand Down
4 changes: 3 additions & 1 deletion src/test/ui/nll/user-annotations/dump-adt-brace-struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@ fn main() {

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

SomeStruct::<u32> { t: 22 }; //~ ERROR [u32]
SomeStruct::<u32> { t: 22 }; // No lifetime bounds given.

SomeStruct::<&'static u32> { t: &22 }; //~ ERROR [&ReStatic u32]
}
8 changes: 4 additions & 4 deletions src/test/ui/nll/user-annotations/dump-adt-brace-struct.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error: user substs: UserSubsts { substs: [u32], user_self_ty: None }
--> $DIR/dump-adt-brace-struct.rs:18:5
error: user substs: UserSubsts { substs: [&ReStatic u32], user_self_ty: None }
--> $DIR/dump-adt-brace-struct.rs:20:5
|
LL | SomeStruct::<u32> { t: 22 }; //~ ERROR [u32]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | SomeStruct::<&'static u32> { t: &22 }; //~ ERROR [&ReStatic u32]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

19 changes: 14 additions & 5 deletions src/test/ui/nll/user-annotations/dump-fn-method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ trait Bazoom<T> {
fn method<U>(&self, arg: T, arg2: U) { }
}

impl<T, U> Bazoom<U> for T {
impl<S, T> Bazoom<T> for S {
}

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

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

let x = foo::<&'static u32>; //~ ERROR [&ReStatic u32]
x(&22);

// Here: we only want the `T` to be given, the rest should be variables.
//
// (`T` refers to the declaration of `Bazoom`)
let x = <_ as Bazoom<u32>>::method::<_>; //~ ERROR [^0, u32, ^1]
x(&22, 44, 66);

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

// Here: all are given and we have a lifetime.
let x = <u8 as Bazoom<&'static u16>>::method::<u32>; //~ ERROR [u8, &ReStatic u16, u32]
x(&22, &44, 66);

// Here: we want in particular that *only* the method `U`
// annotation is given, the rest are variables.
//
Expand Down
20 changes: 10 additions & 10 deletions src/test/ui/nll/user-annotations/dump-fn-method.stderr
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
error: user substs: UserSubsts { substs: [u32], user_self_ty: None }
--> $DIR/dump-fn-method.rs:26:13
error: user substs: UserSubsts { substs: [&ReStatic u32], user_self_ty: None }
--> $DIR/dump-fn-method.rs:30:13
|
LL | let x = foo::<u32>; //~ ERROR [u32]
| ^^^^^^^^^^
LL | let x = foo::<&'static u32>; //~ ERROR [&ReStatic u32]
| ^^^^^^^^^^^^^^^^^^^

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

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

error: user substs: UserSubsts { substs: [^0, ^1, u32], user_self_ty: None }
--> $DIR/dump-fn-method.rs:44:5
--> $DIR/dump-fn-method.rs:53:5
|
LL | y.method::<u32>(44, 66); //~ ERROR [^0, ^1, u32]
| ^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
17 changes: 17 additions & 0 deletions src/test/ui/nll/user-annotations/inherent-associated-constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#![feature(nll)]

struct A<'a>(&'a ());

impl A<'static> {
const IC: i32 = 10;
}

fn non_wf_associated_const<'a>(x: i32) {
A::<'a>::IC; //~ ERROR lifetime may not live long enough
}

fn wf_associated_const<'a>(x: i32) {
A::<'static>::IC;
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
error: lifetime may not live long enough
--> $DIR/inherent-associated-constants.rs:10:5
|
LL | fn non_wf_associated_const<'a>(x: i32) {
| -- lifetime `'a` defined here
LL | A::<'a>::IC; //~ ERROR lifetime may not live long enough
| ^^^^^^^^^^^ requires that `'a` must outlive `'static`

error: aborting due to previous error

0 comments on commit 983899b

Please sign in to comment.