Skip to content

Commit 371d8a8

Browse files
Consider static specially
1 parent e425d85 commit 371d8a8

File tree

3 files changed

+48
-8
lines changed

3 files changed

+48
-8
lines changed

compiler/rustc_borrowck/src/type_check/liveness/trace.rs

+20-8
Original file line numberDiff line numberDiff line change
@@ -619,13 +619,21 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
619619
inflowing_loans: &'b SparseBitMatrix<RegionVid, BorrowIndex>,
620620
}
621621
impl<'tcx> MakeAllRegionsLive<'_, '_, 'tcx> {
622+
/// We can prove that an alias is live two ways:
623+
/// 1. All the components are live.
624+
/// 2. There is a known outlives bound or where-clause, and that
625+
/// region is live.
626+
/// We search through the item bounds and where clauses for
627+
/// either `'static` or a unique outlives region, and if one is
628+
/// found, we just need to prove that that region is still live.
629+
/// If one is not found, then we continue to walk through the alias.
622630
fn make_alias_live(&mut self, t: Ty<'tcx>) -> ControlFlow<!> {
623631
let ty::Alias(_kind, alias_ty) = t.kind() else {
624-
bug!();
632+
bug!("`make_alias_live` only takes alias types");
625633
};
626634
let tcx = self.typeck.infcx.tcx;
627635
let param_env = self.typeck.param_env;
628-
let mut outlives_bounds = tcx
636+
let outlives_bounds: Vec<_> = tcx
629637
.item_bounds(alias_ty.def_id)
630638
.iter_instantiated(tcx, alias_ty.args)
631639
.filter_map(|clause| {
@@ -653,12 +661,16 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
653661
t,
654662
)
655663
}
656-
}));
657-
if let Some(r) = outlives_bounds.next()
658-
&& !r.is_late_bound()
659-
&& outlives_bounds.all(|other_r| {
660-
other_r == r
661-
})
664+
}))
665+
.collect();
666+
// If we find `'static`, then we know the alias doesn't capture *any* regions.
667+
// Otherwise, all of the outlives regions should be equal -- if they're not,
668+
// we don't really know how to proceed, so we continue recursing through the
669+
// alias.
670+
if outlives_bounds.contains(&tcx.lifetimes.re_static) {
671+
ControlFlow::Continue(())
672+
} else if let Some(r) = outlives_bounds.first()
673+
&& outlives_bounds[1..].iter().all(|other_r| other_r == r)
662674
{
663675
r.visit_with(self)
664676
} else {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// check-pass
2+
3+
#![feature(return_type_notation)]
4+
//~^ WARN the feature `return_type_notation` is incomplete
5+
6+
trait Foo {
7+
fn borrow(&mut self) -> impl Sized + '_;
8+
}
9+
10+
// Test that the `'_` item bound in `borrow` does not cause us to
11+
// overlook the `'static` RTN bound.
12+
fn test<T: Foo<borrow(): 'static>>(mut t: T) {
13+
let x = t.borrow();
14+
let x = t.borrow();
15+
}
16+
17+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/rtn-static.rs:3:12
3+
|
4+
LL | #![feature(return_type_notation)]
5+
| ^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
warning: 1 warning emitted
11+

0 commit comments

Comments
 (0)