about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-10-09 06:54:00 +0000
committerMichael Goulet <michael@errs.io>2022-10-12 04:04:09 +0000
commitc646c4d403d8c88cd3450f859fbdc34ec26d5bb5 (patch)
tree45359fc2b1bbf9f2685a1809f9ccc0113134c253
parentdb0597f5619d5ed93feca28e61226d3581cc7867 (diff)
downloadrust-c646c4d403d8c88cd3450f859fbdc34ec26d5bb5.tar.gz
rust-c646c4d403d8c88cd3450f859fbdc34ec26d5bb5.zip
Unify tcx.constness and param env constness checks
-rw-r--r--compiler/rustc_const_eval/src/const_eval/fn_queries.rs72
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs56
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs69
3 files changed, 98 insertions, 99 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
index f1674d04f8d..cdcebb61c2e 100644
--- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
@@ -25,12 +25,10 @@ pub fn is_parent_const_impl_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
 /// report whether said intrinsic has a `rustc_const_{un,}stable` attribute. Otherwise, return
 /// `Constness::NotConst`.
 fn constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness {
-    let def_id = def_id.expect_local();
-    let node = tcx.hir().get_by_def_id(def_id);
-
-    match node {
+    let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
+    match tcx.hir().get(hir_id) {
         hir::Node::Ctor(_) => hir::Constness::Const,
-        hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.constness,
+
         hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => {
             // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other
             // foreign items cannot be evaluated at compile-time.
@@ -41,20 +39,62 @@ fn constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness {
             };
             if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
         }
-        _ => {
-            if let Some(fn_kind) = node.fn_kind() {
-                if fn_kind.constness() == hir::Constness::Const {
-                    return hir::Constness::Const;
-                }
 
-                // If the function itself is not annotated with `const`, it may still be a `const fn`
-                // if it resides in a const trait impl.
-                let is_const = is_parent_const_impl_raw(tcx, def_id);
-                if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
-            } else {
-                hir::Constness::NotConst
+        hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(..), .. })
+            if tcx.is_const_default_method(def_id) =>
+        {
+            hir::Constness::Const
+        }
+
+        hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(..), .. })
+        | hir::Node::Item(hir::Item { kind: hir::ItemKind::Static(..), .. })
+        | hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Const(..), .. })
+        | hir::Node::AnonConst(_)
+        | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. })
+        | hir::Node::ImplItem(hir::ImplItem {
+            kind:
+                hir::ImplItemKind::Fn(
+                    hir::FnSig {
+                        header: hir::FnHeader { constness: hir::Constness::Const, .. },
+                        ..
+                    },
+                    ..,
+                ),
+            ..
+        }) => hir::Constness::Const,
+
+        hir::Node::ImplItem(hir::ImplItem {
+            kind: hir::ImplItemKind::Type(..) | hir::ImplItemKind::Fn(..),
+            ..
+        }) => {
+            let parent_hir_id = tcx.hir().get_parent_node(hir_id);
+            match tcx.hir().get(parent_hir_id) {
+                hir::Node::Item(hir::Item {
+                    kind: hir::ItemKind::Impl(hir::Impl { constness, .. }),
+                    ..
+                }) => *constness,
+                _ => span_bug!(
+                    tcx.def_span(parent_hir_id.owner),
+                    "impl item's parent node is not an impl",
+                ),
             }
         }
+
+        hir::Node::Item(hir::Item {
+            kind: hir::ItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, ..),
+            ..
+        })
+        | hir::Node::TraitItem(hir::TraitItem {
+            kind:
+                hir::TraitItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, ..),
+            ..
+        })
+        | hir::Node::Item(hir::Item {
+            kind: hir::ItemKind::Impl(hir::Impl { constness, .. }),
+            ..
+        }) => *constness,
+
+        _ => hir::Constness::NotConst,
     }
 }
 
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 3fc10197b91..ab4ecec2af3 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1059,6 +1059,43 @@ fn should_encode_const(def_kind: DefKind) -> bool {
     }
 }
 
+fn should_encode_constness(def_kind: DefKind) -> bool {
+    match def_kind {
+        DefKind::Struct
+        | DefKind::Union
+        | DefKind::Enum
+        | DefKind::Trait
+        | DefKind::AssocTy
+        | DefKind::Fn
+        | DefKind::Const
+        | DefKind::Static(..)
+        | DefKind::Ctor(..)
+        | DefKind::AssocFn
+        | DefKind::AssocConst
+        | DefKind::AnonConst
+        | DefKind::InlineConst
+        | DefKind::OpaqueTy
+        | DefKind::ImplTraitPlaceholder
+        | DefKind::Impl
+        | DefKind::Closure
+        | DefKind::Generator => true,
+        DefKind::Variant
+        | DefKind::TyAlias
+        | DefKind::TraitAlias
+        | DefKind::ForeignTy
+        | DefKind::Field
+        | DefKind::TyParam
+        | DefKind::Mod
+        | DefKind::ForeignMod
+        | DefKind::ConstParam
+        | DefKind::Macro(..)
+        | DefKind::Use
+        | DefKind::LifetimeParam
+        | DefKind::GlobalAsm
+        | DefKind::ExternCrate => false,
+    }
+}
+
 fn should_encode_trait_impl_trait_tys<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
     if tcx.def_kind(def_id) != DefKind::AssocFn {
         return false;
@@ -1165,6 +1202,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             {
                 record!(self.tables.trait_impl_trait_tys[def_id] <- table);
             }
+            if should_encode_constness(def_kind) {
+                self.tables.constness.set(def_id.index, tcx.constness(def_id));
+            }
         }
         let inherent_impls = tcx.crate_inherent_impls(());
         for (def_id, implementations) in inherent_impls.inherent_impls.iter() {
@@ -1192,7 +1232,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         };
 
         record!(self.tables.variant_data[def_id] <- data);
-        self.tables.constness.set(def_id.index, hir::Constness::Const);
         record_array!(self.tables.children[def_id] <- variant.fields.iter().map(|f| {
             assert!(f.did.is_local());
             f.did.index
@@ -1220,7 +1259,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         };
 
         record!(self.tables.variant_data[def_id] <- data);
-        self.tables.constness.set(def_id.index, hir::Constness::Const);
         if variant.ctor_kind == CtorKind::Fn {
             record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
         }
@@ -1284,7 +1322,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
 
         record!(self.tables.repr_options[def_id] <- adt_def.repr());
         record!(self.tables.variant_data[def_id] <- data);
-        self.tables.constness.set(def_id.index, hir::Constness::Const);
         if variant.ctor_kind == CtorKind::Fn {
             record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
         }
@@ -1320,7 +1357,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                     }
                 };
                 self.tables.asyncness.set(def_id.index, m_sig.header.asyncness);
-                self.tables.constness.set(def_id.index, hir::Constness::NotConst);
             }
             ty::AssocKind::Type => {
                 self.encode_explicit_item_bounds(def_id);
@@ -1345,13 +1381,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind else { bug!() };
                 self.tables.asyncness.set(def_id.index, sig.header.asyncness);
                 record_array!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body));
-                // Can be inside `impl const Trait`, so using sig.header.constness is not reliable
-                let constness = if self.tcx.is_const_fn_raw(def_id) {
-                    hir::Constness::Const
-                } else {
-                    hir::Constness::NotConst
-                };
-                self.tables.constness.set(def_id.index, constness);
             }
             ty::AssocKind::Const | ty::AssocKind::Type => {}
         }
@@ -1474,7 +1503,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             hir::ItemKind::Fn(ref sig, .., body) => {
                 self.tables.asyncness.set(def_id.index, sig.header.asyncness);
                 record_array!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body));
-                self.tables.constness.set(def_id.index, sig.header.constness);
             }
             hir::ItemKind::Macro(ref macro_def, _) => {
                 if macro_def.macro_rules {
@@ -1495,7 +1523,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             hir::ItemKind::Struct(ref struct_def, _) => {
                 let adt_def = self.tcx.adt_def(def_id);
                 record!(self.tables.repr_options[def_id] <- adt_def.repr());
-                self.tables.constness.set(def_id.index, hir::Constness::Const);
 
                 // Encode def_ids for each field and method
                 // for methods, write all the stuff get_trait_method
@@ -1524,9 +1551,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                     is_non_exhaustive: variant.is_field_list_non_exhaustive(),
                 });
             }
-            hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => {
+            hir::ItemKind::Impl(hir::Impl { defaultness, .. }) => {
                 self.tables.impl_defaultness.set(def_id.index, *defaultness);
-                self.tables.constness.set(def_id.index, *constness);
 
                 let trait_ref = self.tcx.impl_trait_ref(def_id);
                 if let Some(trait_ref) = trait_ref {
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 30efbf66175..344426a18bc 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -133,77 +133,10 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
     let local_did = def_id.as_local();
     let hir_id = local_did.map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id));
 
-    let constness = match hir_id {
-        Some(hir_id) => match tcx.hir().get(hir_id) {
-            hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(..), .. })
-                if tcx.is_const_default_method(def_id) =>
-            {
-                hir::Constness::Const
-            }
-
-            hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(..), .. })
-            | hir::Node::Item(hir::Item { kind: hir::ItemKind::Static(..), .. })
-            | hir::Node::TraitItem(hir::TraitItem {
-                kind: hir::TraitItemKind::Const(..), ..
-            })
-            | hir::Node::AnonConst(_)
-            | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. })
-            | hir::Node::ImplItem(hir::ImplItem {
-                kind:
-                    hir::ImplItemKind::Fn(
-                        hir::FnSig {
-                            header: hir::FnHeader { constness: hir::Constness::Const, .. },
-                            ..
-                        },
-                        ..,
-                    ),
-                ..
-            }) => hir::Constness::Const,
-
-            hir::Node::ImplItem(hir::ImplItem {
-                kind: hir::ImplItemKind::Type(..) | hir::ImplItemKind::Fn(..),
-                ..
-            }) => {
-                let parent_hir_id = tcx.hir().get_parent_node(hir_id);
-                match tcx.hir().get(parent_hir_id) {
-                    hir::Node::Item(hir::Item {
-                        kind: hir::ItemKind::Impl(hir::Impl { constness, .. }),
-                        ..
-                    }) => *constness,
-                    _ => span_bug!(
-                        tcx.def_span(parent_hir_id.owner),
-                        "impl item's parent node is not an impl",
-                    ),
-                }
-            }
-
-            hir::Node::Item(hir::Item {
-                kind:
-                    hir::ItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, ..),
-                ..
-            })
-            | hir::Node::TraitItem(hir::TraitItem {
-                kind:
-                    hir::TraitItemKind::Fn(
-                        hir::FnSig { header: hir::FnHeader { constness, .. }, .. },
-                        ..,
-                    ),
-                ..
-            })
-            | hir::Node::Item(hir::Item {
-                kind: hir::ItemKind::Impl(hir::Impl { constness, .. }),
-                ..
-            }) => *constness,
-
-            _ => hir::Constness::NotConst,
-        },
-        None => hir::Constness::NotConst,
-    };
-
     let unnormalized_env = ty::ParamEnv::new(
         tcx.intern_predicates(&predicates),
         traits::Reveal::UserFacing,
-        constness,
+        tcx.constness(def_id),
     );
 
     let body_id =