about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBastian Kauschke <bastian_kauschke@hotmail.de>2020-11-22 13:57:11 +0100
committerBastian Kauschke <bastian_kauschke@hotmail.de>2021-01-16 19:27:42 +0100
commit15f0921d0c0d95c009bee7d9cd9921306b78615c (patch)
treec0631ec0f0c48ade42fbb04694607680b9ebf0f5
parent63a83c5f55801b17b77adf690db397d17c706c48 (diff)
downloadrust-15f0921d0c0d95c009bee7d9cd9921306b78615c.tar.gz
rust-15f0921d0c0d95c009bee7d9cd9921306b78615c.zip
correctly deal with late-bound lifetimes in anon consts
-rw-r--r--compiler/rustc_middle/src/query/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/context.rs3
-rw-r--r--compiler/rustc_mir/src/borrow_check/universal_regions.rs8
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs32
-rw-r--r--src/test/ui/const-generics/late-bound-vars/in_closure.rs18
-rw-r--r--src/test/ui/const-generics/late-bound-vars/simple.rs16
6 files changed, 71 insertions, 8 deletions
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 9770e67f2d2..0a9f740d53a 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1316,7 +1316,7 @@ rustc_queries! {
             desc { "looking up a named region" }
         }
         query is_late_bound_map(_: LocalDefId) ->
-            Option<&'tcx FxHashSet<ItemLocalId>> {
+            Option<(LocalDefId, &'tcx FxHashSet<ItemLocalId>)> {
             desc { "testing if a region is late bound" }
         }
         query object_lifetime_defaults_map(_: LocalDefId)
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index a355242f5ce..148ac604596 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -2578,7 +2578,8 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     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]> {
diff --git a/compiler/rustc_mir/src/borrow_check/universal_regions.rs b/compiler/rustc_mir/src/borrow_check/universal_regions.rs
index c1a0d9856b7..02d951b70e2 100644
--- a/compiler/rustc_mir/src/borrow_check/universal_regions.rs
+++ b/compiler/rustc_mir/src/borrow_check/universal_regions.rs
@@ -788,13 +788,13 @@ fn for_each_late_bound_region_defined_on<'tcx>(
     fn_def_id: DefId,
     mut f: impl FnMut(ty::Region<'tcx>),
 ) {
-    if let Some(late_bounds) = tcx.is_late_bound_map(fn_def_id.expect_local()) {
-        for late_bound in late_bounds.iter() {
-            let hir_id = HirId { owner: fn_def_id.expect_local(), local_id: *late_bound };
+    if let Some((owner, late_bounds)) = tcx.is_late_bound_map(fn_def_id.expect_local()) {
+        for &late_bound in late_bounds.iter() {
+            let hir_id = HirId { owner, local_id: late_bound };
             let name = tcx.hir().name(hir_id);
             let region_def_id = tcx.hir().local_def_id(hir_id);
             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),
             }));
             f(liberated_region);
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index aab5c3cf8f5..1be06a44687 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -11,7 +11,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
 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::{GenericArg, GenericParam, LifetimeName, Node, ParamName, QPath};
 use rustc_hir::{GenericParamKind, HirIdMap, HirIdSet, LifetimeParamKind};
@@ -20,6 +21,7 @@ use rustc_middle::middle::resolve_lifetime::*;
 use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
+use rustc_span::def_id::{DefId, LocalDefId};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
 use std::borrow::Cow;
@@ -284,7 +286,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
         resolve_lifetimes,
 
         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| {
             tcx.resolve_lifetimes(LOCAL_CRATE).object_lifetime_defaults.get(&id)
         },
@@ -320,6 +322,32 @@ fn resolve_lifetimes(tcx: TyCtxt<'_>, for_krate: CrateNum) -> ResolveLifetimes {
     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 {
     let krate = tcx.hir().krate();
     let mut map = NamedRegionMap {
diff --git a/src/test/ui/const-generics/late-bound-vars/in_closure.rs b/src/test/ui/const-generics/late-bound-vars/in_closure.rs
new file mode 100644
index 00000000000..0aaeaffb4cb
--- /dev/null
+++ b/src/test/ui/const-generics/late-bound-vars/in_closure.rs
@@ -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();
+}
diff --git a/src/test/ui/const-generics/late-bound-vars/simple.rs b/src/test/ui/const-generics/late-bound-vars/simple.rs
new file mode 100644
index 00000000000..2c411a3bdc5
--- /dev/null
+++ b/src/test/ui/const-generics/late-bound-vars/simple.rs
@@ -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();
+}