Auto merge of #48326 - RalfJung:generic-bounds, r=petrochenkov
Warn about ignored generic bounds in `for` This adds a new lint to fix #42181. For consistency and to avoid code duplication, I also moved the existing "bounds in type aliases are ignored" here. Questions to the reviewer: * Is it okay to just remove a diagnostic error code like this? Should I instead keep the warning about type aliases where it is? The old code provided a detailed explanation of what's going on when asked, that information is now lost. On the other hand, `span_warn!` seems deprecated (after this patch, it has exactly one user left!). * Did I miss any syntactic construct that can appear as `for` in the surface syntax? I covered function types (`for<'a> fn(...)`), generic traits (`for <'a> Fn(...)`, can appear both as bounds as as trait objects) and bounds (`for<'a> F: ...`). * For the sake of backwards compatibility, this adds a warning, not an error. @nikomatsakis suggested an error in https://github.com/rust-lang/rust/issues/42181#issuecomment-306924389, but I feel that can only happen in a new epoch -- right? Cc @eddyb
This commit is contained in:
commit
fedce67cd2
20 changed files with 325 additions and 109 deletions
|
|
@ -8,13 +8,18 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// must-compile-successfully
|
||||
#![allow(dead_code, non_camel_case_types)]
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
type SVec<T: Send> = Vec<T>;
|
||||
type VVec<'b, 'a: 'b> = Vec<&'a i32>;
|
||||
type WVec<'b, T: 'b> = Vec<T>;
|
||||
type SVec<T: Send+Send> = Vec<T>;
|
||||
//~^ WARN bounds on generic parameters are ignored in type aliases
|
||||
type VVec<'b, 'a: 'b+'b> = Vec<&'a i32>;
|
||||
//~^ WARN bounds on generic parameters are ignored in type aliases
|
||||
type WVec<'b, T: 'b+'b> = Vec<T>;
|
||||
//~^ WARN bounds on generic parameters are ignored in type aliases
|
||||
type W2Vec<'b, T> where T: 'b, T: 'b = Vec<T>;
|
||||
//~^ WARN where clauses are ignored in type aliases
|
||||
|
||||
fn foo<'a>(y: &'a i32) {
|
||||
// If the bounds above would matter, the code below would be rejected.
|
||||
|
|
@ -26,8 +31,73 @@ fn foo<'a>(y: &'a i32) {
|
|||
|
||||
let mut x : WVec<'static, & 'a i32> = Vec::new();
|
||||
x.push(y);
|
||||
|
||||
let mut x : W2Vec<'static, & 'a i32> = Vec::new();
|
||||
x.push(y);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo(&42);
|
||||
fn bar1<'a, 'b>(
|
||||
x: &'a i32,
|
||||
y: &'b i32,
|
||||
f: for<'xa, 'xb: 'xa+'xa> fn(&'xa i32, &'xb i32) -> &'xa i32)
|
||||
//~^ ERROR lifetime bounds cannot be used in this context
|
||||
{
|
||||
// If the bound in f's type would matter, the call below would (have to)
|
||||
// be rejected.
|
||||
f(x, y);
|
||||
}
|
||||
|
||||
fn bar2<'a, 'b, F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>(
|
||||
//~^ ERROR lifetime bounds cannot be used in this context
|
||||
x: &'a i32,
|
||||
y: &'b i32,
|
||||
f: F)
|
||||
{
|
||||
// If the bound in f's type would matter, the call below would (have to)
|
||||
// be rejected.
|
||||
f(x, y);
|
||||
}
|
||||
|
||||
fn bar3<'a, 'b, F>(
|
||||
x: &'a i32,
|
||||
y: &'b i32,
|
||||
f: F)
|
||||
where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32
|
||||
//~^ ERROR lifetime bounds cannot be used in this context
|
||||
{
|
||||
// If the bound in f's type would matter, the call below would (have to)
|
||||
// be rejected.
|
||||
f(x, y);
|
||||
}
|
||||
|
||||
fn bar4<'a, 'b, F>(
|
||||
x: &'a i32,
|
||||
y: &'b i32,
|
||||
f: F)
|
||||
where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32
|
||||
//~^ ERROR lifetime bounds cannot be used in this context
|
||||
{
|
||||
// If the bound in f's type would matter, the call below would (have to)
|
||||
// be rejected.
|
||||
f(x, y);
|
||||
}
|
||||
|
||||
struct S1<F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>(F);
|
||||
//~^ ERROR lifetime bounds cannot be used in this context
|
||||
struct S2<F>(F) where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32;
|
||||
//~^ ERROR lifetime bounds cannot be used in this context
|
||||
struct S3<F>(F) where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32;
|
||||
//~^ ERROR lifetime bounds cannot be used in this context
|
||||
|
||||
struct S_fnty(for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32);
|
||||
//~^ ERROR lifetime bounds cannot be used in this context
|
||||
|
||||
type T1 = Box<for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>;
|
||||
//~^ ERROR lifetime bounds cannot be used in this context
|
||||
|
||||
fn main() {
|
||||
let _ : Option<for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32> = None;
|
||||
//~^ ERROR lifetime bounds cannot be used in this context
|
||||
let _ : Option<Box<for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>> = None;
|
||||
//~^ ERROR lifetime bounds cannot be used in this context
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,94 @@
|
|||
warning[E0122]: generic bounds are ignored in type aliases
|
||||
--> $DIR/param-bounds-ignored.rs:15:1
|
||||
error: lifetime bounds cannot be used in this context
|
||||
--> $DIR/param-bounds-ignored.rs:42:22
|
||||
|
|
||||
LL | type SVec<T: Send> = Vec<T>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | f: for<'xa, 'xb: 'xa+'xa> fn(&'xa i32, &'xb i32) -> &'xa i32)
|
||||
| ^^^ ^^^
|
||||
|
||||
warning[E0122]: generic bounds are ignored in type aliases
|
||||
--> $DIR/param-bounds-ignored.rs:16:1
|
||||
error: lifetime bounds cannot be used in this context
|
||||
--> $DIR/param-bounds-ignored.rs:50:34
|
||||
|
|
||||
LL | type VVec<'b, 'a: 'b> = Vec<&'a i32>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | fn bar2<'a, 'b, F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>(
|
||||
| ^^^
|
||||
|
||||
warning[E0122]: generic bounds are ignored in type aliases
|
||||
--> $DIR/param-bounds-ignored.rs:17:1
|
||||
error: lifetime bounds cannot be used in this context
|
||||
--> $DIR/param-bounds-ignored.rs:65:28
|
||||
|
|
||||
LL | type WVec<'b, T: 'b> = Vec<T>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32
|
||||
| ^^^
|
||||
|
||||
error: lifetime bounds cannot be used in this context
|
||||
--> $DIR/param-bounds-ignored.rs:77:25
|
||||
|
|
||||
LL | where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32
|
||||
| ^^^
|
||||
|
||||
error: lifetime bounds cannot be used in this context
|
||||
--> $DIR/param-bounds-ignored.rs:85:28
|
||||
|
|
||||
LL | struct S1<F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>(F);
|
||||
| ^^^
|
||||
|
||||
error: lifetime bounds cannot be used in this context
|
||||
--> $DIR/param-bounds-ignored.rs:87:40
|
||||
|
|
||||
LL | struct S2<F>(F) where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32;
|
||||
| ^^^
|
||||
|
||||
error: lifetime bounds cannot be used in this context
|
||||
--> $DIR/param-bounds-ignored.rs:89:37
|
||||
|
|
||||
LL | struct S3<F>(F) where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32;
|
||||
| ^^^
|
||||
|
||||
error: lifetime bounds cannot be used in this context
|
||||
--> $DIR/param-bounds-ignored.rs:92:29
|
||||
|
|
||||
LL | struct S_fnty(for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32);
|
||||
| ^^^
|
||||
|
||||
error: lifetime bounds cannot be used in this context
|
||||
--> $DIR/param-bounds-ignored.rs:95:29
|
||||
|
|
||||
LL | type T1 = Box<for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>;
|
||||
| ^^^
|
||||
|
||||
error: lifetime bounds cannot be used in this context
|
||||
--> $DIR/param-bounds-ignored.rs:99:34
|
||||
|
|
||||
LL | let _ : Option<for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32> = None;
|
||||
| ^^^
|
||||
|
||||
error: lifetime bounds cannot be used in this context
|
||||
--> $DIR/param-bounds-ignored.rs:101:38
|
||||
|
|
||||
LL | let _ : Option<Box<for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>> = None;
|
||||
| ^^^
|
||||
|
||||
warning: bounds on generic parameters are ignored in type aliases
|
||||
--> $DIR/param-bounds-ignored.rs:15:14
|
||||
|
|
||||
LL | type SVec<T: Send+Send> = Vec<T>;
|
||||
| ^^^^ ^^^^
|
||||
|
|
||||
= note: #[warn(ignored_generic_bounds)] on by default
|
||||
|
||||
warning: bounds on generic parameters are ignored in type aliases
|
||||
--> $DIR/param-bounds-ignored.rs:17:19
|
||||
|
|
||||
LL | type VVec<'b, 'a: 'b+'b> = Vec<&'a i32>;
|
||||
| ^^ ^^
|
||||
|
||||
warning: bounds on generic parameters are ignored in type aliases
|
||||
--> $DIR/param-bounds-ignored.rs:19:18
|
||||
|
|
||||
LL | type WVec<'b, T: 'b+'b> = Vec<T>;
|
||||
| ^^ ^^
|
||||
|
||||
warning: where clauses are ignored in type aliases
|
||||
--> $DIR/param-bounds-ignored.rs:21:25
|
||||
|
|
||||
LL | type W2Vec<'b, T> where T: 'b, T: 'b = Vec<T>;
|
||||
| ^^^^^ ^^^^^
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue