diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index 3e4c1a9dfad84..65f8fdd1c5af9 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -53,6 +53,9 @@ attr_parsing_expects_feature_list = attr_parsing_expects_features = `{$name}` expects feature names +attr_parsing_export_symbols_needs_static = + linking modifier `export-symbols` is only compatible with `static` linking kind + attr_parsing_import_name_type_raw = import name type can only be used with link kind `raw-dylib` @@ -95,7 +98,7 @@ attr_parsing_invalid_issue_string = .neg_overflow = number too small to fit in target type attr_parsing_invalid_link_modifier = - invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed + invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols attr_parsing_invalid_meta_item = expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found {$descr} .remove_neg_sugg = negative numbers are not literals, try removing the `-` sign diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index 548f53a986b8f..be2d0178fefd4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -12,10 +12,10 @@ use super::util::parse_single_integer; use crate::attributes::cfg::parse_cfg_entry; use crate::fluent_generated; use crate::session_diagnostics::{ - AsNeededCompatibility, BundleNeedsStatic, EmptyLinkName, ImportNameTypeRaw, ImportNameTypeX86, - IncompatibleWasmLink, InvalidLinkModifier, LinkFrameworkApple, LinkOrdinalOutOfRange, - LinkRequiresName, MultipleModifiers, NullOnLinkSection, RawDylibNoNul, RawDylibOnlyWindows, - WholeArchiveNeedsStatic, + AsNeededCompatibility, BundleNeedsStatic, EmptyLinkName, ExportSymbolsNeedsStatic, + ImportNameTypeRaw, ImportNameTypeX86, IncompatibleWasmLink, InvalidLinkModifier, + LinkFrameworkApple, LinkOrdinalOutOfRange, LinkRequiresName, MultipleModifiers, + NullOnLinkSection, RawDylibNoNul, RawDylibOnlyWindows, WholeArchiveNeedsStatic, }; pub(crate) struct LinkNameParser; @@ -165,6 +165,14 @@ impl CombineAttributeParser for LinkParser { cx.emit_err(BundleNeedsStatic { span }); } + (sym::export_symbols, Some(NativeLibKind::Static { export_symbols, .. })) => { + assign_modifier(export_symbols) + } + + (sym::export_symbols, _) => { + cx.emit_err(ExportSymbolsNeedsStatic { span }); + } + (sym::verbatim, _) => assign_modifier(&mut verbatim), ( @@ -190,6 +198,7 @@ impl CombineAttributeParser for LinkParser { span, &[ sym::bundle, + sym::export_symbols, sym::verbatim, sym::whole_dash_archive, sym::as_dash_needed, @@ -285,7 +294,9 @@ impl LinkParser { }; let link_kind = match link_kind { - kw::Static => NativeLibKind::Static { bundle: None, whole_archive: None }, + kw::Static => { + NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None } + } sym::dylib => NativeLibKind::Dylib { as_needed: None }, sym::framework => { if !sess.target.is_like_darwin { diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 38f728fa9f559..250bceecbd654 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -307,6 +307,14 @@ impl NoArgsAttributeParser for RustcHasIncoherentInherentImplsParse const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcHasIncoherentInherentImpls; } +pub(crate) struct RustcHiddenTypeOfOpaquesParser; + +impl NoArgsAttributeParser for RustcHiddenTypeOfOpaquesParser { + const PATH: &[Symbol] = &[sym::rustc_hidden_type_of_opaques]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcHiddenTypeOfOpaques; +} pub(crate) struct RustcNounwindParser; impl NoArgsAttributeParser for RustcNounwindParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 0cabc0895053e..51da6def086c2 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -75,13 +75,14 @@ use crate::attributes::rustc_dump::{ RustcDumpVtable, }; use crate::attributes::rustc_internal::{ - RustcHasIncoherentInherentImplsParser, RustcLayoutParser, RustcLayoutScalarValidRangeEndParser, - RustcLayoutScalarValidRangeStartParser, RustcLegacyConstGenericsParser, - RustcLintOptDenyFieldAccessParser, RustcLintOptTyParser, RustcLintQueryInstabilityParser, - RustcLintUntrackedQueryInformationParser, RustcMainParser, RustcMustImplementOneOfParser, - RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser, - RustcNonConstTraitMethodParser, RustcNounwindParser, RustcObjectLifetimeDefaultParser, - RustcOffloadKernelParser, RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser, + RustcHasIncoherentInherentImplsParser, RustcHiddenTypeOfOpaquesParser, RustcLayoutParser, + RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, + RustcLegacyConstGenericsParser, RustcLintOptDenyFieldAccessParser, RustcLintOptTyParser, + RustcLintQueryInstabilityParser, RustcLintUntrackedQueryInformationParser, RustcMainParser, + RustcMustImplementOneOfParser, RustcNeverReturnsNullPointerParser, + RustcNoImplicitAutorefsParser, RustcNonConstTraitMethodParser, RustcNounwindParser, + RustcObjectLifetimeDefaultParser, RustcOffloadKernelParser, RustcScalableVectorParser, + RustcSimdMonomorphizeLaneLimitParser, }; use crate::attributes::semantics::MayDangleParser; use crate::attributes::stability::{ @@ -299,6 +300,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index f9748542beb94..7a0bb2eda9736 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -914,6 +914,13 @@ pub(crate) struct BundleNeedsStatic { pub span: Span, } +#[derive(Diagnostic)] +#[diag(attr_parsing_export_symbols_needs_static)] +pub(crate) struct ExportSymbolsNeedsStatic { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(attr_parsing_whole_archive_needs_static)] pub(crate) struct WholeArchiveNeedsStatic { diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index caf6a86af098a..d8587ed81d6de 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -2309,12 +2309,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { tcx: TyCtxt<'hir>, issue_span: Span, expr_span: Span, - body_expr: Option<&'hir hir::Expr<'hir>>, - loop_bind: Option<&'hir Ident>, - loop_span: Option, - head_span: Option, - pat_span: Option, - head: Option<&'hir hir::Expr<'hir>>, + body_expr: Option<&'hir hir::Expr<'hir>> = None, + loop_bind: Option<&'hir Ident> = None, + loop_span: Option = None, + head_span: Option = None, + pat_span: Option = None, + head: Option<&'hir hir::Expr<'hir>> = None, } impl<'hir> Visitor<'hir> for ExprFinder<'hir> { fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) { @@ -2380,17 +2380,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { hir::intravisit::walk_expr(self, ex); } } - let mut finder = ExprFinder { - tcx, - expr_span: span, - issue_span, - loop_bind: None, - body_expr: None, - head_span: None, - loop_span: None, - pat_span: None, - head: None, - }; + let mut finder = ExprFinder { tcx, expr_span: span, issue_span, .. }; finder.visit_expr(tcx.hir_body(body_id).value); if let Some(body_expr) = finder.body_expr @@ -2625,13 +2615,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { struct ExpressionFinder<'tcx> { capture_span: Span, - closure_change_spans: Vec, - closure_arg_span: Option, - in_closure: bool, - suggest_arg: String, + closure_change_spans: Vec = vec![], + closure_arg_span: Option = None, + in_closure: bool = false, + suggest_arg: String = String::new(), tcx: TyCtxt<'tcx>, - closure_local_id: Option, - closure_call_changes: Vec<(Span, String)>, + closure_local_id: Option = None, + closure_call_changes: Vec<(Span, String)> = vec![], } impl<'hir> Visitor<'hir> for ExpressionFinder<'hir> { fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) { @@ -2712,16 +2702,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { }) = self.infcx.tcx.hir_node(self.mir_hir_id()) && let hir::Node::Expr(expr) = self.infcx.tcx.hir_node(body_id.hir_id) { - let mut finder = ExpressionFinder { - capture_span: *capture_kind_span, - closure_change_spans: vec![], - closure_arg_span: None, - in_closure: false, - suggest_arg: String::new(), - closure_local_id: None, - closure_call_changes: vec![], - tcx: self.infcx.tcx, - }; + let mut finder = + ExpressionFinder { capture_span: *capture_kind_span, tcx: self.infcx.tcx, .. }; finder.visit_expr(expr); if finder.closure_change_spans.is_empty() || finder.closure_call_changes.is_empty() { diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 4a059481c326b..7c5cbc58e25c5 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -4,6 +4,7 @@ #![allow(internal_features)] #![feature(assert_matches)] #![feature(box_patterns)] +#![feature(default_field_values)] #![feature(file_buffered)] #![feature(if_let_guard)] #![feature(negative_impls)] diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index c8109db86e2f2..07283fa2557b2 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -11,10 +11,11 @@ use std::{env, fmt, fs, io, mem, str}; use find_msvc_tools; use itertools::Itertools; +use object::{Object, ObjectSection, ObjectSymbol}; use regex::Regex; use rustc_arena::TypedArena; use rustc_attr_parsing::eval_config_entry; -use rustc_data_structures::fx::FxIndexSet; +use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::temp_dir::MaybeTempDir; use rustc_errors::{DiagCtxtHandle, LintDiagnostic}; @@ -2185,6 +2186,76 @@ fn add_rpath_args( } } +fn add_c_staticlib_symbols( + sess: &Session, + lib: &NativeLib, + out: &mut Vec<(String, SymbolExportKind)>, +) -> io::Result<()> { + let file_path = find_native_static_library(lib.name.as_str(), lib.verbatim, sess); + + let archive_map = unsafe { Mmap::map(File::open(&file_path)?)? }; + + let archive = object::read::archive::ArchiveFile::parse(&*archive_map) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + for member in archive.members() { + let member = member.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + let data = member + .data(&*archive_map) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + // clang LTO: raw LLVM bitcode + if data.starts_with(b"BC\xc0\xde") { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "LLVM bitcode object in C static library (LTO not supported)", + )); + } + + let object = object::File::parse(&*data) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + // gcc / clang ELF / Mach-O LTO + if object.sections().any(|s| { + s.name().map(|n| n.starts_with(".gnu.lto_") || n == ".llvm.lto").unwrap_or(false) + }) { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "LTO object in C static library is not supported", + )); + } + + for symbol in object.symbols() { + if symbol.scope() != object::SymbolScope::Dynamic { + continue; + } + + let mut name = match symbol.name() { + Ok(n) => n, + Err(_) => continue, + }; + + if sess.target.is_like_darwin { + if let Some(stripped) = name.strip_prefix('_') { + name = stripped; + } + } + + let export_kind = match symbol.kind() { + object::SymbolKind::Text => SymbolExportKind::Text, + object::SymbolKind::Data => SymbolExportKind::Data, + _ => continue, + }; + + // FIXME:The symbol mangle rules are slightly different in 32-bit Windows. Need to be resolved. + out.push((name.to_string(), export_kind)); + } + } + + Ok(()) +} + /// Produce the linker command line containing linker path and arguments. /// /// When comments in the function say "order-(in)dependent" they mean order-dependence between @@ -2217,6 +2288,25 @@ fn linker_with_args( ); let link_output_kind = link_output_kind(sess, crate_type); + let mut export_symbols = codegen_results.crate_info.exported_symbols[&crate_type].clone(); + + if crate_type == CrateType::Cdylib { + let mut seen = FxHashSet::default(); + + for lib in &codegen_results.crate_info.used_libraries { + if let NativeLibKind::Static { export_symbols: Some(true), .. } = lib.kind + && seen.insert((lib.name, lib.verbatim)) + { + if let Err(err) = add_c_staticlib_symbols(&sess, lib, &mut export_symbols) { + sess.dcx().fatal(format!( + "failed to process C static library `{}`: {}", + lib.name, err + )); + } + } + } + } + // ------------ Early order-dependent options ------------ // If we're building something like a dynamic library then some platforms @@ -2224,11 +2314,7 @@ fn linker_with_args( // dynamic library. // Must be passed before any libraries to prevent the symbols to export from being thrown away, // at least on some platforms (e.g. windows-gnu). - cmd.export_symbols( - tmpdir, - crate_type, - &codegen_results.crate_info.exported_symbols[&crate_type], - ); + cmd.export_symbols(tmpdir, crate_type, &export_symbols); // Can be used for adding custom CRT objects or overriding order-dependent options above. // FIXME: In practice built-in target specs use this for arbitrary order-independent options, @@ -2678,7 +2764,7 @@ fn add_native_libs_from_crate( let name = lib.name.as_str(); let verbatim = lib.verbatim; match lib.kind { - NativeLibKind::Static { bundle, whole_archive } => { + NativeLibKind::Static { bundle, whole_archive, .. } => { if link_static { let bundle = bundle.unwrap_or(true); let whole_archive = whole_archive == Some(true); diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 92dda79b09203..a8d4e6c3306db 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -331,6 +331,8 @@ pub enum NativeLibKind { bundle: Option, /// Whether to link static library without throwing any object files away whole_archive: Option, + /// Whether to export c static library symbols + export_symbols: Option, }, /// Dynamic library (e.g. `libfoo.so` on Linux) /// or an import library corresponding to a dynamic library (e.g. `foo.lib` on Windows/MSVC). @@ -363,8 +365,8 @@ pub enum NativeLibKind { impl NativeLibKind { pub fn has_modifiers(&self) -> bool { match self { - NativeLibKind::Static { bundle, whole_archive } => { - bundle.is_some() || whole_archive.is_some() + NativeLibKind::Static { bundle, whole_archive, export_symbols } => { + bundle.is_some() || whole_archive.is_some() || export_symbols.is_some() } NativeLibKind::Dylib { as_needed } | NativeLibKind::Framework { as_needed } @@ -1057,6 +1059,9 @@ pub enum AttributeKind { /// Represents `#[rustc_has_incoherent_inherent_impls]` RustcHasIncoherentInherentImpls, + /// Represents `#[rustc_hidden_type_of_opaques]` + RustcHiddenTypeOfOpaques, + /// Represents `#[rustc_layout]` RustcLayout(ThinVec), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 816ed07c1dc4c..f03f55f85b391 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -111,6 +111,7 @@ impl AttributeKind { RustcDumpVtable(..) => No, RustcDynIncompatibleTrait(..) => No, RustcHasIncoherentInherentImpls => Yes, + RustcHiddenTypeOfOpaques => No, RustcLayout(..) => No, RustcLayoutScalarValidRangeEnd(..) => Yes, RustcLayoutScalarValidRangeStart(..) => Yes, diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs index 2dfd4ab6111fe..bbf912cd4bde8 100644 --- a/compiler/rustc_hir_analysis/src/collect/dump.rs +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs @@ -7,10 +7,9 @@ use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_span::sym; pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) { - if !tcx.has_attr(CRATE_DEF_ID, sym::rustc_hidden_type_of_opaques) { + if !find_attr!(tcx.get_all_attrs(CRATE_DEF_ID), AttributeKind::RustcHiddenTypeOfOpaques) { return; } - for id in tcx.hir_crate_items(()).opaques() { if let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. } | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, .. } = diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index f879153c5765a..d414f4dbcc240 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -51,12 +51,12 @@ pub(super) fn diagnostic_hir_wf_check<'tcx>( struct HirWfCheck<'tcx> { tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tcx>, - cause: Option>, - cause_depth: usize, + cause: Option> = None, + cause_depth: usize = 0, icx: ItemCtxt<'tcx>, def_id: LocalDefId, param_env: ty::ParamEnv<'tcx>, - depth: usize, + depth: usize = 0, } impl<'tcx> Visitor<'tcx> for HirWfCheck<'tcx> { @@ -124,16 +124,8 @@ pub(super) fn diagnostic_hir_wf_check<'tcx>( } } - let mut visitor = HirWfCheck { - tcx, - predicate, - cause: None, - cause_depth: 0, - icx, - def_id, - param_env: tcx.param_env(def_id.to_def_id()), - depth: 0, - }; + let param_env = tcx.param_env(def_id.to_def_id()); + let mut visitor = HirWfCheck { tcx, predicate, icx, def_id, param_env, .. }; // Get the starting `hir::Ty` using our `WellFormedLoc`. // We will walk 'into' this type to try to find diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 3a4d894239fc6..f7a1434359593 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -57,6 +57,7 @@ This API is completely unstable and subject to change. // tidy-alphabetical-start #![feature(assert_matches)] +#![feature(default_field_values)] #![feature(gen_blocks)] #![feature(if_let_guard)] #![feature(iter_intersperse)] diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 0f60e86e0ca3c..b0272d726bc38 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -379,7 +379,7 @@ fn test_native_libs_tracking_hash_different_values() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -401,7 +401,7 @@ fn test_native_libs_tracking_hash_different_values() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -423,13 +423,13 @@ fn test_native_libs_tracking_hash_different_values() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { name: String::from("b"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -445,7 +445,7 @@ fn test_native_libs_tracking_hash_different_values() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -467,7 +467,7 @@ fn test_native_libs_tracking_hash_different_values() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -501,7 +501,7 @@ fn test_native_libs_tracking_hash_different_order() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -528,7 +528,7 @@ fn test_native_libs_tracking_hash_different_order() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -549,7 +549,7 @@ fn test_native_libs_tracking_hash_different_order() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index b160b3fe9bb3c..0c06d1be9a3fd 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -161,7 +161,7 @@ fn find_bundled_library( tcx: TyCtxt<'_>, ) -> Option { let sess = tcx.sess; - if let NativeLibKind::Static { bundle: Some(true) | None, whole_archive } = kind + if let NativeLibKind::Static { bundle: Some(true) | None, whole_archive, .. } = kind && tcx.crate_types().iter().any(|t| matches!(t, &CrateType::Rlib | CrateType::StaticLib)) && (sess.opts.unstable_opts.packed_bundled_libs || has_cfg || whole_archive == Some(true)) { diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index 393e9c59c3556..973ceccc67f99 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -441,6 +441,8 @@ impl<'tcx> Place<'tcx> { where D: ?Sized + HasLocalDecls<'tcx>, { + // If there's a field projection element in `projection`, we *could* skip everything + // before that, but on 2026-01-31 a perf experiment showed no benefit from doing so. PlaceTy::from_ty(local_decls.local_decls()[local].ty).multi_projection_ty(tcx, projection) } diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs index bc73d36216ef4..fd08b5a972c68 100644 --- a/compiler/rustc_middle/src/values.rs +++ b/compiler/rustc_middle/src/values.rs @@ -50,9 +50,9 @@ impl<'tcx> Value> for ty::Binder<'_, ty::FnSig<'_>> { ) -> Self { let err = Ty::new_error(tcx, guar); - let arity = if let Some(frame) = cycle_error.cycle.get(0) - && frame.query.dep_kind == dep_kinds::fn_sig - && let Some(def_id) = frame.query.def_id + let arity = if let Some(info) = cycle_error.cycle.get(0) + && info.frame.dep_kind == dep_kinds::fn_sig + && let Some(def_id) = info.frame.def_id && let Some(node) = tcx.hir_get_if_local(def_id) && let Some(sig) = node.fn_sig() { @@ -85,10 +85,10 @@ impl<'tcx> Value> for Representability { let mut item_and_field_ids = Vec::new(); let mut representable_ids = FxHashSet::default(); for info in &cycle_error.cycle { - if info.query.dep_kind == dep_kinds::representability - && let Some(field_id) = info.query.def_id + if info.frame.dep_kind == dep_kinds::representability + && let Some(field_id) = info.frame.def_id && let Some(field_id) = field_id.as_local() - && let Some(DefKind::Field) = info.query.info.def_kind + && let Some(DefKind::Field) = info.frame.info.def_kind { let parent_id = tcx.parent(field_id.to_def_id()); let item_id = match tcx.def_kind(parent_id) { @@ -99,8 +99,8 @@ impl<'tcx> Value> for Representability { } } for info in &cycle_error.cycle { - if info.query.dep_kind == dep_kinds::representability_adt_ty - && let Some(def_id) = info.query.def_id_for_ty_in_cycle + if info.frame.dep_kind == dep_kinds::representability_adt_ty + && let Some(def_id) = info.frame.def_id_for_ty_in_cycle && let Some(def_id) = def_id.as_local() && !item_and_field_ids.iter().any(|&(id, _)| id == def_id) { @@ -141,9 +141,9 @@ impl<'tcx> Value> for &[ty::Variance] { search_for_cycle_permutation( &cycle_error.cycle, |cycle| { - if let Some(frame) = cycle.get(0) - && frame.query.dep_kind == dep_kinds::variances_of - && let Some(def_id) = frame.query.def_id + if let Some(info) = cycle.get(0) + && info.frame.dep_kind == dep_kinds::variances_of + && let Some(def_id) = info.frame.def_id { let n = tcx.generics_of(def_id).own_params.len(); ControlFlow::Break(vec![ty::Bivariant; n].leak()) @@ -189,8 +189,8 @@ impl<'tcx, T> Value> for Result> let diag = search_for_cycle_permutation( &cycle_error.cycle, |cycle| { - if cycle[0].query.dep_kind == dep_kinds::layout_of - && let Some(def_id) = cycle[0].query.def_id_for_ty_in_cycle + if cycle[0].frame.dep_kind == dep_kinds::layout_of + && let Some(def_id) = cycle[0].frame.def_id_for_ty_in_cycle && let Some(def_id) = def_id.as_local() && let def_kind = tcx.def_kind(def_id) && matches!(def_kind, DefKind::Closure) @@ -213,18 +213,18 @@ impl<'tcx, T> Value> for Result> tcx.def_kind_descr_article(def_kind, def_id.to_def_id()), tcx.def_kind_descr(def_kind, def_id.to_def_id()), ); - for (i, frame) in cycle.iter().enumerate() { - if frame.query.dep_kind != dep_kinds::layout_of { + for (i, info) in cycle.iter().enumerate() { + if info.frame.dep_kind != dep_kinds::layout_of { continue; } - let Some(frame_def_id) = frame.query.def_id_for_ty_in_cycle else { + let Some(frame_def_id) = info.frame.def_id_for_ty_in_cycle else { continue; }; let Some(frame_coroutine_kind) = tcx.coroutine_kind(frame_def_id) else { continue; }; let frame_span = - frame.query.info.default_span(cycle[(i + 1) % cycle.len()].span); + info.frame.info.default_span(cycle[(i + 1) % cycle.len()].span); if frame_span.is_dummy() { continue; } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 8cf68b280850e..e413780d6c4fd 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -299,6 +299,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcDumpVtable(..) | AttributeKind::RustcDynIncompatibleTrait(..) | AttributeKind::RustcHasIncoherentInherentImpls + | AttributeKind::RustcHiddenTypeOfOpaques | AttributeKind::RustcLayout(..) | AttributeKind::RustcLayoutScalarValidRangeEnd(..) | AttributeKind::RustcLayoutScalarValidRangeStart(..) @@ -390,7 +391,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_capture_analysis | sym::rustc_regions | sym::rustc_strict_coherence - | sym::rustc_hidden_type_of_opaques | sym::rustc_mir | sym::rustc_effective_visibility | sym::rustc_outlives diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 4e79d0842da22..bd69c99a32dc0 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -2,10 +2,13 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![feature(adt_const_params)] #![feature(min_specialization)] #![feature(rustc_attrs)] // tidy-alphabetical-end +use std::marker::ConstParamTy; + use rustc_data_structures::stable_hasher::HashStable; use rustc_data_structures::sync::AtomicU64; use rustc_middle::arena::Arena; @@ -35,29 +38,34 @@ pub use crate::plumbing::{QueryCtxt, query_key_hash_verify_all}; mod profiling_support; pub use self::profiling_support::alloc_self_profile_query_strings; +#[derive(ConstParamTy)] // Allow this struct to be used for const-generic values. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +struct QueryFlags { + /// True if this query has the `anon` modifier. + is_anon: bool, + /// True if this query has the `depth_limit` modifier. + is_depth_limit: bool, + /// True if this query has the `feedable` modifier. + is_feedable: bool, +} + /// Combines a [`QueryVTable`] with some additional compile-time booleans /// to implement [`QueryDispatcher`], for use by code in [`rustc_query_system`]. /// /// Baking these boolean flags into the type gives a modest but measurable /// improvement to compiler perf and compiler code size; see /// . -struct SemiDynamicQueryDispatcher< - 'tcx, - C: QueryCache, - const ANON: bool, - const DEPTH_LIMIT: bool, - const FEEDABLE: bool, -> { +struct SemiDynamicQueryDispatcher<'tcx, C: QueryCache, const FLAGS: QueryFlags> { vtable: &'tcx QueryVTable<'tcx, C>, } // Manually implement Copy/Clone, because deriving would put trait bounds on the cache type. -impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> Copy - for SemiDynamicQueryDispatcher<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE> +impl<'tcx, C: QueryCache, const FLAGS: QueryFlags> Copy + for SemiDynamicQueryDispatcher<'tcx, C, FLAGS> { } -impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> Clone - for SemiDynamicQueryDispatcher<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE> +impl<'tcx, C: QueryCache, const FLAGS: QueryFlags> Clone + for SemiDynamicQueryDispatcher<'tcx, C, FLAGS> { fn clone(&self) -> Self { *self @@ -65,8 +73,8 @@ impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDA } // This is `impl QueryDispatcher for SemiDynamicQueryDispatcher`. -impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> - QueryDispatcher<'tcx> for SemiDynamicQueryDispatcher<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE> +impl<'tcx, C: QueryCache, const FLAGS: QueryFlags> QueryDispatcher<'tcx> + for SemiDynamicQueryDispatcher<'tcx, C, FLAGS> where for<'a> C::Key: HashStable>, { @@ -86,10 +94,7 @@ where } #[inline(always)] - fn query_state<'a>(self, qcx: QueryCtxt<'tcx>) -> &'a QueryState<'tcx, Self::Key> - where - QueryCtxt<'tcx>: 'a, - { + fn query_state(self, qcx: QueryCtxt<'tcx>) -> &'tcx QueryState<'tcx, Self::Key> { // Safety: // This is just manually doing the subfield referencing through pointer math. unsafe { @@ -100,7 +105,7 @@ where } #[inline(always)] - fn query_cache<'a>(self, qcx: QueryCtxt<'tcx>) -> &'a Self::Cache { + fn query_cache(self, qcx: QueryCtxt<'tcx>) -> &'tcx Self::Cache { // Safety: // This is just manually doing the subfield referencing through pointer math. unsafe { @@ -158,7 +163,7 @@ where #[inline(always)] fn anon(self) -> bool { - ANON + FLAGS.is_anon } #[inline(always)] @@ -168,12 +173,12 @@ where #[inline(always)] fn depth_limit(self) -> bool { - DEPTH_LIMIT + FLAGS.is_depth_limit } #[inline(always)] fn feedable(self) -> bool { - FEEDABLE + FLAGS.is_feedable } #[inline(always)] @@ -216,12 +221,12 @@ trait QueryDispatcherUnerased<'tcx> { ) -> Self::UnerasedValue; } -pub fn query_system<'a>( +pub fn query_system<'tcx>( local_providers: Providers, extern_providers: ExternProviders, on_disk_cache: Option, incremental: bool, -) -> QuerySystem<'a> { +) -> QuerySystem<'tcx> { QuerySystem { states: Default::default(), arenas: Default::default(), diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 2d4e10a0380c8..518140d219c60 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -48,6 +48,23 @@ impl<'tcx> QueryCtxt<'tcx> { pub fn new(tcx: TyCtxt<'tcx>) -> Self { QueryCtxt { tcx } } + + fn depth_limit_error(self, job: QueryJobId) { + let query_map = self.collect_active_jobs(true).expect("failed to collect active queries"); + let (info, depth) = job.find_dep_kind_root(query_map); + + let suggested_limit = match self.tcx.recursion_limit() { + Limit(0) => Limit(2), + limit => limit * 2, + }; + + self.tcx.sess.dcx().emit_fatal(QueryOverflow { + span: info.job.span, + note: QueryOverflowNote { desc: info.frame.info.extract().description, depth }, + suggested_limit, + crate_name: self.tcx.crate_name(LOCAL_CRATE), + }); + } } impl<'tcx> HasDepContext for QueryCtxt<'tcx> { @@ -104,13 +121,6 @@ impl<'tcx> QueryContext<'tcx> for QueryCtxt<'tcx> { if complete { Ok(jobs) } else { Err(jobs) } } - fn lift_query_info( - self, - info: &QueryStackDeferred<'tcx>, - ) -> rustc_query_system::query::QueryStackFrameExtra { - info.extract() - } - // Interactions with on_disk_cache fn load_side_effect( self, @@ -162,26 +172,6 @@ impl<'tcx> QueryContext<'tcx> for QueryCtxt<'tcx> { tls::enter_context(&new_icx, compute) }) } - - fn depth_limit_error(self, job: QueryJobId) { - let query_map = self.collect_active_jobs(true).expect("failed to collect active queries"); - let (info, depth) = job.find_dep_kind_root(query_map); - - let suggested_limit = match self.tcx.recursion_limit() { - Limit(0) => Limit(2), - limit => limit * 2, - }; - - self.tcx.sess.dcx().emit_fatal(QueryOverflow { - span: info.job.span, - note: QueryOverflowNote { - desc: self.lift_query_info(&info.query.info).description, - depth, - }, - suggested_limit, - crate_name: self.tcx.crate_name(LOCAL_CRATE), - }); - } } pub(super) fn try_mark_green<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool { @@ -708,14 +698,18 @@ macro_rules! define_queries { data: PhantomData<&'tcx ()> } + const FLAGS: QueryFlags = QueryFlags { + is_anon: is_anon!([$($modifiers)*]), + is_depth_limit: depth_limit!([$($modifiers)*]), + is_feedable: feedable!([$($modifiers)*]), + }; + impl<'tcx> QueryDispatcherUnerased<'tcx> for QueryType<'tcx> { type UnerasedValue = queries::$name::Value<'tcx>; type Dispatcher = SemiDynamicQueryDispatcher< 'tcx, queries::$name::Storage<'tcx>, - { is_anon!([$($modifiers)*]) }, - { depth_limit!([$($modifiers)*]) }, - { feedable!([$($modifiers)*]) }, + FLAGS, >; const NAME: &'static &'static str = &stringify!($name); @@ -738,14 +732,14 @@ macro_rules! define_queries { qmap: &mut QueryMap<'tcx>, require_complete: bool, ) -> Option<()> { - let make_query = |tcx, key| { + let make_frame = |tcx, key| { let kind = rustc_middle::dep_graph::dep_kinds::$name; let name = stringify!($name); $crate::plumbing::create_query_frame(tcx, rustc_middle::query::descs::$name, key, kind, name) }; let res = tcx.query_system.states.$name.collect_active_jobs( tcx, - make_query, + make_frame, qmap, require_complete, ); diff --git a/compiler/rustc_query_system/src/query/dispatcher.rs b/compiler/rustc_query_system/src/query/dispatcher.rs index ac6c38dd7db55..bcd3d0322d07c 100644 --- a/compiler/rustc_query_system/src/query/dispatcher.rs +++ b/compiler/rustc_query_system/src/query/dispatcher.rs @@ -25,7 +25,7 @@ type DepContextOf<'tcx, This: QueryDispatcher<'tcx>> = /// Those types are not visible from this `rustc_query_system` crate. /// /// "Dispatcher" should be understood as a near-synonym of "vtable". -pub trait QueryDispatcher<'tcx>: Copy { +pub trait QueryDispatcher<'tcx>: Copy + 'tcx { fn name(self) -> &'static str; /// Query context used by this dispatcher, i.e. `rustc_query_impl::QueryCtxt`. @@ -41,10 +41,10 @@ pub trait QueryDispatcher<'tcx>: Copy { fn format_value(self) -> fn(&Self::Value) -> String; // Don't use this method to access query results, instead use the methods on TyCtxt - fn query_state<'a>(self, tcx: Self::Qcx) -> &'a QueryState<'tcx, Self::Key>; + fn query_state(self, tcx: Self::Qcx) -> &'tcx QueryState<'tcx, Self::Key>; // Don't use this method to access query results, instead use the methods on TyCtxt - fn query_cache<'a>(self, tcx: Self::Qcx) -> &'a Self::Cache; + fn query_cache(self, tcx: Self::Qcx) -> &'tcx Self::Cache; fn will_cache_on_disk_for_key(self, tcx: DepContextOf<'tcx, Self>, key: &Self::Key) -> bool; diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index 177bcd63cbc62..82b23b022c37e 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -23,15 +23,12 @@ use crate::query::{QueryContext, QueryStackFrame}; pub struct QueryInfo { /// The span corresponding to the reason for which this query was required. pub span: Span, - pub query: QueryStackFrame, + pub frame: QueryStackFrame, } impl<'tcx> QueryInfo> { - pub(crate) fn lift>( - &self, - qcx: Qcx, - ) -> QueryInfo { - QueryInfo { span: self.span, query: self.query.lift(qcx) } + pub(crate) fn lift(&self) -> QueryInfo { + QueryInfo { span: self.span, frame: self.frame.lift() } } } @@ -42,8 +39,8 @@ pub type QueryMap<'tcx> = FxHashMap>; pub struct QueryJobId(pub NonZero); impl QueryJobId { - fn query<'a, 'tcx>(self, map: &'a QueryMap<'tcx>) -> QueryStackFrame> { - map.get(&self).unwrap().query.clone() + fn frame<'a, 'tcx>(self, map: &'a QueryMap<'tcx>) -> QueryStackFrame> { + map.get(&self).unwrap().frame.clone() } fn span<'a, 'tcx>(self, map: &'a QueryMap<'tcx>) -> Span { @@ -61,7 +58,7 @@ impl QueryJobId { #[derive(Clone, Debug)] pub struct QueryJobInfo<'tcx> { - pub query: QueryStackFrame>, + pub frame: QueryStackFrame>, pub job: QueryJob<'tcx>, } @@ -125,7 +122,7 @@ impl QueryJobId { while let Some(job) = current_job { let info = query_map.get(&job).unwrap(); - cycle.push(QueryInfo { span: info.job.span, query: info.query.clone() }); + cycle.push(QueryInfo { span: info.job.span, frame: info.frame.clone() }); if job == *self { cycle.reverse(); @@ -140,7 +137,7 @@ impl QueryJobId { .job .parent .as_ref() - .map(|parent| (info.job.span, parent.query(&query_map))); + .map(|parent| (info.job.span, parent.frame(&query_map))); return CycleError { usage, cycle }; } @@ -158,13 +155,13 @@ impl QueryJobId { ) -> (QueryJobInfo<'tcx>, usize) { let mut depth = 1; let info = query_map.get(&self).unwrap(); - let dep_kind = info.query.dep_kind; + let dep_kind = info.frame.dep_kind; let mut current_id = info.job.parent; let mut last_layout = (info.clone(), depth); while let Some(id) = current_id { let info = query_map.get(&id).unwrap(); - if info.query.dep_kind == dep_kind { + if info.frame.dep_kind == dep_kind { depth += 1; last_layout = (info.clone(), depth); } @@ -389,7 +386,7 @@ where .iter() .min_by_key(|v| { let (span, query) = f(v); - let hash = query.query(query_map).hash; + let hash = query.frame(query_map).hash; // Prefer entry points which have valid spans for nicer error messages // We add an integer to the tuple ensuring that entry points // with valid spans are picked first @@ -473,14 +470,14 @@ fn remove_cycle<'tcx>( stack.rotate_left(pos); } - let usage = usage.as_ref().map(|(span, query)| (*span, query.query(query_map))); + let usage = usage.as_ref().map(|(span, query)| (*span, query.frame(query_map))); // Create the cycle error let error = CycleError { usage, cycle: stack .iter() - .map(|&(s, ref q)| QueryInfo { span: s, query: q.query(query_map) }) + .map(|&(s, ref q)| QueryInfo { span: s, frame: q.frame(query_map) }) .collect(), }; @@ -559,7 +556,7 @@ pub fn report_cycle<'a>( ) -> Diag<'a> { assert!(!stack.is_empty()); - let span = stack[0].query.info.default_span(stack[1 % stack.len()].span); + let span = stack[0].frame.info.default_span(stack[1 % stack.len()].span); let mut cycle_stack = Vec::new(); @@ -567,9 +564,9 @@ pub fn report_cycle<'a>( let stack_count = if stack.len() == 1 { StackCount::Single } else { StackCount::Multiple }; for i in 1..stack.len() { - let query = &stack[i].query; - let span = query.info.default_span(stack[(i + 1) % stack.len()].span); - cycle_stack.push(CycleStack { span, desc: query.info.description.to_owned() }); + let frame = &stack[i].frame; + let span = frame.info.default_span(stack[(i + 1) % stack.len()].span); + cycle_stack.push(CycleStack { span, desc: frame.info.description.to_owned() }); } let mut cycle_usage = None; @@ -581,9 +578,9 @@ pub fn report_cycle<'a>( } let alias = - if stack.iter().all(|entry| matches!(entry.query.info.def_kind, Some(DefKind::TyAlias))) { + if stack.iter().all(|entry| matches!(entry.frame.info.def_kind, Some(DefKind::TyAlias))) { Some(crate::error::Alias::Ty) - } else if stack.iter().all(|entry| entry.query.info.def_kind == Some(DefKind::TraitAlias)) { + } else if stack.iter().all(|entry| entry.frame.info.def_kind == Some(DefKind::TraitAlias)) { Some(crate::error::Alias::Trait) } else { None @@ -592,7 +589,7 @@ pub fn report_cycle<'a>( let cycle_diag = crate::error::Cycle { span, cycle_stack, - stack_bottom: stack[0].query.info.description.to_owned(), + stack_bottom: stack[0].frame.info.description.to_owned(), alias, cycle_usage, stack_count, @@ -628,12 +625,12 @@ pub fn print_query_stack<'tcx, Qcx: QueryContext<'tcx>>( let Some(query_info) = query_map.get(&query) else { break; }; - let query_extra = qcx.lift_query_info(&query_info.query.info); + let query_extra = query_info.frame.info.extract(); if Some(count_printed) < limit_frames || limit_frames.is_none() { // Only print to stderr as many stack frames as `num_frames` when present. dcx.struct_failure_note(format!( "#{} [{:?}] {}", - count_printed, query_info.query.dep_kind, query_extra.description + count_printed, query_info.frame.dep_kind, query_extra.description )) .with_span(query_info.job.span) .emit(); @@ -645,7 +642,7 @@ pub fn print_query_stack<'tcx, Qcx: QueryContext<'tcx>>( file, "#{} [{}] {}", count_total, - qcx.dep_context().dep_kind_vtable(query_info.query.dep_kind).name, + qcx.dep_context().dep_kind_vtable(query_info.frame.dep_kind).name, query_extra.description ); } diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index 63202429679d2..54e5fa4d72297 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -70,9 +70,9 @@ impl<'tcx> QueryStackFrame> { Self { info, def_id, dep_kind, hash, def_id_for_ty_in_cycle } } - fn lift>(&self, qcx: Qcx) -> QueryStackFrame { + fn lift(&self) -> QueryStackFrame { QueryStackFrame { - info: qcx.lift_query_info(&self.info), + info: self.info.extract(), dep_kind: self.dep_kind, hash: self.hash, def_id: self.def_id, @@ -168,8 +168,6 @@ pub trait QueryContext<'tcx>: HasDepContext { fn collect_active_jobs(self, require_complete: bool) -> Result, QueryMap<'tcx>>; - fn lift_query_info(self, info: &QueryStackDeferred<'tcx>) -> QueryStackFrameExtra; - /// Load a side effect associated to the node in the previous session. fn load_side_effect( self, @@ -183,6 +181,4 @@ pub trait QueryContext<'tcx>: HasDepContext { /// new query job while it executes. fn start_query(self, token: QueryJobId, depth_limit: bool, compute: impl FnOnce() -> R) -> R; - - fn depth_limit_error(self, job: QueryJobId); } diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 98bbd3ebc4a0f..4728391161073 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -82,7 +82,7 @@ where pub fn collect_active_jobs( &self, qcx: Qcx, - make_query: fn(Qcx, K) -> QueryStackFrame>, + make_frame: fn(Qcx, K) -> QueryStackFrame>, jobs: &mut QueryMap<'tcx>, require_complete: bool, ) -> Option<()> { @@ -108,11 +108,11 @@ where } } - // Call `make_query` while we're not holding a `self.active` lock as `make_query` may call + // Call `make_frame` while we're not holding a `self.active` lock as `make_frame` may call // queries leading to a deadlock. for (key, job) in active { - let query = make_query(qcx, key); - jobs.insert(job.id, QueryJobInfo { query, job }); + let frame = make_frame(qcx, key); + jobs.insert(job.id, QueryJobInfo { frame, job }); } Some(()) @@ -127,11 +127,11 @@ impl<'tcx, K> Default for QueryState<'tcx, K> { /// A type representing the responsibility to execute the job in the `job` field. /// This will poison the relevant query if dropped. -struct JobOwner<'a, 'tcx, K> +struct JobOwner<'tcx, K> where K: Eq + Hash + Copy, { - state: &'a QueryState<'tcx, K>, + state: &'tcx QueryState<'tcx, K>, key: K, } @@ -170,7 +170,7 @@ where } CycleErrorHandling::Stash => { let guar = if let Some(root) = cycle_error.cycle.first() - && let Some(span) = root.query.info.span + && let Some(span) = root.frame.info.span { error.stash(span, StashKey::Cycle).unwrap() } else { @@ -181,7 +181,7 @@ where } } -impl<'a, 'tcx, K> JobOwner<'a, 'tcx, K> +impl<'tcx, K> JobOwner<'tcx, K> where K: Eq + Hash + Copy, { @@ -218,7 +218,7 @@ where } } -impl<'a, 'tcx, K> Drop for JobOwner<'a, 'tcx, K> +impl<'tcx, K> Drop for JobOwner<'tcx, K> where K: Eq + Hash + Copy, { @@ -253,10 +253,10 @@ pub struct CycleError { } impl<'tcx> CycleError> { - fn lift>(&self, qcx: Qcx) -> CycleError { + fn lift(&self) -> CycleError { CycleError { - usage: self.usage.as_ref().map(|(span, frame)| (*span, frame.lift(qcx))), - cycle: self.cycle.iter().map(|info| info.lift(qcx)).collect(), + usage: self.usage.as_ref().map(|(span, frame)| (*span, frame.lift())), + cycle: self.cycle.iter().map(|info| info.lift()).collect(), } } } @@ -297,7 +297,7 @@ where let query_map = qcx.collect_active_jobs(false).ok().expect("failed to collect active queries"); let error = try_execute.find_cycle_in_stack(query_map, &qcx.current_query_job(), span); - (mk_cycle(query, qcx, error.lift(qcx)), None) + (mk_cycle(query, qcx, error.lift()), None) } #[inline(always)] @@ -345,7 +345,7 @@ where (v, Some(index)) } - Err(cycle) => (mk_cycle(query, qcx, cycle.lift(qcx)), None), + Err(cycle) => (mk_cycle(query, qcx, cycle.lift()), None), } } @@ -422,7 +422,7 @@ where fn execute_job<'tcx, Q, const INCR: bool>( query: Q, qcx: Q::Qcx, - state: &QueryState<'tcx, Q::Key>, + state: &'tcx QueryState<'tcx, Q::Key>, key: Q::Key, key_hash: u64, id: QueryJobId, diff --git a/compiler/rustc_session/src/config/native_libs.rs b/compiler/rustc_session/src/config/native_libs.rs index 71d3e222c8a15..28e2d0f94104b 100644 --- a/compiler/rustc_session/src/config/native_libs.rs +++ b/compiler/rustc_session/src/config/native_libs.rs @@ -53,7 +53,9 @@ fn parse_native_lib(cx: &ParseNativeLibCx<'_>, value: &str) -> NativeLib { let NativeLibParts { kind, modifiers, name, new_name } = split_native_lib_value(value); let kind = kind.map_or(NativeLibKind::Unspecified, |kind| match kind { - "static" => NativeLibKind::Static { bundle: None, whole_archive: None }, + "static" => { + NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None } + } "dylib" => NativeLibKind::Dylib { as_needed: None }, "framework" => NativeLibKind::Framework { as_needed: None }, "link-arg" => { @@ -105,7 +107,7 @@ fn parse_and_apply_modifier(cx: &ParseNativeLibCx<'_>, modifier: &str, native_li Some(("-", m)) => (m, false), _ => cx.early_dcx.early_fatal( "invalid linking modifier syntax, expected '+' or '-' prefix \ - before one of: bundle, verbatim, whole-archive, as-needed", + before one of: bundle, verbatim, whole-archive, as-needed, export-symbols", ), }; @@ -125,6 +127,13 @@ fn parse_and_apply_modifier(cx: &ParseNativeLibCx<'_>, modifier: &str, native_li ("bundle", _) => early_dcx .early_fatal("linking modifier `bundle` is only compatible with `static` linking kind"), + ("export-symbols", NativeLibKind::Static { export_symbols, .. }) => { + assign_modifier(export_symbols) + } + ("export-symbols", _) => early_dcx.early_fatal( + "linking modifier `export-symbols` is only compatible with `static` linking kind", + ), + ("verbatim", _) => assign_modifier(&mut native_lib.verbatim), ("whole-archive", NativeLibKind::Static { whole_archive, .. }) => { @@ -151,7 +160,7 @@ fn parse_and_apply_modifier(cx: &ParseNativeLibCx<'_>, modifier: &str, native_li _ => early_dcx.early_fatal(format!( "unknown linking modifier `{modifier}`, expected one \ - of: bundle, verbatim, whole-archive, as-needed" + of: bundle, verbatim, whole-archive, as-needed, export-symbols" )), } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index b0ef95d10ffa0..c88dd0948b2a9 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1002,6 +1002,7 @@ symbols! { explicit_tail_calls, export_name, export_stable, + export_symbols: "export-symbols", expr, expr_2021, expr_fragment_specifier_2024, diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index cc142fab8e821..4630fd729c6a1 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -108,6 +108,17 @@ pub mod consts { pub const FRAC_1_SQRT_3: f128 = 0.577350269189625764509148780501957455647601751270126876018602_f128; + /// sqrt(5) + #[unstable(feature = "more_float_constants", issue = "146939")] + // Also, #[unstable(feature = "f128", issue = "116909")] + pub const SQRT_5: f128 = 2.23606797749978969640917366873127623544061835961152572427089_f128; + + /// 1/sqrt(5) + #[unstable(feature = "more_float_constants", issue = "146939")] + // Also, #[unstable(feature = "f128", issue = "116909")] + pub const FRAC_1_SQRT_5: f128 = + 0.447213595499957939281834733746255247088123671922305144854179_f128; + /// Euler's number (e) #[unstable(feature = "f128", issue = "116909")] pub const E: f128 = 2.71828182845904523536028747135266249775724709369995957496697_f128; diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index e97a44e991f66..21ba8f1f2828d 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -103,6 +103,16 @@ pub mod consts { // Also, #[unstable(feature = "more_float_constants", issue = "146939")] pub const FRAC_1_SQRT_3: f16 = 0.577350269189625764509148780501957456_f16; + /// sqrt(5) + #[unstable(feature = "more_float_constants", issue = "146939")] + // Also, #[unstable(feature = "f16", issue = "116909")] + pub const SQRT_5: f16 = 2.23606797749978969640917366873127623_f16; + + /// 1/sqrt(5) + #[unstable(feature = "more_float_constants", issue = "146939")] + // Also, #[unstable(feature = "f16", issue = "116909")] + pub const FRAC_1_SQRT_5: f16 = 0.44721359549995793928183473374625524_f16; + /// Euler's number (e) #[unstable(feature = "f16", issue = "116909")] pub const E: f16 = 2.71828182845904523536028747135266250_f16; diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 3d8249631037f..c4ec774f5956f 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -356,6 +356,14 @@ pub mod consts { #[unstable(feature = "more_float_constants", issue = "146939")] pub const FRAC_1_SQRT_3: f32 = 0.577350269189625764509148780501957456_f32; + /// sqrt(5) + #[unstable(feature = "more_float_constants", issue = "146939")] + pub const SQRT_5: f32 = 2.23606797749978969640917366873127623_f32; + + /// 1/sqrt(5) + #[unstable(feature = "more_float_constants", issue = "146939")] + pub const FRAC_1_SQRT_5: f32 = 0.44721359549995793928183473374625524_f32; + /// Euler's number (e) #[stable(feature = "rust1", since = "1.0.0")] pub const E: f32 = 2.71828182845904523536028747135266250_f32; diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 566a6a7ec947f..0bb8813235779 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -356,6 +356,14 @@ pub mod consts { #[unstable(feature = "more_float_constants", issue = "146939")] pub const FRAC_1_SQRT_3: f64 = 0.577350269189625764509148780501957456_f64; + /// sqrt(5) + #[unstable(feature = "more_float_constants", issue = "146939")] + pub const SQRT_5: f64 = 2.23606797749978969640917366873127623_f64; + + /// 1/sqrt(5) + #[unstable(feature = "more_float_constants", issue = "146939")] + pub const FRAC_1_SQRT_5: f64 = 0.44721359549995793928183473374625524_f64; + /// Euler's number (e) #[stable(feature = "rust1", since = "1.0.0")] pub const E: f64 = 2.71828182845904523536028747135266250_f64; diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 52f3d43dfd6dd..5f438d72ac13c 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -690,7 +690,7 @@ impl Result { /// Converts from `Result` to [`Option`]. /// /// Converts `self` into an [`Option`], consuming `self`, - /// and discarding the error, if any. + /// and converting the error to `None`, if any. /// /// # Examples /// diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index b213fa7491775..dcde208fac77b 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -260,6 +260,7 @@ all(target_vendor = "fortanix", target_env = "sgx"), feature(slice_index_methods, coerce_unsized, sgx_platform) )] +#![cfg_attr(all(test, target_os = "uefi"), feature(uefi_std))] #![cfg_attr(target_family = "wasm", feature(stdarch_wasm_atomic_wait))] #![cfg_attr(target_arch = "wasm64", feature(simd_wasm64))] // diff --git a/library/std/src/os/uefi/env.rs b/library/std/src/os/uefi/env.rs index ab5406e605c6b..82e3fc9775cba 100644 --- a/library/std/src/os/uefi/env.rs +++ b/library/std/src/os/uefi/env.rs @@ -4,13 +4,25 @@ use crate::ffi::c_void; use crate::ptr::NonNull; -use crate::sync::atomic::{Atomic, AtomicBool, AtomicPtr, Ordering}; +use crate::sync::atomic::Ordering; -static SYSTEM_TABLE: Atomic<*mut c_void> = AtomicPtr::new(crate::ptr::null_mut()); -static IMAGE_HANDLE: Atomic<*mut c_void> = AtomicPtr::new(crate::ptr::null_mut()); -// Flag to check if BootServices are still valid. -// Start with assuming that they are not available -static BOOT_SERVICES_FLAG: Atomic = AtomicBool::new(false); +#[doc(hidden)] +#[cfg(not(test))] +pub mod globals { + use crate::ffi::c_void; + use crate::sync::atomic::{Atomic, AtomicBool, AtomicPtr}; + + pub static SYSTEM_TABLE: Atomic<*mut c_void> = AtomicPtr::new(crate::ptr::null_mut()); + pub static IMAGE_HANDLE: Atomic<*mut c_void> = AtomicPtr::new(crate::ptr::null_mut()); + // Flag to check if BootServices are still valid. + // Start with assuming that they are not available + pub static BOOT_SERVICES_FLAG: Atomic = AtomicBool::new(false); +} + +#[cfg(not(test))] +use globals::*; +#[cfg(test)] +use realstd::os::uefi::env::globals::*; /// Initializes the global System Table and Image Handle pointers. /// diff --git a/src/tools/compiletest/src/directives/auxiliary.rs b/src/tools/compiletest/src/directives/auxiliary.rs index 14cbab640eb6b..0e7e370adbd41 100644 --- a/src/tools/compiletest/src/directives/auxiliary.rs +++ b/src/tools/compiletest/src/directives/auxiliary.rs @@ -26,8 +26,12 @@ pub struct AuxCrate { } /// The value of a `proc-macro` directive. -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] pub(crate) struct ProcMacro { + /// Contains `--extern` modifiers, if any. See the tracking issue for more + /// info: + /// With `proc-macro: noprelude:bar.rs` this will be `noprelude`. + pub extern_modifiers: Option, /// With `proc-macro: bar.rs` this will be `bar.rs`. pub path: String, } @@ -108,5 +112,17 @@ fn parse_aux_crate(r: String) -> AuxCrate { } fn parse_proc_macro(r: String) -> ProcMacro { - ProcMacro { path: r.trim().to_string() } + let r = r.trim(); + + // Matches: + // path + // modifiers:path + let caps = static_regex!(r"^(?:(?[^=]*?):)?(?.*)$") + .captures(r) + .expect("can never fail"); + + let modifiers = caps.name("modifiers").map(|m| m.as_str().to_string()); + let path = caps["path"].to_string(); + + ProcMacro { extern_modifiers: modifiers, path } } diff --git a/src/tools/compiletest/src/directives/auxiliary/tests.rs b/src/tools/compiletest/src/directives/auxiliary/tests.rs index ad205eaabfda2..74fff630692ea 100644 --- a/src/tools/compiletest/src/directives/auxiliary/tests.rs +++ b/src/tools/compiletest/src/directives/auxiliary/tests.rs @@ -25,3 +25,19 @@ fn test_aux_crate_value_with_modifiers() { fn test_aux_crate_value_invalid() { parse_aux_crate("foo.rs".to_string()); } + +#[test] +fn test_proc_macro_value_no_modifiers() { + assert_eq!( + ProcMacro { extern_modifiers: None, path: "foo.rs".to_string() }, + parse_proc_macro("foo.rs".to_string()) + ); +} + +#[test] +fn test_proc_macro_value_with_modifiers() { + assert_eq!( + ProcMacro { extern_modifiers: Some("noprelude".to_string()), path: "foo.rs".to_string() }, + parse_proc_macro("noprelude:foo.rs".to_string()) + ); +} diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index e6eb1f3bd957f..ef90b81fb2a73 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1312,7 +1312,7 @@ impl<'test> TestCx<'test> { let crate_name = path_to_crate_name(&proc_macro.path); add_extern( rustc, - None, // `extern_modifiers` + proc_macro.extern_modifiers.as_deref(), &crate_name, &proc_macro.path, AuxType::ProcMacro, diff --git a/tests/run-make/cdylib-export-c-library-symbols/foo.c b/tests/run-make/cdylib-export-c-library-symbols/foo.c new file mode 100644 index 0000000000000..a062aca03b315 --- /dev/null +++ b/tests/run-make/cdylib-export-c-library-symbols/foo.c @@ -0,0 +1 @@ +void my_function() {} diff --git a/tests/run-make/cdylib-export-c-library-symbols/foo.rs b/tests/run-make/cdylib-export-c-library-symbols/foo.rs new file mode 100644 index 0000000000000..ac641aaed00f8 --- /dev/null +++ b/tests/run-make/cdylib-export-c-library-symbols/foo.rs @@ -0,0 +1,10 @@ +extern "C" { + pub fn my_function(); +} + +#[no_mangle] +pub extern "C" fn rust_entry() { + unsafe { + my_function(); + } +} diff --git a/tests/run-make/cdylib-export-c-library-symbols/foo_export.rs b/tests/run-make/cdylib-export-c-library-symbols/foo_export.rs new file mode 100644 index 0000000000000..1eda294ef41c3 --- /dev/null +++ b/tests/run-make/cdylib-export-c-library-symbols/foo_export.rs @@ -0,0 +1,10 @@ +extern "C" { + fn my_function(); +} + +#[no_mangle] +pub extern "C" fn rust_entry() { + unsafe { + my_function(); + } +} diff --git a/tests/run-make/cdylib-export-c-library-symbols/rmake.rs b/tests/run-make/cdylib-export-c-library-symbols/rmake.rs new file mode 100644 index 0000000000000..f79ad2dd31091 --- /dev/null +++ b/tests/run-make/cdylib-export-c-library-symbols/rmake.rs @@ -0,0 +1,34 @@ +//@ ignore-nvptx64 +//@ ignore-wasm +//@ ignore-i686-pc-windows-msvc +// FIXME:The symbol mangle rules are slightly different in 32-bit Windows. Need to be resolved. +//@ ignore-cross-compile +// Reason: the compiled binary is executed + +use run_make_support::{build_native_static_lib, cc, dynamic_lib_name, is_darwin, llvm_nm, rustc}; + +fn main() { + cc().input("foo.c").arg("-c").out_exe("foo.o").run(); + build_native_static_lib("foo"); + + rustc().input("foo.rs").arg("-lstatic=foo").crate_type("cdylib").run(); + + let out = llvm_nm() + .input(dynamic_lib_name("foo")) + .run() + .assert_stdout_not_contains_regex("T *my_function"); + + rustc().input("foo_export.rs").arg("-lstatic:+export-symbols=foo").crate_type("cdylib").run(); + + if is_darwin() { + let out = llvm_nm() + .input(dynamic_lib_name("foo_export")) + .run() + .assert_stdout_contains("T _my_function"); + } else { + let out = llvm_nm() + .input(dynamic_lib_name("foo_export")) + .run() + .assert_stdout_contains("T my_function"); + } +} diff --git a/tests/ui/feature-gates/feature-gate-link-arg-attribute.in_flag.stderr b/tests/ui/feature-gates/feature-gate-link-arg-attribute.in_flag.stderr index 4d65db3c66d0b..218a4769d9542 100644 --- a/tests/ui/feature-gates/feature-gate-link-arg-attribute.in_flag.stderr +++ b/tests/ui/feature-gates/feature-gate-link-arg-attribute.in_flag.stderr @@ -1,2 +1,2 @@ -error: unknown linking modifier `link-arg`, expected one of: bundle, verbatim, whole-archive, as-needed +error: unknown linking modifier `link-arg`, expected one of: bundle, verbatim, whole-archive, as-needed, export-symbols diff --git a/tests/ui/link-native-libs/link-arg-error2.rs b/tests/ui/link-native-libs/link-arg-error2.rs new file mode 100644 index 0000000000000..a51dec0614b5f --- /dev/null +++ b/tests/ui/link-native-libs/link-arg-error2.rs @@ -0,0 +1,5 @@ +//@ compile-flags: -l link-arg:+export-symbols=arg -Z unstable-options + +fn main() {} + +//~? ERROR linking modifier `export-symbols` is only compatible with `static` linking kind diff --git a/tests/ui/link-native-libs/link-arg-error2.stderr b/tests/ui/link-native-libs/link-arg-error2.stderr new file mode 100644 index 0000000000000..61bcf7dba2829 --- /dev/null +++ b/tests/ui/link-native-libs/link-arg-error2.stderr @@ -0,0 +1,2 @@ +error: linking modifier `export-symbols` is only compatible with `static` linking kind + diff --git a/tests/ui/link-native-libs/link-arg-from-rs2.rs b/tests/ui/link-native-libs/link-arg-from-rs2.rs new file mode 100644 index 0000000000000..3074fec6c1c8f --- /dev/null +++ b/tests/ui/link-native-libs/link-arg-from-rs2.rs @@ -0,0 +1,7 @@ +#![feature(link_arg_attribute)] + +#[link(kind = "link-arg", name = "arg", modifiers = "+export-symbols")] +//~^ ERROR linking modifier `export-symbols` is only compatible with `static` linking kind +extern "C" {} + +pub fn main() {} diff --git a/tests/ui/link-native-libs/link-arg-from-rs2.stderr b/tests/ui/link-native-libs/link-arg-from-rs2.stderr new file mode 100644 index 0000000000000..af3b25253e052 --- /dev/null +++ b/tests/ui/link-native-libs/link-arg-from-rs2.stderr @@ -0,0 +1,8 @@ +error: linking modifier `export-symbols` is only compatible with `static` linking kind + --> $DIR/link-arg-from-rs2.rs:3:53 + | +LL | #[link(kind = "link-arg", name = "arg", modifiers = "+export-symbols")] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/link-native-libs/link-attr-validation-late.stderr b/tests/ui/link-native-libs/link-attr-validation-late.stderr index b09431f923aaf..4a4a193752070 100644 --- a/tests/ui/link-native-libs/link-attr-validation-late.stderr +++ b/tests/ui/link-native-libs/link-attr-validation-late.stderr @@ -178,13 +178,13 @@ LL | #[link(name = "...", wasm_import_module())] | = note: for more information, visit -error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed +error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols --> $DIR/link-attr-validation-late.rs:31:34 | LL | #[link(name = "...", modifiers = "")] | ^^ -error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed +error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols --> $DIR/link-attr-validation-late.rs:32:34 | LL | #[link(name = "...", modifiers = "no-plus-minus")] @@ -196,7 +196,7 @@ error[E0539]: malformed `link` attribute input LL | #[link(name = "...", modifiers = "+unknown")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------^^ | | - | valid arguments are "bundle", "verbatim", "whole-archive" or "as-needed" + | valid arguments are "bundle", "export-symbols", "verbatim", "whole-archive" or "as-needed" | = note: for more information, visit diff --git a/tests/ui/link-native-libs/modifiers-bad.blank.stderr b/tests/ui/link-native-libs/modifiers-bad.blank.stderr index ea36af0b4cfa9..6a1953e008eef 100644 --- a/tests/ui/link-native-libs/modifiers-bad.blank.stderr +++ b/tests/ui/link-native-libs/modifiers-bad.blank.stderr @@ -1,2 +1,2 @@ -error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed +error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols diff --git a/tests/ui/link-native-libs/modifiers-bad.no-prefix.stderr b/tests/ui/link-native-libs/modifiers-bad.no-prefix.stderr index ea36af0b4cfa9..6a1953e008eef 100644 --- a/tests/ui/link-native-libs/modifiers-bad.no-prefix.stderr +++ b/tests/ui/link-native-libs/modifiers-bad.no-prefix.stderr @@ -1,2 +1,2 @@ -error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed +error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols diff --git a/tests/ui/link-native-libs/modifiers-bad.prefix-only.stderr b/tests/ui/link-native-libs/modifiers-bad.prefix-only.stderr index 1e701374688fe..46720cf0b15e9 100644 --- a/tests/ui/link-native-libs/modifiers-bad.prefix-only.stderr +++ b/tests/ui/link-native-libs/modifiers-bad.prefix-only.stderr @@ -1,2 +1,2 @@ -error: unknown linking modifier ``, expected one of: bundle, verbatim, whole-archive, as-needed +error: unknown linking modifier ``, expected one of: bundle, verbatim, whole-archive, as-needed, export-symbols diff --git a/tests/ui/link-native-libs/modifiers-bad.unknown.stderr b/tests/ui/link-native-libs/modifiers-bad.unknown.stderr index 75950ad9c64c7..d47694a5aeca8 100644 --- a/tests/ui/link-native-libs/modifiers-bad.unknown.stderr +++ b/tests/ui/link-native-libs/modifiers-bad.unknown.stderr @@ -1,2 +1,2 @@ -error: unknown linking modifier `ferris`, expected one of: bundle, verbatim, whole-archive, as-needed +error: unknown linking modifier `ferris`, expected one of: bundle, verbatim, whole-archive, as-needed, export-symbols diff --git a/tests/ui/privacy/pub-priv-dep/auxiliary/pm.rs b/tests/ui/privacy/pub-priv-dep/auxiliary/pm.rs index 9e2aa898afe8d..d45f2639d182f 100644 --- a/tests/ui/privacy/pub-priv-dep/auxiliary/pm.rs +++ b/tests/ui/privacy/pub-priv-dep/auxiliary/pm.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/privacy/pub-priv-dep/pub-priv1.rs b/tests/ui/privacy/pub-priv-dep/pub-priv1.rs index ae86be19cf960..ba947de7f182a 100644 --- a/tests/ui/privacy/pub-priv-dep/pub-priv1.rs +++ b/tests/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -1,6 +1,6 @@ //@ aux-crate:priv:priv_dep=priv_dep.rs //@ aux-build:pub_dep.rs -//@ aux-crate:priv:pm=pm.rs +//@ proc-macro:priv:pm.rs //@ compile-flags: -Zunstable-options // Basic behavior check of exported_private_dependencies from either a public diff --git a/tests/ui/traits/next-solver/generalize/relate-alias-in-lub.rs b/tests/ui/traits/next-solver/generalize/relate-alias-in-lub.rs new file mode 100644 index 0000000000000..a81e18559a391 --- /dev/null +++ b/tests/ui/traits/next-solver/generalize/relate-alias-in-lub.rs @@ -0,0 +1,30 @@ +//@ revisions: old next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ check-pass +// Reproduces https://github.com/rust-lang/rust/pull/151746#issuecomment-3822930803. +// +// The change we tried to make there caused relating a type variable with an alias inside lub, +// In 5bd20bbd0ba6c0285664e55a1ffc677d7487c98b, we moved around code +// that adds an alias-relate predicate to be earlier, from one shared codepath into several +// distinct code paths. However, we forgot the codepath in `LatticeOp`, causing an ICE in serde. +// In the end we dropped said commit, but the reproducer is still a useful as test. + +use std::marker::PhantomData; + +pub trait Trait { + type Error; +} + +pub struct Struct(PhantomData); + +impl Trait for () { + type Error = (); +} + +fn main() { + let _: Struct<<() as Trait>::Error> = match loop {} { + b => loop {}, + a => Struct(PhantomData), + }; +}