From 03ae680e97e667ca7aabc4074268c660603ae474 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 15 Apr 2024 10:45:37 -0400 Subject: [PATCH 1/3] Okay actually check only alias TYPES --- compiler/rustc_trait_selection/src/traits/wf.rs | 12 +++--------- tests/ui/higher-ranked/well-formed-aliases.rs | 8 ++++++++ tests/ui/higher-ranked/well-formed-aliases.stderr | 12 ++++++++++++ 3 files changed, 23 insertions(+), 9 deletions(-) create mode 100644 tests/ui/higher-ranked/well-formed-aliases.rs create mode 100644 tests/ui/higher-ranked/well-formed-aliases.stderr diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 066755f7b3e7c..e3952679f96b3 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -435,12 +435,6 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { } } - /// Pushes the obligations required for an alias (except inherent) to be WF - /// into `self.out`. - fn compute_alias_ty(&mut self, data: ty::AliasTy<'tcx>) { - self.compute_alias_term(data.into()); - } - /// Pushes the obligations required for an alias (except inherent) to be WF /// into `self.out`. fn compute_alias_term(&mut self, data: ty::AliasTerm<'tcx>) { @@ -498,7 +492,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { self.out.extend(obligations); } - self.compute_projection_args(data.args); + data.args.visit_with(self); } fn compute_projection_args(&mut self, args: GenericArgsRef<'tcx>) { @@ -702,8 +696,8 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { } ty::Alias(ty::Projection | ty::Opaque | ty::Weak, data) => { - self.compute_alias_ty(data); - return; // Subtree handled by compute_projection. + let obligations = self.nominal_obligations(data.def_id, data.args); + self.out.extend(obligations); } ty::Alias(ty::Inherent, data) => { self.compute_inherent_projection(data); diff --git a/tests/ui/higher-ranked/well-formed-aliases.rs b/tests/ui/higher-ranked/well-formed-aliases.rs new file mode 100644 index 0000000000000..60e013a54bcd5 --- /dev/null +++ b/tests/ui/higher-ranked/well-formed-aliases.rs @@ -0,0 +1,8 @@ +trait Trait { + type Gat; +} + +fn test(f: for<'a> fn(<&'a T as Trait>::Gat<&'a [str]>)) where for<'a> &'a T: Trait {} +//~^ ERROR the size for values of type `str` cannot be known at compilation time + +fn main() {} diff --git a/tests/ui/higher-ranked/well-formed-aliases.stderr b/tests/ui/higher-ranked/well-formed-aliases.stderr new file mode 100644 index 0000000000000..4a6f4e961d995 --- /dev/null +++ b/tests/ui/higher-ranked/well-formed-aliases.stderr @@ -0,0 +1,12 @@ +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/well-formed-aliases.rs:5:52 + | +LL | fn test(f: for<'a> fn(<&'a T as Trait>::Gat<&'a [str]>)) where for<'a> &'a T: Trait {} + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` + = note: slice and array elements must have `Sized` type + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From 6c7b8ecf873b0e812a0ae0579b848b286f32fdaf Mon Sep 17 00:00:00 2001 From: Florian Schmiderer Date: Tue, 30 Apr 2024 20:44:07 +0200 Subject: [PATCH 2/3] Add hotpatch flag. Proof of concept only working on x86/x64. --- compiler/rustc_codegen_llvm/src/attributes.rs | 9 +++++++++ .../src/back/owned_target_machine.rs | 2 ++ compiler/rustc_codegen_llvm/src/back/write.rs | 5 +++++ compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 1 + compiler/rustc_interface/src/tests.rs | 1 + compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 3 ++- compiler/rustc_session/src/options.rs | 4 ++++ compiler/rustc_target/src/spec/mod.rs | 3 +++ tests/codegen/hotpatch.rs | 12 ++++++++++++ 9 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 tests/codegen/hotpatch.rs diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index cd82894af18eb..0faabf6189399 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -370,6 +370,15 @@ pub fn from_fn_attrs<'ll, 'tcx>( to_add.push(llvm::CreateAttrString(cx.llcx, "use-sample-profile")); } + // patchable-function is only implemented on x86 on LLVM + if cx.sess().opts.unstable_opts.hotpatch && cx.sess().target.is_x86() { + to_add.push(llvm::CreateAttrStringValue( + cx.llcx, + "patchable-function", + "prologue-short-redirect", + )); + } + // FIXME: none of these functions interact with source level attributes. to_add.extend(frame_pointer_type_attr(cx)); to_add.extend(function_return_attr(cx)); diff --git a/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs index 28a88dd2efea0..e8aff8f59df40 100644 --- a/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs +++ b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs @@ -36,6 +36,7 @@ impl OwnedTargetMachine { emit_stack_size_section: bool, relax_elf_relocations: bool, use_init_array: bool, + use_hotpatch: bool, split_dwarf_file: &CStr, output_obj_file: &CStr, debug_info_compression: &CStr, @@ -68,6 +69,7 @@ impl OwnedTargetMachine { emit_stack_size_section, relax_elf_relocations, use_init_array, + use_hotpatch, split_dwarf_file.as_ptr(), output_obj_file.as_ptr(), debug_info_compression.as_ptr(), diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 5e481eb98f55f..77b48f6776aca 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -221,6 +221,10 @@ pub fn target_machine_factory( let use_init_array = !sess.opts.unstable_opts.use_ctors_section.unwrap_or(sess.target.use_ctors_section); + // this annotes in the debug file that code is hotpatchable. In addtion without it -functionpadmin will be ignored. + // See: https://github.com/llvm/llvm-project/blob/d703b922961e0d02a5effdd4bfbb23ad50a3cc9f/lld/COFF/Writer.cpp#L1298 + let use_hotpatch = sess.opts.unstable_opts.hotpatch && sess.target.is_x86(); + let path_mapping = sess.source_map().path_mapping().clone(); let use_emulated_tls = matches!(sess.tls_model(), TlsModel::Emulated); @@ -293,6 +297,7 @@ pub fn target_machine_factory( emit_stack_size_section, relax_elf_relocations, use_init_array, + use_hotpatch, &split_dwarf_file, &output_obj_file, &debuginfo_compression, diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 132e1f9e8fd93..c2fe744c51804 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2189,6 +2189,7 @@ extern "C" { EmitStackSizeSection: bool, RelaxELFRelocations: bool, UseInitArray: bool, + UseHotpatch: bool, SplitDwarfFile: *const c_char, OutputObjFile: *const c_char, DebugInfoCompression: *const c_char, diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 9bd67a1154b7d..6fa39c3058556 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -787,6 +787,7 @@ fn test_unstable_options_tracking_hash() { tracked!(fuel, Some(("abc".to_string(), 99))); tracked!(function_return, FunctionReturn::ThunkExtern); tracked!(function_sections, Some(false)); + tracked!(hotpatch, true); tracked!(human_readable_cgu_names, true); tracked!(incremental_ignore_spans, true); tracked!(inline_in_all_cgus, Some(true)); diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index c4cfc0b6dc6a1..31e70f9a20fd5 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -408,7 +408,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat, bool FunctionSections, bool DataSections, bool UniqueSectionNames, bool TrapUnreachable, bool Singlethread, bool AsmComments, - bool EmitStackSizeSection, bool RelaxELFRelocations, bool UseInitArray, + bool EmitStackSizeSection, bool RelaxELFRelocations, bool UseInitArray, bool UseHotpatch, const char *SplitDwarfFile, const char *OutputObjFile, const char *DebugInfoCompression, bool UseEmulatedTls, const char *ArgsCstrBuff, size_t ArgsCstrBuffLen) { @@ -438,6 +438,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( Options.MCOptions.AsmVerbose = AsmComments; Options.MCOptions.PreserveAsmComments = AsmComments; Options.MCOptions.ABIName = ABIStr; + Options.Hotpatch = UseHotpatch; if (SplitDwarfFile) { Options.MCOptions.SplitDwarfFile = SplitDwarfFile; } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 2e4421d50e313..62475fa478ca7 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1745,6 +1745,10 @@ options! { "explicitly enable the `cfg(target_thread_local)` directive"), hir_stats: bool = (false, parse_bool, [UNTRACKED], "print some statistics about AST and HIR (default: no)"), + hotpatch: bool = (false, parse_bool, [TRACKED], + "ensures hotpatching is always possible by ensuring that the first instruction of \ + each function is at least two bytes, and no jump within the function goes to the first instruction. \ + Should be combined with link-arg passing -functionpadmin to the linker. Currently only supported for x86 (default: false)"), human_readable_cgu_names: bool = (false, parse_bool, [TRACKED], "generate human-readable, predictable names for codegen units (default: no)"), identify_regions: bool = (false, parse_bool, [UNTRACKED], diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 81ada30a59437..c1f2598bd5125 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1963,6 +1963,9 @@ impl Target { Ok(dl) } + pub fn is_x86(&self) -> bool { + ["x86", "x86_64"].contains(&&self.arch[..]) + } } pub trait HasTargetSpec { diff --git a/tests/codegen/hotpatch.rs b/tests/codegen/hotpatch.rs new file mode 100644 index 0000000000000..91d6ac8759d67 --- /dev/null +++ b/tests/codegen/hotpatch.rs @@ -0,0 +1,12 @@ +//@ revisions: x32 x64 +//@[x32] only-x86 +//@[x64] only-x86_64 +//@ compile-flags: -Z hotpatch + +#![crate_type = "lib"] + +#[no_mangle] +pub fn foo() {} + +// CHECK: @foo() unnamed_addr #0 +// CHECK: attributes #0 = { {{.*}} "patchable-function"="prologue-short-redirect" {{.*}}} From 28bb3eda323ee4832cf5e62044080aa262dcdac0 Mon Sep 17 00:00:00 2001 From: Florian Schmiderer Date: Wed, 3 Jul 2024 12:21:53 +0200 Subject: [PATCH 3/3] tidy --- compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 31e70f9a20fd5..90c1313221176 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -408,8 +408,8 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat, bool FunctionSections, bool DataSections, bool UniqueSectionNames, bool TrapUnreachable, bool Singlethread, bool AsmComments, - bool EmitStackSizeSection, bool RelaxELFRelocations, bool UseInitArray, bool UseHotpatch, - const char *SplitDwarfFile, const char *OutputObjFile, + bool EmitStackSizeSection, bool RelaxELFRelocations, bool UseInitArray, + bool UseHotpatch, const char *SplitDwarfFile, const char *OutputObjFile, const char *DebugInfoCompression, bool UseEmulatedTls, const char *ArgsCstrBuff, size_t ArgsCstrBuffLen) {