Add tests for trivial bounds

This commit is contained in:
Matthew Jasper 2018-05-06 22:54:00 +01:00
parent dabb820b00
commit 9b0dfe184e
17 changed files with 587 additions and 0 deletions

View File

@ -0,0 +1,29 @@
// Copyright 2018 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.
// run-pass
// Inconsistent bounds with trait implementations
#![feature(trivial_bounds)]
#![allow(unused)]
trait A {
fn foo(&self) -> Self where Self: Copy;
}
impl A for str {
fn foo(&self) -> Self where Self: Copy { *"" }
}
impl A for i32 {
fn foo(&self) -> Self { 3 }
}
fn main() {}

View File

@ -0,0 +1,19 @@
error[E0596]: cannot borrow immutable item `**t` as mutable
--> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:16:5
|
LL | *t //~ ERROR
| ^^ cannot borrow as mutable
|
= note: the value which is causing this path not to be mutable is...: `*t`
error[E0596]: cannot borrow immutable item `**t` as mutable
--> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:20:6
|
LL | {*t} //~ ERROR
| ^^ cannot borrow as mutable
|
= note: the value which is causing this path not to be mutable is...: `*t`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0596`.

View File

@ -0,0 +1,23 @@
// Copyright 2018 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.
// Check that reborrows are still illegal with Copy mutable references
#![feature(trivial_bounds)]
#![allow(unused)]
fn reborrow_mut<'a>(t: &'a &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
*t //~ ERROR
}
fn copy_reborrow_mut<'a>(t: &'a &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
{*t} //~ ERROR
}
fn main() {}

View File

@ -0,0 +1,19 @@
error[E0389]: cannot borrow data mutably in a `&` reference
--> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:16:5
|
LL | fn reborrow_mut<'a>(t: &'a &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
| --------------- use `&'a mut &'a mut i32` here to make mutable
LL | *t //~ ERROR
| ^^ assignment into an immutable reference
error[E0389]: cannot borrow data mutably in a `&` reference
--> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:20:6
|
LL | fn copy_reborrow_mut<'a>(t: &'a &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
| --------------- use `&'a mut &'a mut i32` here to make mutable
LL | {*t} //~ ERROR
| ^^ assignment into an immutable reference
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0389`.

View File

@ -0,0 +1,43 @@
// Copyright 2018 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.
// run-pass
// Check tautalogically false `Copy` bounds
#![feature(trivial_bounds)]
#![allow(unused)]
fn copy_string(t: String) -> String where String: Copy {
is_copy(&t);
let x = t;
drop(t);
t
}
fn copy_out_string(t: &String) -> String where String: Copy {
*t
}
fn copy_string_with_param<T>(x: String) where String: Copy {
let y = x;
let z = x;
}
// Check that no reborrowing occurs
fn copy_mut<'a>(t: &&'a mut i32) -> &'a mut i32 where for<'b> &'b mut i32: Copy {
is_copy(t);
let x = *t;
drop(x);
x
}
fn is_copy<T: Copy>(t: &T) {}
fn main() {}

View File

@ -0,0 +1,41 @@
warning: Trait bound std::string::String: std::marker::Copy does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent-copy.rs:16:1
|
LL | / fn copy_string(t: String) -> String where String: Copy {
LL | | is_copy(&t);
LL | | let x = t;
LL | | drop(t);
LL | | t
LL | | }
| |_^
|
= note: #[warn(trivial_bounds)] on by default
warning: Trait bound std::string::String: std::marker::Copy does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent-copy.rs:23:1
|
LL | / fn copy_out_string(t: &String) -> String where String: Copy {
LL | | *t
LL | | }
| |_^
warning: Trait bound std::string::String: std::marker::Copy does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent-copy.rs:27:1
|
LL | / fn copy_string_with_param<T>(x: String) where String: Copy {
LL | | let y = x;
LL | | let z = x;
LL | | }
| |_^
warning: Trait bound for<'b> &'b mut i32: std::marker::Copy does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent-copy.rs:33:1
|
LL | / fn copy_mut<'a>(t: &&'a mut i32) -> &'a mut i32 where for<'b> &'b mut i32: Copy {
LL | | is_copy(t);
LL | | let x = *t;
LL | | drop(x);
LL | | x
LL | | }
| |_^

View File

@ -0,0 +1,34 @@
// Copyright 2018 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.
// run-pass
// Check tautalogically false `Sized` bounds
#![feature(trivial_bounds)]
#![allow(unused)]
trait A {}
impl A for i32 {}
struct T<X: ?Sized> {
x: X,
}
struct S(str, str) where str: Sized;
fn unsized_local() where for<'a> T<A + 'a>: Sized {
let x: T<A> = *(Box::new(T { x: 1 }) as Box<T<A>>);
}
fn return_str() -> str where str: Sized {
*"Sized".to_string().into_boxed_str()
}
fn main() {}

View File

@ -0,0 +1,24 @@
warning: Trait bound str: std::marker::Sized does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent-sized.rs:24:1
|
LL | struct S(str, str) where str: Sized;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(trivial_bounds)] on by default
warning: Trait bound for<'a> T<A + 'a>: std::marker::Sized does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent-sized.rs:26:1
|
LL | / fn unsized_local() where for<'a> T<A + 'a>: Sized {
LL | | let x: T<A> = *(Box::new(T { x: 1 }) as Box<T<A>>);
LL | | }
| |_^
warning: Trait bound str: std::marker::Sized does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent-sized.rs:30:1
|
LL | / fn return_str() -> str where str: Sized {
LL | | *"Sized".to_string().into_boxed_str()
LL | | }
| |_^

View File

@ -0,0 +1,22 @@
// Copyright 2018 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.
// run-pass
// Test that inconsistent bounds are used in well-formedness checks
#![feature(trivial_bounds)]
use std::fmt::Debug;
pub fn foo() where Vec<str>: Debug, str: Copy {
let x = vec![*"1"];
println!("{:?}", x);
}
fn main() {}

View File

@ -0,0 +1,20 @@
warning: Trait bound std::vec::Vec<str>: std::fmt::Debug does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent-well-formed.rs:17:1
|
LL | / pub fn foo() where Vec<str>: Debug, str: Copy {
LL | | let x = vec![*"1"];
LL | | println!("{:?}", x);
LL | | }
| |_^
|
= note: #[warn(trivial_bounds)] on by default
warning: Trait bound str: std::marker::Copy does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent-well-formed.rs:17:1
|
LL | / pub fn foo() where Vec<str>: Debug, str: Copy {
LL | | let x = vec![*"1"];
LL | | println!("{:?}", x);
LL | | }
| |_^

View File

@ -0,0 +1,81 @@
// Copyright 2018 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.
// run-pass
// Check that tautalogically false bounds are accepted, and are used
// in type inference.
#![feature(trivial_bounds)]
#![allow(unused)]
pub trait Foo {
fn test(&self);
}
fn generic_function<X: Foo>(x: X) {}
enum E where i32: Foo { V }
struct S where i32: Foo;
trait T where i32: Foo {}
union U where i32: Foo { f: i32 }
type Y where i32: Foo = ();
impl Foo for () where i32: Foo {
fn test(&self) {
3i32.test();
Foo::test(&4i32);
generic_function(5i32);
}
}
fn f() where i32: Foo {
let s = S;
3i32.test();
Foo::test(&4i32);
generic_function(5i32);
}
fn g() where &'static str: Foo {
"Foo".test();
Foo::test(&"Foo");
generic_function("Foo");
}
trait A {}
impl A for i32 {}
struct Dst<X: ?Sized> {
x: X,
}
struct TwoStrs(str, str) where str: Sized;
fn unsized_local() where for<'a> Dst<A + 'a>: Sized {
let x: Dst<A> = *(Box::new(Dst { x: 1 }) as Box<Dst<A>>);
}
fn return_str() -> str where str: Sized {
*"Sized".to_string().into_boxed_str()
}
fn use_op(s: String) -> String where String: ::std::ops::Neg<Output=String> {
-s
}
fn use_for() where i32: Iterator {
for _ in 2i32 {}
}
fn main() {}

View File

@ -0,0 +1,112 @@
warning: Trait bound i32: Foo does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent.rs:24:1
|
LL | enum E where i32: Foo { V }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(trivial_bounds)] on by default
warning: Trait bound i32: Foo does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent.rs:26:1
|
LL | struct S where i32: Foo;
| ^^^^^^^^^^^^^^^^^^^^^^^^
warning: Trait bound i32: Foo does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent.rs:28:1
|
LL | trait T where i32: Foo {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: Trait bound i32: Foo does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent.rs:30:1
|
LL | union U where i32: Foo { f: i32 }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: where clauses are not enforced in type aliases
--> $DIR/trivial-bounds-inconsistent.rs:32:14
|
LL | type Y where i32: Foo = ();
| ^^^^^^^^
|
= note: #[warn(type_alias_bounds)] on by default
= help: the clause will not be checked when the type alias is used, and should be removed
warning: Trait bound i32: Foo does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent.rs:32:1
|
LL | type Y where i32: Foo = ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: Trait bound i32: Foo does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent.rs:34:1
|
LL | / impl Foo for () where i32: Foo {
LL | | fn test(&self) {
LL | | 3i32.test();
LL | | Foo::test(&4i32);
LL | | generic_function(5i32);
LL | | }
LL | | }
| |_^
warning: Trait bound i32: Foo does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent.rs:42:1
|
LL | / fn f() where i32: Foo {
LL | | let s = S;
LL | | 3i32.test();
LL | | Foo::test(&4i32);
LL | | generic_function(5i32);
LL | | }
| |_^
warning: Trait bound &'static str: Foo does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent.rs:49:1
|
LL | / fn g() where &'static str: Foo {
LL | | "Foo".test();
LL | | Foo::test(&"Foo");
LL | | generic_function("Foo");
LL | | }
| |_^
warning: Trait bound str: std::marker::Sized does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent.rs:63:1
|
LL | struct TwoStrs(str, str) where str: Sized;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: Trait bound for<'a> Dst<A + 'a>: std::marker::Sized does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent.rs:65:1
|
LL | / fn unsized_local() where for<'a> Dst<A + 'a>: Sized {
LL | | let x: Dst<A> = *(Box::new(Dst { x: 1 }) as Box<Dst<A>>);
LL | | }
| |_^
warning: Trait bound str: std::marker::Sized does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent.rs:69:1
|
LL | / fn return_str() -> str where str: Sized {
LL | | *"Sized".to_string().into_boxed_str()
LL | | }
| |_^
warning: Trait bound std::string::String: std::ops::Neg does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent.rs:73:1
|
LL | / fn use_op(s: String) -> String where String: ::std::ops::Neg<Output=String> {
LL | | -s
LL | | }
| |_^
warning: Trait bound i32: std::iter::Iterator does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent.rs:77:1
|
LL | / fn use_for() where i32: Iterator {
LL | | for _ in 2i32 {}
LL | | }
| |_^

View File

@ -0,0 +1,22 @@
// Copyright 2018 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.
// Check that false Copy bounds don't leak
#![feature(trivial_bounds)]
fn copy_out_string(t: &String) -> String where String: Copy {
*t
}
fn move_out_string(t: &String) -> String {
*t //~ ERROR
}
fn main() {}

View File

@ -0,0 +1,9 @@
error[E0507]: cannot move out of borrowed content
--> $DIR/trivial-bounds-leak-copy.rs:19:5
|
LL | *t //~ ERROR
| ^^ cannot move out of borrowed content
error: aborting due to previous error
For more information about this error, try `rustc --explain E0507`.

View File

@ -0,0 +1,42 @@
// Copyright 2018 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.
// Check that false bounds don't leak
#![feature(trivial_bounds)]
pub trait Foo {
fn test(&self);
}
fn return_str() -> str where str: Sized {
*"Sized".to_string().into_boxed_str()
}
fn cant_return_str() -> str { //~ ERROR
*"Sized".to_string().into_boxed_str()
}
fn my_function() where i32: Foo
{
3i32.test();
Foo::test(&4i32);
generic_function(5i32);
}
fn foo() {
3i32.test(); //~ ERROR
Foo::test(&4i32); //~ ERROR
generic_function(5i32); //~ ERROR
}
fn generic_function<T: Foo>(t: T) {}
fn main() {}

View File

@ -0,0 +1,47 @@
error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
--> $DIR/trivial-bounds-leak.rs:22:25
|
LL | fn cant_return_str() -> str { //~ ERROR
| ^^^ `str` does not have a constant size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `str`
= note: the return type of a function must have a statically known size
error[E0599]: no method named `test` found for type `i32` in the current scope
--> $DIR/trivial-bounds-leak.rs:34:10
|
LL | 3i32.test(); //~ ERROR
| ^^^^
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `test`, perhaps you need to implement it:
candidate #1: `Foo`
error[E0277]: the trait bound `i32: Foo` is not satisfied
--> $DIR/trivial-bounds-leak.rs:35:5
|
LL | Foo::test(&4i32); //~ ERROR
| ^^^^^^^^^ the trait `Foo` is not implemented for `i32`
|
note: required by `Foo::test`
--> $DIR/trivial-bounds-leak.rs:15:5
|
LL | fn test(&self);
| ^^^^^^^^^^^^^^^
error[E0277]: the trait bound `i32: Foo` is not satisfied
--> $DIR/trivial-bounds-leak.rs:36:5
|
LL | generic_function(5i32); //~ ERROR
| ^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `i32`
|
note: required by `generic_function`
--> $DIR/trivial-bounds-leak.rs:39:1
|
LL | fn generic_function<T: Foo>(t: T) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 4 previous errors
Some errors occurred: E0277, E0599.
For more information about an error, try `rustc --explain E0277`.