correctly deal with late-bound lifetimes in anon consts
This commit is contained in:
parent
63a83c5f55
commit
15f0921d0c
@ -1316,7 +1316,7 @@ fn describe_as_module(def_id: LocalDefId, tcx: TyCtxt<'_>) -> String {
|
|||||||
desc { "looking up a named region" }
|
desc { "looking up a named region" }
|
||||||
}
|
}
|
||||||
query is_late_bound_map(_: LocalDefId) ->
|
query is_late_bound_map(_: LocalDefId) ->
|
||||||
Option<&'tcx FxHashSet<ItemLocalId>> {
|
Option<(LocalDefId, &'tcx FxHashSet<ItemLocalId>)> {
|
||||||
desc { "testing if a region is late bound" }
|
desc { "testing if a region is late bound" }
|
||||||
}
|
}
|
||||||
query object_lifetime_defaults_map(_: LocalDefId)
|
query object_lifetime_defaults_map(_: LocalDefId)
|
||||||
|
@ -2578,7 +2578,8 @@ pub fn named_region(self, id: HirId) -> Option<resolve_lifetime::Region> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_late_bound(self, id: HirId) -> bool {
|
pub fn is_late_bound(self, id: HirId) -> bool {
|
||||||
self.is_late_bound_map(id.owner).map_or(false, |set| set.contains(&id.local_id))
|
self.is_late_bound_map(id.owner)
|
||||||
|
.map_or(false, |(owner, set)| owner == id.owner && set.contains(&id.local_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn object_lifetime_defaults(self, id: HirId) -> Option<&'tcx [ObjectLifetimeDefault]> {
|
pub fn object_lifetime_defaults(self, id: HirId) -> Option<&'tcx [ObjectLifetimeDefault]> {
|
||||||
|
@ -788,13 +788,13 @@ fn for_each_late_bound_region_defined_on<'tcx>(
|
|||||||
fn_def_id: DefId,
|
fn_def_id: DefId,
|
||||||
mut f: impl FnMut(ty::Region<'tcx>),
|
mut f: impl FnMut(ty::Region<'tcx>),
|
||||||
) {
|
) {
|
||||||
if let Some(late_bounds) = tcx.is_late_bound_map(fn_def_id.expect_local()) {
|
if let Some((owner, late_bounds)) = tcx.is_late_bound_map(fn_def_id.expect_local()) {
|
||||||
for late_bound in late_bounds.iter() {
|
for &late_bound in late_bounds.iter() {
|
||||||
let hir_id = HirId { owner: fn_def_id.expect_local(), local_id: *late_bound };
|
let hir_id = HirId { owner, local_id: late_bound };
|
||||||
let name = tcx.hir().name(hir_id);
|
let name = tcx.hir().name(hir_id);
|
||||||
let region_def_id = tcx.hir().local_def_id(hir_id);
|
let region_def_id = tcx.hir().local_def_id(hir_id);
|
||||||
let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion {
|
let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion {
|
||||||
scope: fn_def_id,
|
scope: owner.to_def_id(),
|
||||||
bound_region: ty::BoundRegionKind::BrNamed(region_def_id.to_def_id(), name),
|
bound_region: ty::BoundRegionKind::BrNamed(region_def_id.to_def_id(), name),
|
||||||
}));
|
}));
|
||||||
f(liberated_region);
|
f(liberated_region);
|
||||||
|
@ -11,7 +11,8 @@
|
|||||||
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
|
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE};
|
use rustc_hir::def_id::{CrateNum, DefIdMap, LOCAL_CRATE};
|
||||||
|
use rustc_hir::hir_id::ItemLocalId;
|
||||||
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||||
use rustc_hir::{GenericArg, GenericParam, LifetimeName, Node, ParamName, QPath};
|
use rustc_hir::{GenericArg, GenericParam, LifetimeName, Node, ParamName, QPath};
|
||||||
use rustc_hir::{GenericParamKind, HirIdMap, HirIdSet, LifetimeParamKind};
|
use rustc_hir::{GenericParamKind, HirIdMap, HirIdSet, LifetimeParamKind};
|
||||||
@ -20,6 +21,7 @@
|
|||||||
use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
|
use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
|
||||||
use rustc_middle::{bug, span_bug};
|
use rustc_middle::{bug, span_bug};
|
||||||
use rustc_session::lint;
|
use rustc_session::lint;
|
||||||
|
use rustc_span::def_id::{DefId, LocalDefId};
|
||||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
@ -284,7 +286,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
|
|||||||
resolve_lifetimes,
|
resolve_lifetimes,
|
||||||
|
|
||||||
named_region_map: |tcx, id| tcx.resolve_lifetimes(LOCAL_CRATE).defs.get(&id),
|
named_region_map: |tcx, id| tcx.resolve_lifetimes(LOCAL_CRATE).defs.get(&id),
|
||||||
is_late_bound_map: |tcx, id| tcx.resolve_lifetimes(LOCAL_CRATE).late_bound.get(&id),
|
is_late_bound_map,
|
||||||
object_lifetime_defaults_map: |tcx, id| {
|
object_lifetime_defaults_map: |tcx, id| {
|
||||||
tcx.resolve_lifetimes(LOCAL_CRATE).object_lifetime_defaults.get(&id)
|
tcx.resolve_lifetimes(LOCAL_CRATE).object_lifetime_defaults.get(&id)
|
||||||
},
|
},
|
||||||
@ -320,6 +322,32 @@ fn resolve_lifetimes(tcx: TyCtxt<'_>, for_krate: CrateNum) -> ResolveLifetimes {
|
|||||||
rl
|
rl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_late_bound_map<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
def_id: LocalDefId,
|
||||||
|
) -> Option<(LocalDefId, &'tcx FxHashSet<ItemLocalId>)> {
|
||||||
|
match tcx.def_kind(def_id) {
|
||||||
|
DefKind::AnonConst => {
|
||||||
|
let mut def_id = tcx
|
||||||
|
.parent(def_id.to_def_id())
|
||||||
|
.unwrap_or_else(|| bug!("anon const or closure without a parent"));
|
||||||
|
// We search for the next outer anon const or fn here
|
||||||
|
// while skipping closures.
|
||||||
|
//
|
||||||
|
// Note that for `AnonConst` we still just recurse until we
|
||||||
|
// find a function body, but who cares :shrug:
|
||||||
|
while tcx.is_closure(def_id) {
|
||||||
|
def_id = tcx
|
||||||
|
.parent(def_id)
|
||||||
|
.unwrap_or_else(|| bug!("anon const or closure without a parent"));
|
||||||
|
}
|
||||||
|
|
||||||
|
tcx.is_late_bound_map(def_id.expect_local())
|
||||||
|
}
|
||||||
|
_ => tcx.resolve_lifetimes(LOCAL_CRATE).late_bound.get(&def_id).map(|lt| (def_id, lt)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn krate(tcx: TyCtxt<'_>) -> NamedRegionMap {
|
fn krate(tcx: TyCtxt<'_>) -> NamedRegionMap {
|
||||||
let krate = tcx.hir().krate();
|
let krate = tcx.hir().krate();
|
||||||
let mut map = NamedRegionMap {
|
let mut map = NamedRegionMap {
|
||||||
|
18
src/test/ui/const-generics/late-bound-vars/in_closure.rs
Normal file
18
src/test/ui/const-generics/late-bound-vars/in_closure.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// run-pass
|
||||||
|
#![feature(const_generics)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
const fn inner<'a>() -> usize where &'a (): Sized {
|
||||||
|
3
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test<'a>() {
|
||||||
|
let _ = || {
|
||||||
|
let _: [u8; inner::<'a>()];
|
||||||
|
let _ = [0; inner::<'a>()];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
test();
|
||||||
|
}
|
16
src/test/ui/const-generics/late-bound-vars/simple.rs
Normal file
16
src/test/ui/const-generics/late-bound-vars/simple.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// run-pass
|
||||||
|
#![feature(const_generics)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
const fn inner<'a>() -> usize where &'a (): Sized {
|
||||||
|
3
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test<'a>() {
|
||||||
|
let _: [u8; inner::<'a>()];
|
||||||
|
let _ = [0; inner::<'a>()];
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
test();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user