about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-09-03 19:32:41 +0000
committerbors <bors@rust-lang.org>2022-09-03 19:32:41 +0000
commit84f0c3f79a85329dd79a54694ff8a7f427c842e9 (patch)
tree620046df033b33fe0b352b069d6a209dc4ca7588
parentdec689432fac6720b2f18101ac28a21add98b1b8 (diff)
parente7164267a2af0d7c146db719abccd64258745c42 (diff)
downloadrust-84f0c3f79a85329dd79a54694ff8a7f427c842e9.tar.gz
rust-84f0c3f79a85329dd79a54694ff8a7f427c842e9.zip
Auto merge of #101214 - cjgillot:old-no-lt, r=estebank
Do not call object_lifetime_default on lifetime params.

Small cleanup to avoid unnecessary query invocations in trivial cases.
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs7
-rw-r--r--compiler/rustc_middle/src/query/mod.rs11
-rw-r--r--compiler/rustc_passes/src/check_attr.rs35
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs38
-rw-r--r--src/test/ui/object-lifetime/object-lifetime-default.rs44
-rw-r--r--src/test/ui/object-lifetime/object-lifetime-default.stderr60
6 files changed, 116 insertions, 79 deletions
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 8dc5ed2db7e..15e74db8d74 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1162,10 +1162,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             if should_encode_type(tcx, local_id, def_kind) {
                 record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id));
             }
-            if let DefKind::TyParam | DefKind::ConstParam = def_kind {
-                if let Some(default) = self.tcx.object_lifetime_default(def_id) {
-                    record!(self.tables.object_lifetime_default[def_id] <- default);
-                }
+            if let DefKind::TyParam = def_kind {
+                let default = self.tcx.object_lifetime_default(def_id);
+                record!(self.tables.object_lifetime_default[def_id] <- default);
             }
             if let DefKind::Trait | DefKind::TraitAlias = def_kind {
                 record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index abaef0354ad..8e7bacca262 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1593,12 +1593,13 @@ rustc_queries! {
     query is_late_bound_map(_: LocalDefId) -> Option<&'tcx FxIndexSet<LocalDefId>> {
         desc { "testing if a region is late bound" }
     }
-    /// For a given item (like a struct), gets the default lifetimes to be used
+    /// For a given item's generic parameter, gets the default lifetimes to be used
     /// for each parameter if a trait object were to be passed for that parameter.
-    /// For example, for `struct Foo<'a, T, U>`, this would be `['static, 'static]`.
-    /// For `struct Foo<'a, T: 'a, U>`, this would instead be `['a, 'static]`.
-    query object_lifetime_default(key: DefId) -> Option<ObjectLifetimeDefault> {
-        desc { "looking up lifetime defaults for generic parameter `{:?}`", key }
+    /// For example, for `T` in `struct Foo<'a, T>`, this would be `'static`.
+    /// For `T` in `struct Foo<'a, T: 'a>`, this would instead be `'a`.
+    /// This query will panic if passed something that is not a type parameter.
+    query object_lifetime_default(key: DefId) -> ObjectLifetimeDefault {
+        desc { "looking up lifetime defaults for generic parameter `{}`", tcx.def_path_str(key) }
         separate_provide_extern
     }
     query late_bound_vars_map(_: LocalDefId)
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 100adedfb50..a63af4159e8 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -173,9 +173,7 @@ impl CheckAttrVisitor<'_> {
                 sym::no_implicit_prelude => {
                     self.check_generic_attr(hir_id, attr, target, &[Target::Mod])
                 }
-                sym::rustc_object_lifetime_default => {
-                    self.check_object_lifetime_default(hir_id, span)
-                }
+                sym::rustc_object_lifetime_default => self.check_object_lifetime_default(hir_id),
                 _ => {}
             }
 
@@ -415,26 +413,21 @@ impl CheckAttrVisitor<'_> {
     }
 
     /// Debugging aid for `object_lifetime_default` query.
-    fn check_object_lifetime_default(&self, hir_id: HirId, span: Span) {
+    fn check_object_lifetime_default(&self, hir_id: HirId) {
         let tcx = self.tcx;
         if let Some(generics) = tcx.hir().get_generics(tcx.hir().local_def_id(hir_id)) {
-            let object_lifetime_default_reprs: String = generics
-                .params
-                .iter()
-                .filter_map(|p| {
-                    let param_id = tcx.hir().local_def_id(p.hir_id);
-                    let default = tcx.object_lifetime_default(param_id)?;
-                    Some(match default {
-                        ObjectLifetimeDefault::Empty => "BaseDefault".to_owned(),
-                        ObjectLifetimeDefault::Static => "'static".to_owned(),
-                        ObjectLifetimeDefault::Param(def_id) => tcx.item_name(def_id).to_string(),
-                        ObjectLifetimeDefault::Ambiguous => "Ambiguous".to_owned(),
-                    })
-                })
-                .collect::<Vec<String>>()
-                .join(",");
-
-            tcx.sess.span_err(span, &object_lifetime_default_reprs);
+            for p in generics.params {
+                let hir::GenericParamKind::Type { .. } = p.kind else { continue };
+                let param_id = tcx.hir().local_def_id(p.hir_id);
+                let default = tcx.object_lifetime_default(param_id);
+                let repr = match default {
+                    ObjectLifetimeDefault::Empty => "BaseDefault".to_owned(),
+                    ObjectLifetimeDefault::Static => "'static".to_owned(),
+                    ObjectLifetimeDefault::Param(def_id) => tcx.item_name(def_id).to_string(),
+                    ObjectLifetimeDefault::Ambiguous => "Ambiguous".to_owned(),
+                };
+                tcx.sess.span_err(p.span, &repr);
+            }
         }
     }
 
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index c16eab222f6..c72981ed96f 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -1148,21 +1148,18 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
     }
 }
 
-fn object_lifetime_default<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    param_def_id: DefId,
-) -> Option<ObjectLifetimeDefault> {
+fn object_lifetime_default<'tcx>(tcx: TyCtxt<'tcx>, param_def_id: DefId) -> ObjectLifetimeDefault {
+    debug_assert_eq!(tcx.def_kind(param_def_id), DefKind::TyParam);
     let param_def_id = param_def_id.expect_local();
     let parent_def_id = tcx.local_parent(param_def_id);
-    let generics = tcx.hir().get_generics(parent_def_id)?;
+    let generics = tcx.hir().get_generics(parent_def_id).unwrap();
     let param_hir_id = tcx.local_def_id_to_hir_id(param_def_id);
-    let param = generics.params.iter().find(|p| p.hir_id == param_hir_id)?;
+    let param = generics.params.iter().find(|p| p.hir_id == param_hir_id).unwrap();
 
     // Scan the bounds and where-clauses on parameters to extract bounds
     // of the form `T:'a` so as to determine the `ObjectLifetimeDefault`
     // for each type parameter.
     match param.kind {
-        GenericParamKind::Lifetime { .. } => None,
         GenericParamKind::Type { .. } => {
             let mut set = Set1::Empty;
 
@@ -1181,21 +1178,17 @@ fn object_lifetime_default<'tcx>(
                 }
             }
 
-            Some(match set {
+            match set {
                 Set1::Empty => ObjectLifetimeDefault::Empty,
                 Set1::One(hir::LifetimeName::Static) => ObjectLifetimeDefault::Static,
                 Set1::One(hir::LifetimeName::Param(param_def_id, _)) => {
                     ObjectLifetimeDefault::Param(param_def_id.to_def_id())
                 }
                 _ => ObjectLifetimeDefault::Ambiguous,
-            })
+            }
         }
-        GenericParamKind::Const { .. } => {
-            // Generic consts don't impose any constraints.
-            //
-            // We still store a dummy value here to allow generic parameters
-            // in an arbitrary order.
-            Some(ObjectLifetimeDefault::Empty)
+        _ => {
+            bug!("object_lifetime_default_raw must only be called on a type parameter")
         }
     }
 }
@@ -1512,7 +1505,20 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             generics
                 .params
                 .iter()
-                .filter_map(|param| self.tcx.object_lifetime_default(param.def_id))
+                .filter_map(|param| {
+                    match self.tcx.def_kind(param.def_id) {
+                        // Generic consts don't impose any constraints.
+                        //
+                        // We still store a dummy value here to allow generic parameters
+                        // in an arbitrary order.
+                        DefKind::ConstParam => Some(ObjectLifetimeDefault::Empty),
+                        DefKind::TyParam => Some(self.tcx.object_lifetime_default(param.def_id)),
+                        // We may also get a `Trait` or `TraitAlias` because of how generics `Self` parameter
+                        // works.  Ignore it because it can't have a meaningful lifetime default.
+                        DefKind::LifetimeParam | DefKind::Trait | DefKind::TraitAlias => None,
+                        dk => bug!("unexpected def_kind {:?}", dk),
+                    }
+                })
                 .map(set_to_region)
                 .collect()
         });
diff --git a/src/test/ui/object-lifetime/object-lifetime-default.rs b/src/test/ui/object-lifetime/object-lifetime-default.rs
index 60b6629e694..74f5bb7ddb0 100644
--- a/src/test/ui/object-lifetime/object-lifetime-default.rs
+++ b/src/test/ui/object-lifetime/object-lifetime-default.rs
@@ -1,24 +1,50 @@
 #![feature(rustc_attrs)]
 
 #[rustc_object_lifetime_default]
-struct A<T>(T); //~ ERROR BaseDefault
+struct A<
+    T, //~ ERROR BaseDefault
+>(T);
 
 #[rustc_object_lifetime_default]
-struct B<'a,T>(&'a (), T); //~ ERROR BaseDefault
+struct B<
+    'a,
+    T, //~ ERROR BaseDefault
+>(&'a (), T);
 
 #[rustc_object_lifetime_default]
-struct C<'a,T:'a>(&'a T); //~ ERROR 'a
+struct C<
+    'a,
+    T: 'a, //~ ERROR 'a
+>(&'a T);
 
 #[rustc_object_lifetime_default]
-struct D<'a,'b,T:'a+'b>(&'a T, &'b T); //~ ERROR Ambiguous
+struct D<
+    'a,
+    'b,
+    T: 'a + 'b, //~ ERROR Ambiguous
+>(&'a T, &'b T);
 
 #[rustc_object_lifetime_default]
-struct E<'a,'b:'a,T:'b>(&'a T, &'b T); //~ ERROR 'b
+struct E<
+    'a,
+    'b: 'a,
+    T: 'b, //~ ERROR 'b
+>(&'a T, &'b T);
 
 #[rustc_object_lifetime_default]
-struct F<'a,'b,T:'a,U:'b>(&'a T, &'b U); //~ ERROR 'a,'b
+struct F<
+    'a,
+    'b,
+    T: 'a, //~ ERROR 'a
+    U: 'b, //~ ERROR 'b
+>(&'a T, &'b U);
 
 #[rustc_object_lifetime_default]
-struct G<'a,'b,T:'a,U:'a+'b>(&'a T, &'b U); //~ ERROR 'a,Ambiguous
-
-fn main() { }
+struct G<
+    'a,
+    'b,
+    T: 'a,      //~ ERROR 'a
+    U: 'a + 'b, //~ ERROR Ambiguous
+>(&'a T, &'b U);
+
+fn main() {}
diff --git a/src/test/ui/object-lifetime/object-lifetime-default.stderr b/src/test/ui/object-lifetime/object-lifetime-default.stderr
index 60cb98c8fd3..a58afad3ef2 100644
--- a/src/test/ui/object-lifetime/object-lifetime-default.stderr
+++ b/src/test/ui/object-lifetime/object-lifetime-default.stderr
@@ -1,44 +1,56 @@
 error: BaseDefault
-  --> $DIR/object-lifetime-default.rs:4:1
+  --> $DIR/object-lifetime-default.rs:5:5
    |
-LL | struct A<T>(T);
-   | ^^^^^^^^^^^^^^^
+LL |     T,
+   |     ^
 
 error: BaseDefault
-  --> $DIR/object-lifetime-default.rs:7:1
+  --> $DIR/object-lifetime-default.rs:11:5
    |
-LL | struct B<'a,T>(&'a (), T);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     T,
+   |     ^
 
 error: 'a
-  --> $DIR/object-lifetime-default.rs:10:1
+  --> $DIR/object-lifetime-default.rs:17:5
    |
-LL | struct C<'a,T:'a>(&'a T);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     T: 'a,
+   |     ^
 
 error: Ambiguous
-  --> $DIR/object-lifetime-default.rs:13:1
+  --> $DIR/object-lifetime-default.rs:24:5
    |
-LL | struct D<'a,'b,T:'a+'b>(&'a T, &'b T);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     T: 'a + 'b,
+   |     ^
 
 error: 'b
-  --> $DIR/object-lifetime-default.rs:16:1
+  --> $DIR/object-lifetime-default.rs:31:5
    |
-LL | struct E<'a,'b:'a,T:'b>(&'a T, &'b T);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     T: 'b,
+   |     ^
 
-error: 'a,'b
-  --> $DIR/object-lifetime-default.rs:19:1
+error: 'a
+  --> $DIR/object-lifetime-default.rs:38:5
+   |
+LL |     T: 'a,
+   |     ^
+
+error: 'b
+  --> $DIR/object-lifetime-default.rs:39:5
    |
-LL | struct F<'a,'b,T:'a,U:'b>(&'a T, &'b U);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     U: 'b,
+   |     ^
 
-error: 'a,Ambiguous
-  --> $DIR/object-lifetime-default.rs:22:1
+error: 'a
+  --> $DIR/object-lifetime-default.rs:46:5
+   |
+LL |     T: 'a,
+   |     ^
+
+error: Ambiguous
+  --> $DIR/object-lifetime-default.rs:47:5
    |
-LL | struct G<'a,'b,T:'a,U:'a+'b>(&'a T, &'b U);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     U: 'a + 'b,
+   |     ^
 
-error: aborting due to 7 previous errors
+error: aborting due to 9 previous errors