diff --git a/compiler/rustc_ast_lowering/src/lifetime_collector.rs b/compiler/rustc_ast_lowering/src/lifetime_collector.rs index 0e0bdf1738918..6f75419c38765 100644 --- a/compiler/rustc_ast_lowering/src/lifetime_collector.rs +++ b/compiler/rustc_ast_lowering/src/lifetime_collector.rs @@ -1,7 +1,7 @@ use super::ResolverAstLoweringExt; use rustc_ast::visit::{self, BoundKind, LifetimeCtxt, Visitor}; use rustc_ast::{GenericBounds, Lifetime, NodeId, PathSegment, PolyTraitRef, Ty, TyKind}; -use rustc_hir::def::LifetimeRes; +use rustc_hir::def::{DefKind, LifetimeRes, Res}; use rustc_middle::span_bug; use rustc_middle::ty::ResolverAstLowering; use rustc_span::symbol::{kw, Ident}; @@ -77,7 +77,20 @@ impl<'ast> Visitor<'ast> for LifetimeCollectVisitor<'ast> { } fn visit_ty(&mut self, t: &'ast Ty) { - match t.kind { + match &t.kind { + TyKind::Path(None, _) => { + // We can sometimes encounter bare trait objects + // which are represented in AST as paths. + if let Some(partial_res) = self.resolver.get_partial_res(t.id) + && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res() + { + self.current_binders.push(t.id); + visit::walk_ty(self, t); + self.current_binders.pop(); + } else { + visit::walk_ty(self, t); + } + } TyKind::BareFn(_) => { self.current_binders.push(t.id); visit::walk_ty(self, t); diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 8fb2ccb7e8a4c..0409e586d4f66 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -245,50 +245,41 @@ fn exported_symbols_provider_local( )) } + // Rust assumes that all code provided to (non-plugin) LTO comes from Rust, so it knows about + // all symbols that are involved. This doesn't hold up for symbols that get injected by LLVM, + // so they need to be special-cased. + let mut externally_injected_weak_symbols = Vec::new(); if tcx.sess.instrument_coverage() || tcx.sess.opts.cg.profile_generate.enabled() { // These are weak symbols that point to the profile version and the // profile name, which need to be treated as exported so LTO doesn't nix // them. - const PROFILER_WEAK_SYMBOLS: [&str; 2] = - ["__llvm_profile_raw_version", "__llvm_profile_filename"]; - - symbols.extend(PROFILER_WEAK_SYMBOLS.iter().map(|sym| { - let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym)); - ( - exported_symbol, - SymbolExportInfo { - level: SymbolExportLevel::C, - kind: SymbolExportKind::Data, - used: false, - }, - ) - })); + externally_injected_weak_symbols.push("__llvm_profile_raw_version"); + externally_injected_weak_symbols.push("__llvm_profile_filename"); } - if tcx.sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::MEMORY) { - let mut msan_weak_symbols = Vec::new(); - // Similar to profiling, preserve weak msan symbol during LTO. if tcx.sess.opts.unstable_opts.sanitizer_recover.contains(SanitizerSet::MEMORY) { - msan_weak_symbols.push("__msan_keep_going"); + externally_injected_weak_symbols.push("__msan_keep_going"); } - if tcx.sess.opts.unstable_opts.sanitizer_memory_track_origins != 0 { - msan_weak_symbols.push("__msan_track_origins"); + externally_injected_weak_symbols.push("__msan_track_origins"); } - - symbols.extend(msan_weak_symbols.into_iter().map(|sym| { - let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym)); - ( - exported_symbol, - SymbolExportInfo { - level: SymbolExportLevel::C, - kind: SymbolExportKind::Data, - used: false, - }, - ) - })); } + if tcx.sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::ADDRESS) { + // Similar to profiling, preserve weak asan symbols during LTO. + externally_injected_weak_symbols.push("___asan_globals_registered"); + } + symbols.extend(externally_injected_weak_symbols.into_iter().map(|sym| { + let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym)); + ( + exported_symbol, + SymbolExportInfo { + level: SymbolExportLevel::C, + kind: SymbolExportKind::Data, + used: false, + }, + ) + })); if tcx.crate_types().contains(&CrateType::Dylib) || tcx.crate_types().contains(&CrateType::ProcMacro) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index a0d31d3a22c3b..72a04a02bf4fb 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1681,7 +1681,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { || found_assoc(tcx.types.u64) || found_assoc(tcx.types.u128) || found_assoc(tcx.types.f32) - || found_assoc(tcx.types.f32); + || found_assoc(tcx.types.f64); if found_candidate && actual.is_numeric() && !actual.has_concrete_skeleton() diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 6ab473c3b54c5..bc12422e7d7c0 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -1165,7 +1165,9 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::ConstantKind<'tcx> { let const_val = tables.tcx.valtree_to_const_val((c.ty(), val)); stable_mir::ty::ConstantKind::Allocated(new_allocation(self, const_val, tables)) } - _ => todo!(), + ty::ParamCt(param) => stable_mir::ty::ConstantKind::ParamCt(opaque(¶m)), + ty::ErrorCt(_) => unreachable!(), + _ => unimplemented!(), }, ConstantKind::Unevaluated(unev_const, ty) => { stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst { diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs index 8a23af75749ac..875d5ae70da1c 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -417,6 +417,7 @@ pub fn allocation_filter<'tcx>( pub enum ConstantKind { Allocated(Allocation), Unevaluated(UnevaluatedConst), + ParamCt(Opaque), } #[derive(Clone, Debug)] diff --git a/tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs b/tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs new file mode 100644 index 0000000000000..ec1028d8bd9eb --- /dev/null +++ b/tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs @@ -0,0 +1,36 @@ +// Verifies that AddressSanitizer symbols show up as expected in LLVM IR +// with -Zsanitizer (DO NOT SUBMIT: add ASAN (no LTO) and ASAN-LTO2 (lto=fat) tests). +// +// Notes about the `compile-flags` below: +// +// * The original issue only reproed with LTO - this is why this angle has +// extra test coverage via different `revisions` +// * To observe the failure/repro at LLVM-IR level we need to use `staticlib` +// which necessitates `-C prefer-dynamic=false` - without the latter flag, +// we would have run into "cannot prefer dynamic linking when performing LTO". +// +// needs-sanitizer-address +// +// revisions:ASAN ASAN-LTO +//[ASAN] compile-flags: -Zsanitizer=address +//[ASAN-LTO] compile-flags: -Zsanitizer=address -C prefer-dynamic=false -C lto + +#![crate_type="staticlib"] + +// The test below mimics `CACHED_POW10` from `library/core/src/num/flt2dec/strategy/grisu.rs` which +// (because of incorrect handling of `___asan_globals_registered` during LTO) was incorrectly +// reported as an ODR violation in https://crbug.com/1459233#c1. Before this bug was fixed, +// `___asan_globals_registered` would show up as `internal global i64`. +// +// See https://github.com/rust-lang/rust/issues/113404 for more discussion. +// +// CHECK: @___asan_globals_registered = common hidden global i64 0 +// CHECK: @__start_asan_globals = extern_weak hidden global i64 +// CHECK: @__stop_asan_globals = extern_weak hidden global i64 +#[no_mangle] +pub static CACHED_POW10: [(u64, i16, i16); 4] = [ + (0xe61acf033d1a45df, -1087, -308), + (0xab70fe17c79ac6ca, -1060, -300), + (0xff77b1fcbebcdc4f, -1034, -292), + (0xbe5691ef416bd60c, -1007, -284), +]; diff --git a/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.rs b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.rs new file mode 100644 index 0000000000000..57d688492515b --- /dev/null +++ b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.rs @@ -0,0 +1,22 @@ +// edition:2015 +// check-pass +// issue: 114664 + +fn ice() -> impl AsRef<Fn(&())> { + //~^ WARN trait objects without an explicit `dyn` are deprecated + //~| WARN trait objects without an explicit `dyn` are deprecated + //~| WARN trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + Foo +} + +struct Foo; +impl AsRef<dyn Fn(&())> for Foo { + fn as_ref(&self) -> &(dyn for<'a> Fn(&'a ()) + 'static) { + todo!() + } +} + +pub fn main() {} diff --git a/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr new file mode 100644 index 0000000000000..fad0b812d43dd --- /dev/null +++ b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr @@ -0,0 +1,42 @@ +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/fresh-lifetime-from-bare-trait-obj-114664.rs:5:24 + | +LL | fn ice() -> impl AsRef<Fn(&())> { + | ^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: `#[warn(bare_trait_objects)]` on by default +help: use `dyn` + | +LL | fn ice() -> impl AsRef<dyn Fn(&())> { + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/fresh-lifetime-from-bare-trait-obj-114664.rs:5:24 + | +LL | fn ice() -> impl AsRef<Fn(&())> { + | ^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> +help: use `dyn` + | +LL | fn ice() -> impl AsRef<dyn Fn(&())> { + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/fresh-lifetime-from-bare-trait-obj-114664.rs:5:24 + | +LL | fn ice() -> impl AsRef<Fn(&())> { + | ^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> +help: use `dyn` + | +LL | fn ice() -> impl AsRef<dyn Fn(&())> { + | +++ + +warning: 3 warnings emitted + diff --git a/triagebot.toml b/triagebot.toml index c513dce3f4048..b2ea206a8a285 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -490,7 +490,7 @@ cc = ["@nnethercote"] [assign] warn_non_default_branch = true contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html" -users_on_vacation = ["jyn514", "WaffleLapkin", "clubby789"] +users_on_vacation = ["jyn514", "WaffleLapkin", "clubby789", "oli-obk"] [assign.adhoc_groups] compiler-team = [