Skip to content

Commit 15f0921

Browse files
committed
correctly deal with late-bound lifetimes in anon consts
1 parent 63a83c5 commit 15f0921

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)