Skip to content

Commit f783871

Browse files
authored
Rollup merge of #79298 - lcnr:new-elysium, r=matthewjasper
correctly deal with late-bound lifetimes in anon consts adds support for using late bound lifetimes of the parent context in anon consts. ```rust #![feature(const_generics)] const fn inner<'a>() -> usize where &'a (): Sized { 3 } fn test<'a>() { let _: [u8; inner::<'a>()]; } ``` The lifetime `'a` is late bound in `test` so it's not included in its generics but is instead dealt with separately in borrowck. This didn't previously work for anon consts as they have to use the late bound lifetimes of their parent which has to be explicitly handled. r? ```@matthewjasper``` cc ```@varkor``` ```@eddyb```
2 parents d51cf96 + 15f0921 commit f783871

File tree

6 files changed

+71
-8
lines changed

6 files changed

+71
-8
lines changed

compiler/rustc_middle/src/query/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1316,7 +1316,7 @@ rustc_queries! {
13161316
desc { "looking up a named region" }
13171317
}
13181318
query is_late_bound_map(_: LocalDefId) ->
1319-
Option<&'tcx FxHashSet<ItemLocalId>> {
1319+
Option<(LocalDefId, &'tcx FxHashSet<ItemLocalId>)> {
13201320
desc { "testing if a region is late bound" }
13211321
}
13221322
query object_lifetime_defaults_map(_: LocalDefId)

compiler/rustc_middle/src/ty/context.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2578,7 +2578,8 @@ impl<'tcx> TyCtxt<'tcx> {
25782578
}
25792579

25802580
pub fn is_late_bound(self, id: HirId) -> bool {
2581-
self.is_late_bound_map(id.owner).map_or(false, |set| set.contains(&id.local_id))
2581+
self.is_late_bound_map(id.owner)
2582+
.map_or(false, |(owner, set)| owner == id.owner && set.contains(&id.local_id))
25822583
}
25832584

25842585
pub fn object_lifetime_defaults(self, id: HirId) -> Option<&'tcx [ObjectLifetimeDefault]> {

compiler/rustc_mir/src/borrow_check/universal_regions.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -788,13 +788,13 @@ fn for_each_late_bound_region_defined_on<'tcx>(
788788
fn_def_id: DefId,
789789
mut f: impl FnMut(ty::Region<'tcx>),
790790
) {
791-
if let Some(late_bounds) = tcx.is_late_bound_map(fn_def_id.expect_local()) {
792-
for late_bound in late_bounds.iter() {
793-
let hir_id = HirId { owner: fn_def_id.expect_local(), local_id: *late_bound };
791+
if let Some((owner, late_bounds)) = tcx.is_late_bound_map(fn_def_id.expect_local()) {
792+
for &late_bound in late_bounds.iter() {
793+
let hir_id = HirId { owner, local_id: late_bound };
794794
let name = tcx.hir().name(hir_id);
795795
let region_def_id = tcx.hir().local_def_id(hir_id);
796796
let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion {
797-
scope: fn_def_id,
797+
scope: owner.to_def_id(),
798798
bound_region: ty::BoundRegionKind::BrNamed(region_def_id.to_def_id(), name),
799799
}));
800800
f(liberated_region);

compiler/rustc_resolve/src/late/lifetimes.rs

+30-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1111
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
1212
use rustc_hir as hir;
1313
use rustc_hir::def::{DefKind, Res};
14-
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE};
14+
use rustc_hir::def_id::{CrateNum, DefIdMap, LOCAL_CRATE};
15+
use rustc_hir::hir_id::ItemLocalId;
1516
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
1617
use rustc_hir::{GenericArg, GenericParam, LifetimeName, Node, ParamName, QPath};
1718
use rustc_hir::{GenericParamKind, HirIdMap, HirIdSet, LifetimeParamKind};
@@ -20,6 +21,7 @@ use rustc_middle::middle::resolve_lifetime::*;
2021
use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
2122
use rustc_middle::{bug, span_bug};
2223
use rustc_session::lint;
24+
use rustc_span::def_id::{DefId, LocalDefId};
2325
use rustc_span::symbol::{kw, sym, Ident, Symbol};
2426
use rustc_span::Span;
2527
use std::borrow::Cow;
@@ -284,7 +286,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
284286
resolve_lifetimes,
285287

286288
named_region_map: |tcx, id| tcx.resolve_lifetimes(LOCAL_CRATE).defs.get(&id),
287-
is_late_bound_map: |tcx, id| tcx.resolve_lifetimes(LOCAL_CRATE).late_bound.get(&id),
289+
is_late_bound_map,
288290
object_lifetime_defaults_map: |tcx, id| {
289291
tcx.resolve_lifetimes(LOCAL_CRATE).object_lifetime_defaults.get(&id)
290292
},
@@ -320,6 +322,32 @@ fn resolve_lifetimes(tcx: TyCtxt<'_>, for_krate: CrateNum) -> ResolveLifetimes {
320322
rl
321323
}
322324

325+
fn is_late_bound_map<'tcx>(
326+
tcx: TyCtxt<'tcx>,
327+
def_id: LocalDefId,
328+
) -> Option<(LocalDefId, &'tcx FxHashSet<ItemLocalId>)> {
329+
match tcx.def_kind(def_id) {
330+
DefKind::AnonConst => {
331+
let mut def_id = tcx
332+
.parent(def_id.to_def_id())
333+
.unwrap_or_else(|| bug!("anon const or closure without a parent"));
334+
// We search for the next outer anon const or fn here
335+
// while skipping closures.
336+
//
337+
// Note that for `AnonConst` we still just recurse until we
338+
// find a function body, but who cares :shrug:
339+
while tcx.is_closure(def_id) {
340+
def_id = tcx
341+
.parent(def_id)
342+
.unwrap_or_else(|| bug!("anon const or closure without a parent"));
343+
}
344+
345+
tcx.is_late_bound_map(def_id.expect_local())
346+
}
347+
_ => tcx.resolve_lifetimes(LOCAL_CRATE).late_bound.get(&def_id).map(|lt| (def_id, lt)),
348+
}
349+
}
350+
323351
fn krate(tcx: TyCtxt<'_>) -> NamedRegionMap {
324352
let krate = tcx.hir().krate();
325353
let mut map = NamedRegionMap {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// run-pass
2+
#![feature(const_generics)]
3+
#![allow(incomplete_features)]
4+
5+
const fn inner<'a>() -> usize where &'a (): Sized {
6+
3
7+
}
8+
9+
fn test<'a>() {
10+
let _ = || {
11+
let _: [u8; inner::<'a>()];
12+
let _ = [0; inner::<'a>()];
13+
};
14+
}
15+
16+
fn main() {
17+
test();
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// run-pass
2+
#![feature(const_generics)]
3+
#![allow(incomplete_features)]
4+
5+
const fn inner<'a>() -> usize where &'a (): Sized {
6+
3
7+
}
8+
9+
fn test<'a>() {
10+
let _: [u8; inner::<'a>()];
11+
let _ = [0; inner::<'a>()];
12+
}
13+
14+
fn main() {
15+
test();
16+
}

0 commit comments

Comments
 (0)