Consider static specially
This commit is contained in:
parent
e425d85518
commit
371d8a8215
@ -619,13 +619,21 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
|
|||||||
inflowing_loans: &'b SparseBitMatrix<RegionVid, BorrowIndex>,
|
inflowing_loans: &'b SparseBitMatrix<RegionVid, BorrowIndex>,
|
||||||
}
|
}
|
||||||
impl<'tcx> MakeAllRegionsLive<'_, '_, 'tcx> {
|
impl<'tcx> MakeAllRegionsLive<'_, '_, 'tcx> {
|
||||||
|
/// We can prove that an alias is live two ways:
|
||||||
|
/// 1. All the components are live.
|
||||||
|
/// 2. There is a known outlives bound or where-clause, and that
|
||||||
|
/// region is live.
|
||||||
|
/// We search through the item bounds and where clauses for
|
||||||
|
/// either `'static` or a unique outlives region, and if one is
|
||||||
|
/// found, we just need to prove that that region is still live.
|
||||||
|
/// If one is not found, then we continue to walk through the alias.
|
||||||
fn make_alias_live(&mut self, t: Ty<'tcx>) -> ControlFlow<!> {
|
fn make_alias_live(&mut self, t: Ty<'tcx>) -> ControlFlow<!> {
|
||||||
let ty::Alias(_kind, alias_ty) = t.kind() else {
|
let ty::Alias(_kind, alias_ty) = t.kind() else {
|
||||||
bug!();
|
bug!("`make_alias_live` only takes alias types");
|
||||||
};
|
};
|
||||||
let tcx = self.typeck.infcx.tcx;
|
let tcx = self.typeck.infcx.tcx;
|
||||||
let param_env = self.typeck.param_env;
|
let param_env = self.typeck.param_env;
|
||||||
let mut outlives_bounds = tcx
|
let outlives_bounds: Vec<_> = tcx
|
||||||
.item_bounds(alias_ty.def_id)
|
.item_bounds(alias_ty.def_id)
|
||||||
.iter_instantiated(tcx, alias_ty.args)
|
.iter_instantiated(tcx, alias_ty.args)
|
||||||
.filter_map(|clause| {
|
.filter_map(|clause| {
|
||||||
@ -653,12 +661,16 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
|
|||||||
t,
|
t,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}));
|
}))
|
||||||
if let Some(r) = outlives_bounds.next()
|
.collect();
|
||||||
&& !r.is_late_bound()
|
// If we find `'static`, then we know the alias doesn't capture *any* regions.
|
||||||
&& outlives_bounds.all(|other_r| {
|
// Otherwise, all of the outlives regions should be equal -- if they're not,
|
||||||
other_r == r
|
// we don't really know how to proceed, so we continue recursing through the
|
||||||
})
|
// alias.
|
||||||
|
if outlives_bounds.contains(&tcx.lifetimes.re_static) {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
} else if let Some(r) = outlives_bounds.first()
|
||||||
|
&& outlives_bounds[1..].iter().all(|other_r| other_r == r)
|
||||||
{
|
{
|
||||||
r.visit_with(self)
|
r.visit_with(self)
|
||||||
} else {
|
} else {
|
||||||
|
17
tests/ui/borrowck/alias-liveness/rtn-static.rs
Normal file
17
tests/ui/borrowck/alias-liveness/rtn-static.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(return_type_notation)]
|
||||||
|
//~^ WARN the feature `return_type_notation` is incomplete
|
||||||
|
|
||||||
|
trait Foo {
|
||||||
|
fn borrow(&mut self) -> impl Sized + '_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that the `'_` item bound in `borrow` does not cause us to
|
||||||
|
// overlook the `'static` RTN bound.
|
||||||
|
fn test<T: Foo<borrow(): 'static>>(mut t: T) {
|
||||||
|
let x = t.borrow();
|
||||||
|
let x = t.borrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
11
tests/ui/borrowck/alias-liveness/rtn-static.stderr
Normal file
11
tests/ui/borrowck/alias-liveness/rtn-static.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/rtn-static.rs:3:12
|
||||||
|
|
|
||||||
|
LL | #![feature(return_type_notation)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
warning: 1 warning emitted
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user