Skip to content

Commit

Permalink
Split param-bounds-ignored into two, it was testing two independent t…
Browse files Browse the repository at this point in the history
…hings

Also, tweak the test for ignored type aliases such that replacing the type alias
by a newtype struct leads to a well-formed type definition, and errors when used
the way the type alias is used.
  • Loading branch information
RalfJung committed Mar 10, 2018
1 parent 3edb3cc commit 81130ed
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 62 deletions.
Expand Up @@ -10,31 +10,7 @@

#![allow(dead_code, non_camel_case_types)]

use std::rc::Rc;

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.
let mut x : SVec<_> = Vec::new();
x.push(Rc::new(42));

let mut x : VVec<'static, 'a> = Vec::new();
x.push(y);

let mut x : WVec<'static, & 'a i32> = Vec::new();
x.push(y);

let mut x : W2Vec<'static, & 'a i32> = Vec::new();
x.push(y);
}
// Test that bounds on higher-kinded lifetime binders are rejected.

fn bar1<'a, 'b>(
x: &'a i32,
Expand Down
@@ -1,94 +1,68 @@
error: lifetime bounds cannot be used in this context
--> $DIR/param-bounds-ignored.rs:42:22
--> $DIR/higher-lifetime-bounds.rs:18:22
|
LL | f: for<'xa, 'xb: 'xa+'xa> fn(&'xa i32, &'xb i32) -> &'xa i32)
| ^^^ ^^^

error: lifetime bounds cannot be used in this context
--> $DIR/param-bounds-ignored.rs:50:34
--> $DIR/higher-lifetime-bounds.rs:26:34
|
LL | 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
--> $DIR/param-bounds-ignored.rs:65:28
--> $DIR/higher-lifetime-bounds.rs:41:28
|
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
--> $DIR/higher-lifetime-bounds.rs:53: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
--> $DIR/higher-lifetime-bounds.rs:61: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
--> $DIR/higher-lifetime-bounds.rs:63: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
--> $DIR/higher-lifetime-bounds.rs:65: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
--> $DIR/higher-lifetime-bounds.rs:68: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
--> $DIR/higher-lifetime-bounds.rs:71: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
--> $DIR/higher-lifetime-bounds.rs:75: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
--> $DIR/higher-lifetime-bounds.rs:77: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

51 changes: 51 additions & 0 deletions src/test/ui/type-alias-bounds.rs
@@ -0,0 +1,51 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Test ignored_generic_bounds lint warning about bounds in type aliases

// must-compile-successfully
#![allow(dead_code)]

use std::rc::Rc;

type SVec<T: Send+Send> = Vec<T>;
//~^ WARN bounds on generic parameters are ignored in type aliases
type S2Vec<T> where T: Send = Vec<T>;
//~^ WARN where clauses are ignored in type aliases
type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>);
//~^ WARN bounds on generic parameters are ignored in type aliases
type WVec<'b, T: 'b+'b> = (&'b u32, Vec<T>);
//~^ WARN bounds on generic parameters are ignored in type aliases
type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>);
//~^ WARN where clauses are ignored in type aliases

static STATIC : u32 = 0;

fn foo<'a>(y: &'a i32) {
// If any of the bounds above would matter, the code below would be rejected.
// This can be seen when replacing the type aliases above by newtype structs.
// (The type aliases have no unused parameters to make that a valid transformation.)
let mut x : SVec<_> = Vec::new();
x.push(Rc::new(42)); // is not send

let mut x : S2Vec<_> = Vec::new();
x.push(Rc::new(42)); // is not send

let mut x : VVec<'static, 'a> = (&STATIC, Vec::new());
x.1.push(y); // 'a: 'static does not hold

let mut x : WVec<'static, &'a i32> = (&STATIC, Vec::new());
x.1.push(y); // &'a i32: 'static does not hold

let mut x : W2Vec<'static, &'a i32> = (&STATIC, Vec::new());
x.1.push(y); // &'a i32: 'static does not hold
}

fn main() {}
32 changes: 32 additions & 0 deletions src/test/ui/type-alias-bounds.stderr
@@ -0,0 +1,32 @@
warning: bounds on generic parameters are ignored in type aliases
--> $DIR/type-alias-bounds.rs:18:14
|
LL | type SVec<T: Send+Send> = Vec<T>;
| ^^^^ ^^^^
|
= note: #[warn(ignored_generic_bounds)] on by default

warning: where clauses are ignored in type aliases
--> $DIR/type-alias-bounds.rs:20:21
|
LL | type S2Vec<T> where T: Send = Vec<T>;
| ^^^^^^^

warning: bounds on generic parameters are ignored in type aliases
--> $DIR/type-alias-bounds.rs:22:19
|
LL | type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>);
| ^^ ^^

warning: bounds on generic parameters are ignored in type aliases
--> $DIR/type-alias-bounds.rs:24:18
|
LL | type WVec<'b, T: 'b+'b> = (&'b u32, Vec<T>);
| ^^ ^^

warning: where clauses are ignored in type aliases
--> $DIR/type-alias-bounds.rs:26:25
|
LL | type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>);
| ^^^^^ ^^^^^

0 comments on commit 81130ed

Please sign in to comment.