From 6958debe4d6921487887a2b2ae5bcebf19bf791c Mon Sep 17 00:00:00 2001 From: Amanjeev Sethi Date: Fri, 2 Sep 2022 19:12:03 -0400 Subject: [PATCH 01/14] Add tests showing how we duplicate allocations when we shouldn't --- .../consts/auxiliary/const_mut_refs_crate.rs | 23 ++++++++++++ tests/ui/consts/const-mut-refs-crate.rs | 35 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 tests/ui/consts/auxiliary/const_mut_refs_crate.rs create mode 100644 tests/ui/consts/const-mut-refs-crate.rs diff --git a/tests/ui/consts/auxiliary/const_mut_refs_crate.rs b/tests/ui/consts/auxiliary/const_mut_refs_crate.rs new file mode 100644 index 0000000000000..8e78748e896e1 --- /dev/null +++ b/tests/ui/consts/auxiliary/const_mut_refs_crate.rs @@ -0,0 +1,23 @@ +// This is a support file for ../const-mut-refs-crate.rs + +// This is to test that static inners from an external +// crate like this one, still preserves the alloc. +// That is, the address from the standpoint of rustc+llvm +// is the same. +// The need for this test originated from the GH issue +// https://github.com/rust-lang/rust/issues/57349 + +// See also ../const-mut-refs-crate.rs for more details +// about this test. + +#![feature(const_mut_refs)] + +// if we used immutable references here, then promotion would +// turn the `&42` into a promoted, which gets duplicated arbitrarily. +pub static mut FOO: &'static mut i32 = &mut 42; +pub static mut BAR: &'static mut i32 = unsafe { FOO }; + +pub mod inner { + pub static INNER_MOD_FOO: &'static i32 = &43; + pub static INNER_MOD_BAR: &'static i32 = INNER_MOD_FOO; +} diff --git a/tests/ui/consts/const-mut-refs-crate.rs b/tests/ui/consts/const-mut-refs-crate.rs new file mode 100644 index 0000000000000..96df2cefce27b --- /dev/null +++ b/tests/ui/consts/const-mut-refs-crate.rs @@ -0,0 +1,35 @@ +//@ run-pass +//@ aux-build:const_mut_refs_crate.rs + +#![feature(const_mut_refs)] + +//! Regression test for https://github.com/rust-lang/rust/issues/79738 +//! Show how we are duplicationg allocations, even though static items that +//! copy their value from another static should not also be duplicating +//! memory behind references. + +extern crate const_mut_refs_crate as other; + +use other::{ + inner::{INNER_MOD_BAR, INNER_MOD_FOO}, + BAR, FOO, +}; + +pub static LOCAL_FOO: &'static i32 = &41; +pub static LOCAL_BAR: &'static i32 = LOCAL_FOO; +pub static mut COPY_OF_REMOTE_FOO: &'static mut i32 = unsafe { FOO }; + +static DOUBLE_REF: &&i32 = &&99; +static ONE_STEP_ABOVE: &i32 = *DOUBLE_REF; + +pub fn main() { + unsafe { + assert_ne!(FOO as *const i32, BAR as *const i32); + assert_eq!(INNER_MOD_FOO as *const i32, INNER_MOD_BAR as *const i32); + assert_eq!(LOCAL_FOO as *const i32, LOCAL_BAR as *const i32); + assert_eq!(*DOUBLE_REF as *const i32, ONE_STEP_ABOVE as *const i32); + + // bug! + assert_ne!(FOO as *const i32, COPY_OF_REMOTE_FOO as *const i32); + } +} From 81e62b82152df05d7dfc26fdeabf79acf0bac85a Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 6 Oct 2023 12:16:56 +0000 Subject: [PATCH 02/14] Share the llvm type computation between both arms of a condition --- compiler/rustc_codegen_llvm/src/consts.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index ec2fb2c6e546b..f8fca39ec3c85 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -17,7 +17,7 @@ use rustc_middle::mir::interpret::{ }; use rustc_middle::mir::mono::MonoItem; use rustc_middle::ty::layout::LayoutOf; -use rustc_middle::ty::{self, Instance, Ty}; +use rustc_middle::ty::{self, Instance}; use rustc_middle::{bug, span_bug}; use rustc_session::config::Lto; use rustc_target::abi::{ @@ -147,11 +147,10 @@ fn set_global_alignment<'ll>(cx: &CodegenCx<'ll, '_>, gv: &'ll Value, mut align: fn check_and_apply_linkage<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, attrs: &CodegenFnAttrs, - ty: Ty<'tcx>, + llty: &'ll Type, sym: &str, def_id: DefId, ) -> &'ll Value { - let llty = cx.layout_of(ty).llvm_type(cx); if let Some(linkage) = attrs.import_linkage { debug!("get_static: sym={} linkage={:?}", sym, linkage); @@ -245,9 +244,9 @@ impl<'ll> CodegenCx<'ll, '_> { let fn_attrs = self.tcx.codegen_fn_attrs(def_id); debug!("get_static: sym={} instance={:?} fn_attrs={:?}", sym, instance, fn_attrs); + let llty = self.layout_of(ty).llvm_type(self); let g = if def_id.is_local() && !self.tcx.is_foreign_item(def_id) { - let llty = self.layout_of(ty).llvm_type(self); if let Some(g) = self.get_declared_value(sym) { if self.val_ty(g) != self.type_ptr() { span_bug!(self.tcx.def_span(def_id), "Conflicting types for static"); @@ -264,7 +263,7 @@ impl<'ll> CodegenCx<'ll, '_> { g } else { - check_and_apply_linkage(self, fn_attrs, ty, sym, def_id) + check_and_apply_linkage(self, fn_attrs, llty, sym, def_id) }; // Thread-local statics in some other crate need to *always* be linked From 374be3f68211e680eaecd4adfca175be1cd66419 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 6 Oct 2023 12:32:20 +0000 Subject: [PATCH 03/14] Create a separate deduplication cache for static items --- compiler/rustc_codegen_llvm/src/consts.rs | 4 ++-- compiler/rustc_codegen_llvm/src/context.rs | 4 ++++ compiler/rustc_codegen_llvm/src/mono_item.rs | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index f8fca39ec3c85..ab71a63cbb048 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -227,7 +227,7 @@ impl<'ll> CodegenCx<'ll, '_> { pub(crate) fn get_static(&self, def_id: DefId) -> &'ll Value { let instance = Instance::mono(self.tcx, def_id); - if let Some(&g) = self.instances.borrow().get(&instance) { + if let Some(&g) = self.statics.borrow().get(&def_id) { return g; } @@ -331,7 +331,7 @@ impl<'ll> CodegenCx<'ll, '_> { } } - self.instances.borrow_mut().insert(instance, g); + self.statics.borrow_mut().insert(def_id, g); g } } diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 7dfcf1ab50e41..e9dcb6d738557 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -54,6 +54,9 @@ pub struct CodegenCx<'ll, 'tcx> { /// Cache instances of monomorphic and polymorphic items pub instances: RefCell, &'ll Value>>, + + /// Cache static's allocations + pub statics: RefCell>, /// Cache generated vtables pub vtables: RefCell, Option>), &'ll Value>>, @@ -467,6 +470,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { llcx, codegen_unit, instances: Default::default(), + statics: Default::default(), vtables: Default::default(), const_str_cache: Default::default(), const_globals: Default::default(), diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index f763071936837..ab09ce2c2b749 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -38,7 +38,7 @@ impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'_, 'tcx> { } } - self.instances.borrow_mut().insert(instance, g); + self.statics.borrow_mut().insert(def_id, g); } fn predefine_fn( From 7a6411e682112380c79a3968d3608f70ad366102 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 6 Oct 2023 13:32:57 +0000 Subject: [PATCH 04/14] Reduce some duplicate work that is being done around statics --- compiler/rustc_codegen_llvm/src/consts.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index ab71a63cbb048..8e2f1fd30e943 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -225,9 +225,20 @@ impl<'ll> CodegenCx<'ll, '_> { } } + #[instrument(level = "debug", skip(self))] pub(crate) fn get_static(&self, def_id: DefId) -> &'ll Value { let instance = Instance::mono(self.tcx, def_id); + trace!(?instance); + let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); + trace!(?ty); + let llty = self.layout_of(ty).llvm_type(self); + self.get_static_inner(def_id, llty) + } + + #[instrument(level = "debug", skip(self, llty))] + pub(crate) fn get_static_inner(&self, def_id: DefId, llty: &'ll Type) -> &'ll Value { if let Some(&g) = self.statics.borrow().get(&def_id) { + trace!("used cached value"); return g; } @@ -239,12 +250,10 @@ impl<'ll> CodegenCx<'ll, '_> { statics defined in the same CGU, but did not for `{def_id:?}`" ); - let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); - let sym = self.tcx.symbol_name(instance).name; + let sym = self.tcx.symbol_name(Instance::mono(self.tcx, def_id)).name; let fn_attrs = self.tcx.codegen_fn_attrs(def_id); - debug!("get_static: sym={} instance={:?} fn_attrs={:?}", sym, instance, fn_attrs); - let llty = self.layout_of(ty).llvm_type(self); + debug!(?sym, ?fn_attrs); let g = if def_id.is_local() && !self.tcx.is_foreign_item(def_id) { if let Some(g) = self.get_declared_value(sym) { @@ -367,13 +376,14 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> { }; let alloc = alloc.inner(); - let g = self.get_static(def_id); - let val_llty = self.val_ty(v); let instance = Instance::mono(self.tcx, def_id); let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); let llty = self.layout_of(ty).llvm_type(self); + + let g = self.get_static_inner(def_id, llty); + let g = if val_llty == llty { g } else { From e951a5c549d47ee64de253f15d553b063051dca3 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 6 Oct 2023 14:12:51 +0000 Subject: [PATCH 05/14] Move `codegen_static` function body to an inherent method in preparation of splitting it. This should make the diff easier to read, as this commit does no functional changes at all. --- compiler/rustc_codegen_llvm/src/consts.rs | 50 ++++++++++++----------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 8e2f1fd30e943..e2a5acb3cc29c 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -343,30 +343,8 @@ impl<'ll> CodegenCx<'ll, '_> { self.statics.borrow_mut().insert(def_id, g); g } -} - -impl<'ll> StaticMethods for CodegenCx<'ll, '_> { - fn static_addr_of(&self, cv: &'ll Value, align: Align, kind: Option<&str>) -> &'ll Value { - if let Some(&gv) = self.const_globals.borrow().get(&cv) { - unsafe { - // Upgrade the alignment in cases where the same constant is used with different - // alignment requirements - let llalign = align.bytes() as u32; - if llalign > llvm::LLVMGetAlignment(gv) { - llvm::LLVMSetAlignment(gv, llalign); - } - } - return gv; - } - let gv = self.static_addr_of_mut(cv, align, kind); - unsafe { - llvm::LLVMSetGlobalConstant(gv, True); - } - self.const_globals.borrow_mut().insert(cv, gv); - gv - } - fn codegen_static(&self, def_id: DefId, is_mutable: bool) { + fn codegen_static_item(&self, def_id: DefId, is_mutable: bool) { unsafe { let attrs = self.tcx.codegen_fn_attrs(def_id); @@ -550,6 +528,32 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> { } } } +} + +impl<'ll> StaticMethods for CodegenCx<'ll, '_> { + fn static_addr_of(&self, cv: &'ll Value, align: Align, kind: Option<&str>) -> &'ll Value { + if let Some(&gv) = self.const_globals.borrow().get(&cv) { + unsafe { + // Upgrade the alignment in cases where the same constant is used with different + // alignment requirements + let llalign = align.bytes() as u32; + if llalign > llvm::LLVMGetAlignment(gv) { + llvm::LLVMSetAlignment(gv, llalign); + } + } + return gv; + } + let gv = self.static_addr_of_mut(cv, align, kind); + unsafe { + llvm::LLVMSetGlobalConstant(gv, True); + } + self.const_globals.borrow_mut().insert(cv, gv); + gv + } + + fn codegen_static(&self, def_id: DefId, is_mutable: bool) { + self.codegen_static_item(def_id, is_mutable) + } /// Add a global value to a list to be stored in the `llvm.used` variable, an array of ptr. fn add_used_global(&self, global: &'ll Value) { From 4402286120e879c7c6635e5b020f91f0e3a9a1a0 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 6 Oct 2023 14:39:23 +0000 Subject: [PATCH 06/14] Use information from allocation instead of from the static's type --- compiler/rustc_codegen_llvm/src/consts.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index e2a5acb3cc29c..22fb947194953 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -358,6 +358,10 @@ impl<'ll> CodegenCx<'ll, '_> { let instance = Instance::mono(self.tcx, def_id); let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); + if !is_mutable { + debug_assert_eq!(alloc.mutability.is_not(), self.type_is_freeze(ty)); + } + debug_assert_eq!(alloc.align, self.align_of(ty)); let llty = self.layout_of(ty).llvm_type(self); let g = self.get_static_inner(def_id, llty); @@ -396,7 +400,7 @@ impl<'ll> CodegenCx<'ll, '_> { self.statics_to_rauw.borrow_mut().push((g, new_g)); new_g }; - set_global_alignment(self, g, self.align_of(ty)); + set_global_alignment(self, g, alloc.align); llvm::LLVMSetInitializer(g, v); if self.should_assume_dso_local(g, true) { @@ -405,7 +409,7 @@ impl<'ll> CodegenCx<'ll, '_> { // As an optimization, all shared statics which do not have interior // mutability are placed into read-only memory. - if !is_mutable && self.type_is_freeze(ty) { + if !is_mutable && alloc.mutability.is_not() { llvm::LLVMSetGlobalConstant(g, llvm::True); } From 611051227f8f60c03e13b9bb59ec4c7405333c27 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 6 Oct 2023 14:43:37 +0000 Subject: [PATCH 07/14] Swap the order of a piece of code to make follow up diffs simpler --- compiler/rustc_codegen_llvm/src/consts.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 22fb947194953..391e75626c603 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -354,8 +354,6 @@ impl<'ll> CodegenCx<'ll, '_> { }; let alloc = alloc.inner(); - let val_llty = self.val_ty(v); - let instance = Instance::mono(self.tcx, def_id); let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); if !is_mutable { @@ -366,6 +364,8 @@ impl<'ll> CodegenCx<'ll, '_> { let g = self.get_static_inner(def_id, llty); + let val_llty = self.val_ty(v); + let g = if val_llty == llty { g } else { From 6a71aa0de36943750dbd25a1ab2689fba904a8f0 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 6 Oct 2023 15:00:44 +0000 Subject: [PATCH 08/14] Check whether a static is mutable instead of passing it down --- compiler/rustc_codegen_gcc/src/consts.rs | 4 ++-- compiler/rustc_codegen_llvm/src/consts.rs | 10 +++++----- compiler/rustc_codegen_ssa/src/mono_item.rs | 2 +- compiler/rustc_codegen_ssa/src/traits/statics.rs | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs index 70d8db02247ce..5c6ff72b64c33 100644 --- a/compiler/rustc_codegen_gcc/src/consts.rs +++ b/compiler/rustc_codegen_gcc/src/consts.rs @@ -55,7 +55,7 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> { global_value } - fn codegen_static(&self, def_id: DefId, is_mutable: bool) { + fn codegen_static(&self, def_id: DefId) { let attrs = self.tcx.codegen_fn_attrs(def_id); let value = @@ -89,7 +89,7 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> { // As an optimization, all shared statics which do not have interior // mutability are placed into read-only memory. - if !is_mutable { + if !self.tcx.static_mutability(def_id).unwrap().is_mut() { if self.type_is_freeze(ty) { #[cfg(feature = "master")] global.global_set_readonly(); diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 391e75626c603..35e29951bc3c6 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -344,7 +344,7 @@ impl<'ll> CodegenCx<'ll, '_> { g } - fn codegen_static_item(&self, def_id: DefId, is_mutable: bool) { + fn codegen_static_item(&self, def_id: DefId) { unsafe { let attrs = self.tcx.codegen_fn_attrs(def_id); @@ -356,7 +356,7 @@ impl<'ll> CodegenCx<'ll, '_> { let instance = Instance::mono(self.tcx, def_id); let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); - if !is_mutable { + if !self.tcx.is_mutable_static(def_id) { debug_assert_eq!(alloc.mutability.is_not(), self.type_is_freeze(ty)); } debug_assert_eq!(alloc.align, self.align_of(ty)); @@ -409,7 +409,7 @@ impl<'ll> CodegenCx<'ll, '_> { // As an optimization, all shared statics which do not have interior // mutability are placed into read-only memory. - if !is_mutable && alloc.mutability.is_not() { + if !self.tcx.is_mutable_static(def_id) && alloc.mutability.is_not() { llvm::LLVMSetGlobalConstant(g, llvm::True); } @@ -555,8 +555,8 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> { gv } - fn codegen_static(&self, def_id: DefId, is_mutable: bool) { - self.codegen_static_item(def_id, is_mutable) + fn codegen_static(&self, def_id: DefId) { + self.codegen_static_item(def_id) } /// Add a global value to a list to be stored in the `llvm.used` variable, an array of ptr. diff --git a/compiler/rustc_codegen_ssa/src/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs index 295e27691090c..a0c5b89bc0aa6 100644 --- a/compiler/rustc_codegen_ssa/src/mono_item.rs +++ b/compiler/rustc_codegen_ssa/src/mono_item.rs @@ -30,7 +30,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { match *self { MonoItem::Static(def_id) => { - cx.codegen_static(def_id, cx.tcx().is_mutable_static(def_id)); + cx.codegen_static(def_id); } MonoItem::GlobalAsm(item_id) => { let item = cx.tcx().hir().item(item_id); diff --git a/compiler/rustc_codegen_ssa/src/traits/statics.rs b/compiler/rustc_codegen_ssa/src/traits/statics.rs index 413d31bb94293..737d93fd80ab0 100644 --- a/compiler/rustc_codegen_ssa/src/traits/statics.rs +++ b/compiler/rustc_codegen_ssa/src/traits/statics.rs @@ -4,7 +4,7 @@ use rustc_target::abi::Align; pub trait StaticMethods: BackendTypes { fn static_addr_of(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value; - fn codegen_static(&self, def_id: DefId, is_mutable: bool); + fn codegen_static(&self, def_id: DefId); /// Mark the given global value as "used", to prevent the compiler and linker from potentially /// removing a static variable that may otherwise appear unused. From 9823f305922fca84bd1bcb3fefa15def0b8fd620 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 23 Feb 2024 16:06:04 +0000 Subject: [PATCH 09/14] Stop requiring a type when codegenning types. We can get all the type info we need from the `ConstAllocation` --- compiler/rustc_codegen_llvm/src/consts.rs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 35e29951bc3c6..2a1cb0a20ff79 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -354,18 +354,11 @@ impl<'ll> CodegenCx<'ll, '_> { }; let alloc = alloc.inner(); - let instance = Instance::mono(self.tcx, def_id); - let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); - if !self.tcx.is_mutable_static(def_id) { - debug_assert_eq!(alloc.mutability.is_not(), self.type_is_freeze(ty)); - } - debug_assert_eq!(alloc.align, self.align_of(ty)); - let llty = self.layout_of(ty).llvm_type(self); - - let g = self.get_static_inner(def_id, llty); - let val_llty = self.val_ty(v); + let g = self.get_static_inner(def_id, val_llty); + let llty = self.val_ty(g); + let g = if val_llty == llty { g } else { From 130c0f924b8cd526c65401564a1ce54c2f782c57 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 23 Feb 2024 23:12:20 +0000 Subject: [PATCH 10/14] Change `DefKind::Static` to a struct variant --- compiler/rustc_ast_lowering/src/asm.rs | 2 +- .../src/back/symbol_export.rs | 4 ++-- .../src/const_eval/eval_queries.rs | 2 +- .../src/interpret/validity.rs | 19 ++++++++------- compiler/rustc_hir/src/def.rs | 13 ++++++---- compiler/rustc_hir/src/hir.rs | 2 +- compiler/rustc_hir/src/target.rs | 4 ++-- .../rustc_hir_analysis/src/astconv/mod.rs | 2 +- .../rustc_hir_analysis/src/check/check.rs | 4 ++-- compiler/rustc_hir_analysis/src/check/errs.rs | 2 +- compiler/rustc_hir_analysis/src/lib.rs | 2 +- compiler/rustc_hir_typeck/src/demand.rs | 2 +- .../src/mem_categorization.rs | 2 +- .../infer/error_reporting/note_and_explain.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 24 +++++++++---------- compiler/rustc_metadata/src/rmeta/table.rs | 4 ++-- compiler/rustc_middle/src/hir/map/mod.rs | 2 +- compiler/rustc_middle/src/mir/pretty.rs | 4 ++-- compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 4 ++-- compiler/rustc_mir_build/src/build/mod.rs | 2 +- compiler/rustc_mir_build/src/thir/cx/expr.rs | 2 +- .../rustc_mir_build/src/thir/pattern/mod.rs | 2 +- compiler/rustc_mir_transform/src/lib.rs | 2 +- compiler/rustc_monomorphize/src/collector.rs | 4 ++-- .../rustc_monomorphize/src/polymorphize.rs | 2 +- compiler/rustc_passes/src/dead.rs | 4 ++-- compiler/rustc_passes/src/reachable.rs | 2 +- compiler/rustc_privacy/src/lib.rs | 8 +++---- .../rustc_resolve/src/build_reduced_graph.rs | 2 +- compiler/rustc_resolve/src/def_collector.rs | 4 ++-- compiler/rustc_resolve/src/diagnostics.rs | 2 +- compiler/rustc_resolve/src/late.rs | 4 ++-- compiler/rustc_smir/src/rustc_smir/context.rs | 2 +- compiler/rustc_smir/src/rustc_smir/mod.rs | 2 +- compiler/rustc_ty_utils/src/implied_bounds.rs | 2 +- compiler/rustc_ty_utils/src/opaque_types.rs | 2 +- compiler/rustc_ty_utils/src/sig_types.rs | 2 +- src/librustdoc/clean/inline.rs | 2 +- src/librustdoc/clean/utils.rs | 2 +- src/librustdoc/formats/item_type.rs | 2 +- .../passes/collect_intra_doc_links.rs | 6 ++--- .../src/loops/needless_range_loop.rs | 2 +- .../src/loops/while_immutable_condition.rs | 2 +- .../src/methods/expect_fun_call.rs | 2 +- .../src/multiple_unsafe_ops_per_block.rs | 4 ++-- 47 files changed, 90 insertions(+), 86 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index fd717e82d26df..e9a6aa4208f23 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -195,7 +195,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .get_partial_res(sym.id) .and_then(|res| res.full_res()) .and_then(|res| match res { - Res::Def(DefKind::Static(_), def_id) => Some(def_id), + Res::Def(DefKind::Static { .. }, def_id) => Some(def_id), _ => None, }); diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 2dba04e0bb71b..bc63b3c5cc32b 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -83,7 +83,7 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap {} + DefKind::Fn | DefKind::Static { .. } => {} DefKind::AssocFn if tcx.impl_of_method(def_id.to_def_id()).is_some() => {} _ => return None, }; @@ -479,7 +479,7 @@ fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel let target = &tcx.sess.target.llvm_target; // WebAssembly cannot export data symbols, so reduce their export level if target.contains("emscripten") { - if let DefKind::Static(_) = tcx.def_kind(sym_def_id) { + if let DefKind::Static { .. } = tcx.def_kind(sym_def_id) { return SymbolExportLevel::Rust; } } diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 9e4e7911c3a73..58916c6001f9b 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -37,7 +37,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( || matches!( ecx.tcx.def_kind(cid.instance.def_id()), DefKind::Const - | DefKind::Static(_) + | DefKind::Static { .. } | DefKind::ConstParam | DefKind::AnonConst | DefKind::InlineConst diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 792e1c9e736a4..e800317d8b143 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -465,15 +465,16 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' // Special handling for pointers to statics (irrespective of their type). assert!(!self.ecx.tcx.is_thread_local_static(did)); assert!(self.ecx.tcx.is_static(did)); - let is_mut = - matches!(self.ecx.tcx.def_kind(did), DefKind::Static(Mutability::Mut)) - || !self - .ecx - .tcx - .type_of(did) - .no_bound_vars() - .expect("statics should not have generic parameters") - .is_freeze(*self.ecx.tcx, ty::ParamEnv::reveal_all()); + let is_mut = matches!( + self.ecx.tcx.def_kind(did), + DefKind::Static { mt: Mutability::Mut } + ) || !self + .ecx + .tcx + .type_of(did) + .no_bound_vars() + .expect("statics should not have generic parameters") + .is_freeze(*self.ecx.tcx, ty::ParamEnv::reveal_all()); // Mode-specific checks match self.ctfe_mode { Some( diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 23943ee28e2ea..3dc4a6a641f6c 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -75,7 +75,10 @@ pub enum DefKind { Const, /// Constant generic parameter: `struct Foo { ... }` ConstParam, - Static(ast::Mutability), + Static { + /// Whether it's a `static mut` or just a `static`. + mt: ast::Mutability, + }, /// Refers to the struct or enum variant's constructor. /// /// The reason `Ctor` exists in addition to [`DefKind::Struct`] and @@ -136,7 +139,7 @@ impl DefKind { DefKind::Fn => "function", DefKind::Mod if def_id.is_crate_root() && !def_id.is_local() => "crate", DefKind::Mod => "module", - DefKind::Static(..) => "static", + DefKind::Static { .. } => "static", DefKind::Enum => "enum", DefKind::Variant => "variant", DefKind::Ctor(CtorOf::Variant, CtorKind::Fn) => "tuple variant", @@ -209,7 +212,7 @@ impl DefKind { DefKind::Fn | DefKind::Const | DefKind::ConstParam - | DefKind::Static(..) + | DefKind::Static { .. } | DefKind::Ctor(..) | DefKind::AssocFn | DefKind::AssocConst => Some(Namespace::ValueNS), @@ -248,7 +251,7 @@ impl DefKind { DefKind::Fn | DefKind::Const | DefKind::ConstParam - | DefKind::Static(..) + | DefKind::Static { .. } | DefKind::AssocFn | DefKind::AssocConst | DefKind::Field => DefPathData::ValueNs(name), @@ -278,7 +281,7 @@ impl DefKind { | DefKind::AssocFn | DefKind::Ctor(..) | DefKind::Closure - | DefKind::Static(_) => true, + | DefKind::Static { .. } => true, DefKind::Mod | DefKind::Struct | DefKind::Union diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index fcb15925f6a7b..3f93dccfb0b61 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1616,7 +1616,7 @@ impl Expr<'_> { pub fn is_place_expr(&self, mut allow_projections_from: impl FnMut(&Self) -> bool) -> bool { match self.kind { ExprKind::Path(QPath::Resolved(_, ref path)) => { - matches!(path.res, Res::Local(..) | Res::Def(DefKind::Static(_), _) | Res::Err) + matches!(path.res, Res::Local(..) | Res::Def(DefKind::Static { .. }, _) | Res::Err) } // Type ascription inherits its place expression kind from its diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs index 8948a03e4a6f8..e448d29e55fb7 100644 --- a/compiler/rustc_hir/src/target.rs +++ b/compiler/rustc_hir/src/target.rs @@ -107,7 +107,7 @@ impl Target { match item.kind { ItemKind::ExternCrate(..) => Target::ExternCrate, ItemKind::Use(..) => Target::Use, - ItemKind::Static(..) => Target::Static, + ItemKind::Static { .. } => Target::Static, ItemKind::Const(..) => Target::Const, ItemKind::Fn(..) => Target::Fn, ItemKind::Macro(..) => Target::MacroDef, @@ -130,7 +130,7 @@ impl Target { match def_kind { DefKind::ExternCrate => Target::ExternCrate, DefKind::Use => Target::Use, - DefKind::Static(..) => Target::Static, + DefKind::Static { .. } => Target::Static, DefKind::Const => Target::Const, DefKind::Fn => Target::Fn, DefKind::Macro(..) => Target::MacroDef, diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index f374b955d9eb0..d8df4363456ab 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1937,7 +1937,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } // Case 3. Reference to a top-level value. - DefKind::Fn | DefKind::Const | DefKind::ConstParam | DefKind::Static(_) => { + DefKind::Fn | DefKind::Const | DefKind::ConstParam | DefKind::Static { .. } => { path_segs.push(PathSeg(def_id, last)); } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index deabb9c373857..95d1bcba7c75f 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -226,7 +226,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { Ok(l) => l, // Foreign statics that overflow their allowed size should emit an error Err(LayoutError::SizeOverflow(_)) - if matches!(tcx.def_kind(def_id), DefKind::Static(_) + if matches!(tcx.def_kind(def_id), DefKind::Static{..} if tcx.def_kind(tcx.local_parent(def_id)) == DefKind::ForeignMod) => { tcx.dcx().emit_err(errors::TooLargeStatic { span }); @@ -514,7 +514,7 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) { pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { let _indenter = indenter(); match tcx.def_kind(def_id) { - DefKind::Static(..) => { + DefKind::Static { .. } => { tcx.ensure().typeck(def_id); maybe_check_static_with_link_section(tcx, def_id); check_static_inhabited(tcx, def_id); diff --git a/compiler/rustc_hir_analysis/src/check/errs.rs b/compiler/rustc_hir_analysis/src/check/errs.rs index 4a7ace274c5bb..03ddb5a2e4653 100644 --- a/compiler/rustc_hir_analysis/src/check/errs.rs +++ b/compiler/rustc_hir_analysis/src/check/errs.rs @@ -49,7 +49,7 @@ fn is_path_static_mut(expr: hir::Expr<'_>) -> Option { if let hir::ExprKind::Path(qpath) = expr.kind && let hir::QPath::Resolved(_, path) = qpath && let hir::def::Res::Def(def_kind, _) = path.res - && let hir::def::DefKind::Static(mt) = def_kind + && let hir::def::DefKind::Static { mt } = def_kind && matches!(mt, Mutability::Mut) { return Some(qpath_to_string(&qpath)); diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 7cb103626da77..b2827a59ed80e 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -203,7 +203,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { tcx.hir().par_body_owners(|item_def_id| { let def_kind = tcx.def_kind(item_def_id); match def_kind { - DefKind::Static(_) => tcx.ensure().eval_static_initializer(item_def_id), + DefKind::Static { .. } => tcx.ensure().eval_static_initializer(item_def_id), DefKind::Const => tcx.ensure().const_eval_poly(item_def_id.into()), _ => (), } diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 98e3fbb8b11ab..48bf5a6ac596e 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -699,7 +699,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::Path { res: hir::def::Res::Def( - hir::def::DefKind::Static(_) | hir::def::DefKind::Const, + hir::def::DefKind::Static { .. } | hir::def::DefKind::Const, def_id, ), .. diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs index c300ec7444b2e..8454ceae89d60 100644 --- a/compiler/rustc_hir_typeck/src/mem_categorization.rs +++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs @@ -398,7 +398,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { ) | Res::SelfCtor(..) => Ok(self.cat_rvalue(hir_id, expr_ty)), - Res::Def(DefKind::Static(_), _) => { + Res::Def(DefKind::Static { .. }, _) => { Ok(PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::StaticItem, Vec::new())) } diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index 9df2f929501a6..fe6b01af85329 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -372,7 +372,7 @@ impl Trait for X { && matches!( tcx.def_kind(body_owner_def_id), DefKind::Fn - | DefKind::Static(_) + | DefKind::Static { .. } | DefKind::Const | DefKind::AssocFn | DefKind::AssocConst diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index fdb2b4f202415..34f58e466f95f 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -851,7 +851,7 @@ fn should_encode_span(def_kind: DefKind) -> bool { | DefKind::LifetimeParam | DefKind::Fn | DefKind::Const - | DefKind::Static(_) + | DefKind::Static { .. } | DefKind::Ctor(..) | DefKind::AssocFn | DefKind::AssocConst @@ -882,7 +882,7 @@ fn should_encode_attrs(def_kind: DefKind) -> bool { | DefKind::AssocTy | DefKind::Fn | DefKind::Const - | DefKind::Static(_) + | DefKind::Static { .. } | DefKind::AssocFn | DefKind::AssocConst | DefKind::Macro(_) @@ -924,7 +924,7 @@ fn should_encode_expn_that_defined(def_kind: DefKind) -> bool { | DefKind::Fn | DefKind::Const | DefKind::ConstParam - | DefKind::Static(_) + | DefKind::Static { .. } | DefKind::Ctor(..) | DefKind::AssocFn | DefKind::AssocConst @@ -956,7 +956,7 @@ fn should_encode_visibility(def_kind: DefKind) -> bool { | DefKind::AssocTy | DefKind::Fn | DefKind::Const - | DefKind::Static(..) + | DefKind::Static { .. } | DefKind::Ctor(..) | DefKind::AssocFn | DefKind::AssocConst @@ -989,7 +989,7 @@ fn should_encode_stability(def_kind: DefKind) -> bool { | DefKind::AssocConst | DefKind::TyParam | DefKind::ConstParam - | DefKind::Static(..) + | DefKind::Static { .. } | DefKind::Const | DefKind::Fn | DefKind::ForeignMod @@ -1084,7 +1084,7 @@ fn should_encode_variances<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, def_kind: Def | DefKind::AssocConst | DefKind::TyParam | DefKind::ConstParam - | DefKind::Static(..) + | DefKind::Static { .. } | DefKind::Const | DefKind::ForeignMod | DefKind::Impl { .. } @@ -1116,7 +1116,7 @@ fn should_encode_generics(def_kind: DefKind) -> bool { | DefKind::AssocTy | DefKind::Fn | DefKind::Const - | DefKind::Static(..) + | DefKind::Static { .. } | DefKind::Ctor(..) | DefKind::AssocFn | DefKind::AssocConst @@ -1148,7 +1148,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) -> | DefKind::Field | DefKind::Fn | DefKind::Const - | DefKind::Static(..) + | DefKind::Static { .. } | DefKind::TyAlias | DefKind::ForeignTy | DefKind::Impl { .. } @@ -1207,7 +1207,7 @@ fn should_encode_fn_sig(def_kind: DefKind) -> bool { | DefKind::Variant | DefKind::Field | DefKind::Const - | DefKind::Static(..) + | DefKind::Static { .. } | DefKind::Ctor(..) | DefKind::TyAlias | DefKind::OpaqueTy @@ -1248,7 +1248,7 @@ fn should_encode_constness(def_kind: DefKind) -> bool { | DefKind::Const | DefKind::AssocConst | DefKind::AnonConst - | DefKind::Static(..) + | DefKind::Static { .. } | DefKind::TyAlias | DefKind::OpaqueTy | DefKind::Impl { of_trait: false } @@ -1280,7 +1280,7 @@ fn should_encode_const(def_kind: DefKind) -> bool { | DefKind::Ctor(..) | DefKind::Field | DefKind::Fn - | DefKind::Static(..) + | DefKind::Static { .. } | DefKind::TyAlias | DefKind::OpaqueTy | DefKind::ForeignTy @@ -1454,7 +1454,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { .coroutine_for_closure .set_some(def_id.index, self.tcx.coroutine_for_closure(def_id).into()); } - if let DefKind::Static(_) = def_kind { + if let DefKind::Static { .. } = def_kind { if !self.tcx.is_foreign_item(def_id) { let data = self.tcx.eval_static_initializer(def_id).unwrap(); record!(self.tables.eval_static_initializer[def_id] <- data); diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index c5f281964df02..dd5a560033f04 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -155,8 +155,8 @@ fixed_size_enum! { ( Impl { of_trait: false } ) ( Impl { of_trait: true } ) ( Closure ) - ( Static(ast::Mutability::Not) ) - ( Static(ast::Mutability::Mut) ) + ( Static{mt:ast::Mutability::Not} ) + ( Static{mt:ast::Mutability::Mut} ) ( Ctor(CtorOf::Struct, CtorKind::Fn) ) ( Ctor(CtorOf::Struct, CtorKind::Const) ) ( Ctor(CtorOf::Variant, CtorKind::Fn) ) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index db27e2bd6301b..9462a28e309c3 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -344,7 +344,7 @@ impl<'hir> Map<'hir> { DefKind::InlineConst => BodyOwnerKind::Const { inline: true }, DefKind::Ctor(..) | DefKind::Fn | DefKind::AssocFn => BodyOwnerKind::Fn, DefKind::Closure => BodyOwnerKind::Closure, - DefKind::Static(mt) => BodyOwnerKind::Static(mt), + DefKind::Static { mt } => BodyOwnerKind::Static(mt), dk => bug!("{:?} is not a body node: {:?}", def_id, dk), } } diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 5638b575b319c..db6884a33100c 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -498,8 +498,8 @@ fn write_mir_sig(tcx: TyCtxt<'_>, body: &Body<'_>, w: &mut dyn io::Write) -> io: match (kind, body.source.promoted) { (_, Some(i)) => write!(w, "{i:?} in ")?, (DefKind::Const | DefKind::AssocConst, _) => write!(w, "const ")?, - (DefKind::Static(hir::Mutability::Not), _) => write!(w, "static ")?, - (DefKind::Static(hir::Mutability::Mut), _) => write!(w, "static mut ")?, + (DefKind::Static { mt: hir::Mutability::Not }, _) => write!(w, "static ")?, + (DefKind::Static { mt: hir::Mutability::Mut }, _) => write!(w, "static mut ")?, (_, _) if is_function => write!(w, "fn ")?, (DefKind::AnonConst | DefKind::InlineConst, _) => {} // things like anon const, not an item _ => bug!("Unexpected def kind {:?}", kind), diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 30409e990e13c..1a32f366cd982 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1698,7 +1698,7 @@ impl<'tcx> TyCtxt<'tcx> { debug!("returned from def_kind: {:?}", def_kind); match def_kind { DefKind::Const - | DefKind::Static(..) + | DefKind::Static { .. } | DefKind::AssocConst | DefKind::Ctor(..) | DefKind::AnonConst diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 1910841f2684e..0291726b48f14 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -350,7 +350,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { | DefKind::TyAlias | DefKind::Fn | DefKind::Const - | DefKind::Static(_) = kind + | DefKind::Static { .. } = kind { } else { // If not covered above, like for example items out of `impl` blocks, fallback. diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 72a1905c147ae..d9dddf6f6cf66 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -616,12 +616,12 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns `true` if the node pointed to by `def_id` is a `static` item. #[inline] pub fn is_static(self, def_id: DefId) -> bool { - matches!(self.def_kind(def_id), DefKind::Static(_)) + matches!(self.def_kind(def_id), DefKind::Static { .. }) } #[inline] pub fn static_mutability(self, def_id: DefId) -> Option { - if let DefKind::Static(mt) = self.def_kind(def_id) { Some(mt) } else { None } + if let DefKind::Static { mt } = self.def_kind(def_id) { Some(mt) } else { None } } /// Returns `true` if this is a `static` item with the `#[thread_local]` attribute. diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 2b1a9fef360c0..d06899e2a34db 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -631,7 +631,7 @@ fn construct_error(tcx: TyCtxt<'_>, def_id: LocalDefId, guar: ErrorGuaranteed) - | DefKind::AssocConst | DefKind::AnonConst | DefKind::InlineConst - | DefKind::Static(_) => (vec![], tcx.type_of(def_id).instantiate_identity(), None), + | DefKind::Static { .. } => (vec![], tcx.type_of(def_id).instantiate_identity(), None), DefKind::Ctor(..) | DefKind::Fn | DefKind::AssocFn => { let sig = tcx.liberate_late_bound_regions( def_id.to_def_id(), diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 62762168cf420..53d9720904635 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -939,7 +939,7 @@ impl<'tcx> Cx<'tcx> { // We encode uses of statics as a `*&STATIC` where the `&STATIC` part is // a constant reference (or constant raw pointer for `static mut`) in MIR - Res::Def(DefKind::Static(_), id) => { + Res::Def(DefKind::Static { .. }, id) => { let ty = self.tcx.static_ptr_ty(id); let temp_lifetime = self .rvalue_scopes diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 0329e1d3096dc..cbd3bcb8f5083 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -458,7 +458,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { Res::Def(DefKind::ConstParam, _) => { self.tcx.dcx().emit_err(ConstParamInPattern { span }) } - Res::Def(DefKind::Static(_), _) => { + Res::Def(DefKind::Static { .. }, _) => { self.tcx.dcx().emit_err(StaticInPattern { span }) } _ => self.tcx.dcx().emit_err(NonConstPath { span }), diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 945c3c662a604..85db6237f8697 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -333,7 +333,7 @@ fn mir_promoted( } DefKind::AssocConst | DefKind::Const - | DefKind::Static(_) + | DefKind::Static { .. } | DefKind::InlineConst | DefKind::AnonConst => tcx.mir_const_qualif(def), _ => ConstQualifs::default(), diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 5593de607844d..8c1105cf8339e 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1031,7 +1031,7 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> return false; } - if let DefKind::Static(_) = tcx.def_kind(def_id) { + if let DefKind::Static { .. } = tcx.def_kind(def_id) { // We cannot monomorphize statics from upstream crates. return false; } @@ -1248,7 +1248,7 @@ impl<'v> RootCollector<'_, 'v> { ); self.output.push(dummy_spanned(MonoItem::GlobalAsm(id))); } - DefKind::Static(..) => { + DefKind::Static { .. } => { let def_id = id.owner_id.to_def_id(); debug!("RootCollector: ItemKind::Static({})", self.tcx.def_path_str(def_id)); self.output.push(dummy_spanned(MonoItem::Static(def_id))); diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index fb42532e247af..34c4266aca5a7 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -151,7 +151,7 @@ fn mark_used_by_default_parameters<'tcx>( | DefKind::Fn | DefKind::Const | DefKind::ConstParam - | DefKind::Static(_) + | DefKind::Static { .. } | DefKind::Ctor(_, _) | DefKind::AssocFn | DefKind::AssocConst diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index a3106856a6701..a6eee9e7c976b 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -734,7 +734,7 @@ fn check_foreign_item( worklist: &mut Vec<(LocalDefId, ComesFromAllowExpect)>, id: hir::ForeignItemId, ) { - if matches!(tcx.def_kind(id.owner_id), DefKind::Static(_) | DefKind::Fn) + if matches!(tcx.def_kind(id.owner_id), DefKind::Static { .. } | DefKind::Fn) && let Some(comes_from_allow) = has_allow_dead_code_or_lang_attr(tcx, id.owner_id.def_id) { worklist.push((id.owner_id.def_id, comes_from_allow)); @@ -984,7 +984,7 @@ impl<'tcx> DeadVisitor<'tcx> { DefKind::AssocConst | DefKind::AssocFn | DefKind::Fn - | DefKind::Static(_) + | DefKind::Static { .. } | DefKind::Const | DefKind::TyAlias | DefKind::Enum diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index f46f831ddd7c9..9a22f5a1b63ac 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -73,7 +73,7 @@ impl<'tcx> Visitor<'tcx> for ReachableContext<'tcx> { match res { // Reachable constants and reachable statics can have their contents inlined // into other crates. Mark them as reachable and recurse into their body. - Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::Static(_), _) => { + Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::Static { .. }, _) => { self.worklist.push(def_id); } _ => { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 9d8a9f5fce3e4..6f5b10ccb5d1f 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -554,7 +554,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { self.update(def_id, macro_ev, Level::Reachable); match def_kind { // No type privacy, so can be directly marked as reachable. - DefKind::Const | DefKind::Static(_) | DefKind::TraitAlias | DefKind::TyAlias => { + DefKind::Const | DefKind::Static { .. } | DefKind::TraitAlias | DefKind::TyAlias => { if vis.is_accessible_from(module, self.tcx) { self.update(def_id, macro_ev, Level::Reachable); } @@ -1181,12 +1181,12 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> { let def = def.filter(|(kind, _)| { matches!( kind, - DefKind::AssocFn | DefKind::AssocConst | DefKind::AssocTy | DefKind::Static(_) + DefKind::AssocFn | DefKind::AssocConst | DefKind::AssocTy | DefKind::Static { .. } ) }); if let Some((kind, def_id)) = def { let is_local_static = - if let DefKind::Static(_) = kind { def_id.is_local() } else { false }; + if let DefKind::Static { .. } = kind { def_id.is_local() } else { false }; if !self.item_is_accessible(def_id) && !is_local_static { let name = match *qpath { hir::QPath::LangItem(it, ..) => { @@ -1505,7 +1505,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> { let def_kind = tcx.def_kind(def_id); match def_kind { - DefKind::Const | DefKind::Static(_) | DefKind::Fn | DefKind::TyAlias => { + DefKind::Const | DefKind::Static { .. } | DefKind::Fn | DefKind::TyAlias => { if let DefKind::TyAlias = def_kind { self.check_unnameable(def_id, effective_vis); } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 1c4aeefcbcfd0..2f5557d109850 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -984,7 +984,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { Res::Def( DefKind::Fn | DefKind::AssocFn - | DefKind::Static(_) + | DefKind::Static { .. } | DefKind::Const | DefKind::AssocConst | DefKind::Ctor(..), diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 12bf462a6fdfd..1241c09bd901d 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -125,7 +125,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { ItemKind::Union(..) => DefKind::Union, ItemKind::ExternCrate(..) => DefKind::ExternCrate, ItemKind::TyAlias(..) => DefKind::TyAlias, - ItemKind::Static(s) => DefKind::Static(s.mutability), + ItemKind::Static(s) => DefKind::Static { mt: s.mutability }, ItemKind::Const(..) => DefKind::Const, ItemKind::Fn(..) | ItemKind::Delegation(..) => DefKind::Fn, ItemKind::MacroDef(..) => { @@ -212,7 +212,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { fn visit_foreign_item(&mut self, fi: &'a ForeignItem) { let def_kind = match fi.kind { - ForeignItemKind::Static(_, mt, _) => DefKind::Static(mt), + ForeignItemKind::Static(_, mt, _) => DefKind::Static { mt }, ForeignItemKind::Fn(_) => DefKind::Fn, ForeignItemKind::TyAlias(_) => DefKind::ForeignTy, ForeignItemKind::MacCall(_) => return self.visit_macro_invoc(fi.id), diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index d64a3b43aad31..19c1ef03ce5cc 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -567,7 +567,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ResolutionError::GenericParamsFromOuterItem(outer_res, has_generic_params, def_kind) => { use errs::GenericParamsFromOuterItemLabel as Label; let static_or_const = match def_kind { - DefKind::Static(_) => Some(errs::GenericParamsFromOuterItemStaticOrConst::Static), + DefKind::Static{..} => Some(errs::GenericParamsFromOuterItemStaticOrConst::Static), DefKind::Const => Some(errs::GenericParamsFromOuterItemStaticOrConst::Const), _ => None, }; diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 2f4da29133f1b..f3ee69a2955e8 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -500,7 +500,7 @@ impl<'a> PathSource<'a> { Res::Def( DefKind::Ctor(_, CtorKind::Const | CtorKind::Fn) | DefKind::Const - | DefKind::Static(_) + | DefKind::Static { .. } | DefKind::Fn | DefKind::AssocFn | DefKind::AssocConst @@ -3640,7 +3640,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } Some(res) } - Res::Def(DefKind::Ctor(..) | DefKind::Const | DefKind::Static(_), _) => { + Res::Def(DefKind::Ctor(..) | DefKind::Const | DefKind::Static{..}, _) => { // This is unambiguously a fresh binding, either syntactically // (e.g., `IDENT @ PAT` or `ref IDENT`) or because `IDENT` resolves // to something unusable as a pattern (e.g., constructor function), diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index b95186b0a1c5b..61125eab78e17 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -265,7 +265,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { use rustc_hir::def::DefKind; match tcx.def_kind(def_id) { DefKind::Fn => ForeignItemKind::Fn(tables.fn_def(def_id)), - DefKind::Static(..) => ForeignItemKind::Static(tables.static_def(def_id)), + DefKind::Static { .. } => ForeignItemKind::Static(tables.static_def(def_id)), DefKind::ForeignTy => ForeignItemKind::Type( tables.intern_ty(rustc_middle::ty::Ty::new_foreign(tcx, def_id)), ), diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index bd02e52794c0c..aba7e7dc9c21d 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -95,7 +95,7 @@ pub(crate) fn new_item_kind(kind: DefKind) -> ItemKind { DefKind::Const | DefKind::InlineConst | DefKind::AssocConst | DefKind::AnonConst => { ItemKind::Const } - DefKind::Static(_) => ItemKind::Static, + DefKind::Static { .. } => ItemKind::Static, DefKind::Ctor(_, rustc_hir::def::CtorKind::Const) => ItemKind::Ctor(CtorKind::Const), DefKind::Ctor(_, rustc_hir::def::CtorKind::Fn) => ItemKind::Ctor(CtorKind::Fn), } diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 3f9bd509b087c..d3e601f6d71ed 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -145,7 +145,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' | DefKind::TyParam | DefKind::Const | DefKind::ConstParam - | DefKind::Static(_) + | DefKind::Static { .. } | DefKind::Ctor(_, _) | DefKind::Macro(_) | DefKind::ExternCrate diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 86c7551882aab..9412b28504311 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -371,7 +371,7 @@ fn opaque_types_defined_by<'tcx>( match kind { DefKind::AssocFn | DefKind::Fn - | DefKind::Static(_) + | DefKind::Static { .. } | DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => { diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs index 38cc558380cd8..cf60ea355918d 100644 --- a/compiler/rustc_ty_utils/src/sig_types.rs +++ b/compiler/rustc_ty_utils/src/sig_types.rs @@ -41,7 +41,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( // Walk over the type behind the alias DefKind::TyAlias {..} | DefKind::AssocTy | // Walk over the type of the item - DefKind::Static(_) | DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => { + DefKind::Static{..} | DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => { if let Some(ty) = tcx.hir_node_by_def_id(item).ty() { // Associated types in traits don't necessarily have a type that we can visit visitor.visit(ty.span, tcx.type_of(item).instantiate_identity())?; diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 03f62f41a26f4..77a78f57e950c 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -120,7 +120,7 @@ pub(crate) fn try_inline( record_extern_fqn(cx, did, ItemType::Module); clean::ModuleItem(build_module(cx, did, visited)) } - Res::Def(DefKind::Static(_), did) => { + Res::Def(DefKind::Static { .. }, did) => { record_extern_fqn(cx, did, ItemType::Static); cx.with_param_env(did, |cx| { clean::StaticItem(build_static(cx, did, cx.tcx.is_mutable_static(did))) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 0b7d35d7be4c8..57916ff0ff781 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -526,7 +526,7 @@ pub(crate) fn register_res(cx: &mut DocContext<'_>, res: Res) -> DefId { | Mod | ForeignTy | Const - | Static(_) + | Static { .. } | Macro(..) | TraitAlias), did, diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs index f10c829bf4eed..d5468798bd397 100644 --- a/src/librustdoc/formats/item_type.rs +++ b/src/librustdoc/formats/item_type.rs @@ -128,7 +128,7 @@ impl ItemType { DefKind::Fn => Self::Function, DefKind::Mod => Self::Module, DefKind::Const => Self::Constant, - DefKind::Static(_) => Self::Static, + DefKind::Static { .. } => Self::Static, DefKind::Struct => Self::Struct, DefKind::Union => Self::Union, DefKind::Trait => Self::Trait, diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index a172580ac3f04..1a7027e1c105a 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -123,7 +123,7 @@ impl Res { DefKind::Const | DefKind::ConstParam | DefKind::AssocConst | DefKind::AnonConst => { "const" } - DefKind::Static(_) => "static", + DefKind::Static { .. } => "static", // Now handle things that don't have a specific disambiguator _ => match kind .ns() @@ -1515,7 +1515,7 @@ impl Disambiguator { "union" => Kind(DefKind::Union), "module" | "mod" => Kind(DefKind::Mod), "const" | "constant" => Kind(DefKind::Const), - "static" => Kind(DefKind::Static(Mutability::Not)), + "static" => Kind(DefKind::Static { mt: Mutability::Not }), "function" | "fn" | "method" => Kind(DefKind::Fn), "derive" => Kind(DefKind::Macro(MacroKind::Derive)), "type" => NS(Namespace::TypeNS), @@ -1927,7 +1927,7 @@ fn resolution_failure( | OpaqueTy | TraitAlias | TyParam - | Static(_) => "associated item", + | Static { .. } => "associated item", Impl { .. } | GlobalAsm => unreachable!("not a path"), } } else { diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs index 08b8a9e2ff072..47dc3807e624f 100644 --- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs @@ -273,7 +273,7 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> { } return false; // no need to walk further *on the variable* }, - Res::Def(DefKind::Static(_) | DefKind::Const, ..) => { + Res::Def(DefKind::Static{..} | DefKind::Const, ..) => { if index_used_directly { self.indexed_directly.insert( seqvar.segments[0].ident.name, diff --git a/src/tools/clippy/clippy_lints/src/loops/while_immutable_condition.rs b/src/tools/clippy/clippy_lints/src/loops/while_immutable_condition.rs index 9fd9b7a163121..3511d24e8134e 100644 --- a/src/tools/clippy/clippy_lints/src/loops/while_immutable_condition.rs +++ b/src/tools/clippy/clippy_lints/src/loops/while_immutable_condition.rs @@ -101,7 +101,7 @@ impl<'a, 'tcx> VarCollectorVisitor<'a, 'tcx> { Res::Local(hir_id) => { self.ids.insert(hir_id); }, - Res::Def(DefKind::Static(_), def_id) => { + Res::Def(DefKind::Static{..}, def_id) => { let mutable = self.cx.tcx.is_mutable_static(def_id); self.def_ids.insert(def_id, mutable); }, diff --git a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs index f0fc925799a35..e2c2997594ad9 100644 --- a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs +++ b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs @@ -91,7 +91,7 @@ pub(super) fn check<'tcx>( }, hir::ExprKind::Path(ref p) => matches!( cx.qpath_res(p, arg.hir_id), - hir::def::Res::Def(hir::def::DefKind::Const | hir::def::DefKind::Static(_), _) + hir::def::Res::Def(hir::def::DefKind::Const | hir::def::DefKind::Static{..}, _) ), _ => false, } diff --git a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs index 049f44f3246f4..d8caa632b9389 100644 --- a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs +++ b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs @@ -109,7 +109,7 @@ fn collect_unsafe_exprs<'tcx>( ExprKind::Path(QPath::Resolved( _, hir::Path { - res: Res::Def(DefKind::Static(Mutability::Mut), _), + res: Res::Def(DefKind::Static{mt:Mutability::Mut}, _), .. }, )) => { @@ -149,7 +149,7 @@ fn collect_unsafe_exprs<'tcx>( ExprKind::Path(QPath::Resolved( _, hir::Path { - res: Res::Def(DefKind::Static(Mutability::Mut), _), + res: Res::Def(DefKind::Static{mt:Mutability::Mut}, _), .. } )) From 05d3b63bd0e61ac3b455d2f2f8b24b58292efc08 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 23 Feb 2024 23:29:09 +0000 Subject: [PATCH 11/14] Add `nested` bool to `DefKind::Static`. Will be used in the next commit --- compiler/rustc_const_eval/src/interpret/validity.rs | 2 +- compiler/rustc_hir/src/def.rs | 2 ++ compiler/rustc_hir_analysis/src/check/errs.rs | 2 +- compiler/rustc_metadata/src/rmeta/table.rs | 6 ++++-- compiler/rustc_middle/src/hir/map/mod.rs | 2 +- compiler/rustc_middle/src/mir/pretty.rs | 6 ++++-- compiler/rustc_middle/src/ty/util.rs | 2 +- compiler/rustc_resolve/src/def_collector.rs | 4 ++-- src/librustdoc/passes/collect_intra_doc_links.rs | 2 +- .../clippy_lints/src/multiple_unsafe_ops_per_block.rs | 4 ++-- 10 files changed, 19 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index e800317d8b143..25f2450edab7f 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -467,7 +467,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' assert!(self.ecx.tcx.is_static(did)); let is_mut = matches!( self.ecx.tcx.def_kind(did), - DefKind::Static { mt: Mutability::Mut } + DefKind::Static { mt: Mutability::Mut, .. } ) || !self .ecx .tcx diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 3dc4a6a641f6c..63dee3a5738ce 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -78,6 +78,8 @@ pub enum DefKind { Static { /// Whether it's a `static mut` or just a `static`. mt: ast::Mutability, + /// Whether it's an anonymous static generated for nested allocations. + nested: bool, }, /// Refers to the struct or enum variant's constructor. /// diff --git a/compiler/rustc_hir_analysis/src/check/errs.rs b/compiler/rustc_hir_analysis/src/check/errs.rs index 03ddb5a2e4653..107fe2aa6b8d7 100644 --- a/compiler/rustc_hir_analysis/src/check/errs.rs +++ b/compiler/rustc_hir_analysis/src/check/errs.rs @@ -49,7 +49,7 @@ fn is_path_static_mut(expr: hir::Expr<'_>) -> Option { if let hir::ExprKind::Path(qpath) = expr.kind && let hir::QPath::Resolved(_, path) = qpath && let hir::def::Res::Def(def_kind, _) = path.res - && let hir::def::DefKind::Static { mt } = def_kind + && let hir::def::DefKind::Static { mt, nested: false } = def_kind && matches!(mt, Mutability::Mut) { return Some(qpath_to_string(&qpath)); diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index dd5a560033f04..3c966cf3a9f70 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -155,8 +155,10 @@ fixed_size_enum! { ( Impl { of_trait: false } ) ( Impl { of_trait: true } ) ( Closure ) - ( Static{mt:ast::Mutability::Not} ) - ( Static{mt:ast::Mutability::Mut} ) + ( Static{mt:ast::Mutability::Not, nested: false}) + ( Static{mt:ast::Mutability::Mut, nested: false}) + ( Static{mt:ast::Mutability::Not, nested: true}) + ( Static{mt:ast::Mutability::Mut, nested: true}) ( Ctor(CtorOf::Struct, CtorKind::Fn) ) ( Ctor(CtorOf::Struct, CtorKind::Const) ) ( Ctor(CtorOf::Variant, CtorKind::Fn) ) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 9462a28e309c3..39f19669ac85e 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -344,7 +344,7 @@ impl<'hir> Map<'hir> { DefKind::InlineConst => BodyOwnerKind::Const { inline: true }, DefKind::Ctor(..) | DefKind::Fn | DefKind::AssocFn => BodyOwnerKind::Fn, DefKind::Closure => BodyOwnerKind::Closure, - DefKind::Static { mt } => BodyOwnerKind::Static(mt), + DefKind::Static { mt, nested: false } => BodyOwnerKind::Static(mt), dk => bug!("{:?} is not a body node: {:?}", def_id, dk), } } diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index db6884a33100c..a61c6745ee775 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -498,8 +498,10 @@ fn write_mir_sig(tcx: TyCtxt<'_>, body: &Body<'_>, w: &mut dyn io::Write) -> io: match (kind, body.source.promoted) { (_, Some(i)) => write!(w, "{i:?} in ")?, (DefKind::Const | DefKind::AssocConst, _) => write!(w, "const ")?, - (DefKind::Static { mt: hir::Mutability::Not }, _) => write!(w, "static ")?, - (DefKind::Static { mt: hir::Mutability::Mut }, _) => write!(w, "static mut ")?, + (DefKind::Static { mt: hir::Mutability::Not, nested: false }, _) => write!(w, "static ")?, + (DefKind::Static { mt: hir::Mutability::Mut, nested: false }, _) => { + write!(w, "static mut ")? + } (_, _) if is_function => write!(w, "fn ")?, (DefKind::AnonConst | DefKind::InlineConst, _) => {} // things like anon const, not an item _ => bug!("Unexpected def kind {:?}", kind), diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index d9dddf6f6cf66..5409aeee509d1 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -621,7 +621,7 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn static_mutability(self, def_id: DefId) -> Option { - if let DefKind::Static { mt } = self.def_kind(def_id) { Some(mt) } else { None } + if let DefKind::Static { mt, .. } = self.def_kind(def_id) { Some(mt) } else { None } } /// Returns `true` if this is a `static` item with the `#[thread_local]` attribute. diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 1241c09bd901d..739c91981c333 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -125,7 +125,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { ItemKind::Union(..) => DefKind::Union, ItemKind::ExternCrate(..) => DefKind::ExternCrate, ItemKind::TyAlias(..) => DefKind::TyAlias, - ItemKind::Static(s) => DefKind::Static { mt: s.mutability }, + ItemKind::Static(s) => DefKind::Static { mt: s.mutability, nested: false }, ItemKind::Const(..) => DefKind::Const, ItemKind::Fn(..) | ItemKind::Delegation(..) => DefKind::Fn, ItemKind::MacroDef(..) => { @@ -212,7 +212,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { fn visit_foreign_item(&mut self, fi: &'a ForeignItem) { let def_kind = match fi.kind { - ForeignItemKind::Static(_, mt, _) => DefKind::Static { mt }, + ForeignItemKind::Static(_, mt, _) => DefKind::Static { mt, nested: false }, ForeignItemKind::Fn(_) => DefKind::Fn, ForeignItemKind::TyAlias(_) => DefKind::ForeignTy, ForeignItemKind::MacCall(_) => return self.visit_macro_invoc(fi.id), diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 1a7027e1c105a..d109b9b00e986 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1515,7 +1515,7 @@ impl Disambiguator { "union" => Kind(DefKind::Union), "module" | "mod" => Kind(DefKind::Mod), "const" | "constant" => Kind(DefKind::Const), - "static" => Kind(DefKind::Static { mt: Mutability::Not }), + "static" => Kind(DefKind::Static { mt: Mutability::Not, nested: false }), "function" | "fn" | "method" => Kind(DefKind::Fn), "derive" => Kind(DefKind::Macro(MacroKind::Derive)), "type" => NS(Namespace::TypeNS), diff --git a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs index d8caa632b9389..4155e608026e3 100644 --- a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs +++ b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs @@ -109,7 +109,7 @@ fn collect_unsafe_exprs<'tcx>( ExprKind::Path(QPath::Resolved( _, hir::Path { - res: Res::Def(DefKind::Static{mt:Mutability::Mut}, _), + res: Res::Def(DefKind::Static{mt:Mutability::Mut, ..}, _), .. }, )) => { @@ -149,7 +149,7 @@ fn collect_unsafe_exprs<'tcx>( ExprKind::Path(QPath::Resolved( _, hir::Path { - res: Res::Def(DefKind::Static{mt:Mutability::Mut}, _), + res: Res::Def(DefKind::Static{mt:Mutability::Mut, ..}, _), .. } )) From 737208dd14425a808559af4c599ef3a204962ee8 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 26 Feb 2024 17:43:18 +0000 Subject: [PATCH 12/14] Make some functions private that are only ever used in the same module --- compiler/rustc_codegen_gcc/src/consts.rs | 2 +- compiler/rustc_codegen_llvm/src/consts.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs index 5c6ff72b64c33..958188450cbda 100644 --- a/compiler/rustc_codegen_gcc/src/consts.rs +++ b/compiler/rustc_codegen_gcc/src/consts.rs @@ -337,7 +337,7 @@ pub fn const_alloc_to_gcc<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, alloc: ConstAl cx.const_struct(&llvals, true) } -pub fn codegen_static_initializer<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, def_id: DefId) -> Result<(RValue<'gcc>, ConstAllocation<'tcx>), ErrorHandled> { +fn codegen_static_initializer<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, def_id: DefId) -> Result<(RValue<'gcc>, ConstAllocation<'tcx>), ErrorHandled> { let alloc = cx.tcx.eval_static_initializer(def_id)?; Ok((const_alloc_to_gcc(cx, alloc), alloc)) } diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 2a1cb0a20ff79..e39f2b6cd6196 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -114,7 +114,7 @@ pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation< cx.const_struct(&llvals, true) } -pub fn codegen_static_initializer<'ll, 'tcx>( +fn codegen_static_initializer<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, def_id: DefId, ) -> Result<(&'ll Value, ConstAllocation<'tcx>), ErrorHandled> { From 681b9929fce4c7e30747172b7eda5a0d523b926d Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 26 Feb 2024 18:03:06 +0000 Subject: [PATCH 13/14] Ensure nested allocations in statics do not get deduplicated --- compiler/rustc_codegen_gcc/src/mono_item.rs | 7 +++- compiler/rustc_codegen_llvm/src/consts.rs | 18 ++++++++-- .../src/debuginfo/metadata.rs | 8 ++++- compiler/rustc_codegen_llvm/src/mono_item.rs | 11 +++++- .../src/const_eval/eval_queries.rs | 8 ++--- .../src/const_eval/machine.rs | 19 ++++++++-- .../rustc_const_eval/src/interpret/intern.rs | 34 ++++++++++++++++-- .../rustc_const_eval/src/interpret/memory.rs | 35 +++++++++++++------ .../rustc_const_eval/src/interpret/util.rs | 10 +++--- compiler/rustc_hir/src/def.rs | 3 ++ compiler/rustc_metadata/src/rmeta/encoder.rs | 9 +++-- .../rustc_middle/src/mir/interpret/mod.rs | 12 ++++++- compiler/rustc_middle/src/query/mod.rs | 2 ++ .../src/dataflow_const_prop.rs | 7 ++++ compiler/rustc_monomorphize/src/collector.rs | 8 +++-- compiler/rustc_passes/src/reachable.rs | 34 +++++++++++++++++- compiler/rustc_span/src/symbol.rs | 1 + tests/ui/consts/const-mut-refs-crate.rs | 5 ++- 18 files changed, 190 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/mono_item.rs b/compiler/rustc_codegen_gcc/src/mono_item.rs index 3322d56513bbe..258872208d462 100644 --- a/compiler/rustc_codegen_gcc/src/mono_item.rs +++ b/compiler/rustc_codegen_gcc/src/mono_item.rs @@ -3,9 +3,11 @@ use gccjit::{VarAttribute, FnAttribute}; use rustc_codegen_ssa::traits::PreDefineMethods; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; +use rustc_middle::bug; use rustc_middle::mir::mono::{Linkage, Visibility}; use rustc_middle::ty::{self, Instance, TypeVisitableExt}; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf}; +use rustc_hir::def::DefKind; use crate::attributes; use crate::base; @@ -17,7 +19,10 @@ impl<'gcc, 'tcx> PreDefineMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn predefine_static(&self, def_id: DefId, _linkage: Linkage, visibility: Visibility, symbol_name: &str) { let attrs = self.tcx.codegen_fn_attrs(def_id); let instance = Instance::mono(self.tcx, def_id); - let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); + let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() }; + // Nested statics do not have a type, so pick a random type and let `define_static` figure out + // the llvm type from the actual evaluated initializer. + let ty = if nested { self.tcx.types.unit} else { instance.ty(self.tcx, ty::ParamEnv::reveal_all()) }; let gcc_type = self.layout_of(ty).gcc_type(self); let is_tls = attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL); diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index e39f2b6cd6196..39ad025e58a10 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -9,6 +9,7 @@ use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; use rustc_codegen_ssa::traits::*; +use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::interpret::{ @@ -229,9 +230,17 @@ impl<'ll> CodegenCx<'ll, '_> { pub(crate) fn get_static(&self, def_id: DefId) -> &'ll Value { let instance = Instance::mono(self.tcx, def_id); trace!(?instance); - let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); - trace!(?ty); - let llty = self.layout_of(ty).llvm_type(self); + + let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() }; + // Nested statics do not have a type, so pick a random type and let `define_static` figure out + // the llvm type from the actual evaluated initializer. + let llty = if nested { + self.type_i8() + } else { + let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); + trace!(?ty); + self.layout_of(ty).llvm_type(self) + }; self.get_static_inner(def_id, llty) } @@ -346,6 +355,9 @@ impl<'ll> CodegenCx<'ll, '_> { fn codegen_static_item(&self, def_id: DefId) { unsafe { + assert!( + llvm::LLVMGetInitializer(self.statics.borrow().get(&def_id).unwrap()).is_none() + ); let attrs = self.tcx.codegen_fn_attrs(def_id); let Ok((v, alloc)) = codegen_static_initializer(self, def_id) else { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index f961cd2d00b06..25a08b3056dfc 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -26,6 +26,7 @@ use rustc_codegen_ssa::debuginfo::type_names::VTableNameKind; use rustc_codegen_ssa::traits::*; use rustc_fs_util::path_to_c_string; use rustc_hir::def::CtorKind; +use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; @@ -1301,7 +1302,12 @@ pub fn build_global_var_di_node<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId, glo }; let is_local_to_unit = is_node_local_to_unit(cx, def_id); - let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx, ty::ParamEnv::reveal_all()); + + let DefKind::Static { nested, .. } = cx.tcx.def_kind(def_id) else { bug!() }; + if nested { + return; + } + let variable_type = cx.tcx.type_of(def_id).instantiate_identity(); let type_di_node = type_di_node(cx, variable_type); let var_name = tcx.item_name(def_id); let var_name = var_name.as_str(); diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index ab09ce2c2b749..ca8853b689b35 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -5,7 +5,9 @@ use crate::errors::SymbolAlreadyDefined; use crate::llvm; use crate::type_of::LayoutLlvmExt; use rustc_codegen_ssa::traits::*; +use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_middle::bug; use rustc_middle::mir::mono::{Linkage, Visibility}; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf}; use rustc_middle::ty::{self, Instance, TypeVisitableExt}; @@ -21,7 +23,14 @@ impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'_, 'tcx> { symbol_name: &str, ) { let instance = Instance::mono(self.tcx, def_id); - let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); + let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() }; + // Nested statics do not have a type, so pick a random type and let `define_static` figure out + // the llvm type from the actual evaluated initializer. + let ty = if nested { + self.tcx.types.unit + } else { + instance.ty(self.tcx, ty::ParamEnv::reveal_all()) + }; let llty = self.layout_of(ty).llvm_type(self); let g = self.define_global(symbol_name, llty).unwrap_or_else(|| { diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 58916c6001f9b..64ace89b01968 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -59,7 +59,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( }; let ret = if let InternKind::Static(_) = intern_kind { - create_static_alloc(ecx, cid.instance.def_id(), layout)? + create_static_alloc(ecx, cid.instance.def_id().expect_local(), layout)? } else { ecx.allocate(layout, MemoryKind::Stack)? }; @@ -381,10 +381,10 @@ pub fn eval_in_interpreter<'mir, 'tcx>( Ok(mplace) => { // Since evaluation had no errors, validate the resulting constant. - // Temporarily allow access to the static_root_alloc_id for the purpose of validation. - let static_root_alloc_id = ecx.machine.static_root_alloc_id.take(); + // Temporarily allow access to the static_root_ids for the purpose of validation. + let static_root_ids = ecx.machine.static_root_ids.take(); let validation = const_validate_mplace(&ecx, &mplace, cid); - ecx.machine.static_root_alloc_id = static_root_alloc_id; + ecx.machine.static_root_ids = static_root_ids; let alloc_id = mplace.ptr().provenance.unwrap().alloc_id(); diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 946ffc05cc14f..40d848dab9702 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -8,6 +8,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::fx::IndexEntry; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; +use rustc_hir::def_id::LocalDefId; use rustc_hir::LangItem; use rustc_middle::mir; use rustc_middle::mir::AssertMessage; @@ -60,7 +61,19 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> { pub(super) check_alignment: CheckAlignment, /// Used to prevent reads from a static's base allocation, as that may allow for self-initialization. - pub(crate) static_root_alloc_id: Option, + pub(crate) static_root_ids: Option<(AllocId, LocalDefId)>, +} + +pub trait HasStaticRootDefId { + /// Returns the `DefId` of the static item that is currently being evaluated. + /// Used for interning to be able to handle nested allocations. + fn static_def_id(&self) -> Option; +} + +impl HasStaticRootDefId for CompileTimeInterpreter<'_, '_> { + fn static_def_id(&self) -> Option { + Some(self.static_root_ids?.1) + } } #[derive(Copy, Clone)] @@ -94,7 +107,7 @@ impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> { stack: Vec::new(), can_access_mut_global, check_alignment, - static_root_alloc_id: None, + static_root_ids: None, } } } @@ -751,7 +764,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ecx: &InterpCx<'mir, 'tcx, Self>, alloc_id: AllocId, ) -> InterpResult<'tcx> { - if Some(alloc_id) == ecx.machine.static_root_alloc_id { + if Some(alloc_id) == ecx.machine.static_root_ids.map(|(id, _)| id) { Err(ConstEvalErrKind::RecursiveStatic.into()) } else { Ok(()) diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index 959ec2ca86558..d9476b9150211 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -13,12 +13,16 @@ //! but that would require relying on type information, and given how many ways Rust has to lie //! about type information, we want to avoid doing that. +use hir::def::DefKind; use rustc_ast::Mutability; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; -use rustc_middle::mir::interpret::{CtfeProvenance, InterpResult}; +use rustc_middle::mir::interpret::{ConstAllocation, CtfeProvenance, InterpResult}; +use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::layout::TyAndLayout; +use rustc_span::def_id::LocalDefId; +use rustc_span::sym; use super::{AllocId, Allocation, InterpCx, MPlaceTy, Machine, MemoryKind, PlaceTy}; use crate::const_eval; @@ -33,7 +37,7 @@ pub trait CompileTimeMachine<'mir, 'tcx: 'mir, T> = Machine< FrameExtra = (), AllocExtra = (), MemoryMap = FxIndexMap, Allocation)>, - >; + > + const_eval::HasStaticRootDefId; /// Intern an allocation. Returns `Err` if the allocation does not exist in the local memory. /// @@ -67,10 +71,34 @@ fn intern_shallow<'rt, 'mir, 'tcx, T, M: CompileTimeMachine<'mir, 'tcx, T>>( } // link the alloc id to the actual allocation let alloc = ecx.tcx.mk_const_alloc(alloc); - ecx.tcx.set_alloc_id_memory(alloc_id, alloc); + if let Some(static_id) = ecx.machine.static_def_id() { + intern_as_new_static(ecx.tcx, static_id, alloc_id, alloc); + } else { + ecx.tcx.set_alloc_id_memory(alloc_id, alloc); + } Ok(alloc.0.0.provenance().ptrs().iter().map(|&(_, prov)| prov)) } +/// Creates a new `DefId` and feeds all the right queries to make this `DefId` +/// appear as if it were a user-written `static` (though it has no HIR). +fn intern_as_new_static<'tcx>( + tcx: TyCtxtAt<'tcx>, + static_id: LocalDefId, + alloc_id: AllocId, + alloc: ConstAllocation<'tcx>, +) { + let feed = tcx.create_def( + static_id, + sym::nested, + DefKind::Static { mt: alloc.0.mutability, nested: true }, + ); + tcx.set_nested_alloc_id_static(alloc_id, feed.def_id()); + feed.codegen_fn_attrs(tcx.codegen_fn_attrs(static_id).clone()); + feed.eval_static_initializer(Ok(alloc)); + feed.generics_of(tcx.generics_of(static_id).clone()); + feed.def_ident_span(tcx.def_ident_span(static_id)); + feed.explicit_predicates_of(tcx.explicit_predicates_of(static_id)); +} /// How a constant value should be interned. #[derive(Copy, Clone, Debug, PartialEq, Hash, Eq)] pub enum InternKind { diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 3b2208b8caa8a..8c36393301f36 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -14,6 +14,7 @@ use std::ptr; use rustc_ast::Mutability; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; +use rustc_hir::def::DefKind; use rustc_middle::mir::display_allocation; use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TyCtxt}; use rustc_target::abi::{Align, HasDataLayout, Size}; @@ -744,19 +745,33 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // be held throughout the match. match self.tcx.try_get_global_alloc(id) { Some(GlobalAlloc::Static(def_id)) => { - assert!(self.tcx.is_static(def_id)); // Thread-local statics do not have a constant address. They *must* be accessed via // `ThreadLocalRef`; we can never have a pointer to them as a regular constant value. assert!(!self.tcx.is_thread_local_static(def_id)); - // Use size and align of the type. - let ty = self - .tcx - .type_of(def_id) - .no_bound_vars() - .expect("statics should not have generic parameters"); - let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap(); - assert!(layout.is_sized()); - (layout.size, layout.align.abi, AllocKind::LiveData) + + let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { + bug!("GlobalAlloc::Static is not a static") + }; + + let (size, align) = if nested { + // Nested anonymous statics are untyped, so let's get their + // size and alignment from the allocaiton itself. This always + // succeeds, as the query is fed at DefId creation time, so no + // evaluation actually occurs. + let alloc = self.tcx.eval_static_initializer(def_id).unwrap(); + (alloc.0.size(), alloc.0.align) + } else { + // Use size and align of the type. + let ty = self + .tcx + .type_of(def_id) + .no_bound_vars() + .expect("statics should not have generic parameters"); + let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap(); + assert!(layout.is_sized()); + (layout.size, layout.align.abi) + }; + (size, align, AllocKind::LiveData) } Some(GlobalAlloc::Memory(alloc)) => { // Need to duplicate the logic here, because the global allocations have diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index 2a13671a82978..e7566886857dd 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -1,11 +1,11 @@ use crate::const_eval::CompileTimeEvalContext; use crate::interpret::{MemPlaceMeta, MemoryKind}; +use rustc_hir::def_id::LocalDefId; use rustc_middle::mir::interpret::{AllocId, Allocation, InterpResult, Pointer}; use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; -use rustc_span::def_id::DefId; use std::ops::ControlFlow; use super::MPlaceTy; @@ -89,13 +89,13 @@ pub(crate) fn take_static_root_alloc<'mir, 'tcx: 'mir>( pub(crate) fn create_static_alloc<'mir, 'tcx: 'mir>( ecx: &mut CompileTimeEvalContext<'mir, 'tcx>, - static_def_id: DefId, + static_def_id: LocalDefId, layout: TyAndLayout<'tcx>, ) -> InterpResult<'tcx, MPlaceTy<'tcx>> { let alloc = Allocation::try_uninit(layout.size, layout.align.abi)?; - let alloc_id = ecx.tcx.reserve_and_set_static_alloc(static_def_id); - assert_eq!(ecx.machine.static_root_alloc_id, None); - ecx.machine.static_root_alloc_id = Some(alloc_id); + let alloc_id = ecx.tcx.reserve_and_set_static_alloc(static_def_id.into()); + assert_eq!(ecx.machine.static_root_ids, None); + ecx.machine.static_root_ids = Some((alloc_id, static_def_id)); assert!(ecx.memory.alloc_map.insert(alloc_id, (MemoryKind::Stack, alloc)).is_none()); Ok(ecx.ptr_with_meta_to_mplace(Pointer::from(alloc_id).into(), MemPlaceMeta::None, layout)) } diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 63dee3a5738ce..361ca167010b3 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -250,6 +250,9 @@ impl DefKind { | DefKind::AssocTy | DefKind::TyParam | DefKind::ExternCrate => DefPathData::TypeNs(name), + // It's not exactly an anon const, but wrt DefPathData, there + // is not difference. + DefKind::Static { nested: true, .. } => DefPathData::AnonConst, DefKind::Fn | DefKind::Const | DefKind::ConstParam diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 34f58e466f95f..58367cc2f2a0f 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -882,7 +882,7 @@ fn should_encode_attrs(def_kind: DefKind) -> bool { | DefKind::AssocTy | DefKind::Fn | DefKind::Const - | DefKind::Static { .. } + | DefKind::Static { nested: false, .. } | DefKind::AssocFn | DefKind::AssocConst | DefKind::Macro(_) @@ -903,6 +903,7 @@ fn should_encode_attrs(def_kind: DefKind) -> bool { | DefKind::InlineConst | DefKind::OpaqueTy | DefKind::LifetimeParam + | DefKind::Static { nested: true, .. } | DefKind::GlobalAsm => false, } } @@ -956,7 +957,7 @@ fn should_encode_visibility(def_kind: DefKind) -> bool { | DefKind::AssocTy | DefKind::Fn | DefKind::Const - | DefKind::Static { .. } + | DefKind::Static { nested: false, .. } | DefKind::Ctor(..) | DefKind::AssocFn | DefKind::AssocConst @@ -969,6 +970,7 @@ fn should_encode_visibility(def_kind: DefKind) -> bool { | DefKind::LifetimeParam | DefKind::AnonConst | DefKind::InlineConst + | DefKind::Static { nested: true, .. } | DefKind::OpaqueTy | DefKind::GlobalAsm | DefKind::Impl { .. } @@ -1148,7 +1150,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) -> | DefKind::Field | DefKind::Fn | DefKind::Const - | DefKind::Static { .. } + | DefKind::Static { nested: false, .. } | DefKind::TyAlias | DefKind::ForeignTy | DefKind::Impl { .. } @@ -1190,6 +1192,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) -> | DefKind::Mod | DefKind::ForeignMod | DefKind::Macro(..) + | DefKind::Static { nested: true, .. } | DefKind::Use | DefKind::LifetimeParam | DefKind::GlobalAsm diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 5be09b06d9e4b..ad46ee45d89a9 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -130,7 +130,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{HashMapExt, Lock}; use rustc_data_structures::tiny_list::TinyList; use rustc_errors::ErrorGuaranteed; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_macros::HashStable; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_serialize::{Decodable, Encodable}; @@ -627,6 +627,16 @@ impl<'tcx> TyCtxt<'tcx> { } } + /// Freezes an `AllocId` created with `reserve` by pointing it at a static item. Trying to + /// call this function twice, even with the same `DefId` will ICE the compiler. + pub fn set_nested_alloc_id_static(self, id: AllocId, def_id: LocalDefId) { + if let Some(old) = + self.alloc_map.lock().alloc_map.insert(id, GlobalAlloc::Static(def_id.to_def_id())) + { + bug!("tried to set allocation ID {id:?}, but it was already existing as {old:#?}"); + } + } + /// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. May be called /// twice for the same `(AllocId, Allocation)` pair. fn set_alloc_id_same_memory(self, id: AllocId, mem: ConstAllocation<'tcx>) { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index e87bc581e6eab..f9e4b0e8f158c 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1080,6 +1080,7 @@ rustc_queries! { } cache_on_disk_if { key.is_local() } separate_provide_extern + feedable } /// Evaluates const items or anonymous constants @@ -1238,6 +1239,7 @@ rustc_queries! { arena_cache cache_on_disk_if { def_id.is_local() } separate_provide_extern + feedable } query asm_target_features(def_id: DefId) -> &'tcx FxIndexSet { diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 9dc7a50eca9f5..ab621842f1886 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -2,6 +2,7 @@ //! //! Currently, this pass only propagates scalar values. +use rustc_const_eval::const_eval::HasStaticRootDefId; use rustc_const_eval::interpret::{ ImmTy, Immediate, InterpCx, OpTy, PlaceTy, PointerArithmetic, Projectable, }; @@ -889,6 +890,12 @@ impl<'tcx> Visitor<'tcx> for OperandCollector<'tcx, '_, '_, '_> { pub(crate) struct DummyMachine; +impl HasStaticRootDefId for DummyMachine { + fn static_def_id(&self) -> Option { + None + } +} + impl<'mir, 'tcx: 'mir> rustc_const_eval::interpret::Machine<'mir, 'tcx> for DummyMachine { rustc_const_eval::interpret::compile_time_machine!(<'mir, 'tcx>); type MemoryKind = !; diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 8c1105cf8339e..f08934a94a7c7 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -380,8 +380,12 @@ fn collect_items_rec<'tcx>( // Sanity check whether this ended up being collected accidentally debug_assert!(should_codegen_locally(tcx, &instance)); - let ty = instance.ty(tcx, ty::ParamEnv::reveal_all()); - visit_drop_use(tcx, ty, true, starting_item.span, &mut used_items); + let DefKind::Static { nested, .. } = tcx.def_kind(def_id) else { bug!() }; + // Nested statics have no type. + if !nested { + let ty = instance.ty(tcx, ty::ParamEnv::reveal_all()); + visit_drop_use(tcx, ty, true, starting_item.span, &mut used_items); + } recursion_depth_reset = None; diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 9a22f5a1b63ac..d95acbd75b30e 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -13,6 +13,7 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::Node; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::middle::privacy::{self, Level}; +use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc}; use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::config::CrateType; @@ -197,10 +198,20 @@ impl<'tcx> ReachableContext<'tcx> { // Reachable constants will be inlined into other crates // unconditionally, so we need to make sure that their // contents are also reachable. - hir::ItemKind::Const(_, _, init) | hir::ItemKind::Static(_, _, init) => { + hir::ItemKind::Const(_, _, init) => { self.visit_nested_body(init); } + // Reachable statics are inlined if read from another constant or static + // in other crates. Additionally anonymous nested statics may be created + // when evaluating a static, so preserve those, too. + hir::ItemKind::Static(_, _, init) => { + self.visit_nested_body(init); + if let Ok(alloc) = self.tcx.eval_static_initializer(item.owner_id.def_id) { + self.propagate_statics_from_alloc(item.owner_id.def_id, alloc); + } + } + // These are normal, nothing reachable about these // inherently and their children are already in the // worklist, as determined by the privacy pass @@ -266,6 +277,27 @@ impl<'tcx> ReachableContext<'tcx> { } } } + + /// Finds anonymous nested statics created for nested allocations. + fn propagate_statics_from_alloc(&mut self, root: LocalDefId, alloc: ConstAllocation<'tcx>) { + if !self.any_library { + return; + } + for (_, prov) in alloc.0.provenance().ptrs().iter() { + match self.tcx.global_alloc(prov.alloc_id()) { + GlobalAlloc::Static(def_id) => { + if let Some(def_id) = def_id.as_local() + && self.tcx.local_parent(def_id) == root + && self.reachable_symbols.insert(def_id) + && let Ok(alloc) = self.tcx.eval_static_initializer(def_id) + { + self.propagate_statics_from_alloc(root, alloc); + } + } + GlobalAlloc::Function(_) | GlobalAlloc::VTable(_, _) | GlobalAlloc::Memory(_) => {} + } + } + } } fn check_item<'tcx>( diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 46472a131ff4b..795d874db774f 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1109,6 +1109,7 @@ symbols! { negative_bounds, negative_impls, neon, + nested, never, never_patterns, never_type, diff --git a/tests/ui/consts/const-mut-refs-crate.rs b/tests/ui/consts/const-mut-refs-crate.rs index 96df2cefce27b..c540cbf2b5c51 100644 --- a/tests/ui/consts/const-mut-refs-crate.rs +++ b/tests/ui/consts/const-mut-refs-crate.rs @@ -24,12 +24,11 @@ static ONE_STEP_ABOVE: &i32 = *DOUBLE_REF; pub fn main() { unsafe { - assert_ne!(FOO as *const i32, BAR as *const i32); + assert_eq!(FOO as *const i32, BAR as *const i32); assert_eq!(INNER_MOD_FOO as *const i32, INNER_MOD_BAR as *const i32); assert_eq!(LOCAL_FOO as *const i32, LOCAL_BAR as *const i32); assert_eq!(*DOUBLE_REF as *const i32, ONE_STEP_ABOVE as *const i32); - // bug! - assert_ne!(FOO as *const i32, COPY_OF_REMOTE_FOO as *const i32); + assert_eq!(FOO as *const i32, COPY_OF_REMOTE_FOO as *const i32); } } From e5836ab3dbbbfb95d15ec6452eaec24fe6e80e61 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 26 Feb 2024 20:23:48 +0000 Subject: [PATCH 14/14] Allow validation of complex nested statics --- .../src/interpret/validity.rs | 29 ++++++++++++------- tests/ui/statics/nested_struct.rs | 19 ++++++++++++ 2 files changed, 37 insertions(+), 11 deletions(-) create mode 100644 tests/ui/statics/nested_struct.rs diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 25f2450edab7f..27ee5227def3a 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -465,16 +465,6 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' // Special handling for pointers to statics (irrespective of their type). assert!(!self.ecx.tcx.is_thread_local_static(did)); assert!(self.ecx.tcx.is_static(did)); - let is_mut = matches!( - self.ecx.tcx.def_kind(did), - DefKind::Static { mt: Mutability::Mut, .. } - ) || !self - .ecx - .tcx - .type_of(did) - .no_bound_vars() - .expect("statics should not have generic parameters") - .is_freeze(*self.ecx.tcx, ty::ParamEnv::reveal_all()); // Mode-specific checks match self.ctfe_mode { Some( @@ -500,7 +490,24 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' None => {} } // Return alloc mutability - if is_mut { Mutability::Mut } else { Mutability::Not } + if let DefKind::Static { mt, nested } = self.ecx.tcx.def_kind(did) { + if nested { + mt + } else if self + .ecx + .tcx + .type_of(did) + .no_bound_vars() + .expect("statics should not have generic parameters") + .is_freeze(*self.ecx.tcx, ty::ParamEnv::reveal_all()) + { + Mutability::Not + } else { + mt + } + } else { + Mutability::Not + } } GlobalAlloc::Memory(alloc) => alloc.inner().mutability, GlobalAlloc::Function(..) | GlobalAlloc::VTable(..) => { diff --git a/tests/ui/statics/nested_struct.rs b/tests/ui/statics/nested_struct.rs new file mode 100644 index 0000000000000..06ee5ffcdf975 --- /dev/null +++ b/tests/ui/statics/nested_struct.rs @@ -0,0 +1,19 @@ +//@ check-pass + +pub struct Lint { + pub name: &'static str, + pub desc: &'static str, + pub report_in_external_macro: bool, + pub is_loaded: bool, + pub crate_level_only: bool, +} + +static FOO: &Lint = &Lint { + name: &"foo", + desc: "desc", + report_in_external_macro: false, + is_loaded: true, + crate_level_only: false, +}; + +fn main() {}