-
Notifications
You must be signed in to change notification settings - Fork 13.6k
fix fn/const items implied bounds and wf check #104098
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// The method `assert_static` should be callable only for static values, | ||
// because the impl has an implied bound `where T: 'static`. | ||
|
||
// check-fail | ||
|
||
trait AnyStatic<Witness>: Sized { | ||
fn assert_static(self) {} | ||
} | ||
|
||
impl<T> AnyStatic<&'static T> for T {} | ||
|
||
fn main() { | ||
(&String::new()).assert_static(); | ||
//~^ ERROR temporary value dropped while borrowed | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
error[E0716]: temporary value dropped while borrowed | ||
--> $DIR/fn-item-check-trait-ref.rs:13:7 | ||
| | ||
LL | (&String::new()).assert_static(); | ||
| --^^^^^^^^^^^^^------------------ temporary value is freed at the end of this statement | ||
| | | | ||
| | creates a temporary value which is freed while still in use | ||
| argument requires that borrow lasts for `'static` | ||
|
||
error: aborting due to previous error | ||
|
||
For more information about this error, try `rustc --explain E0716`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// Regression test for #104005. | ||
// | ||
// Previously, different borrowck implementations used to disagree here. | ||
// The status of each is documented on `fn test_*`. | ||
|
||
// check-fail | ||
|
||
use std::fmt::Display; | ||
|
||
trait Displayable { | ||
fn display(self) -> Box<dyn Display>; | ||
} | ||
|
||
impl<T: Display> Displayable for (T, Option<&'static T>) { | ||
fn display(self) -> Box<dyn Display> { | ||
Box::new(self.0) | ||
} | ||
} | ||
|
||
fn extend_lt<T, U>(val: T) -> Box<dyn Display> | ||
where | ||
(T, Option<U>): Displayable, | ||
{ | ||
Displayable::display((val, None)) | ||
} | ||
|
||
// AST: fail | ||
// HIR: pass | ||
// MIR: pass | ||
pub fn test_call<'a>(val: &'a str) { | ||
extend_lt(val); | ||
//~^ ERROR borrowed data escapes outside of function | ||
} | ||
|
||
// AST: fail | ||
// HIR: fail | ||
// MIR: pass | ||
pub fn test_coercion<'a>() { | ||
let _: fn(&'a str) -> _ = extend_lt; | ||
//~^ ERROR lifetime may not live long enough | ||
} | ||
|
||
// AST: fail | ||
// HIR: fail | ||
// MIR: fail | ||
pub fn test_arg() { | ||
fn want<I, O>(_: I, _: impl Fn(I) -> O) {} | ||
want(&String::new(), extend_lt); | ||
//~^ ERROR temporary value dropped while borrowed | ||
} | ||
|
||
// An exploit of the unsoundness. | ||
fn main() { | ||
let val = extend_lt(&String::from("blah blah blah")); | ||
//~^ ERROR temporary value dropped while borrowed | ||
println!("{}", val); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
error[E0521]: borrowed data escapes outside of function | ||
--> $DIR/fn-item-check-type-params.rs:31:5 | ||
| | ||
LL | pub fn test_call<'a>(val: &'a str) { | ||
| -- --- `val` is a reference that is only valid in the function body | ||
| | | ||
| lifetime `'a` defined here | ||
LL | extend_lt(val); | ||
| ^^^^^^^^^^^^^^ | ||
| | | ||
| `val` escapes the function body here | ||
| argument requires that `'a` must outlive `'static` | ||
|
||
error: lifetime may not live long enough | ||
--> $DIR/fn-item-check-type-params.rs:39:12 | ||
| | ||
LL | pub fn test_coercion<'a>() { | ||
| -- lifetime `'a` defined here | ||
LL | let _: fn(&'a str) -> _ = extend_lt; | ||
| ^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` | ||
|
||
error[E0716]: temporary value dropped while borrowed | ||
--> $DIR/fn-item-check-type-params.rs:48:11 | ||
| | ||
LL | want(&String::new(), extend_lt); | ||
| ------^^^^^^^^^^^^^------------- temporary value is freed at the end of this statement | ||
| | | | ||
| | creates a temporary value which is freed while still in use | ||
| argument requires that borrow lasts for `'static` | ||
|
||
error[E0716]: temporary value dropped while borrowed | ||
--> $DIR/fn-item-check-type-params.rs:54:26 | ||
| | ||
LL | let val = extend_lt(&String::from("blah blah blah")); | ||
| -----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-- temporary value is freed at the end of this statement | ||
| | | | ||
| | creates a temporary value which is freed while still in use | ||
| argument requires that borrow lasts for `'static` | ||
|
||
error: aborting due to 4 previous errors | ||
|
||
Some errors have detailed explanations: E0521, E0716. | ||
For more information about an error, try `rustc --explain E0521`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,7 @@ | ||
// check-pass | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. #84591 is still unsound, even with this PR, is it? do we have a test which still incorrectly compiles. It feels like we're not fixing this issue but only making it harder to trigger |
||
// known-bug: #84591 | ||
// issue: #84591 | ||
|
||
// Should fail. Subtrait can incorrectly extend supertrait lifetimes even when | ||
// supertrait has weaker implied bounds than subtrait. Strongly related to | ||
// issue #25860. | ||
// Subtrait was able to incorrectly extend supertrait lifetimes even when | ||
// supertrait had weaker implied bounds than subtrait. | ||
|
||
trait Subtrait<T>: Supertrait {} | ||
trait Supertrait { | ||
|
@@ -34,6 +32,7 @@ fn main() { | |
{ | ||
let x = "Hello World".to_string(); | ||
subs_to_soup((x.as_str(), &mut d)); | ||
//~^ does not live long enough | ||
} | ||
println!("{}", d); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
error[E0597]: `x` does not live long enough | ||
--> $DIR/implied-bounds-on-trait-hierarchy.rs:34:23 | ||
| | ||
LL | let x = "Hello World".to_string(); | ||
| - binding `x` declared here | ||
LL | subs_to_soup((x.as_str(), &mut d)); | ||
| ^ borrowed value does not live long enough | ||
LL | | ||
LL | } | ||
| - `x` dropped here while still borrowed | ||
LL | println!("{}", d); | ||
| - borrow later used here | ||
|
||
error: aborting due to previous error | ||
|
||
For more information about this error, try `rustc --explain E0597`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,7 @@ | ||
// check-pass | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove this test instead, you already added a new test for it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this comment still applies |
||
// known-bug: #104005 | ||
// issue: #104005 | ||
|
||
// Should fail. Function type parameters with implicit type annotations are not | ||
// checked for well-formedness, which allows incorrect borrowing. | ||
|
||
// In contrast, user annotations are always checked for well-formedness, and the | ||
// commented code below is correctly rejected by the borrow checker. | ||
// Function type parameters with implicit type annotations were not | ||
// checked for well-formedness, which allowed incorrect borrowing. | ||
|
||
use std::fmt::Display; | ||
|
||
|
@@ -27,11 +23,8 @@ where | |
} | ||
|
||
fn main() { | ||
// *incorrectly* compiles | ||
// This used to compile | ||
let val = extend_lt(&String::from("blah blah blah")); | ||
//~^ ERROR temporary value dropped while borrowed | ||
println!("{}", val); | ||
|
||
// *correctly* fails to compile | ||
// let val = extend_lt::<_, &_>(&String::from("blah blah blah")); | ||
// println!("{}", val); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
error[E0716]: temporary value dropped while borrowed | ||
--> $DIR/wf-in-fn-type-implicit.rs:27:26 | ||
| | ||
LL | let val = extend_lt(&String::from("blah blah blah")); | ||
| -----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-- temporary value is freed at the end of this statement | ||
| | | | ||
| | creates a temporary value which is freed while still in use | ||
| argument requires that borrow lasts for `'static` | ||
|
||
error: aborting due to previous error | ||
|
||
For more information about this error, try `rustc --explain E0716`. |
Uh oh!
There was an error while loading. Please reload this page.