diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 6d45e9a81b2fe..929334c561389 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -13,6 +13,8 @@ ], // Require manual approval from the Dependency Dashboard before opening PRs "dependencyDashboardApproval": true, + // Renovate shouldn't update a PR if it is in the bors merge queue. + "stopUpdatingLabel": "S-waiting-on-bors", "packageRules": [ { // No dashboard approval necessary for GitHub Actions updates diff --git a/RELEASES.md b/RELEASES.md index 3146bdeb1b118..81310c20c5ef9 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,13 @@ +Version 1.97.1 (2026-07-16) +========================== + + + +- [rustc: Fix miscompilation in LLVM optimization](https://github.com/rust-lang/rust/issues/159035) + This backports an LLVM submodule bump to include the LLVM-side fix and a + revert of the rustc change that is one known trigger for the bug. The rustc + side revert should not be strictly necessary but is done out of abundance of caution. + Version 1.97.0 (2026-07-09) ========================== diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs index 435367e7dcfbe..2486b5e3a65ed 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs @@ -28,6 +28,7 @@ pub(crate) mod on_type_error; pub(crate) mod on_unimplemented; pub(crate) mod on_unknown; pub(crate) mod on_unmatched_args; +pub(crate) mod opaque; #[derive(Copy, Clone)] pub(crate) enum Mode { diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/opaque.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/opaque.rs new file mode 100644 index 0000000000000..0a18b69dda0ed --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/opaque.rs @@ -0,0 +1,64 @@ +use rustc_feature::AttributeStability; +use rustc_hir::Target; +use rustc_hir::attrs::AttributeKind; +use rustc_session::lint::builtin::MALFORMED_DIAGNOSTIC_ATTRIBUTES; +use rustc_span::{Span, sym}; + +use crate::attributes::{AcceptMapping, AttributeParser}; +use crate::context::{AcceptContext, FinalizeContext}; +use crate::diagnostics::OpaqueDoesNotExpectArgs; +use crate::parser::ArgParser; +use crate::target_checking::AllowedTargets; +use crate::target_checking::Policy::Allow; +use crate::{template, unstable}; + +#[derive(Default)] +pub(crate) struct OpaqueParser { + attr_span: Option, +} + +impl AttributeParser for OpaqueParser { + const ATTRIBUTES: AcceptMapping = &[ + ( + &[sym::diagnostic, sym::opaque], + template!(Word), + AttributeStability::Stable, // Unstable, stability checked manually in the parser + |this, cx, args| { + if !cx.features().diagnostic_opaque() { + return; + } + this.parse(cx, args); + }, + ), + ( + // For use on exported macros, where using tool attributes is an error. + &[sym::rustc_diagnostic_opaque], + template!(Word), + unstable!( + rustc_attrs, + "see `#[diagnostic::opaque]` for the nightly equivalent of this attribute" + ), + OpaqueParser::parse, + ), + ]; + const ALLOWED_TARGETS: AllowedTargets<'_> = + AllowedTargets::AllowListWarnRest(&[Allow(Target::MacroDef)]); + + fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option { + if let Some(_) = self.attr_span { Some(AttributeKind::Opaque) } else { None } + } +} + +impl OpaqueParser { + fn parse<'sess>(&mut self, cx: &mut AcceptContext<'_, 'sess>, args: &ArgParser) { + let attr_span = cx.attr_span; + if let Some(earlier_span) = self.attr_span { + cx.warn_unused_duplicate(earlier_span, attr_span); + } + self.attr_span = Some(attr_span); + + if !matches!(args, ArgParser::NoArgs) { + cx.emit_lint(MALFORMED_DIAGNOSTIC_ATTRIBUTES, OpaqueDoesNotExpectArgs, attr_span); + } + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index e094447ec454b..7ae275b940bd0 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -36,6 +36,7 @@ use crate::attributes::diagnostic::on_type_error::*; use crate::attributes::diagnostic::on_unimplemented::*; use crate::attributes::diagnostic::on_unknown::*; use crate::attributes::diagnostic::on_unmatched_args::*; +use crate::attributes::diagnostic::opaque::*; use crate::attributes::doc::*; use crate::attributes::dummy::*; use crate::attributes::inline::*; @@ -151,6 +152,7 @@ attribute_parsers!( OnUnimplementedParser, OnUnknownParser, OnUnmatchedArgsParser, + OpaqueParser, RustcAlignParser, RustcAlignStaticParser, RustcCguTestAttributeParser, diff --git a/compiler/rustc_attr_parsing/src/diagnostics.rs b/compiler/rustc_attr_parsing/src/diagnostics.rs index 50667952b814d..e360f5221c138 100644 --- a/compiler/rustc_attr_parsing/src/diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/diagnostics.rs @@ -279,6 +279,10 @@ pub(crate) struct AttrCrateLevelOnly; #[diag("`#[diagnostic::do_not_recommend]` does not expect any arguments")] pub(crate) struct DoNotRecommendDoesNotExpectArgs; +#[derive(Diagnostic)] +#[diag("`#[diagnostic::opaque]` does not expect any arguments")] +pub(crate) struct OpaqueDoesNotExpectArgs; + #[derive(Diagnostic)] #[diag("invalid `crate_type` value")] pub(crate) struct UnknownCrateTypes { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index b8037fc83aad0..0e07de31c2baa 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -791,12 +791,18 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { fn give_name_if_anonymous_region_appears_in_output(&self, fr: RegionVid) -> Option { let tcx = self.infcx.tcx; - let return_ty = self.regioncx.universal_regions().unnormalized_output_ty; + let mut return_ty = self.regioncx.universal_regions().unnormalized_output_ty; debug!("give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", return_ty); if !tcx.any_free_region_meets(&return_ty, |r| r.as_var() == fr) { return None; } + if let ty::Coroutine(_, args) = return_ty.kind() { + // When the return type is identified to be `{async closure body}`, we instead care + // about the actual return type of that coroutine. + return_ty = args.as_coroutine().return_ty(); + } + let mir_hir_id = self.mir_hir_id(); let (return_span, mir_description, hir_ty) = match tcx.hir_node(mir_hir_id) { diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index fa3ff21b2726f..6d5f8462ff496 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -175,7 +175,7 @@ pub trait Emitter { ExpnKind::Desugaring(..) | ExpnKind::AstPass(..) => None, ExpnKind::Macro(macro_kind, name) => { - Some((macro_kind, name, expn_data.hide_backtrace)) + Some((macro_kind, name, expn_data.diagnostic_opaque)) } } }) @@ -188,8 +188,7 @@ pub trait Emitter { self.render_multispans_macro_backtrace(span, children, backtrace); if !backtrace { - // Skip builtin macros, as their expansion isn't relevant to the end user. This includes - // actual intrinsics, like `asm!`. + // Skip macros annotated with `#[diagnostic::opaque]`. Builtin macros are "opaque" too. if let Some((macro_kind, name, _)) = has_macro_spans.first() && let Some((_, _, false)) = has_macro_spans.last() { @@ -334,6 +333,13 @@ pub trait Emitter { // we move these spans from the external macros to their corresponding use site. fn fix_multispan_in_extern_macros(&self, span: &mut MultiSpan) { let Some(source_map) = self.source_map() else { return }; + let should_hide = |span| { + source_map.is_imported(span) || { + let expn = span.data().ctxt.outer_expn_data(); + expn.diagnostic_opaque && matches!(expn.kind, ExpnKind::Macro(MacroKind::Bang, _)) + } + }; + // First, find all the spans in external macros and point instead at their use site. let replacements: Vec<(Span, Span)> = span .primary_spans() @@ -341,11 +347,11 @@ pub trait Emitter { .copied() .chain(span.span_labels().iter().map(|sp_label| sp_label.span)) .filter_map(|sp| { - if !sp.is_dummy() && source_map.is_imported(sp) { + if !sp.is_dummy() && should_hide(sp) { let mut span = sp; while let Some(callsite) = span.parent_callsite() { span = callsite; - if !source_map.is_imported(span) { + if !should_hide(span) { return Some((sp, span)); } } diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 24501524edf04..3cf39a68aa3bb 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -797,9 +797,9 @@ pub struct SyntaxExtension { /// Should debuginfo for the macro be collapsed to the outermost expansion site (in other /// words, was the macro definition annotated with `#[collapse_debuginfo]`)? pub collapse_debuginfo: bool, - /// Suppresses the "this error originates in the macro" note when a diagnostic points at this - /// macro. - pub hide_backtrace: bool, + /// Prevents diagnostics pointing into this macro and suppresses the "this error originates in + /// the macro" note when a diagnostic points at this macro. + pub diagnostic_opaque: bool, } impl SyntaxExtension { @@ -833,7 +833,7 @@ impl SyntaxExtension { allow_internal_unsafe: false, local_inner_macros: false, collapse_debuginfo: false, - hide_backtrace: false, + diagnostic_opaque: false, } } @@ -863,12 +863,6 @@ impl SyntaxExtension { collapse_table[flag as usize][attr as usize] } - fn get_hide_backtrace(attrs: &[hir::Attribute]) -> bool { - // FIXME(estebank): instead of reusing `#[rustc_diagnostic_item]` as a proxy, introduce a - // new attribute purely for this under the `#[diagnostic]` namespace. - find_attr!(attrs, RustcDiagnosticItem(..)) - } - /// Constructs a syntax extension with the given properties /// and other properties converted from attributes. pub fn new( @@ -903,7 +897,8 @@ impl SyntaxExtension { // Not a built-in macro None => (None, helper_attrs), }; - let hide_backtrace = builtin_name.is_some() || Self::get_hide_backtrace(attrs); + let diagnostic_opaque = builtin_name.is_some() + || (!sess.opts.unstable_opts.macro_backtrace && find_attr!(attrs, Opaque)); let stability = find_attr!(attrs, Stability { stability, .. } => *stability); @@ -931,7 +926,7 @@ impl SyntaxExtension { allow_internal_unsafe, local_inner_macros, collapse_debuginfo, - hide_backtrace, + diagnostic_opaque, } } @@ -1017,7 +1012,7 @@ impl SyntaxExtension { self.allow_internal_unsafe, self.local_inner_macros, self.collapse_debuginfo, - self.hide_backtrace, + self.diagnostic_opaque, ) } } diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 88aa1b77cbaed..ed09a2eb958e2 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -321,6 +321,7 @@ pub static BUILTIN_ATTRIBUTES: &[Symbol] = &[ // Used by the `rustc::bad_opt_access` lint on fields // types (as well as any others in future). sym::rustc_lint_opt_deny_field_access, + sym::rustc_diagnostic_opaque, // ========================================================================== // Internal attributes, Const related: diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 01a4a7c499da0..056ea889afe7b 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -520,6 +520,8 @@ declare_features! ( (unstable, diagnostic_on_unknown, "1.96.0", Some(152900)), /// Allows macros to customize macro argument matcher diagnostics. (unstable, diagnostic_on_unmatched_args, "1.97.0", Some(155642)), + // Used by macros to not show their bodies in error messages. No-op with `-Z macro-backtrace`. + (unstable, diagnostic_opaque, "CURRENT_RUSTC_VERSION", Some(158813)), /// Allows `#[doc(cfg(...))]`. (unstable, doc_cfg, "1.21.0", Some(43781)), /// Allows `#[doc(masked)]`. diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 01f51e9dc8422..765954d3c7369 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1263,6 +1263,9 @@ pub enum AttributeKind { directive: Option>, }, + /// Represents `#[diagnostic::opaque]`. + Opaque, + /// Represents `#[optimize(size|speed)]` Optimize(OptimizeAttr, Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 01eab3cc8cb52..e36602a2e3c73 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -83,6 +83,7 @@ impl AttributeKind { OnUnimplemented { .. } => Yes, OnUnknown { .. } => Yes, OnUnmatchedArgs { .. } => Yes, + Opaque => Yes, Optimize(..) => No, PanicRuntime => No, PatchableFunctionEntry { .. } => Yes, diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 494a6f2903a07..a9d67ff4a1d4e 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -2726,7 +2726,7 @@ pub(crate) enum MutRefSugg { #[derive(Subdiagnostic)] #[suggestion( - "this type already provides \"interior mutability\", so its binding doesn't need to be declared as mutable", + "this type already provides \"interior mutability\", so its binding doesn't need to be declared as mutable when borrowed with a shared reference", style = "verbose", applicability = "maybe-incorrect", code = "" diff --git a/compiler/rustc_lint/src/static_mut_refs.rs b/compiler/rustc_lint/src/static_mut_refs.rs index 67e83d0652c3d..0dbed4ed1c0da 100644 --- a/compiler/rustc_lint/src/static_mut_refs.rs +++ b/compiler/rustc_lint/src/static_mut_refs.rs @@ -184,7 +184,7 @@ fn emit_static_mut_refs( }; let (interior_mutability_help, interior_mutability_sugg) = - interior_mutability_suggestion(cx, def_id); + interior_mutability_suggestion(cx, def_id, mut_note, suggest_addr_of); cx.emit_span_lint( STATIC_MUT_REFS, @@ -208,17 +208,23 @@ fn emit_static_mut_refs( fn interior_mutability_suggestion( cx: &LateContext<'_>, def_id: DefId, + mut_ref: bool, + suggest_addr_of: bool, ) -> (bool, Option) { let static_ty = cx.tcx.type_of(def_id).skip_binder(); let has_interior_mutability = !static_ty.is_freeze(cx.tcx, cx.typing_env()); if !has_interior_mutability { + return (!suggest_addr_of, None); + } + + if mut_ref { return (false, None); } let sugg = static_mutability_span(cx, def_id).map(|span| StaticMutRefsInteriorMutabilitySugg { span }); - (sugg.is_none(), sugg) + (false, sugg) } fn static_mutability_span(cx: &LateContext<'_>, def_id: DefId) -> Option { diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 27874aacc5ed9..afc716284391b 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -296,6 +296,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { AttributeKind::NoStd { .. } => (), AttributeKind::OnUnknown { .. } => (), AttributeKind::OnUnmatchedArgs { .. } => (), + AttributeKind::Opaque => (), AttributeKind::Optimize(..) => (), AttributeKind::PanicRuntime => (), AttributeKind::PatchableFunctionEntry { .. } => (), diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index f78b790e2aa87..a1e293af69433 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -248,19 +248,30 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { force: bool, ) -> Result, Indeterminate> { let invoc_id = invoc.expansion_data.id; - let parent_scope = match self.invocation_parent_scopes.get(&invoc_id) { - Some(parent_scope) => *parent_scope, - None => { - // If there's no entry in the table, then we are resolving an eagerly expanded - // macro, which should inherit its parent scope from its eager expansion root - + let (parent_scope, invocation_parent) = match ( + self.invocation_parent_scopes.get(&invoc_id), + self.invocation_parents.get(&invoc_id), + ) { + (Some(parent_scope), Some(invocation_parent)) => (*parent_scope, *invocation_parent), + (None, None) => { + // Eager macro invocations are not collected into the reduced graph, so they + // inherit their parent scope and invocation parent from the eager expansion root - // the macro that requested this eager expansion. let parent_scope = *self .invocation_parent_scopes .get(&eager_expansion_root) .expect("non-eager expansion without a parent scope"); + let invocation_parent = *self + .invocation_parents + .get(&eager_expansion_root) + .expect("non-eager expansion without an invocation parent"); self.invocation_parent_scopes.insert(invoc_id, parent_scope); - parent_scope + self.invocation_parents.insert(invoc_id, invocation_parent); + (parent_scope, invocation_parent) } + _ => unreachable!( + "invocation parent tables must both contain or both miss an invocation" + ), }; let (mut derives, mut inner_attr, mut deleg_impl) = (&[][..], false, None); @@ -275,7 +286,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { InvocationKind::GlobDelegation { ref item, .. } => { let ast::AssocItemKind::DelegationMac(deleg) = &item.kind else { unreachable!() }; let DelegationSuffixes::Glob(star_span) = deleg.suffixes else { unreachable!() }; - deleg_impl = Some((self.invocation_parent(invoc_id), star_span)); + deleg_impl = Some((invocation_parent.parent_def, star_span)); // It is sufficient to consider glob delegation a bang macro for now. (&deleg.prefix, MacroKind::Bang) } @@ -286,16 +297,13 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { let supports_macro_expansion = invoc.fragment_kind.supports_macro_expansion(); let node_id = invoc.expansion_data.lint_node_id; // This is a heuristic, but it's good enough for the lint. - let looks_like_invoc_in_mod_inert_attr = self - .invocation_parents - .get(&invoc_id) - .or_else(|| self.invocation_parents.get(&eager_expansion_root)) - .filter(|&&InvocationParent { parent_def: mod_def_id, in_attr, .. }| { + let looks_like_invoc_in_mod_inert_attr = Some(invocation_parent) + .filter(|&InvocationParent { parent_def: mod_def_id, in_attr, .. }| { in_attr && invoc.fragment_kind == AstFragmentKind::Expr && self.tcx.def_kind(mod_def_id) == DefKind::Mod }) - .map(|&InvocationParent { parent_def: mod_def_id, .. }| mod_def_id); + .map(|InvocationParent { parent_def: mod_def_id, .. }| mod_def_id); let sugg_span = match &invoc.kind { InvocationKind::Attr { item: Annotatable::Item(item), .. } if !item.span.from_expansion() => @@ -721,6 +729,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { (sym::on_unknown, Some(sym::diagnostic_on_unknown)), (sym::on_unmatched_args, Some(sym::diagnostic_on_unmatched_args)), (sym::on_type_error, Some(sym::diagnostic_on_type_error)), + (sym::opaque, Some(sym::diagnostic_opaque)), ]; if res == Res::NonMacroAttr(NonMacroAttrKind::Tool) diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 1c742052783cd..1cdce5cd04567 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -1020,8 +1020,9 @@ pub struct ExpnData { /// Should debuginfo for the macro be collapsed to the outermost expansion site (in other /// words, was the macro definition annotated with `#[collapse_debuginfo]`)? pub(crate) collapse_debuginfo: bool, - /// When true, we do not display the note telling people to use the `-Zmacro-backtrace` flag. - pub hide_backtrace: bool, + /// When true, we prevent diagnostics pointing into this macro, if it is one, and we do not + /// display the note telling people to use the `-Zmacro-backtrace` flag. + pub diagnostic_opaque: bool, } impl !PartialEq for ExpnData {} @@ -1040,7 +1041,7 @@ impl ExpnData { allow_internal_unsafe: bool, local_inner_macros: bool, collapse_debuginfo: bool, - hide_backtrace: bool, + diagnostic_opaque: bool, ) -> ExpnData { ExpnData { kind, @@ -1055,7 +1056,7 @@ impl ExpnData { allow_internal_unsafe, local_inner_macros, collapse_debuginfo, - hide_backtrace, + diagnostic_opaque, } } @@ -1080,7 +1081,7 @@ impl ExpnData { allow_internal_unsafe: false, local_inner_macros: false, collapse_debuginfo: false, - hide_backtrace: false, + diagnostic_opaque: false, } } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index ae01956be9301..318d0b60e240d 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1238,20 +1238,25 @@ impl Span { /// If "self" is the span of the outer_ident, and "within" is the span of the `($ident,)` /// expr, then this will return the span of the `$ident` macro variable. pub fn within_macro(self, within: Span, sm: &SourceMap) -> Option { - match Span::prepare_to_combine(self, within) { - // Only return something if it doesn't overlap with the original span, - // and the span isn't "imported" (i.e. from unavailable sources). - // FIXME: This does limit the usefulness of the error when the macro is - // from a foreign crate; we could also take into account `-Zmacro-backtrace`, - // which doesn't redact this span (but that would mean passing in even more - // args to this function, lol). - Ok((self_, _, parent)) - if self_.hi < self.lo() || self.hi() < self_.lo && !sm.is_imported(within) => - { - Some(Span::new(self_.lo, self_.hi, self_.ctxt, parent)) - } - _ => None, + let (self_, _, parent) = Span::prepare_to_combine(self, within).ok()?; + + // Only return something if it doesn't overlap with the original span + // and the span isn't "imported" (i.e. from unavailable sources). + // FIXME: This does limit the usefulness of the error when the macro is + // from a foreign crate; we could also take into account `-Zmacro-backtrace`, + // which doesn't redact this span (but that would mean passing in even more + // args to this function, lol). + if self.data().contains(self_) || sm.is_imported(within) { + return None; } + + // Don't return something if it's marked with `#[diagnostic::opaque]`. + // This already accounts for `-Zmacro-backtrace`. + if within.data().ctxt.outer_expn_data().diagnostic_opaque { + return None; + } + + Some(Span::new(self_.lo, self_.hi, self_.ctxt, parent)) } pub fn from_inner(self, inner: InnerSpan) -> Span { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 1d3f0adf86829..3b44015b4f452 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -820,6 +820,7 @@ symbols! { diagnostic_on_unknown, diagnostic_on_unmatch_args, diagnostic_on_unmatched_args, + diagnostic_opaque, dialect, direct, direct_const_arg, @@ -1780,6 +1781,7 @@ symbols! { rustc_deprecated_safe_2024, rustc_diagnostic_item, rustc_diagnostic_macros, + rustc_diagnostic_opaque, rustc_do_not_const_check, rustc_doc_primitive, rustc_driver, diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 8c1ebee8416e5..fc25849b2d602 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -423,7 +423,6 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("amx-fp16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]), ("amx-int8", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]), ("amx-movrs", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]), - ("amx-tf32", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]), ("amx-tile", Unstable(sym::x86_amx_intrinsics), &[]), ("apxf", Unstable(sym::apx_target_feature), &[]), ("avx", Stable, &["sse4.2"]), diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 44211354f520e..9eac8bcde1d1c 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -133,21 +133,21 @@ impl Clone for VecDeque { } } -#[stable(feature = "rust1", since = "1.0.0")] -unsafe impl<#[may_dangle] T, A: Allocator> Drop for VecDeque { - fn drop(&mut self) { - /// Runs the destructor for all items in the slice when it gets dropped (normally or - /// during unwinding). - struct Dropper<'a, T>(&'a mut [T]); +/// Runs the destructor for all items in the slice when it gets dropped (normally or +/// during unwinding). +struct Dropper<'a, T>(&'a mut [T]); - impl<'a, T> Drop for Dropper<'a, T> { - fn drop(&mut self) { - unsafe { - ptr::drop_in_place(self.0); - } - } +impl Drop for Dropper<'_, T> { + fn drop(&mut self) { + unsafe { + ptr::drop_in_place(self.0); } + } +} +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl<#[may_dangle] T, A: Allocator> Drop for VecDeque { + fn drop(&mut self) { let (front, back) = self.as_mut_slices(); unsafe { let _back_dropper = Dropper(back); @@ -1433,18 +1433,6 @@ impl VecDeque { #[doc(alias = "retain_front")] #[stable(feature = "deque_extras", since = "1.16.0")] pub fn truncate(&mut self, len: usize) { - /// Runs the destructor for all items in the slice when it gets dropped (normally or - /// during unwinding). - struct Dropper<'a, T>(&'a mut [T]); - - impl<'a, T> Drop for Dropper<'a, T> { - fn drop(&mut self) { - unsafe { - ptr::drop_in_place(self.0); - } - } - } - // Safe because: // // * Any slice passed to `drop_in_place` is valid; the second case has @@ -1499,18 +1487,6 @@ impl VecDeque { #[doc(alias = "truncate_front")] #[stable(feature = "vec_deque_truncate_front", since = "CURRENT_RUSTC_VERSION")] pub fn retain_back(&mut self, len: usize) { - /// Runs the destructor for all items in the slice when it gets dropped (normally or - /// during unwinding). - struct Dropper<'a, T>(&'a mut [T]); - - impl<'a, T> Drop for Dropper<'a, T> { - fn drop(&mut self) { - unsafe { - ptr::drop_in_place(self.0); - } - } - } - unsafe { if len >= self.len { // No action is taken @@ -1543,6 +1519,92 @@ impl VecDeque { } } + /// Shortens the deque to the elements within `range`, dropping the rest. + /// + /// # Panics + /// + /// Panics if the starting point is greater than the end point or if + /// the end point is greater than the length of the deque. + /// + /// # Examples + /// + /// ``` + /// # #![feature(vec_deque_retain_range)] + /// use std::collections::VecDeque; + /// + /// let mut buf: VecDeque<_> = (0..6).collect(); + /// buf.truncate_to_range(2..5); + /// assert_eq!(buf, [2, 3, 4]); + /// ``` + #[unstable(feature = "vec_deque_retain_range", issue = "156215")] + pub fn truncate_to_range(&mut self, range: R) + where + R: RangeBounds, + { + let Range { start, end } = slice::range(range, ..self.len); + + if start == 0 && end == self.len { + return; + } else if start == end { + self.clear(); + return; + } else if start == 0 { + self.truncate(end); + return; + } else if end == self.len { + self.retain_back(self.len - start); + return; + } + + // Both the dropped prefix [0..start) and the dropped suffix [end..self.len) are + // non-empty. Plan up to three physical slices to drop, then update head/len, then + // drop. Only one of the dropped prefix or dropped suffix can cross between slices. + let (front, back) = self.as_mut_slices(); + let flen = front.len(); + let blen = back.len(); + let fptr = front.as_mut_ptr(); + let bptr = back.as_mut_ptr(); + + unsafe { + let (drop_a, drop_b, drop_c) = if end <= flen { + // Kept range lies in `front`. The dropped suffix is the rest of `front` + // plus all of `back`. + let pre = ptr::slice_from_raw_parts_mut(fptr, start); + let mid = ptr::slice_from_raw_parts_mut(fptr.add(end), flen - end); + (pre, mid, Some(back as *mut [T])) + } else if start >= flen { + // Kept range lies in `back`. The dropped prefix is all of `front` plus the + // start of `back`. + let mid = ptr::slice_from_raw_parts_mut(bptr, start - flen); + let suf = ptr::slice_from_raw_parts_mut(bptr.add(end - flen), blen - (end - flen)); + (front as *mut [T], mid, Some(suf)) + } else { + // Kept range straddles the boundary. The dropped prefix is in `front`, the + // dropped suffix is in `back`. Only two regions to drop. + let pre = ptr::slice_from_raw_parts_mut(fptr, start); + let suf = ptr::slice_from_raw_parts_mut(bptr.add(end - flen), blen - (end - flen)); + (pre, suf, None) + }; + + // Set these once only, then drop. If we called truncate + retain_back, a panic in + // a destructor could leave this truncation in a half completed state. + self.head = self.to_wrapped_index(start); + self.len = end - start; + + match drop_c { + Some(c) => { + let _g_a = Dropper(&mut *drop_a); + let _g_b = Dropper(&mut *drop_b); + ptr::drop_in_place(c); + } + None => { + let _g_a = Dropper(&mut *drop_a); + ptr::drop_in_place(drop_b); + } + } + } + } + /// Returns a reference to the underlying allocator. #[unstable(feature = "allocator_api", issue = "32838")] #[inline] diff --git a/library/alloc/src/macros.rs b/library/alloc/src/macros.rs index b99107fb345a4..d93e279df7cfb 100644 --- a/library/alloc/src/macros.rs +++ b/library/alloc/src/macros.rs @@ -39,6 +39,7 @@ #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "vec_macro"] #[allow_internal_unstable(rustc_attrs, liballoc_internals)] +#[rustc_diagnostic_opaque] macro_rules! vec { () => ( $crate::vec::Vec::new() @@ -108,6 +109,7 @@ macro_rules! vec { #[stable(feature = "rust1", since = "1.0.0")] #[allow_internal_unstable(hint_must_use, liballoc_internals)] #[rustc_diagnostic_item = "format_macro"] +#[rustc_diagnostic_opaque] macro_rules! format { ($($arg:tt)*) => { $crate::__export::must_use({ diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs index e5b3646f14a58..96dcde71fc071 100644 --- a/library/alloctests/tests/lib.rs +++ b/library/alloctests/tests/lib.rs @@ -1,48 +1,51 @@ +// tidy-alphabetical-start +#![allow(internal_features)] +#![deny(implicit_provenance_casts)] +#![deny(unsafe_op_in_unsafe_fn)] #![feature(allocator_api)] +#![feature(binary_heap_drain_sorted)] +#![feature(binary_heap_into_iter_sorted)] #![feature(binary_heap_pop_if)] -#![feature(const_heap)] -#![feature(deque_extend_front)] -#![feature(iter_array_chunks)] #![feature(casefold)] -#![feature(cow_is_borrowed)] +#![feature(const_btree_len)] +#![feature(const_heap)] +#![feature(const_trait_impl)] #![feature(core_intrinsics)] +#![feature(cow_is_borrowed)] +#![feature(deque_extend_front)] #![feature(downcast_unchecked)] +#![feature(drain_keep_rest)] #![feature(exact_size_is_empty)] #![feature(hashmap_internals)] +#![feature(inplace_iteration)] +#![feature(iter_advance_by)] +#![feature(iter_array_chunks)] +#![feature(iter_next_chunk)] #![feature(linked_list_cursors)] +#![feature(local_waker)] +#![feature(macro_metavar_expr_concat)] #![feature(map_try_insert)] #![feature(pattern)] -#![feature(trusted_len)] -#![feature(try_reserve_kind)] -#![feature(try_with_capacity)] -#![feature(unboxed_closures)] -#![feature(binary_heap_into_iter_sorted)] -#![feature(binary_heap_drain_sorted)] -#![feature(slice_ptr_get)] -#![feature(slice_range)] +#![feature(ptr_cast_slice)] #![feature(slice_partial_sort_unstable)] -#![feature(inplace_iteration)] -#![feature(iter_advance_by)] -#![feature(iter_next_chunk)] #![feature(slice_partition_dedup)] -#![feature(string_remove_matches)] -#![feature(const_btree_len)] -#![feature(const_trait_impl)] -#![feature(test)] -#![feature(thin_box)] -#![feature(drain_keep_rest)] -#![feature(local_waker)] +#![feature(slice_ptr_get)] +#![feature(slice_range)] #![feature(str_as_str)] #![feature(strict_provenance_lints)] +#![feature(string_remove_matches)] #![feature(string_replace_in_place)] +#![feature(test)] +#![feature(thin_box)] +#![feature(trusted_len)] +#![feature(try_reserve_kind)] +#![feature(try_with_capacity)] +#![feature(unboxed_closures)] #![feature(unique_rc_arc)] -#![feature(macro_metavar_expr_concat)] +#![feature(vec_deque_retain_range)] #![feature(vec_peek_mut)] #![feature(vec_try_remove)] -#![feature(ptr_cast_slice)] -#![allow(internal_features)] -#![deny(implicit_provenance_casts)] -#![deny(unsafe_op_in_unsafe_fn)] +// tidy-alphabetical-end extern crate alloc; diff --git a/library/alloctests/tests/vec_deque.rs b/library/alloctests/tests/vec_deque.rs index 2e75b7b07e63f..15cc156d6988f 100644 --- a/library/alloctests/tests/vec_deque.rs +++ b/library/alloctests/tests/vec_deque.rs @@ -7,6 +7,7 @@ use std::collections::vec_deque::Drain; use std::fmt::Debug; use std::ops::Bound::*; use std::panic::{AssertUnwindSafe, catch_unwind}; +use std::sync::atomic::{AtomicUsize, Ordering}; use Taggy::*; use Taggypar::*; @@ -2360,3 +2361,137 @@ fn test_splice_wrapping_and_resize() { assert_eq!(Vec::from(vec), [1, 2, 3, 4, 1, 1, 1, 1, 1]) } + +#[test] +fn truncate_to_range_basic() { + // no-op + let mut v: VecDeque<_> = (0..6).collect(); + v.truncate_to_range(..); + assert_eq!(v, [0, 1, 2, 3, 4, 5]); + + // clear + let mut v: VecDeque<_> = (0..6).collect(); + v.truncate_to_range(3..3); + assert_eq!(v, [] as [i32; 0]); + + // truncate + let mut v: VecDeque<_> = (0..6).collect(); + v.truncate_to_range(..3); + assert_eq!(v, [0, 1, 2]); + + // truncate front + let mut v: VecDeque<_> = (0..6).collect(); + v.truncate_to_range(2..); + assert_eq!(v, [2, 3, 4, 5]); + + let mut v: VecDeque<_> = (0..6).collect(); + v.truncate_to_range(2..5); + assert_eq!(v, [2, 3, 4]); + + let mut v: VecDeque<_> = (0..6).collect(); + v.truncate_to_range(3..=5); + assert_eq!(v, [3, 4, 5]); + + let mut v: VecDeque<_> = (0..6).collect(); + v.truncate_to_range(..=3); + assert_eq!(v, [0, 1, 2, 3]); +} + +fn make_wrapped() -> VecDeque { + let mut v = VecDeque::new(); + v.extend(0..5); + v.push_front(-1); + v.push_front(-2); + v.push_front(-3); + assert_eq!(v.as_slices(), ([-3, -2, -1].as_slice(), [0, 1, 2, 3, 4].as_slice())); + v +} + +#[test] +fn truncate_to_range_kept_in_front() { + let mut v = make_wrapped(); + v.truncate_to_range(1..3); + assert_eq!(v, [-2, -1]); +} + +#[test] +fn truncate_to_range_kept_in_back() { + let mut v = make_wrapped(); + v.truncate_to_range(4..7); + assert_eq!(v, [1, 2, 3]); +} + +#[test] +fn truncate_to_range_kept_straddles() { + let mut v = make_wrapped(); + v.truncate_to_range(1..6); + assert_eq!(v, [-2, -1, 0, 1, 2]); +} + +#[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] +fn truncate_to_range_leak() { + struct_with_counted_drop!(D(bool), DROPS => |this: &D| if this.0 { panic!("panic in `drop`"); } ); + + let mut q = VecDeque::new(); + q.push_back(D(true)); + q.push_back(D(false)); + q.push_back(D(false)); + q.push_back(D(false)); + q.push_back(D(false)); + q.push_front(D(false)); + q.push_front(D(false)); + q.push_front(D(false)); + + catch_unwind(AssertUnwindSafe(|| q.truncate_to_range(4..7))).ok(); + + assert_eq!(DROPS.get(), 5); +} + +#[test] +fn truncate_to_range_calls_drop() { + static DROPPED: AtomicUsize = AtomicUsize::new(0); + + #[derive(Debug)] + struct Foo(u8); + + impl Drop for Foo { + fn drop(&mut self) { + DROPPED.fetch_add(1, Ordering::Relaxed); + } + } + + let mut deque: VecDeque<_> = (0..12).map(Foo).collect(); + deque.truncate_to_range(1..5); + assert!(deque.iter().map(|x| x.0).eq([1, 2, 3, 4])); + assert_eq!(8, DROPPED.load(Ordering::Relaxed)); +} + +#[test] +#[should_panic] +fn truncate_to_range_start_greater_than_end() { + let mut v: VecDeque<_> = (0..6).collect(); + #[allow(clippy::reversed_empty_ranges)] + v.truncate_to_range(4..2); +} + +#[test] +#[should_panic] +fn truncate_to_range_end_past_len() { + let mut v: VecDeque<_> = (0..6).collect(); + v.truncate_to_range(2..7); +} + +#[test] +#[should_panic] +fn truncate_to_range_start_past_len() { + let mut v: VecDeque<_> = (0..6).collect(); + v.truncate_to_range(7..8); +} + +#[test] +#[should_panic] +fn truncate_to_range_inclusive_end_overflow() { + let mut v: VecDeque<_> = (0..6).collect(); + v.truncate_to_range(0..=usize::MAX); +} diff --git a/library/core/src/attribute_docs.rs b/library/core/src/attribute_docs.rs index 94ff7a8fee6d3..8591e866f482b 100644 --- a/library/core/src/attribute_docs.rs +++ b/library/core/src/attribute_docs.rs @@ -405,3 +405,43 @@ mod warn_attribute {} /// [`Result`]: result::Result /// [the `no_std` attribute]: ../reference/names/preludes.html#the-no_std-attribute mod no_std_attribute {} + +#[doc(attribute = "inline")] +// +/// Suggest that the compiler inline a function at its call sites. +/// +/// Inlining replaces a call with a copy of the called function's body, which can remove the +/// overhead of the call. The `inline` attribute is only a hint: the compiler may ignore it, and +/// it already inlines functions on its own when that looks worthwhile. Poor choices about what to +/// inline can make a program larger or slower. +/// +/// Where it does matter is inlining across crate boundaries. A non-generic function is not +/// normally inlined into another crate, since the calling crate compiles against only its +/// signature. Marking it `#[inline]` makes the body available to other crates so they can inline +/// it too: +/// +/// ```rust +/// # #![allow(dead_code)] +/// #[inline] +/// pub fn square(x: i32) -> i32 { +/// x * x +/// } +/// ``` +/// +/// Generic functions do not need this. They are instantiated in each crate that uses them, so +/// their bodies are already available to inline. +/// +/// The attribute applies to functions and has three forms: +/// +/// - `#[inline]` suggests inlining the function. +/// - `#[inline(always)]` suggests inlining it at every call site. +/// - `#[inline(never)]` suggests never inlining it. +/// +/// You should almost never need `#[inline(always)]`: prefer to let the compiler decide unless +/// profiling shows a small, hot function that benefits from it. `#[inline(never)]` is useful to +/// keep a rarely used path, such as a function that only reports an error, out of its caller. +/// +/// For more information, see the Reference on [the `inline` attribute]. +/// +/// [the `inline` attribute]: ../reference/attributes/codegen.html#the-inline-attribute +mod inline_attribute {} diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 9b2015ddc7101..1b8ec2a91478a 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -68,7 +68,7 @@ //! [`OnceCell`] is somewhat of a hybrid of `Cell` and `RefCell` that works for values that //! typically only need to be set once. This means that a reference `&T` can be obtained without //! moving or copying the inner value (unlike `Cell`) but also without runtime checks (unlike -//! `RefCell`). However, its value can also not be updated once set unless you have a mutable +//! `RefCell`). However, once set, its value cannot be updated unless you have a mutable //! reference to the `OnceCell`. //! //! `OnceCell` provides the following methods: diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 2d7dd41ebac2f..6e670375fcc5e 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -121,6 +121,7 @@ #![feature(derive_const)] #![feature(diagnostic_on_const)] #![feature(diagnostic_on_unmatched_args)] +#![feature(diagnostic_opaque)] #![feature(doc_cfg)] #![feature(doc_notable_trait)] #![feature(extern_types)] diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 932a2fc0bad92..4b1ce0351f7d7 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -39,6 +39,7 @@ macro_rules! panic { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "assert_eq_macro"] #[allow_internal_unstable(panic_internals)] +#[rustc_diagnostic_opaque] macro_rules! assert_eq { ($left:expr, $right:expr $(,)?) => {{ match (&$left, &$right) { @@ -95,6 +96,7 @@ macro_rules! assert_eq { #[stable(feature = "assert_ne", since = "1.13.0")] #[rustc_diagnostic_item = "assert_ne_macro"] #[allow_internal_unstable(panic_internals)] +#[rustc_diagnostic_opaque] macro_rules! assert_ne { ($left:expr, $right:expr $(,)?) => {{ match (&$left, &$right) { @@ -284,6 +286,7 @@ pub macro cfg_select($($tt:tt)*) { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "debug_assert_macro"] #[allow_internal_unstable(edition_panic)] +#[rustc_diagnostic_opaque] macro_rules! debug_assert { ($($arg:tt)*) => { if $crate::cfg!(debug_assertions) { @@ -424,6 +427,7 @@ pub macro debug_assert_matches($($arg:tt)*) { #[stable(feature = "matches_macro", since = "1.42.0")] #[rustc_diagnostic_item = "matches_macro"] #[allow_internal_unstable(non_exhaustive_omitted_patterns_lint, stmt_expr_attributes)] +#[rustc_diagnostic_opaque] macro_rules! matches { ($expression:expr, $pattern:pat $(if $guard:expr)? $(,)?) => { #[allow(non_exhaustive_omitted_patterns)] @@ -600,6 +604,7 @@ macro_rules! r#try { #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "write_macro"] +#[rustc_diagnostic_opaque] macro_rules! write { ($dst:expr, $($arg:tt)*) => { $dst.write_fmt($crate::format_args!($($arg)*)) @@ -638,6 +643,7 @@ macro_rules! write { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "writeln_macro"] #[allow_internal_unstable(format_args_nl)] +#[rustc_diagnostic_opaque] macro_rules! writeln { ($dst:expr $(,)?) => { $crate::write!($dst, "\n") @@ -793,6 +799,7 @@ macro_rules! unreachable { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "unimplemented_macro"] #[allow_internal_unstable(panic_internals)] +#[rustc_diagnostic_opaque] macro_rules! unimplemented { () => { $crate::panicking::panic("not implemented") @@ -873,6 +880,7 @@ macro_rules! unimplemented { #[stable(feature = "todo_macro", since = "1.40.0")] #[rustc_diagnostic_item = "todo_macro"] #[allow_internal_unstable(panic_internals)] +#[rustc_diagnostic_opaque] macro_rules! todo { () => { $crate::panicking::panic("not yet implemented") diff --git a/library/core/src/marker/variance.rs b/library/core/src/marker/variance.rs index 31e30a16d45a3..9e135e89c451e 100644 --- a/library/core/src/marker/variance.rs +++ b/library/core/src/marker/variance.rs @@ -234,6 +234,7 @@ phantom_type! { } mod private_items { + #[unstable(feature = "std_internals", issue = "none")] pub trait PrivateItems { const VALUE: Self; } diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs index a70cb8ad67297..6c2f77a373393 100644 --- a/library/core/src/mem/manually_drop.rs +++ b/library/core/src/mem/manually_drop.rs @@ -178,6 +178,7 @@ impl ManuallyDrop { #[stable(feature = "manually_drop", since = "1.20.0")] #[rustc_const_stable(feature = "const_manually_drop", since = "1.32.0")] #[inline(always)] + #[rustc_no_writable] pub const fn new(value: T) -> ManuallyDrop { ManuallyDrop { value: MaybeDangling::new(value) } } diff --git a/library/core/src/mem/maybe_dangling.rs b/library/core/src/mem/maybe_dangling.rs index 7ae1bf899dd4f..46e5228a2da3f 100644 --- a/library/core/src/mem/maybe_dangling.rs +++ b/library/core/src/mem/maybe_dangling.rs @@ -74,6 +74,7 @@ pub struct MaybeDangling(P); impl MaybeDangling

{ /// Wraps a value in a `MaybeDangling`, allowing it to dangle. + #[rustc_no_writable] pub const fn new(x: P) -> Self where P: Sized, diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index e24b220acb43b..2317999d2f888 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -187,6 +187,7 @@ pub mod type_info; #[rustc_const_stable(feature = "const_forget", since = "1.46.0")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "mem_forget"] +#[rustc_no_writable] pub const fn forget(t: T) { let _ = ManuallyDrop::new(t); } @@ -1204,6 +1205,7 @@ pub const unsafe fn transmute_copy(src: &Src) -> Dst { /// let _: std::mem::MaybeUninit = unsafe { transmute_prefix(123_u8) }; /// ``` #[unstable(feature = "transmute_prefix", issue = "155079")] +#[rustc_no_writable] pub const unsafe fn transmute_prefix(src: Src) -> Dst { #[repr(C)] union Transmute { @@ -1253,6 +1255,7 @@ pub const unsafe fn transmute_prefix(src: Src) -> Dst { #[unstable(feature = "transmute_neo", issue = "155079")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[inline] +#[rustc_no_writable] pub const unsafe fn transmute_neo(src: Src) -> Dst { const { assert!(Src::SIZE == Dst::SIZE) }; diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 40f774806046a..b766a767df64d 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -2025,6 +2025,7 @@ unsafe impl PinCoerceUnsized for Pin {} #[rustc_diagnostic_item = "pin_macro"] // `super` gets removed by rustfmt #[rustfmt::skip] +#[diagnostic::opaque] pub macro pin($value:expr $(,)?) { 'p: { super let mut pinned = $value; diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs index 829945d08e2a9..ea574fc4146e7 100644 --- a/library/std/src/macros.rs +++ b/library/std/src/macros.rs @@ -82,6 +82,7 @@ macro_rules! panic { #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "print_macro")] #[allow_internal_unstable(print_internals)] +#[rustc_diagnostic_opaque] macro_rules! print { ($($arg:tt)*) => {{ $crate::io::_print($crate::format_args!($($arg)*)); @@ -138,6 +139,7 @@ macro_rules! print { #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "println_macro")] #[allow_internal_unstable(print_internals, format_args_nl)] +#[rustc_diagnostic_opaque] macro_rules! println { () => { $crate::print!("\n") @@ -352,6 +354,7 @@ macro_rules! eprintln { #[macro_export] #[cfg_attr(not(test), rustc_diagnostic_item = "dbg_macro")] #[stable(feature = "dbg_macro", since = "1.32.0")] +#[rustc_diagnostic_opaque] macro_rules! dbg { // NOTE: We cannot use `concat!` to make a static string as a format argument // of `eprintln!` because `file!` could contain a `{` or diff --git a/library/std/src/thread/functions.rs b/library/std/src/thread/functions.rs index 70642108e1e01..21e7a2b2ed087 100644 --- a/library/std/src/thread/functions.rs +++ b/library/std/src/thread/functions.rs @@ -640,10 +640,13 @@ pub fn park_timeout(dur: Duration) { /// /// On Windows: /// - It may undercount the amount of parallelism available on systems with more -/// than 64 logical CPUs. However, programs typically need specific support to -/// take advantage of more than 64 logical CPUs, and in the absence of such -/// support, the number returned by this function accurately reflects the -/// number of logical CPUs the program can use by default. +/// than 64 logical CPUs, because it reports only the logical CPUs in one +/// processor group. Before Windows 11 and Windows Server 2022, a process was by +/// default confined to a single processor group, so this count reflected the CPUs +/// it could use without explicitly opting into other groups. Starting with Windows +/// 11 and Windows Server 2022, a process and its threads have affinities that by +/// default span all processor groups, so on systems with more than 64 logical CPUs +/// this may report fewer CPUs than are available to the program. /// - It may overcount the amount of parallelism available on systems limited by /// process-wide affinity masks, or job object limitations. /// diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index 321fc4440f330..118d9e07cd4eb 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -346,6 +346,7 @@ pub macro thread_local_process_attrs { #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "thread_local_macro")] #[allow_internal_unstable(thread_local_internals)] +#[rustc_diagnostic_opaque] macro_rules! thread_local { () => {}; diff --git a/library/std_detect/src/detect/arch/x86.rs b/library/std_detect/src/detect/arch/x86.rs index ede4a80c088ed..e054546afcb19 100644 --- a/library/std_detect/src/detect/arch/x86.rs +++ b/library/std_detect/src/detect/arch/x86.rs @@ -91,7 +91,6 @@ features! { /// * `"amx-avx512"` /// * `"amx-fp8"` /// * `"amx-movrs"` - /// * `"amx-tf32"` /// * `"f16c"` /// * `"fma"` /// * `"bmi1"` @@ -228,8 +227,6 @@ features! { /// AMX-FP8 (Float8 Operations) @FEATURE: #[unstable(feature = "x86_amx_intrinsics", issue = "126622")] amx_movrs: "amx-movrs"; /// AMX-MOVRS (Matrix MOVERS operations) - @FEATURE: #[unstable(feature = "x86_amx_intrinsics", issue = "126622")] amx_tf32: "amx-tf32"; - /// AMX-TF32 (TensorFloat32 Operations) @FEATURE: #[unstable(feature = "apx_target_feature", issue = "139284")] apxf: "apxf"; /// APX-F (Advanced Performance Extensions - Foundation) @FEATURE: #[unstable(feature = "avx10_target_feature", issue = "138843")] avx10_1: "avx10.1"; diff --git a/library/std_detect/src/detect/os/x86.rs b/library/std_detect/src/detect/os/x86.rs index 2b75cd6257087..4e739fb38d56e 100644 --- a/library/std_detect/src/detect/os/x86.rs +++ b/library/std_detect/src/detect/os/x86.rs @@ -216,7 +216,6 @@ pub(crate) fn detect_features() -> cache::Initializer { __cpuid_count(0x1e_u32, 1); enable(amx_feature_flags_eax, 4, Feature::amx_fp8); - enable(amx_feature_flags_eax, 6, Feature::amx_tf32); enable(amx_feature_flags_eax, 7, Feature::amx_avx512); enable(amx_feature_flags_eax, 8, Feature::amx_movrs); } diff --git a/library/std_detect/tests/x86-specific.rs b/library/std_detect/tests/x86-specific.rs index 4b02f78b7944e..117182558f46a 100644 --- a/library/std_detect/tests/x86-specific.rs +++ b/library/std_detect/tests/x86-specific.rs @@ -83,7 +83,6 @@ fn dump() { println!("widekl: {:?}", is_x86_feature_detected!("widekl")); println!("movrs: {:?}", is_x86_feature_detected!("movrs")); println!("amx-fp8: {:?}", is_x86_feature_detected!("amx-fp8")); - println!("amx-tf32: {:?}", is_x86_feature_detected!("amx-tf32")); println!("amx-avx512: {:?}", is_x86_feature_detected!("amx-avx512")); println!("amx-movrs: {:?}", is_x86_feature_detected!("amx-movrs")); } diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index f90cae4fb7e72..31ff38b78e70f 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -172,34 +172,36 @@ fn clean_param_env<'tcx>( // FIXME(#111101): Incorporate the explicit predicates of the item here... let item_clauses: FxIndexSet<_> = tcx.param_env(item_def_id).caller_bounds().iter().collect(); - let where_predicates = param_env - .caller_bounds() - .iter() - // FIXME: ...which hopefully allows us to simplify this: - .filter(|clause| { - !item_clauses.contains(clause) - || clause - .as_trait_clause() - .is_some_and(|clause| tcx.lang_items().sized_trait() == Some(clause.def_id())) - }) - .map(|clause| { - fold_regions(tcx, clause, |r, _| match r.kind() { - // FIXME: Don't `unwrap_or`, I think we should panic if we encounter an infer var that - // we can't map to a concrete region. However, `AutoTraitFinder` *does* leak those kinds - // of `ReVar`s for some reason at the time of writing. See `rustdoc-ui/` tests. - // This is in dire need of an investigation into `AutoTraitFinder`. - ty::ReVar(vid) => vid_to_region.get(&vid).copied().unwrap_or(r), - ty::ReEarlyParam(_) | ty::ReStatic | ty::ReBound(..) | ty::ReError(_) => r, - // FIXME(#120606): `AutoTraitFinder` can actually leak placeholder regions which feels - // incorrect. Needs investigation. - ty::ReLateParam(_) | ty::RePlaceholder(_) | ty::ReErased => { - bug!("unexpected region kind: {r:?}") - } + let where_predicates = cx.with_exact_param_env(param_env, |cx| { + param_env + .caller_bounds() + .iter() + // FIXME: ...which hopefully allows us to simplify this: + .filter(|clause| { + !item_clauses.contains(clause) + || clause.as_trait_clause().is_some_and(|clause| { + tcx.lang_items().sized_trait() == Some(clause.def_id()) + }) }) - }) - .flat_map(|clause| clean_predicate(clause, cx)) - .chain(clean_region_outlives_constraints(®ion_data, generics)) - .collect(); + .map(|clause| { + fold_regions(tcx, clause, |r, _| match r.kind() { + // FIXME: Don't `unwrap_or`, I think we should panic if we encounter an infer var that + // we can't map to a concrete region. However, `AutoTraitFinder` *does* leak those kinds + // of `ReVar`s for some reason at the time of writing. See `rustdoc-ui/` tests. + // This is in dire need of an investigation into `AutoTraitFinder`. + ty::ReVar(vid) => vid_to_region.get(&vid).copied().unwrap_or(r), + ty::ReEarlyParam(_) | ty::ReStatic | ty::ReBound(..) | ty::ReError(_) => r, + // FIXME(#120606): `AutoTraitFinder` can actually leak placeholder regions which feels + // incorrect. Needs investigation. + ty::ReLateParam(_) | ty::RePlaceholder(_) | ty::ReErased => { + bug!("unexpected region kind: {r:?}") + } + }) + }) + .flat_map(|clause| clean_predicate(clause, cx)) + .chain(clean_region_outlives_constraints(®ion_data, generics)) + .collect() + }); let mut generics = clean::Generics { params, where_predicates }; simplify::sizedness_bounds(cx, &mut generics); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 5bdedf7ae3d54..c1ae5f977cb89 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -87,7 +87,15 @@ impl<'tcx> DocContext<'tcx> { def_id: DefId, f: F, ) -> T { - let old_param_env = mem::replace(&mut self.param_env, self.tcx.param_env(def_id)); + self.with_exact_param_env(self.tcx.param_env(def_id), f) + } + + pub(crate) fn with_exact_param_env T>( + &mut self, + param_env: ParamEnv<'tcx>, + f: F, + ) -> T { + let old_param_env = mem::replace(&mut self.param_env, param_env); let ret = f(self); self.param_env = old_param_env; ret diff --git a/src/tools/miri/tests/pass/tree_borrows/mem_forget-implicit_writes.rs b/src/tools/miri/tests/pass/tree_borrows/mem_forget-implicit_writes.rs new file mode 100644 index 0000000000000..77cf6997761bb --- /dev/null +++ b/src/tools/miri/tests/pass/tree_borrows/mem_forget-implicit_writes.rs @@ -0,0 +1,20 @@ +// Regression test. This failed before applying `#[rustc_no_writable]` to `mem::forget`, `ManuallyDrop::new`, and `MaybeDangling::new`. +//@compile-flags: -Zmiri-tree-borrows -Zmiri-tree-borrows-implicit-writes + +use std::mem; + +// This function is taken from the crate `derive_more`, from the file `into.rs` +unsafe fn transmute(from: From) -> To { + let to = unsafe { mem::transmute_copy(&from) }; + mem::forget(from); + to +} + +fn main() { + let mut val = 10u32; + let r: &mut u32 = &mut val; + + let to: &mut i32 = unsafe { transmute(r) }; + + assert_eq!(*to, 10); +} diff --git a/tests/rustdoc-html/synthetic_auto/issue-159065.rs b/tests/rustdoc-html/synthetic_auto/issue-159065.rs new file mode 100644 index 0000000000000..ff809c732cc35 --- /dev/null +++ b/tests/rustdoc-html/synthetic_auto/issue-159065.rs @@ -0,0 +1,6 @@ +//@ compile-flags: -Znext-solver=globally -Znormalize-docs + +#![crate_name = "foo"] + +#[doc(inline)] +pub use std as other; diff --git a/tests/ui/async-await/async-closures/higher-ranked-return.stderr b/tests/ui/async-await/async-closures/higher-ranked-return.stderr index 23ce3df661654..efd5698e9731f 100644 --- a/tests/ui/async-await/async-closures/higher-ranked-return.stderr +++ b/tests/ui/async-await/async-closures/higher-ranked-return.stderr @@ -2,9 +2,9 @@ error: lifetime may not live long enough --> $DIR/higher-ranked-return.rs:11:46 | LL | let x = async move |x: &str| -> &str { - | ________________________________-________----_^ + | ________________________________-________-____^ | | | | - | | | return type of async closure `{async closure body@$DIR/higher-ranked-return.rs:11:46: 13:10}` contains a lifetime `'2` + | | | let's call the lifetime of this reference `'2` | | let's call the lifetime of this reference `'1` LL | | x LL | | }; diff --git a/tests/ui/async-await/async-closures/not-lending.stderr b/tests/ui/async-await/async-closures/not-lending.stderr index fb941502d3646..989b9ccb88a76 100644 --- a/tests/ui/async-await/async-closures/not-lending.stderr +++ b/tests/ui/async-await/async-closures/not-lending.stderr @@ -4,7 +4,7 @@ error: lifetime may not live long enough LL | let x = async move || -> &String { &s }; | ------------------------ ^^^^^^ returning this value requires that `'1` must outlive `'2` | | | - | | return type of async closure `{async closure body@$DIR/not-lending.rs:12:42: 12:48}` contains a lifetime `'2` + | | let's call the lifetime of this reference `'2` | lifetime `'1` represents this closure's body | = note: closure implements `AsyncFn`, so references to captured variables can't escape the closure @@ -15,7 +15,7 @@ error: lifetime may not live long enough LL | let x = async move || { &s }; | ------------- ^^^^^^ returning this value requires that `'1` must outlive `'2` | | | - | | return type of async closure `{async closure body@$DIR/not-lending.rs:16:31: 16:37}` contains a lifetime `'2` + | | return type of async closure is &'2 String | lifetime `'1` represents this closure's body | = note: closure implements `AsyncFn`, so references to captured variables can't escape the closure diff --git a/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr b/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr index c479adfa56d7e..3cf2d20f155fd 100644 --- a/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr +++ b/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr @@ -29,7 +29,7 @@ error: lifetime may not live long enough LL | (async move || { | ______-------------_^ | | | | - | | | return type of async closure `{async closure body@$DIR/issue-74072-lifetime-name-annotations.rs:13:20: 19:6}` contains a lifetime `'2` + | | | return type of async closure is &'2 i32 | | lifetime `'1` represents this closure's body LL | | LL | | @@ -78,7 +78,7 @@ error: lifetime may not live long enough LL | (async move || -> &i32 { | ______---------------------_^ | | | | - | | | return type of async closure `{async closure body@$DIR/issue-74072-lifetime-name-annotations.rs:23:28: 29:6}` contains a lifetime `'2` + | | | let's call the lifetime of this reference `'2` | | lifetime `'1` represents this closure's body LL | | LL | | diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr index 98ba1de498bbe..eca0813e6a286 100644 --- a/tests/ui/check-cfg/target_feature.stderr +++ b/tests/ui/check-cfg/target_feature.stderr @@ -28,7 +28,6 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `amx-fp8` `amx-int8` `amx-movrs` -`amx-tf32` `amx-tile` `apxf` `atomics` diff --git a/tests/ui/delegation/eager-format-glob-delegation-ice-159233.rs b/tests/ui/delegation/eager-format-glob-delegation-ice-159233.rs new file mode 100644 index 0000000000000..3c909b18dea5c --- /dev/null +++ b/tests/ui/delegation/eager-format-glob-delegation-ice-159233.rs @@ -0,0 +1,10 @@ +//@ edition: 2024 + +#![feature(fn_delegation)] + +static REGEX: () = format!(|| { reuse impl Trait for S; }); +//~^ ERROR format argument must be a string literal +//~| ERROR cannot find type `Trait` in this scope +//~| ERROR mismatched types + +fn main() {} diff --git a/tests/ui/delegation/eager-format-glob-delegation-ice-159233.stderr b/tests/ui/delegation/eager-format-glob-delegation-ice-159233.stderr new file mode 100644 index 0000000000000..0b644cbc7f879 --- /dev/null +++ b/tests/ui/delegation/eager-format-glob-delegation-ice-159233.stderr @@ -0,0 +1,27 @@ +error: format argument must be a string literal + --> $DIR/eager-format-glob-delegation-ice-159233.rs:5:28 + | +LL | static REGEX: () = format!(|| { reuse impl Trait for S; }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: you might be missing a string literal to format with + | +LL | static REGEX: () = format!("{}", || { reuse impl Trait for S; }); + | +++++ + +error[E0433]: cannot find type `Trait` in this scope + --> $DIR/eager-format-glob-delegation-ice-159233.rs:5:44 + | +LL | static REGEX: () = format!(|| { reuse impl Trait for S; }); + | ^^^^^ use of undeclared type `Trait` + +error[E0308]: mismatched types + --> $DIR/eager-format-glob-delegation-ice-159233.rs:5:20 + | +LL | static REGEX: () = format!(|| { reuse impl Trait for S; }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `String` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0308, E0433. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/diagnostic_namespace/opaque/auxiliary/wrap.rs b/tests/ui/diagnostic_namespace/opaque/auxiliary/wrap.rs new file mode 100644 index 0000000000000..f046e82b8f9e7 --- /dev/null +++ b/tests/ui/diagnostic_namespace/opaque/auxiliary/wrap.rs @@ -0,0 +1,9 @@ +#![feature(diagnostic_opaque)] + +#[diagnostic::opaque] +#[macro_export] +macro_rules! wrap { + ($x:ident) => {{ + let x = blah::$x; + }}; +} diff --git a/tests/ui/diagnostic_namespace/opaque/duplicate.rs b/tests/ui/diagnostic_namespace/opaque/duplicate.rs new file mode 100644 index 0000000000000..2341e72ddc5e3 --- /dev/null +++ b/tests/ui/diagnostic_namespace/opaque/duplicate.rs @@ -0,0 +1,9 @@ +#![crate_type = "lib"] +#![feature(diagnostic_opaque)] +#![deny(unused_attributes)] +#[diagnostic::opaque] +#[diagnostic::opaque] +//~^ERROR unused attribute +macro_rules! m { + () => {} +} diff --git a/tests/ui/diagnostic_namespace/opaque/duplicate.stderr b/tests/ui/diagnostic_namespace/opaque/duplicate.stderr new file mode 100644 index 0000000000000..d4420d3b63a9f --- /dev/null +++ b/tests/ui/diagnostic_namespace/opaque/duplicate.stderr @@ -0,0 +1,19 @@ +error: unused attribute + --> $DIR/duplicate.rs:5:1 + | +LL | #[diagnostic::opaque] + | ^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/duplicate.rs:4:1 + | +LL | #[diagnostic::opaque] + | ^^^^^^^^^^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/duplicate.rs:3:9 + | +LL | #![deny(unused_attributes)] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/diagnostic_namespace/opaque/highlight_maccall.-Zmacro-backtrace.stderr b/tests/ui/diagnostic_namespace/opaque/highlight_maccall.-Zmacro-backtrace.stderr new file mode 100644 index 0000000000000..d53e5cb526061 --- /dev/null +++ b/tests/ui/diagnostic_namespace/opaque/highlight_maccall.-Zmacro-backtrace.stderr @@ -0,0 +1,16 @@ +error: oh no + --> $DIR/highlight_maccall.rs:9:9 + | +LL | / macro_rules! my_error { +LL | | () => {{ +LL | | compile_error!("oh no") + | | ^^^^^^^^^^^^^^^^^^^^^^^ +... | +LL | | } + | |_- in this expansion of `my_error!` +... +LL | my_error!(); + | ----------- in this macro invocation + +error: aborting due to 1 previous error + diff --git a/tests/ui/diagnostic_namespace/opaque/highlight_maccall.default.stderr b/tests/ui/diagnostic_namespace/opaque/highlight_maccall.default.stderr new file mode 100644 index 0000000000000..07521e003e3e2 --- /dev/null +++ b/tests/ui/diagnostic_namespace/opaque/highlight_maccall.default.stderr @@ -0,0 +1,8 @@ +error: oh no + --> $DIR/highlight_maccall.rs:16:5 + | +LL | my_error!(); + | ^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/diagnostic_namespace/opaque/highlight_maccall.rs b/tests/ui/diagnostic_namespace/opaque/highlight_maccall.rs new file mode 100644 index 0000000000000..f8095838b2368 --- /dev/null +++ b/tests/ui/diagnostic_namespace/opaque/highlight_maccall.rs @@ -0,0 +1,17 @@ +//@revisions: default -Zmacro-backtrace +//@[-Zmacro-backtrace] compile-flags: -Z macro-backtrace + +#![feature(diagnostic_opaque)] + +#[diagnostic::opaque] +macro_rules! my_error { + () => {{ + compile_error!("oh no") + //~^ ERROR oh no + }} +} + + +fn main() { + my_error!(); +} diff --git a/tests/ui/diagnostic_namespace/opaque/only_point_at_input.-Zmacro-backtrace.stderr b/tests/ui/diagnostic_namespace/opaque/only_point_at_input.-Zmacro-backtrace.stderr new file mode 100644 index 0000000000000..47ed10e2bcfdc --- /dev/null +++ b/tests/ui/diagnostic_namespace/opaque/only_point_at_input.-Zmacro-backtrace.stderr @@ -0,0 +1,18 @@ +error[E0425]: cannot find value `x` in module `blah` + --> $DIR/only_point_at_input.rs:17:17 + | +LL | wrap::wrap!(x); + | ^ not found in `blah` + +error[E0425]: cannot find value `x` in module `blah` + --> $DIR/only_point_at_input.rs:20:17 + | +LL | let x = blah::$x; + | -- due to this macro variable +... +LL | local_wrap!(x); + | ^ not found in `blah` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/diagnostic_namespace/opaque/only_point_at_input.default.stderr b/tests/ui/diagnostic_namespace/opaque/only_point_at_input.default.stderr new file mode 100644 index 0000000000000..366e1c3aead24 --- /dev/null +++ b/tests/ui/diagnostic_namespace/opaque/only_point_at_input.default.stderr @@ -0,0 +1,15 @@ +error[E0425]: cannot find value `x` in module `blah` + --> $DIR/only_point_at_input.rs:17:17 + | +LL | wrap::wrap!(x); + | ^ not found in `blah` + +error[E0425]: cannot find value `x` in module `blah` + --> $DIR/only_point_at_input.rs:20:17 + | +LL | local_wrap!(x); + | ^ not found in `blah` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/diagnostic_namespace/opaque/only_point_at_input.rs b/tests/ui/diagnostic_namespace/opaque/only_point_at_input.rs new file mode 100644 index 0000000000000..003b6dbacf6c0 --- /dev/null +++ b/tests/ui/diagnostic_namespace/opaque/only_point_at_input.rs @@ -0,0 +1,23 @@ +//@revisions: default -Zmacro-backtrace +//@[-Zmacro-backtrace] compile-flags: -Z macro-backtrace +//@ aux-crate:wrap=wrap.rs +#![feature(diagnostic_opaque)] + +mod blah {} + +#[diagnostic::opaque] +macro_rules! local_wrap { + ($x:ident) => {{ + let x = blah::$x; + }}; +} + + +fn main() { + wrap::wrap!(x); + //~^ ERROR cannot find value `x` in module `blah` + + local_wrap!(x); + //~^ ERROR cannot find value `x` in module `blah` + +} diff --git a/tests/ui/feature-gates/feature-gate-diagnostic-opaque.rs b/tests/ui/feature-gates/feature-gate-diagnostic-opaque.rs new file mode 100644 index 0000000000000..0dc3a4569098f --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-diagnostic-opaque.rs @@ -0,0 +1,13 @@ +#![crate_type = "lib"] +#![feature(decl_macro)] +#![deny(unknown_diagnostic_attributes)] + +#[diagnostic::opaque] +//~^ ERROR unknown diagnostic attribute +macro_rules! foo { + () => {} +} + +#[diagnostic::opaque] +//~^ ERROR unknown diagnostic attribute +macro bar() {} diff --git a/tests/ui/feature-gates/feature-gate-diagnostic-opaque.stderr b/tests/ui/feature-gates/feature-gate-diagnostic-opaque.stderr new file mode 100644 index 0000000000000..90426a1324e81 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-diagnostic-opaque.stderr @@ -0,0 +1,23 @@ +error: unknown diagnostic attribute + --> $DIR/feature-gate-diagnostic-opaque.rs:5:15 + | +LL | #[diagnostic::opaque] + | ^^^^^^ + | + = help: add `#![feature(diagnostic_opaque)]` to the crate attributes to enable +note: the lint level is defined here + --> $DIR/feature-gate-diagnostic-opaque.rs:3:9 + | +LL | #![deny(unknown_diagnostic_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unknown diagnostic attribute + --> $DIR/feature-gate-diagnostic-opaque.rs:11:15 + | +LL | #[diagnostic::opaque] + | ^^^^^^ + | + = help: add `#![feature(diagnostic_opaque)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + diff --git a/tests/ui/include-macros/mismatched-types.stderr b/tests/ui/include-macros/mismatched-types.stderr index 4fab832c2d8e8..ab6b599c2beda 100644 --- a/tests/ui/include-macros/mismatched-types.stderr +++ b/tests/ui/include-macros/mismatched-types.stderr @@ -1,13 +1,8 @@ error[E0308]: mismatched types - --> $DIR/file.txt:0:1 - | -LL | - | ^ expected `&[u8]`, found `&str` - | - ::: $DIR/mismatched-types.rs:2:12 + --> $DIR/mismatched-types.rs:2:20 | LL | let b: &[u8] = include_str!("file.txt"); - | ----- ------------------------ in this macro invocation + | ----- ^^^^^^^^^^^^^^^^^^^^^^^^ expected `&[u8]`, found `&str` | | | expected due to this | diff --git a/tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.stderr b/tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.stderr index 5ce69e1a14d83..e5db09a670cc9 100644 --- a/tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.stderr +++ b/tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.stderr @@ -5,7 +5,6 @@ LL | let _lock = unsafe { MACRO_MUTEX.lock().unwrap() }; | ^^^^^^^^^^^^^^^^^^ shared reference to mutable static | = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[deny(static_mut_refs)]` (part of `#[deny(rust_2024_compatibility)]`) on by default diff --git a/tests/ui/lint/static-mut-refs-interior-mutability.stderr b/tests/ui/lint/static-mut-refs-interior-mutability.stderr index 29ab5a5c404de..d6a644374d8a2 100644 --- a/tests/ui/lint/static-mut-refs-interior-mutability.stderr +++ b/tests/ui/lint/static-mut-refs-interior-mutability.stderr @@ -7,7 +7,7 @@ LL | let _lock = unsafe { STDINOUT_MUTEX.lock().unwrap() }; = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives = note: for more information, see = note: `#[deny(static_mut_refs)]` (part of `#[deny(rust_2024_compatibility)]`) on by default -help: this type already provides "interior mutability", so its binding doesn't need to be declared as mutable +help: this type already provides "interior mutability", so its binding doesn't need to be declared as mutable when borrowed with a shared reference | LL - static mut STDINOUT_MUTEX: Mutex = Mutex::new(false); LL + static STDINOUT_MUTEX: Mutex = Mutex::new(false); diff --git a/tests/ui/lint/static-mut-refs.e2021.stderr b/tests/ui/lint/static-mut-refs.e2021.stderr index 56b4ad239afe3..e616ba0aa4b28 100644 --- a/tests/ui/lint/static-mut-refs.e2021.stderr +++ b/tests/ui/lint/static-mut-refs.e2021.stderr @@ -32,6 +32,7 @@ LL | let ref _a = X; | ^ shared reference to mutable static | = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see warning: creating a shared reference to mutable static @@ -80,6 +81,7 @@ LL | let _ = Z.len(); | ^^^^^^^ shared reference to mutable static | = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see warning: creating a shared reference to mutable static @@ -89,6 +91,7 @@ LL | let _ = format!("{:?}", Z); | ^ shared reference to mutable static | = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see warning: creating a shared reference to mutable static @@ -124,6 +127,7 @@ LL | let ref _v = A.value; | ^^^^^^^ shared reference to mutable static | = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see warning: creating a mutable reference to mutable static @@ -136,6 +140,7 @@ LL | let _x = bar!(FOO); | --------- in this macro invocation | = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: this warning originates in the macro `bar` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/lint/static-mut-refs.e2024.stderr b/tests/ui/lint/static-mut-refs.e2024.stderr index 0b7f48a507c94..a8985fc8a1763 100644 --- a/tests/ui/lint/static-mut-refs.e2024.stderr +++ b/tests/ui/lint/static-mut-refs.e2024.stderr @@ -32,6 +32,7 @@ LL | let ref _a = X; | ^ shared reference to mutable static | = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see error: creating a shared reference to mutable static @@ -80,6 +81,7 @@ LL | let _ = Z.len(); | ^^^^^^^ shared reference to mutable static | = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see error: creating a shared reference to mutable static @@ -89,6 +91,7 @@ LL | let _ = format!("{:?}", Z); | ^ shared reference to mutable static | = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see error: creating a shared reference to mutable static @@ -124,6 +127,7 @@ LL | let ref _v = A.value; | ^^^^^^^ shared reference to mutable static | = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see error: creating a mutable reference to mutable static @@ -136,6 +140,7 @@ LL | let _x = bar!(FOO); | --------- in this macro invocation | = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: this error originates in the macro `bar` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/statics/static-lazy-init-with-arena-set.stderr b/tests/ui/statics/static-lazy-init-with-arena-set.stderr index 43b244607885d..4aed8b06166c8 100644 --- a/tests/ui/statics/static-lazy-init-with-arena-set.stderr +++ b/tests/ui/statics/static-lazy-init-with-arena-set.stderr @@ -12,7 +12,7 @@ LL | | }); = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives = note: for more information, see = note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default -help: this type already provides "interior mutability", so its binding doesn't need to be declared as mutable +help: this type already provides "interior mutability", so its binding doesn't need to be declared as mutable when borrowed with a shared reference | LL - static mut ONCE: Once = Once::new(); LL + static ONCE: Once = Once::new(); diff --git a/tests/ui/statics/static-mut-xc.stderr b/tests/ui/statics/static-mut-xc.stderr index d0b30ce6f8514..f8fa25e152f67 100644 --- a/tests/ui/statics/static-mut-xc.stderr +++ b/tests/ui/statics/static-mut-xc.stderr @@ -5,6 +5,7 @@ LL | assert_eq!(static_mut_xc::a, 3); | ^^^^^^^^^^^^^^^^ shared reference to mutable static | = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default @@ -15,6 +16,7 @@ LL | assert_eq!(static_mut_xc::a, 4); | ^^^^^^^^^^^^^^^^ shared reference to mutable static | = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see warning: creating a shared reference to mutable static @@ -24,6 +26,7 @@ LL | assert_eq!(static_mut_xc::a, 5); | ^^^^^^^^^^^^^^^^ shared reference to mutable static | = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see warning: creating a shared reference to mutable static @@ -33,6 +36,7 @@ LL | assert_eq!(static_mut_xc::a, 15); | ^^^^^^^^^^^^^^^^ shared reference to mutable static | = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see warning: creating a shared reference to mutable static @@ -42,6 +46,7 @@ LL | assert_eq!(static_mut_xc::a, -3); | ^^^^^^^^^^^^^^^^ shared reference to mutable static | = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see warning: creating a shared reference to mutable static diff --git a/tests/ui/statics/static-recursive.stderr b/tests/ui/statics/static-recursive.stderr index 1ae96dfd5a832..9578808ec7b03 100644 --- a/tests/ui/statics/static-recursive.stderr +++ b/tests/ui/statics/static-recursive.stderr @@ -19,6 +19,7 @@ LL | assert_eq!(S, *(S as *const *const u8)); | ^ shared reference to mutable static | = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see warning: 2 warnings emitted diff --git a/triagebot.toml b/triagebot.toml index 9fd7bad75160f..e817e99ddf375 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -779,8 +779,8 @@ PR #{number} "{title}" fixes a regression and has been nominated for backport. This topic will help T-compiler getting context about it. Tip: to approve or decline from this Zulip thread, use: -@_**triagebot** backport approve beta #{number} -@_**triagebot** backport decline beta #{number} +@_**triagebot** backport approve +@_**triagebot** backport decline """, """\ /poll Should #{number} be beta backported? @@ -809,8 +809,8 @@ PR #{number} "{title}" fixes a regression and has been nominated for backport. This topic will help T-compiler getting context about it. Tip: to approve or decline from this Zulip thread, use: -@_**triagebot** backport approve stable #{number} -@_**triagebot** backport decline stable #{number} +@_**triagebot** backport approve +@_**triagebot** backport decline """, """\ /poll Approve stable backport of #{number}?