Skip to content

Commit

Permalink
Consider static specially
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Oct 2, 2023
1 parent 3113e6e commit 56ec828
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 8 deletions.
28 changes: 20 additions & 8 deletions compiler/rustc_borrowck/src/type_check/liveness/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -565,13 +565,21 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
live_at: &'b IntervalSet<PointIndex>,
}
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<!> {
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 param_env = self.typeck.param_env;
let mut outlives_bounds = tcx
let outlives_bounds: Vec<_> = tcx
.item_bounds(alias_ty.def_id)
.iter_instantiated(tcx, alias_ty.args)
.filter_map(|clause| {
Expand Down Expand Up @@ -599,12 +607,16 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
t,
)
}
}));
if let Some(r) = outlives_bounds.next()
&& !r.is_late_bound()
&& outlives_bounds.all(|other_r| {
other_r == r
})
}))
.collect();
// If we find `'static`, then we know the alias doesn't capture *any* regions.
// Otherwise, all of the outlives regions should be equal -- if they're not,
// 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)
} else {
Expand Down
17 changes: 17 additions & 0 deletions tests/ui/borrowck/alias-liveness/rtn-static.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// check-pass

#![feature(return_position_impl_trait_in_trait, 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 changes: 11 additions & 0 deletions tests/ui/borrowck/alias-liveness/rtn-static.stderr
Original file line number Diff line number Diff line change
@@ -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:49
|
LL | #![feature(return_position_impl_trait_in_trait, 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

0 comments on commit 56ec828

Please sign in to comment.