mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
Check normalized call signature for WF in mir typeck
This commit is contained in:
parent
bc1b9e0e9a
commit
2b4a2b95dd
@ -1432,7 +1432,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let (sig, map) = tcx.instantiate_bound_regions(sig, |br| {
|
let (unnormalized_sig, map) = tcx.instantiate_bound_regions(sig, |br| {
|
||||||
use crate::renumber::RegionCtxt;
|
use crate::renumber::RegionCtxt;
|
||||||
|
|
||||||
let region_ctxt_fn = || {
|
let region_ctxt_fn = || {
|
||||||
@ -1454,7 +1454,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||||||
region_ctxt_fn,
|
region_ctxt_fn,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
debug!(?sig);
|
debug!(?unnormalized_sig);
|
||||||
// IMPORTANT: We have to prove well formed for the function signature before
|
// IMPORTANT: We have to prove well formed for the function signature before
|
||||||
// we normalize it, as otherwise types like `<&'a &'b () as Trait>::Assoc`
|
// we normalize it, as otherwise types like `<&'a &'b () as Trait>::Assoc`
|
||||||
// get normalized away, causing us to ignore the `'b: 'a` bound used by the function.
|
// get normalized away, causing us to ignore the `'b: 'a` bound used by the function.
|
||||||
@ -1464,7 +1464,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||||||
//
|
//
|
||||||
// See #91068 for an example.
|
// See #91068 for an example.
|
||||||
self.prove_predicates(
|
self.prove_predicates(
|
||||||
sig.inputs_and_output.iter().map(|ty| {
|
unnormalized_sig.inputs_and_output.iter().map(|ty| {
|
||||||
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(
|
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(
|
||||||
ty.into(),
|
ty.into(),
|
||||||
)))
|
)))
|
||||||
@ -1472,7 +1472,23 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||||||
term_location.to_locations(),
|
term_location.to_locations(),
|
||||||
ConstraintCategory::Boring,
|
ConstraintCategory::Boring,
|
||||||
);
|
);
|
||||||
let sig = self.normalize(sig, term_location);
|
|
||||||
|
let sig = self.normalize(unnormalized_sig, term_location);
|
||||||
|
// HACK(#114936): `WF(sig)` does not imply `WF(normalized(sig))`
|
||||||
|
// with built-in `Fn` implementations, since the impl may not be
|
||||||
|
// well-formed itself.
|
||||||
|
if sig != unnormalized_sig {
|
||||||
|
self.prove_predicates(
|
||||||
|
sig.inputs_and_output.iter().map(|ty| {
|
||||||
|
ty::Binder::dummy(ty::PredicateKind::Clause(
|
||||||
|
ty::ClauseKind::WellFormed(ty.into()),
|
||||||
|
))
|
||||||
|
}),
|
||||||
|
term_location.to_locations(),
|
||||||
|
ConstraintCategory::Boring,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
self.check_call_dest(body, term, &sig, *destination, *target, term_location);
|
self.check_call_dest(body, term, &sig, *destination, *target, term_location);
|
||||||
|
|
||||||
// The ordinary liveness rules will ensure that all
|
// The ordinary liveness rules will ensure that all
|
||||||
|
27
tests/ui/nll/check-normalized-sig-for-wf.rs
Normal file
27
tests/ui/nll/check-normalized-sig-for-wf.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// <https://github.com/rust-lang/rust/issues/114936>
|
||||||
|
fn whoops(
|
||||||
|
s: String,
|
||||||
|
f: impl for<'s> FnOnce(&'s str) -> (&'static str, [&'static &'s (); 0]),
|
||||||
|
) -> &'static str
|
||||||
|
{
|
||||||
|
f(&s).0
|
||||||
|
//~^ ERROR `s` does not live long enough
|
||||||
|
}
|
||||||
|
|
||||||
|
// <https://github.com/rust-lang/rust/issues/118876>
|
||||||
|
fn extend<T>(input: &T) -> &'static T {
|
||||||
|
struct Bounded<'a, 'b: 'static, T>(&'a T, [&'b (); 0]);
|
||||||
|
let n: Box<dyn FnOnce(&T) -> Bounded<'static, '_, T>> = Box::new(|x| Bounded(x, []));
|
||||||
|
n(input).0
|
||||||
|
//~^ ERROR borrowed data escapes outside of function
|
||||||
|
}
|
||||||
|
|
||||||
|
// <https://github.com/rust-lang/rust/issues/118876>
|
||||||
|
fn extend_mut<'a, T>(input: &'a mut T) -> &'static mut T {
|
||||||
|
struct Bounded<'a, 'b: 'static, T>(&'a mut T, [&'b (); 0]);
|
||||||
|
let mut n: Box<dyn FnMut(&mut T) -> Bounded<'static, '_, T>> = Box::new(|x| Bounded(x, []));
|
||||||
|
n(input).0
|
||||||
|
//~^ ERROR borrowed data escapes outside of function
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
47
tests/ui/nll/check-normalized-sig-for-wf.stderr
Normal file
47
tests/ui/nll/check-normalized-sig-for-wf.stderr
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
error[E0597]: `s` does not live long enough
|
||||||
|
--> $DIR/check-normalized-sig-for-wf.rs:7:7
|
||||||
|
|
|
||||||
|
LL | s: String,
|
||||||
|
| - binding `s` declared here
|
||||||
|
...
|
||||||
|
LL | f(&s).0
|
||||||
|
| --^^-
|
||||||
|
| | |
|
||||||
|
| | borrowed value does not live long enough
|
||||||
|
| argument requires that `s` is borrowed for `'static`
|
||||||
|
LL |
|
||||||
|
LL | }
|
||||||
|
| - `s` dropped here while still borrowed
|
||||||
|
|
||||||
|
error[E0521]: borrowed data escapes outside of function
|
||||||
|
--> $DIR/check-normalized-sig-for-wf.rs:15:5
|
||||||
|
|
|
||||||
|
LL | fn extend<T>(input: &T) -> &'static T {
|
||||||
|
| ----- - let's call the lifetime of this reference `'1`
|
||||||
|
| |
|
||||||
|
| `input` is a reference that is only valid in the function body
|
||||||
|
...
|
||||||
|
LL | n(input).0
|
||||||
|
| ^^^^^^^^
|
||||||
|
| |
|
||||||
|
| `input` escapes the function body here
|
||||||
|
| argument requires that `'1` must outlive `'static`
|
||||||
|
|
||||||
|
error[E0521]: borrowed data escapes outside of function
|
||||||
|
--> $DIR/check-normalized-sig-for-wf.rs:23:5
|
||||||
|
|
|
||||||
|
LL | fn extend_mut<'a, T>(input: &'a mut T) -> &'static mut T {
|
||||||
|
| -- ----- `input` is a reference that is only valid in the function body
|
||||||
|
| |
|
||||||
|
| lifetime `'a` defined here
|
||||||
|
...
|
||||||
|
LL | n(input).0
|
||||||
|
| ^^^^^^^^
|
||||||
|
| |
|
||||||
|
| `input` escapes the function body here
|
||||||
|
| argument requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0521, E0597.
|
||||||
|
For more information about an error, try `rustc --explain E0521`.
|
Loading…
Reference in New Issue
Block a user