diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index d496c397395e9..a36e7f3248dd0 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3514,7 +3514,7 @@ pub enum SyntheticAttr { /// because they are not needed. /// /// The attribute is used by some clippy lints. - CfgAttrTrace, + CfgAttrTrace(CfgEntry), } impl AttrItem { diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 39c4f403bf855..40a1b4bd32218 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -106,7 +106,7 @@ impl AttributeExt for Attribute { use SyntheticAttr::*; match &self.kind { AttrKind::Normal(normal) => normal.item.name(), - AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace) => None, + AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) => None, AttrKind::DocComment(..) => None, } } @@ -117,7 +117,7 @@ impl AttributeExt for Attribute { AttrKind::Normal(normal) => { Some(normal.item.path.segments.iter().map(|i| i.ident.name).collect()) } - AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace) => None, + AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) => None, AttrKind::DocComment(_, _) => None, } } diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index fe1da820cf74f..1276aa8f4fb96 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -525,7 +525,7 @@ impl<'a> AstValidator<'a> { [sym::allow, sym::deny, sym::expect, sym::forbid, sym::splat, sym::warn]; !attr.has_any_name(&arr) && rustc_attr_parsing::is_builtin_attr(&normal.item) } - AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace) => false, + AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) => false, AttrKind::DocComment(..) => true, }) .for_each(|attr| { @@ -1202,6 +1202,48 @@ impl<'a> AstValidator<'a> { self.visit_vis(vis); self.visit_ident(ident); } + + // Check EII implementation attributes against an allowlist. + fn check_eii_impl_attrs(&self, attrs: &[Attribute], eii_impls: &[EiiImpl]) { + if eii_impls.is_empty() { + return; + } + + let allowed_attrs: &[Symbol] = &[ + sym::allow, + sym::warn, + sym::deny, + sym::forbid, + sym::expect, + sym::doc, + sym::inline, + sym::cold, + sym::optimize, + sym::coverage, + sym::sanitize, + sym::must_use, + sym::deprecated, + ]; + + for attr in attrs { + let AttrKind::Normal(normal) = &attr.kind else { + continue; + }; + if attr.has_any_name(allowed_attrs) { + continue; + } + + let attr_name = pprust::path_to_string(&normal.item.path); + for eii_impl in eii_impls { + self.dcx().emit_err(diagnostics::EiiImplAttributeNotSupported { + attr_span: attr.span, + attr_name: &attr_name, + eii_span: eii_impl.span, + eii_name: pprust::path_to_string(&eii_impl.eii_macro_path), + }); + } + } + } } /// Checks that generic parameters are in the correct order, @@ -1391,6 +1433,7 @@ impl Visitor<'_> for AstValidator<'_> { for EiiImpl { eii_macro_path, .. } in eii_impls { self.visit_path(eii_macro_path); } + self.check_eii_impl_attrs(&item.attrs, eii_impls); let is_intrinsic = item.attrs.iter().any(|a| a.has_name(sym::rustc_intrinsic)); if body.is_none() && !is_intrinsic && !self.is_sdylib_interface { @@ -1566,8 +1609,9 @@ impl Visitor<'_> for AstValidator<'_> { visit::walk_item(self, item); } - ItemKind::Static(StaticItem { expr, safety, .. }) => { + ItemKind::Static(StaticItem { expr, safety, eii_impls, .. }) => { self.check_item_safety(item.span, *safety); + self.check_eii_impl_attrs(&item.attrs, eii_impls); if matches!(safety, Safety::Unsafe(_)) { self.dcx().emit_err(diagnostics::UnsafeStatic { span: item.span }); } diff --git a/compiler/rustc_ast_passes/src/diagnostics.rs b/compiler/rustc_ast_passes/src/diagnostics.rs index 0cf7ef5c1de19..5bcffe96f6086 100644 --- a/compiler/rustc_ast_passes/src/diagnostics.rs +++ b/compiler/rustc_ast_passes/src/diagnostics.rs @@ -189,6 +189,17 @@ pub(crate) struct FnParamForbiddenAttr { pub span: Span, } +#[derive(Diagnostic)] +#[diag("`#[{$eii_name}]` is not allowed to have `#[{$attr_name}]`")] +pub(crate) struct EiiImplAttributeNotSupported<'a> { + #[primary_span] + pub attr_span: Span, + pub attr_name: &'a str, + pub eii_name: String, + #[label("`#[{$eii_name}]` is not allowed to have `#[{$attr_name}]`")] + pub eii_span: Span, +} + #[derive(Diagnostic)] #[diag("`self` parameter is only allowed in associated functions")] #[note("associated functions are those in `impl` or `trait` definitions")] diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 42d01a92eebbf..3b0c90264e32d 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -665,7 +665,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere fn print_attribute_inline(&mut self, attr: &ast::Attribute, is_inline: bool) -> bool { use ast::SyntheticAttr::*; match attr.kind { - AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace) => { + AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) => { // These are internal synthetic attributes with no syntax, so avoid printing them // to keep the printed code reasonably parse-able. return false; diff --git a/compiler/rustc_attr_parsing/src/synthetic.rs b/compiler/rustc_attr_parsing/src/synthetic.rs index 5e633e6ee3685..290730aaee132 100644 --- a/compiler/rustc_attr_parsing/src/synthetic.rs +++ b/compiler/rustc_attr_parsing/src/synthetic.rs @@ -15,9 +15,7 @@ pub(crate) struct SyntheticAttrState { cfg_trace: ThinVec<(CfgEntry, Span)>, /// Attribute state for `SyntheticAttr::CfgAttrTrace` attributes. - /// The arguments of these attributes is no longer relevant for any later passes, only their - /// presence. So we discard the arguments here. - cfg_attr_trace: bool, + cfg_attr_trace: ThinVec<(CfgEntry, Span)>, } impl SyntheticAttrState { @@ -33,8 +31,10 @@ impl SyntheticAttrState { cfg.lower_spans(lower_span); self.cfg_trace.push((cfg, attr_span)); } - SyntheticAttr::CfgAttrTrace => { - self.cfg_attr_trace = true; + SyntheticAttr::CfgAttrTrace(cfg) => { + let mut cfg = cfg.clone(); + cfg.lower_spans(lower_span); + self.cfg_attr_trace.push((cfg, attr_span)); } } } @@ -43,8 +43,8 @@ impl SyntheticAttrState { if !self.cfg_trace.is_empty() { attributes.push(Attribute::Parsed(AttributeKind::CfgTrace(self.cfg_trace))); } - if self.cfg_attr_trace { - attributes.push(Attribute::Parsed(AttributeKind::CfgAttrTrace)); + if !self.cfg_attr_trace.is_empty() { + attributes.push(Attribute::Parsed(AttributeKind::CfgAttrTrace(self.cfg_attr_trace))); } } } diff --git a/compiler/rustc_attr_parsing/src/validate_attr.rs b/compiler/rustc_attr_parsing/src/validate_attr.rs index 90380c08fdba1..08c73352f27eb 100644 --- a/compiler/rustc_attr_parsing/src/validate_attr.rs +++ b/compiler/rustc_attr_parsing/src/validate_attr.rs @@ -24,7 +24,7 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) { use ast::SyntheticAttr::*; match &attr.kind { AttrKind::Normal(_) => {} - AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace) | AttrKind::DocComment(..) => return, + AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) | AttrKind::DocComment(..) => return, } let builtin_attr_info = attr.name().and_then(|name| BUILTIN_ATTRIBUTE_MAP.get(&name)); diff --git a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh index c2b0e37a8eca7..ab31c43fb1b12 100644 --- a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh +++ b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh @@ -62,19 +62,6 @@ index 2e16f2cf27..3ac3df99a8 100644 # Add RUSTFLAGS_BOOTSTRAP to RUSTFLAGS for bootstrap compilation. # Note that RUSTFLAGS_BOOTSTRAP should always be added to the end of # RUSTFLAGS, since that causes RUSTFLAGS_BOOTSTRAP to override RUSTFLAGS. -diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs -index 6de70c7d70c..d5035b581ce 100644 ---- a/src/bootstrap/src/core/builder/cargo.rs -+++ b/src/bootstrap/src/core/builder/cargo.rs -@@ -1197,7 +1197,7 @@ fn cargo( - cargo.env("RUSTC_BOOTSTRAP", "1"); - - if matches!(mode, Mode::Std) { -- cargo.arg("-Zno-embed-metadata"); -+ cargo.arg("-Zembed-metadata=no"); - } - - if self.config.dump_bootstrap_shims { diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index bc68bfe396..00143ef3ed 100644 --- a/src/bootstrap/src/core/config/config.rs diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 105093e37b237..0a9af492b1f45 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -884,9 +884,9 @@ fn is_msvc_link_exe(sess: &Session) -> bool { && linker_path.to_str() == Some("link.exe") } -fn is_macos_ld(sess: &Session) -> bool { +fn is_macos_linker(sess: &Session) -> bool { let (_, flavor) = linker_and_flavor(sess); - sess.target.is_like_darwin && matches!(flavor, LinkerFlavor::Darwin(_, Lld::No)) + sess.target.is_like_darwin && matches!(flavor, LinkerFlavor::Darwin(..)) } fn is_windows_gnu_ld(sess: &Session) -> bool { @@ -953,8 +953,8 @@ fn report_linker_output( *output += "\r\n" } }); - } else if is_macos_ld(sess) { - info!("inferred macOS LD"); + } else if is_macos_linker(sess) { + info!("inferred macOS linker"); // FIXME: Tracked by https://github.com/rust-lang/rust/issues/136113 let deployment_mismatch = |line: &str| { @@ -967,6 +967,8 @@ fn report_linker_output( && line.contains("building for") && line.contains("but linking with") && line.contains("which was built for newer version")) + // lld (ld64.lld / rust-lld): + || line.contains("which is newer than target minimum of") }; // FIXME: This is a real warning we would like to show, but it hits too many crates // to want to turn it on immediately. diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 030fa96a9fa68..29f78ff5769a5 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -2,6 +2,7 @@ use std::iter; +use rustc_ast::attr::data_structures::CfgEntry; use rustc_ast::token::{Delimiter, Token, TokenKind}; use rustc_ast::tokenstream::{ AttrTokenStream, AttrTokenTree, LazyAttrTokenStream, Spacing, TokenTree, WithTokens, @@ -248,16 +249,15 @@ impl<'a> StripUnconfigured<'a> { /// is in the original source file. Gives a compiler error if the syntax of /// the attribute is incorrect. pub(crate) fn expand_cfg_attr(&self, cfg_attr: &Attribute, recursive: bool) -> Vec { - // A synthetic trace attribute left in AST in place of the original `cfg_attr` attribute. - // It can later be used by lints or other diagnostics. - let trace_attr = cfg_attr.clone().convert_normal_to_synthetic(SyntheticAttr::CfgAttrTrace); - let Some((cfg_predicate, expanded_attrs)) = rustc_attr_parsing::parse_cfg_attr( cfg_attr, self.sess, self.features, self.lint_node_id, ) else { + let trace_attr = cfg_attr.clone().convert_normal_to_synthetic( + SyntheticAttr::CfgAttrTrace(CfgEntry::Bool(true, cfg_attr.span)), + ); return vec![trace_attr]; }; @@ -271,7 +271,15 @@ impl<'a> StripUnconfigured<'a> { ); } - if !attr::eval_config_entry(self.sess, &cfg_predicate).as_bool() { + let cfg_eval = attr::eval_config_entry(self.sess, &cfg_predicate).as_bool(); + + // A synthetic trace attribute left in AST in place of the original `cfg_attr` attribute. + // It can later be used by lints or other diagnostics. + let trace_attr = cfg_attr + .clone() + .convert_normal_to_synthetic(SyntheticAttr::CfgAttrTrace(cfg_predicate)); + + if !cfg_eval { return vec![trace_attr]; } diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 8b897aa3c5f96..dacd7c47e91e7 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -2276,7 +2276,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { ); } AttrKind::Normal(_) => {} - AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace) => {} + AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) => {} AttrKind::DocComment(..) => unreachable!(), // handled above } } diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index bbec92786f047..db492475a3aa4 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1011,7 +1011,7 @@ pub enum AttributeKind { AutomaticallyDerived, /// Represents the trace attribute of `#[cfg_attr]` - CfgAttrTrace, + CfgAttrTrace(ThinVec<(CfgEntry, Span)>), /// Represents the trace attribute of `#[cfg]` CfgTrace(ThinVec<(CfgEntry, Span)>), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index f703aebdbc6f1..1e634513fdce2 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -21,7 +21,7 @@ impl AttributeKind { AllowInternalUnsafe(..) => Yes, AllowInternalUnstable(..) => Yes, AutomaticallyDerived => Yes, - CfgAttrTrace => Yes, + CfgAttrTrace(..) => Yes, CfgTrace(..) => Yes, CfiEncoding { .. } => Yes, Cold => No, diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 9d1cf7046f4b0..1481cb0726082 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use rustc_ast as ast; use rustc_ast::NodeId; -use rustc_data_structures::unord::UnordMap; +use rustc_data_structures::fx::FxIndexMap; use rustc_error_messages::{DiagArgValue, IntoDiagArg}; use rustc_macros::{Decodable, Encodable, StableHash}; use rustc_span::Symbol; @@ -962,4 +962,6 @@ pub enum LifetimeRes { ElidedAnchor { start: NodeId, end: NodeId }, } -pub type DocLinkResMap = UnordMap<(Symbol, Namespace), Option>>; +// FxIndexMap is necessary because its data ends up in .rmeta files, +// so its iteration order must be consistent. See #159677 for context. +pub type DocLinkResMap = FxIndexMap<(Symbol, Namespace), Option>>; diff --git a/compiler/rustc_next_trait_solver/src/placeholder.rs b/compiler/rustc_next_trait_solver/src/placeholder.rs index 04247a17edcca..83b2eb6ac6295 100644 --- a/compiler/rustc_next_trait_solver/src/placeholder.rs +++ b/compiler/rustc_next_trait_solver/src/placeholder.rs @@ -47,6 +47,7 @@ where IndexMap, ty::BoundTy>, IndexMap, ty::BoundConst>, ) { + let old_universes = universe_indices.clone(); let mut replacer = BoundVarReplacer { infcx, mapped_regions: Default::default(), @@ -57,8 +58,29 @@ where }; let value = value.fold_with(&mut replacer); + let BoundVarReplacer { + mapped_regions, + mapped_types, + mapped_consts, + universe_indices, + infcx: _, + current_index: _, + } = replacer; + + if infcx.cx().assumptions_on_binders() { + for (old, new) in old_universes.into_iter().zip(universe_indices.iter()) { + if let (None, Some(new)) = (old, new) { + // FIXME(-Zassumptions-on-binders): `replace_bound_vars` does not have enough + // context to compute placeholder assumptions for the binders it enters. + infcx.insert_placeholder_assumptions( + *new, + Some(rustc_type_ir::region_constraint::Assumptions::empty()), + ); + } + } + } - (value, replacer.mapped_regions, replacer.mapped_types, replacer.mapped_consts) + (value, mapped_regions, mapped_types, mapped_consts) } fn universe_for(&mut self, debruijn: ty::DebruijnIndex) -> ty::UniverseIndex { diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 1a30d5f1e79a0..4f7c76e7df816 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -987,7 +987,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { let lo = start + BytePos(possible_offset); let hi = lo + BytePos(found_terminators); let span = self.mk_sp(lo, hi); - err.span_suggestion( + err.span_suggestion_verbose( span, "consider terminating the string here", "#".repeat(n_hashes as usize), diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index 54c8f3c09ec48..9176192c95640 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -162,7 +162,7 @@ pub(crate) fn emit_unescape_error( ); } else { if mode == Mode::Str || mode == Mode::Char { - diag.span_suggestion( + diag.span_suggestion_verbose( full_lit_span, "if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal", format!("r\"{lit}\""), @@ -204,7 +204,7 @@ pub(crate) fn emit_unescape_error( // Note: the \\xHH suggestions are not given for raw byte string // literals, because they are araw and so cannot use any escapes. if (c as u32) <= 0xFF && mode != Mode::RawByteStr { - err.span_suggestion( + err.span_suggestion_verbose( span, format!( "if you meant to use the unicode code point for {c:?}, use a \\xHH escape" @@ -217,7 +217,7 @@ pub(crate) fn emit_unescape_error( } else if mode != Mode::RawByteStr { let mut utf8 = String::new(); utf8.push(c); - err.span_suggestion( + err.span_suggestion_verbose( span, format!("if you meant to use the UTF-8 encoding of {c:?}, use \\xHH escapes"), utf8.as_bytes() @@ -313,7 +313,7 @@ fn foreign_escape_suggestion( err_span: Span, ) { if escaped_char == "?" { - diag.span_suggestion( + diag.span_suggestion_verbose( err_span, "if you meant to write a literal question mark, don't escape the character", "?", @@ -336,7 +336,7 @@ fn foreign_escape_suggestion( _ => return, }; - diag.span_suggestion( + diag.span_suggestion_verbose( escape_span, format!("if you meant to write {name}, use a hex escape"), format!("x{hex}"), diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index e5be778458135..3064c0b22592d 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -597,7 +597,7 @@ impl<'a> Parser<'a> { .iter() .any(|tok| matches!(tok, TokenType::FatArrow | TokenType::CloseBrace)) { - err.span_suggestion( + err.span_suggestion_verbose( self.token.span, "you might have meant to write a \"greater than or equal to\" comparison", ">=", @@ -942,7 +942,7 @@ impl<'a> Parser<'a> { count += 1; } err.span(span); - err.span_suggestion( + err.span_suggestion_verbose( span, format!("remove the extra `#`{}", pluralize!(count)), "", @@ -2062,7 +2062,15 @@ impl<'a> Parser<'a> { Applicability::MachineApplicable, ); } - err.span_suggestion(lo.shrink_to_lo(), format!("{prefix}you can still access the deprecated `try!()` macro using the \"raw identifier\" syntax"), "r#", Applicability::MachineApplicable); + err.span_suggestion_verbose( + lo.shrink_to_lo(), + format!( + "{prefix}you can still access the deprecated `try!()` macro using the \ + \"raw identifier\" syntax" + ), + "r#", + Applicability::MachineApplicable, + ); let guar = err.emit(); Ok(self.mk_expr_err(lo.to(hi), guar)) } else { @@ -2243,7 +2251,7 @@ impl<'a> Parser<'a> { let ident = self.parse_ident_common(true).unwrap(); let span = pat.span.with_hi(ident.span.hi()); - err.span_suggestion( + err.span_suggestion_verbose( span, "declare the type after the parameter binding", ": ", @@ -2641,7 +2649,7 @@ impl<'a> Parser<'a> { Ok((expr, _)) => { // Find a mistake like `MyTrait`. if snapshot.token == token::EqEq { - err.span_suggestion( + err.span_suggestion_verbose( snapshot.token.span, "if you meant to use an associated type binding, replace `==` with `=`", "=", @@ -2655,7 +2663,7 @@ impl<'a> Parser<'a> { && matches!(expr.kind, ExprKind::Path(..)) { // Find a mistake like "foo::var:A". - err.span_suggestion( + err.span_suggestion_verbose( snapshot.token.span, "write a path separator here", "::", @@ -2938,7 +2946,7 @@ impl<'a> Parser<'a> { Applicability::MachineApplicable, ); if let CommaRecoveryMode::EitherTupleOrPipe = rt { - err.span_suggestion( + err.span_suggestion_verbose( comma_span, "...or a vertical bar to match on alternatives", " |", @@ -2975,7 +2983,7 @@ impl<'a> Parser<'a> { && (self.expected_token_types.contains(TokenType::Gt) || matches!(self.token.kind, token::Literal(..))) { - err.span_suggestion( + err.span_suggestion_verbose( maybe_lt.span, "remove the `<` to write an exclusive range", "", diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index c5757f36b2e6a..9798138b48b80 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1697,7 +1697,12 @@ impl<'a> Parser<'a> { // directly adjacent (i.e. '=<') if maybe_eq_tok == TokenKind::Eq && maybe_eq_tok.span.hi() == lt_span.lo() { let eq_lt = maybe_eq_tok.span.to(lt_span); - err.span_suggestion(eq_lt, "did you mean", "<=", Applicability::Unspecified); + err.span_suggestion_verbose( + eq_lt, + "you might have meant to write a \"less than or equal to\" comparison", + "<=", + Applicability::Unspecified, + ); } err })?; @@ -2752,7 +2757,7 @@ impl<'a> Parser<'a> { && let maybe_let = self.look_ahead(1, |t| t.clone()) && maybe_let.is_keyword(kw::Let) { - err.span_suggestion( + err.span_suggestion_verbose( self.prev_token.span, "consider removing this semicolon to parse the `let` as part of the same chain", "", @@ -2764,7 +2769,7 @@ impl<'a> Parser<'a> { } else { // Look for usages of '=>' where '>=' might be intended if maybe_fatarrow == token::FatArrow { - err.span_suggestion( + err.span_suggestion_verbose( maybe_fatarrow.span, "you might have meant to write a \"greater than or equal to\" comparison", ">=", @@ -3378,7 +3383,7 @@ impl<'a> Parser<'a> { if let Err(mut err) = this.expect(exp!(FatArrow)) { // We might have a `=>` -> `=` or `->` typo (issue #89396). if is_almost_fat_arrow { - err.span_suggestion( + err.span_suggestion_verbose( this.token.span, "use a fat arrow to start a match arm", "=>", diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index ceaed5833ec33..1b06c80f83687 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -603,7 +603,7 @@ impl<'a> Parser<'a> { && let [segment] = path.segments.as_slice() && edit_distance("macro_rules", &segment.ident.to_string(), 2).is_some() { - err.span_suggestion( + err.span_suggestion_verbose( path.span, "perhaps you meant to define a macro", "macro_rules", @@ -628,13 +628,16 @@ impl<'a> Parser<'a> { let mut err = self.dcx().struct_span_err(end.span, msg); if end.is_doc_comment() { err.span_label(end.span, "this doc comment doesn't document anything"); - } else if self.token == TokenKind::Semi { - err.span_suggestion_verbose( - self.token.span, - "consider removing this semicolon", - "", - Applicability::MaybeIncorrect, - ); + } else { + err.span_label(end.span, "expected an item after this"); + if self.token == TokenKind::Semi { + err.span_suggestion_verbose( + self.token.span, + "remove the semicolon after the attribute", + "", + Applicability::MaybeIncorrect, + ); + } } if let [.., penultimate, _] = attrs { err.span_label(start.span.to(penultimate.span), "other attributes here"); @@ -2435,16 +2438,19 @@ impl<'a> Parser<'a> { &inherited_vis, Case::Insensitive, ) { - Ok(_) => { - self.dcx().struct_span_err( + Ok(_) => self + .dcx() + .struct_span_err( lo.to(self.prev_token.span), format!("functions are not allowed in {adt_ty} definitions"), ) .with_help( "unlike in C++, Java, and C#, functions are declared in `impl` blocks", ) - .with_help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information") - } + .with_help( + "see https://doc.rust-lang.org/book/ch05-03-method-syntax.html \ + for more information", + ), Err(err) => { err.cancel(); self.restore_snapshot(snapshot); @@ -2480,14 +2486,17 @@ impl<'a> Parser<'a> { .map_err(|err| err.cancel()) && self.token == TokenKind::Colon { - err.span_suggestion( + err.span_suggestion_verbose( removal_span, - "remove this `let` keyword", + "remove the `let` keyword", String::new(), Applicability::MachineApplicable, ); err.note("the `let` keyword is not allowed in `struct` fields"); - err.note("see for more information"); + err.note( + "see \ + for more information", + ); err.emit(); return Ok(ident); } else { @@ -2638,7 +2647,7 @@ impl<'a> Parser<'a> { vec![(open, "{".to_string()), (close, '}'.to_string())], Applicability::MaybeIncorrect, ); - err.span_suggestion( + err.span_suggestion_verbose( span.with_neighbor(self.token.span).shrink_to_hi(), "add a semicolon", ';', @@ -3254,7 +3263,7 @@ impl<'a> Parser<'a> { .span_to_snippet(original_sp) .expect("Span extracted directly from keyword should always work"); - err.span_suggestion( + err.span_suggestion_verbose( self.token_uninterpolated_span(), format!("`{original_kw}` already used earlier, remove this one"), "", @@ -3269,7 +3278,7 @@ impl<'a> Parser<'a> { let misplaced_qual_sp = self.token_uninterpolated_span(); let misplaced_qual = self.span_to_snippet(misplaced_qual_sp).unwrap(); - err.span_suggestion( + err.span_suggestion_verbose( correct_pos_sp.to(misplaced_qual_sp), format!("`{misplaced_qual}` must come before `{current_qual}`"), format!("{misplaced_qual} {current_qual}"), @@ -3293,7 +3302,7 @@ impl<'a> Parser<'a> { // There was no explicit visibility if matches!(orig_vis.kind, VisibilityKind::Inherited) { - err.span_suggestion( + err.span_suggestion_verbose( sp_start.to(self.prev_token.span), format!("visibility `{vs}` must come before `{snippet}`"), format!("{vs} {snippet}"), @@ -3302,7 +3311,7 @@ impl<'a> Parser<'a> { } // There was an explicit visibility else { - err.span_suggestion( + err.span_suggestion_verbose( current_vis.span, "there is already a visibility modifier, remove one", "", diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index a3be28e96db3b..fc539405249a6 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1802,7 +1802,7 @@ impl<'a> Parser<'a> { format!("the {kind_desc} was parsed as having {op_desc} binary expression"), ); - err.span_suggestion( + err.span_suggestion_verbose( lhs_end_span, format!("you may have meant to write a `;` to terminate the {kind_desc} earlier"), ";", diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 2dfcbccfe60ec..8ed2734b7de9c 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -817,13 +817,13 @@ impl<'a> Parser<'a> { .dcx() .struct_span_err(after_eq.to(before_next), "missing type to the right of `=`"); if matches!(self.token.kind, token::Comma | token::Gt) { - err.span_suggestion( + err.span_suggestion_verbose( self.psess.source_map().next_point(eq_span).to(before_next), "to constrain the associated type, add a type after `=`", " TheType", Applicability::HasPlaceholders, ); - err.span_suggestion( + err.span_suggestion_verbose( prev_token_span.shrink_to_hi().to(before_next), format!("remove the `=` if `{ident}` is a type"), "", diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 032cbcbc1e794..f9b508476689e 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -237,7 +237,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // All of the following attributes have no specific checks. // tidy-alphabetical-start AttributeKind::AutomaticallyDerived => (), - AttributeKind::CfgAttrTrace => (), + AttributeKind::CfgAttrTrace(..) => (), AttributeKind::CfgTrace(..) => (), AttributeKind::CfiEncoding { .. } => (), AttributeKind::Cold => (), @@ -781,22 +781,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { sig_span: sig.span, }); } - - if let Some(impls) = find_attr!(attrs, EiiImpls(impls) => impls) { - let sig = self.tcx.hir_node(hir_id).fn_sig().unwrap(); - for i in impls { - let name = match i.resolution { - EiiImplResolution::Macro(def_id) => self.tcx.item_name(def_id), - EiiImplResolution::Known(def_id) => self.tcx.item_name(def_id), - EiiImplResolution::Error(_eg) => continue, - }; - self.dcx().emit_err(diagnostics::EiiWithTrackCaller { - attr_span, - name, - sig_span: sig.span, - }); - } - } } _ => {} } diff --git a/compiler/rustc_passes/src/diagnostics.rs b/compiler/rustc_passes/src/diagnostics.rs index bd58ea7142e5b..34fa0b264319d 100644 --- a/compiler/rustc_passes/src/diagnostics.rs +++ b/compiler/rustc_passes/src/diagnostics.rs @@ -1082,16 +1082,6 @@ pub(crate) struct EiiImplRequiresUnsafeSuggestion { pub right: Span, } -#[derive(Diagnostic)] -#[diag("`#[{$name}]` is not allowed to have `#[track_caller]`")] -pub(crate) struct EiiWithTrackCaller { - #[primary_span] - pub attr_span: Span, - pub name: Symbol, - #[label("`#[{$name}]` is not allowed to have `#[track_caller]`")] - pub sig_span: Span, -} - #[derive(Diagnostic)] #[diag("`#[{$name}]` {$kind} required, but not found")] pub(crate) struct EiiWithoutImpl { diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 1ef2414b0af49..0b54b265fcee7 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -565,7 +565,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { .push((normal.item.path.segments[0].ident, self.parent_scope)); } } - AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace) => {} + AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) => {} AttrKind::DocComment(..) => {} } visit::walk_attribute(self, attr); diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs index 8ed4e09adbbfe..088d4821042d8 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { metadata: TargetMetadata { description: Some("RISC-V Linux (kernel 4.20, musl 1.2.5)".into()), tier: Some(2), - host_tools: Some(false), + host_tools: Some(true), std: Some(true), }, pointer_width: 64, diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 4ee41bc807243..58996703023ce 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -246,7 +246,8 @@ pub struct Box< #[rustc_no_mir_inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[cfg(not(no_global_oom_handling))] -fn box_new_uninit(layout: Layout) -> *mut u8 { +#[rustc_const_unstable(feature = "const_heap", issue = "79597")] +const fn box_new_uninit(layout: Layout) -> *mut u8 { match Global.allocate(layout) { Ok(ptr) => ptr.as_mut_ptr(), Err(_) => handle_alloc_error(layout), @@ -258,10 +259,11 @@ fn box_new_uninit(layout: Layout) -> *mut u8 { /// This is unsafe, but has to be marked as safe or else we couldn't use it in `vec!`. #[doc(hidden)] #[unstable(feature = "liballoc_internals", issue = "none")] +#[rustc_const_unstable(feature = "const_heap", issue = "79597")] #[inline(always)] #[cfg(not(no_global_oom_handling))] #[rustc_diagnostic_item = "box_assume_init_into_vec_unsafe"] -pub fn box_assume_init_into_vec_unsafe( +pub const fn box_assume_init_into_vec_unsafe( b: Box>, ) -> crate::vec::Vec { unsafe { (b.assume_init() as Box<[T]>).into_vec() } @@ -307,10 +309,11 @@ impl Box { /// ``` #[cfg(not(no_global_oom_handling))] #[stable(feature = "new_uninit", since = "1.82.0")] + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] #[must_use] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - pub fn new_uninit() -> Box> { + pub const fn new_uninit() -> Box> { // This is the same as `Self::new_uninit_in(Global)`, but manually inlined (just like // `Box::new`). @@ -1197,8 +1200,9 @@ impl Box, A> { /// assert_eq!(*five, 5) /// ``` #[stable(feature = "new_uninit", since = "1.82.0")] + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] #[inline(always)] - pub unsafe fn assume_init(self) -> Box { + pub const unsafe fn assume_init(self) -> Box { // This is used in the `vec!` macro, so we optimize for minimal IR generation // even in debug builds. // SAFETY: `Box` and `Box>` have the same layout. @@ -1668,8 +1672,9 @@ impl Box { /// [memory layout]: self#memory-layout #[must_use = "losing the pointer will leak memory"] #[unstable(feature = "allocator_api", issue = "32838")] + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] #[inline] - pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) { + pub const fn into_raw_with_allocator(b: Self) -> (*mut T, A) { let mut b = mem::ManuallyDrop::new(b); // We carefully get the raw pointer out in a way that Miri's aliasing model understands what // is happening: using the primitive "deref" of `Box`. In case `A` is *not* `Global`, we diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index 39e72e383eacb..da9b40c2c3ce0 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -476,8 +476,9 @@ impl [T] { /// ``` #[rustc_allow_incoherent_impl] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] #[inline] - pub fn into_vec(self: Box) -> Vec { + pub const fn into_vec(self: Box) -> Vec { unsafe { let len = self.len(); let (b, alloc) = Box::into_raw_with_allocator(self); diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index 52cdbe20ba176..1bd728170611f 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -552,11 +552,10 @@ impl str { without modifying the original"] #[unstable(feature = "titlecase", issue = "153892")] pub fn word_to_titlecase(&self) -> String { - // FIXME: add ASCII fast path - let mut s = String::with_capacity(self.len()); let mut chars = self.char_indices(); + // The first cased character is title-cased; leading uncased characters pass through. 'until_first_cased_char: for (_, c) in chars.by_ref() { if c.is_cased() { s.extend(c.to_titlecase()); @@ -566,14 +565,23 @@ impl str { } } - for (i, c) in chars { + // Everything after the first cased character is lower-cased. Use the ASCII fast + // path (auto-vectorized) for its ASCII prefix, mirroring `to_lowercase`. + let remainder = chars.as_str(); + let rest_start = self.len() - remainder.len(); + // SAFETY: `to_ascii_lowercase` preserves ASCII bytes, so the prefix stays valid UTF-8. + let (ascii, rest) = unsafe { convert_while_ascii(remainder, u8::to_ascii_lowercase) }; + s.push_str(&ascii); + let prefix_len = rest_start + ascii.len(); + + for (i, c) in rest.char_indices() { if c == 'Σ' { // Σ maps to σ, except at the end of a word where it maps to ς. // This is the only conditional (contextual) but language-independent mapping // in `SpecialCasing.txt`, // so hard-code it rather than have a generic "condition" mechanism. // See https://github.com/rust-lang/rust/issues/26035 - let sigma_lowercase = map_uppercase_sigma(self, i); + let sigma_lowercase = map_uppercase_sigma(self, prefix_len + i); s.push(sigma_lowercase); } else { match conversions::to_lower(c) { diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs index 96dcde71fc071..5e80ea2a78843 100644 --- a/library/alloctests/tests/lib.rs +++ b/library/alloctests/tests/lib.rs @@ -8,6 +8,7 @@ #![feature(binary_heap_pop_if)] #![feature(casefold)] #![feature(const_btree_len)] +#![feature(const_cmp)] #![feature(const_heap)] #![feature(const_trait_impl)] #![feature(core_intrinsics)] @@ -37,6 +38,7 @@ #![feature(string_replace_in_place)] #![feature(test)] #![feature(thin_box)] +#![feature(titlecase)] #![feature(trusted_len)] #![feature(try_reserve_kind)] #![feature(try_with_capacity)] diff --git a/library/alloctests/tests/str.rs b/library/alloctests/tests/str.rs index c11496e6e1b6b..9f39f578935ad 100644 --- a/library/alloctests/tests/str.rs +++ b/library/alloctests/tests/str.rs @@ -1904,6 +1904,56 @@ fn to_uppercase() { assert_eq!("aéDžßẞfiᾀ".to_uppercase(), "AÉDŽSSẞFIἈΙ"); } +#[test] +fn word_to_titlecase() { + // ASCII fast path: first cased letter is upper-cased, the rest lower-cased. + assert_eq!("hello WORLD".word_to_titlecase(), "Hello world"); + assert_eq!("HELLO".word_to_titlecase(), "Hello"); + + // Leading uncased characters pass through, then the first cased letter is title-cased. + assert_eq!("'twas".word_to_titlecase(), "'Twas"); + assert_eq!("123 abc".word_to_titlecase(), "123 Abc"); + + // Empty and no-cased-character inputs are unchanged. + assert_eq!("".word_to_titlecase(), ""); + assert_eq!("农历新年".word_to_titlecase(), "农历新年"); + assert_eq!("123 456".word_to_titlecase(), "123 456"); + + // Final-sigma handling: Σ maps to ς at the end of a word, σ elsewhere. + assert_eq!("ὈΔΥΣΣΕΎΣ".word_to_titlecase(), "Ὀδυσσεύς"); + assert_eq!("ΑΣ".word_to_titlecase(), "Ας"); + assert_eq!("ΑΣΑ".word_to_titlecase(), "Ασα"); + + // Mixed ASCII prefix followed by a non-ASCII tail exercises the boundary index math, + // including around the chunk size used by the ASCII prefix optimization. + assert_eq!("HELLO ὈΔΥΣΣΕΎΣ".word_to_titlecase(), "Hello ὀδυσσεύς"); + assert_eq!("ABCDEFGHIJKLMNOΣ".word_to_titlecase(), "Abcdefghijklmnoς"); + assert_eq!("ABCDEFGHIJKLMNOPΣ".word_to_titlecase(), "Abcdefghijklmnopς"); + assert_eq!("ABCDEFGHIJKLMNOPQΣ".word_to_titlecase(), "Abcdefghijklmnopqς"); + + // A long ASCII-only string exercises the auto-vectorized fast path. + assert_eq!(str::repeat("A", 511).word_to_titlecase(), { + let mut expected = String::from("A"); + expected.push_str(&str::repeat("a", 510)); + expected + }); + + // LJ ligatures and title-case characters. + // Lj is already a title-case letter, so it stays as the first char. + assert_eq!("Ljj".word_to_titlecase(), "Ljj"); + assert_eq!("LjJ".word_to_titlecase(), "Ljj"); + // l is the first cased char (uppercases to L), Lj lowercases to lj. + assert_eq!("lLjfi".word_to_titlecase(), "Lljfi"); + assert_eq!("LLjfi".word_to_titlecase(), "Lljfi"); + + // LJ ligatures: lower=lj (U+01C9), upper=LJ (U+01C7), title=Lj (U+01C8). + // ß decomposes to "Ss" in title case (first char) but stays ß elsewhere. + assert_eq!("ßljLJLj".word_to_titlecase(), "Ssljljlj"); + assert_eq!("ljLJLjß".word_to_titlecase(), "Ljljljß"); + assert_eq!("LJLjßlj".word_to_titlecase(), "Ljljßlj"); + assert_eq!("LjßljLJ".word_to_titlecase(), "Ljßljlj"); +} + #[test] fn to_casefold_unnormalized() { assert_eq!("".to_casefold_unnormalized(), ""); diff --git a/library/alloctests/tests/vec.rs b/library/alloctests/tests/vec.rs index fc58e4364fe66..4620a9f373d6c 100644 --- a/library/alloctests/tests/vec.rs +++ b/library/alloctests/tests/vec.rs @@ -2807,3 +2807,26 @@ fn const_make_global_empty_or_zst_regression() { assert_eq!(ZST_SLICE, &[(), (), ()]); } + +#[test] +fn const_heap_vec_macro() { + const X: &'static [u32] = { + let x: Vec = vec![]; + assert!(x == []); + x.const_make_global() + }; + + const Y: &'static [u32] = { + let y: Vec = vec![1, 2, 3]; + assert!(y == [1, 2, 3]); + y.const_make_global() + }; + + // This arm isn't const yet. + // const Z: &'static [u32] = { + // vec![4; 2].const_make_global() + // }; + + assert_eq!(X, []); + assert_eq!(Y, [1, 2, 3]); +} diff --git a/src/bootstrap/download-ci-llvm-stamp b/src/bootstrap/download-ci-llvm-stamp index b61c7b18bad01..ba6dcfc761c5a 100644 --- a/src/bootstrap/download-ci-llvm-stamp +++ b/src/bootstrap/download-ci-llvm-stamp @@ -1,4 +1,4 @@ Change this file to make users of the `download-ci-llvm` configuration download a new version of LLVM from CI, even if the LLVM submodule hasn’t changed. -Last change is for: https://github.com/rust-lang/rust/pull/157385 +Last change is for: https://github.com/rust-lang/rust/pull/158766 diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index df3fb001e5bc5..99e2c61e442ff 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -721,7 +721,7 @@ impl Step for Std { DocumentationFormat::Html => { vec!["--markdown-css", "rust.css", "--markdown-no-toc", "--index-page", &index_page] } - DocumentationFormat::Json => vec!["--output-format", "json"], + DocumentationFormat::Json => vec![], }; if !builder.config.docs_minification { @@ -730,7 +730,47 @@ impl Step for Std { // For `--index-page` and `--output-format=json`. extra_args.push("-Zunstable-options"); - doc_std(builder, self.format, self.build_compiler, target, &out, &extra_args, &crates); + let target_doc_dir_name = + if self.format == DocumentationFormat::Json { "json-doc" } else { "doc" }; + let target_dir = builder + .stage_out(self.build_compiler, Mode::Std) + .join(target) + .join(target_doc_dir_name); + + // This is directory where the compiler will place the output of the command. + // We will then copy the files from this directory into the final `out` directory, the specified + // as a function parameter. + let out_dir = target_dir.join(target).join("doc"); + + let mut cargo = doc_std( + builder, + self.format, + self.build_compiler, + target, + &target_dir, + &extra_args, + &crates, + ); + match self.format { + DocumentationFormat::Html => {} + DocumentationFormat::Json => { + // We have to pass these directly to cargo, rather than through RUSTDOCFLAGS, + // otherwise Cargo will not detect freshness of the output correctly, and keep + // rebuilding the docs on every invocation. + cargo.args(["-Zunstable-options", "--output-format", "json"]); + } + } + + let description = + format!("library{} in {} format", crate_description(&crates), self.format.as_str()); + + { + let _guard = + builder.msg(Kind::Doc, description, Mode::Std, self.build_compiler, target); + + cargo.into_cmd().run(builder); + builder.cp_link_r(&out_dir, &out); + } // Open if the format is HTML if let DocumentationFormat::Html = self.format { @@ -787,25 +827,16 @@ impl DocumentationFormat { } } -/// Build the documentation for public standard library crates. +/// Prepare a Cargo command for building the documentation for public standard library crates. fn doc_std( builder: &Builder<'_>, format: DocumentationFormat, build_compiler: Compiler, target: TargetSelection, - out: &Path, + target_dir: &Path, extra_args: &[&str], requested_crates: &[String], -) { - let target_doc_dir_name = if format == DocumentationFormat::Json { "json-doc" } else { "doc" }; - let target_dir = - builder.stage_out(build_compiler, Mode::Std).join(target).join(target_doc_dir_name); - - // This is directory where the compiler will place the output of the command. - // We will then copy the files from this directory into the final `out` directory, the specified - // as a function parameter. - let out_dir = target_dir.join(target).join("doc"); - +) -> builder::Cargo { let mut cargo = builder::Cargo::new( builder, build_compiler, @@ -836,13 +867,7 @@ fn doc_std( if format == DocumentationFormat::Json || builder.config.library_docs_private_items { cargo.rustdocflag("--document-private-items").rustdocflag("--document-hidden-items"); } - - let description = - format!("library{} in {} format", crate_description(requested_crates), format.as_str()); - let _guard = builder.msg(Kind::Doc, description, Mode::Std, build_compiler, target); - - cargo.into_cmd().run(builder); - builder.cp_link_r(&out_dir, out); + cargo } /// Prepare a compiler that will be able to document something for `target` at `stage`. diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 0a13bf5d487b3..be70d9f4f106c 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -249,6 +249,7 @@ pub(crate) fn is_ci_llvm_available_for_target( ("powerpc64le-unknown-linux-gnu", false), ("powerpc64le-unknown-linux-musl", false), ("riscv64gc-unknown-linux-gnu", false), + ("riscv64gc-unknown-linux-musl", false), ("s390x-unknown-linux-gnu", false), ("x86_64-pc-windows-gnullvm", false), ("x86_64-unknown-freebsd", false), diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 6de70c7d70cde..3a1e4299b5475 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -1197,7 +1197,12 @@ impl Builder<'_> { cargo.env("RUSTC_BOOTSTRAP", "1"); if matches!(mode, Mode::Std) { - cargo.arg("-Zno-embed-metadata"); + // The `-Zembed-metadata` flag was renamed from `-Zno-embed-metadata`. + if self.local_rebuild { + cargo.arg("-Zembed-metadata=no"); + } else { + cargo.arg("-Zno-embed-metadata"); + } } if self.config.dump_bootstrap_shims { diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index d19c928e7c553..e6d55fd530adb 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -481,6 +481,7 @@ pub(crate) fn is_download_ci_available(target_triple: &str, llvm_assertions: boo "powerpc64le-unknown-linux-gnu", "powerpc64le-unknown-linux-musl", "riscv64gc-unknown-linux-gnu", + "riscv64gc-unknown-linux-musl", "s390x-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-pc-windows-gnu", diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index 6e5a38a3c515a..b113adc2008cd 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -462,6 +462,22 @@ For targets: `riscv64-unknown-linux-gnu` - C compiler > gcc version = 8.5.0 - C compiler > C++ = ENABLE -- to cross compile LLVM +### `riscv64-unknown-linux-musl.defconfig` + +For targets: `riscv64-unknown-linux-musl` + +- Path and misc options > Prefix directory = /x-tools/${CT\_TARGET} +- Path and misc options > Use a mirror = ENABLE +- Path and misc options > Base URL = https://ci-mirrors.rust-lang.org/rustc +- Target options > Target Architecture = riscv +- Target options > Bitness = 64-bit +- Operating System > Target OS = linux +- Operating System > Linux kernel version = 4.20.17 +- Binary utilities > Version of binutils = 2.40 +- C-library > musl version = 1.2.5 +- C compiler > gcc version = 8.5.0 +- C compiler > C++ = ENABLE -- to cross compile LLVM + ### `s390x-linux-gnu.defconfig` For targets: `s390x-unknown-linux-gnu` diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-riscv64-linux-gnu/Dockerfile similarity index 92% rename from src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile rename to src/ci/docker/host-x86_64/dist-riscv64-linux-gnu/Dockerfile index 5186c99c4f430..57f3b68a96e3f 100644 --- a/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-riscv64-linux-gnu/Dockerfile @@ -12,7 +12,7 @@ RUN sh /scripts/rustbuild-setup.sh WORKDIR /tmp COPY scripts/crosstool-ng-build.sh /scripts/ -COPY host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.defconfig /tmp/crosstool.defconfig +COPY host-x86_64/dist-riscv64-linux-gnu/riscv64-unknown-linux-gnu.defconfig /tmp/crosstool.defconfig RUN /scripts/crosstool-ng-build.sh COPY scripts/sccache.sh /scripts/ diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.defconfig b/src/ci/docker/host-x86_64/dist-riscv64-linux-gnu/riscv64-unknown-linux-gnu.defconfig similarity index 100% rename from src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.defconfig rename to src/ci/docker/host-x86_64/dist-riscv64-linux-gnu/riscv64-unknown-linux-gnu.defconfig diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-riscv64-linux-musl/Dockerfile new file mode 100644 index 0000000000000..bb7537fc7d279 --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-riscv64-linux-musl/Dockerfile @@ -0,0 +1,39 @@ +FROM ubuntu:22.04 + +COPY scripts/cross-apt-packages.sh /scripts/ +RUN sh /scripts/cross-apt-packages.sh + +COPY scripts/crosstool-ng.sh /scripts/ +COPY scripts/crosstool-ng-sha256-20260705.diff /scripts/ +RUN sh /scripts/crosstool-ng.sh + +COPY scripts/rustbuild-setup.sh /scripts/ +RUN sh /scripts/rustbuild-setup.sh + +WORKDIR /tmp + +COPY scripts/crosstool-ng-build.sh /scripts/ +COPY host-x86_64/dist-riscv64-linux-musl/riscv64-unknown-linux-musl.defconfig /tmp/crosstool.defconfig +RUN /scripts/crosstool-ng-build.sh + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +ENV PATH=$PATH:/x-tools/riscv64-unknown-linux-musl/bin + +ENV CC_riscv64gc_unknown_linux_musl=riscv64-unknown-linux-musl-gcc \ + AR_riscv64gc_unknown_linux_musl=riscv64-unknown-linux-musl-ar \ + CXX_riscv64gc_unknown_linux_musl=riscv64-unknown-linux-musl-g++ + +ENV HOSTS=riscv64gc-unknown-linux-musl +ENV TARGETS=riscv64gc-unknown-linux-musl + +ENV RUST_CONFIGURE_ARGS="--enable-extended \ + --enable-full-tools \ + --enable-profiler \ + --enable-sanitizers \ + --disable-docs \ + --set target.riscv64gc-unknown-linux-musl.crt-static=false \ + --musl-root-riscv64gc=/x-tools/riscv64-unknown-linux-musl/riscv64-unknown-linux-musl/sysroot/usr" + +ENV SCRIPT="python3 ../x.py dist --target $TARGETS --host $HOSTS" diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux-musl/riscv64-unknown-linux-musl.defconfig b/src/ci/docker/host-x86_64/dist-riscv64-linux-musl/riscv64-unknown-linux-musl.defconfig new file mode 100644 index 0000000000000..435a2bea80d36 --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-riscv64-linux-musl/riscv64-unknown-linux-musl.defconfig @@ -0,0 +1,16 @@ +CT_CONFIG_VERSION="4" +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_USE_MIRROR=y +CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" +CT_VERIFY_DOWNLOAD_DIGEST_SHA256=y +CT_ARCH_RISCV=y +CT_ARCH_USE_MMU=y +CT_ARCH_64=y +CT_ARCH_ARCH="rv64gc" +CT_KERNEL_LINUX=y +CT_LINUX_V_4_20=y +CT_LIBC_MUSL=y +CT_BINUTILS_V_2_40=y +CT_MUSL_V_1_2_5=y +CT_GCC_V_8=y +CT_CC_LANG_CXX=y diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile index f07fb91edaf0b..12705809e4290 100644 --- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile @@ -24,8 +24,7 @@ RUN apt-get update && apt-get build-dep -y clang llvm && apt-get install -y --no # Needed for apt-key to work: dirmngr \ gpg-agent \ - g++-9-arm-linux-gnueabi \ - g++-11-riscv64-linux-gnu + g++-9-arm-linux-gnueabi ENV \ AR_x86_64_unknown_fuchsia=x86_64-unknown-fuchsia-ar \ @@ -71,10 +70,6 @@ RUN env \ CC=arm-linux-gnueabi-gcc-9 CFLAGS="-march=armv7-a" \ CXX=arm-linux-gnueabi-g++-9 CXXFLAGS="-march=armv7-a" \ bash musl.sh armv7 && \ - env \ - CC=riscv64-linux-gnu-gcc-11 \ - CXX=riscv64-linux-gnu-g++-11 \ - bash musl.sh riscv64gc && \ rm -rf /build/* WORKDIR /tmp @@ -120,7 +115,6 @@ ENV TARGETS=$TARGETS,x86_64-unknown-none ENV TARGETS=$TARGETS,aarch64-unknown-uefi ENV TARGETS=$TARGETS,i686-unknown-uefi ENV TARGETS=$TARGETS,x86_64-unknown-uefi -ENV TARGETS=$TARGETS,riscv64gc-unknown-linux-musl ENV TARGETS_SANITIZERS=x86_64-unknown-linux-gnuasan ENV TARGETS_SANITIZERS=$TARGETS_SANITIZERS,x86_64-unknown-linux-gnumsan @@ -132,11 +126,7 @@ ENV TARGETS_SANITIZERS=$TARGETS_SANITIZERS,x86_64-unknown-linux-gnutsan # Luckily one of the folders is /usr/local/include so symlink /usr/include/x86_64-linux-gnu/asm there RUN ln -s /usr/include/x86_64-linux-gnu/asm /usr/local/include/asm -# musl-gcc can't find libgcc_s.so.1 since it doesn't use the standard search paths. -RUN ln -s /usr/riscv64-linux-gnu/lib/libgcc_s.so.1 /usr/lib/gcc-cross/riscv64-linux-gnu/11/ - ENV RUST_CONFIGURE_ARGS="--enable-extended --enable-lld --enable-llvm-bitcode-linker --disable-docs \ - --musl-root-armv7=/musl-armv7 \ - --musl-root-riscv64gc=/musl-riscv64gc" + --musl-root-armv7=/musl-armv7" ENV SCRIPT="python3 ../x.py dist --host= --target $TARGETS && python3 ../x.py dist --host= --set build.sanitizers=true --target $TARGETS_SANITIZERS" diff --git a/src/ci/docker/host-x86_64/optional-x86_64-gnu-autodiff/Dockerfile b/src/ci/docker/host-x86_64/optional-x86_64-gnu-autodiff/Dockerfile new file mode 100644 index 0000000000000..a7b6dc620e967 --- /dev/null +++ b/src/ci/docker/host-x86_64/optional-x86_64-gnu-autodiff/Dockerfile @@ -0,0 +1,39 @@ +FROM ubuntu:24.04 + +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y --no-install-recommends \ + g++ \ + make \ + ninja-build \ + file \ + curl \ + ca-certificates \ + python3 \ + git \ + cmake \ + pkg-config \ + xz-utils \ + zlib1g-dev \ + && rm -rf /var/lib/apt/lists/* + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +ENV NO_DOWNLOAD_CI_LLVM 1 +ENV CODEGEN_BACKENDS llvm + +ENV RUST_CONFIGURE_ARGS \ + --build=x86_64-unknown-linux-gnu \ + --enable-llvm-enzyme \ + --enable-llvm-link-shared \ + --enable-ninja \ + --enable-option-checking \ + --disable-docs \ + --set llvm.download-ci-llvm=false + +ENV SCRIPT="../x.py test --stage 2 --no-fail-fast \ + tests/codegen-llvm/autodiff \ + tests/pretty/autodiff \ + tests/ui/autodiff \ + tests/ui/feature-gates/feature-gate-autodiff.rs" diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 0a1d7d464e9a3..e03ad184842e3 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -272,7 +272,10 @@ auto: - name: dist-powerpc64le-linux-musl <<: *job-linux-4c - - name: dist-riscv64-linux + - name: dist-riscv64-linux-gnu + <<: *job-linux-4c + + - name: dist-riscv64-linux-musl <<: *job-linux-4c - name: dist-s390x-linux @@ -474,6 +477,11 @@ auto: - name: x86_64-gnu-miri <<: *job-linux-4c + - name: optional-x86_64-gnu-autodiff + continue_on_error: true + doc_url: https://rustc-dev-guide.rust-lang.org/tests/autodiff-ci-job.html + <<: *job-linux-4c + #################### # macOS Builders # #################### diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index bf2de84575d69..a2b386cc83071 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -35,6 +35,7 @@ - [Cranelift codegen backend](./tests/codegen-backend-tests/cg_clif.md) - [GCC codegen backend](./tests/codegen-backend-tests/cg_gcc.md) - [Performance testing](./tests/perf.md) + - [Autodiff CI job](./tests/autodiff-ci-job.md) - [Pre-stabilization CI job for the next solver and polonius alpha](./tests/x86_64-gnu-next-trait-solver-polonius-ci-job.md) - [Misc info](./tests/misc.md) - [Debugging the compiler](./compiler-debugging.md) diff --git a/src/doc/rustc-dev-guide/src/tests/autodiff-ci-job.md b/src/doc/rustc-dev-guide/src/tests/autodiff-ci-job.md new file mode 100644 index 0000000000000..3e5d55fbc81a9 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/tests/autodiff-ci-job.md @@ -0,0 +1,45 @@ +# Autodiff CI job + +The [`optional-x86_64-gnu-autodiff`] job provides continuous test coverage for +the experimental `autodiff` feature and its integration with LLVM Enzyme. It is +an optional [auto job](./ci.md#auto-builds), so a failure does not prevent a +pull request from being merged. + +For more context about the feature, see the [autodiff tracking issue] and the +[autodiff internals](../autodiff/internals.md) chapter. + +## What is tested + +The job checks: + +- forward- and reverse-mode macro expansion and diagnostics; +- LLVM IR generation for autodiff; +- enforcement of the `autodiff` feature gate. + +## Running the job + +To run the job in a try build, comment on a pull request: + +```text +@bors try jobs=optional-x86_64-gnu-autodiff +``` + +To run the job locally, run this command from a Rust checkout: + +```console +$ cargo run --manifest-path src/ci/citool/Cargo.toml run-local optional-x86_64-gnu-autodiff +``` + +See [Testing with Docker](./docker.md) for more information about running CI +jobs locally. + +## Point of contact + +If you have questions or need help with a failure in this job, open a new topic +in the [autodiff Zulip channel]. For suspected Enzyme backend failures, see the +[autodiff debugging guide]. + +[autodiff Zulip channel]: https://rust-lang.zulipchat.com/#narrow/channel/390790-wg-autodiff +[autodiff debugging guide]: ../autodiff/debugging.md +[autodiff tracking issue]: https://github.com/rust-lang/rust/issues/124509 +[`optional-x86_64-gnu-autodiff`]: https://github.com/rust-lang/rust/blob/HEAD/src/ci/github-actions/jobs.yml diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index ce4d55c2d2b00..c527911bc96a2 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -105,6 +105,7 @@ target | notes [`powerpc64le-unknown-linux-gnu`](platform-support/powerpc64le-unknown-linux-gnu.md) | PPC64LE Linux (kernel 3.10+, glibc 2.17) [`powerpc64le-unknown-linux-musl`](platform-support/powerpc64le-unknown-linux-musl.md) | PPC64LE Linux (kernel 4.19+, musl 1.2.5) [`riscv64gc-unknown-linux-gnu`](platform-support/riscv64gc-unknown-linux-gnu.md) | RISC-V Linux (kernel 4.20+, glibc 2.29) +[`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20+, musl 1.2.5) [`s390x-unknown-linux-gnu`](platform-support/s390x-unknown-linux-gnu.md) | S390x Linux (kernel 3.2+, glibc 2.17) [`x86_64-apple-darwin`](platform-support/apple-darwin.md) | 64-bit macOS (10.12+, Sierra+) [`x86_64-pc-windows-gnullvm`](platform-support/windows-gnullvm.md) | 64-bit x86 MinGW (Windows 10+), LLVM ABI @@ -196,7 +197,6 @@ target | std | notes [`riscv32imafc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAFC ISA) [`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA) [`riscv64a23-unknown-linux-gnu`](platform-support/riscv64a23-unknown-linux-gnu.md) | ✓ | RISC-V Linux (kernel 6.8.0+, glibc 2.39) -[`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | ✓ |RISC-V Linux (kernel 4.20+, musl 1.2.5) `riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA) [`riscv64im-unknown-none-elf`](platform-support/riscv64im-unknown-none-elf.md) | * | Bare RISC-V (RV64IM ISA) `riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA) diff --git a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md index d62a65b21904f..119c3053cda7e 100644 --- a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md +++ b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md @@ -2,7 +2,8 @@ **Tier: 2 (with Host Tools)** -RISC-V targets using the *RV64I* base instruction set with the *G* collection of extensions, as well as the *C* extension. +Linux GNU libc RISC-V target using the *RV64I* base instruction set with the +*G* collection of extensions, as well as the *C* extension. ## Target maintainers @@ -22,10 +23,10 @@ This target requires: ## Building the target -These targets are distributed through `rustup`, and otherwise require no +This target is distributed through `rustup`, and otherwise requires no special configuration. -If you need to build your own Rust for some reason though, the targets can be +If you need to build your own Rust for some reason though, the target can be enabled in `bootstrap.toml`. For example: ```toml @@ -37,10 +38,10 @@ target = ["riscv64gc-unknown-linux-gnu"] ## Building Rust programs -On a RISC-V host, the `riscv64gc-unknown-linux-gnu` target should be automatically -installed and used by default. +On a riscv64gc-unknown-linux-gnu host, the `riscv64gc-unknown-linux-gnu` +target should be automatically installed and used by default. -On a non-RISC-V host, add the target: +On all other hosts, add the target: ```bash rustup target add riscv64gc-unknown-linux-gnu @@ -55,7 +56,7 @@ cargo build --target riscv64gc-unknown-linux-gnu ## Testing -There are no special requirements for testing and running the targets. +There are no special requirements for testing and running the target. For testing cross builds on the host, please refer to the "Cross-compilation toolchains and C code" section below. diff --git a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md index 2e88b5aa813ff..12872b74b6820 100644 --- a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md +++ b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md @@ -1,8 +1,10 @@ # riscv64gc-unknown-linux-musl -**Tier: 2** +**Tier: 2 (with Host Tools)** + +Linux musl libc RISC-V target using the *RV64I* base instruction set with the +*G* collection of extensions, as well as the *C* extension. -Target for RISC-V Linux programs using musl libc. ## Target maintainers @@ -11,37 +13,44 @@ Target for RISC-V Linux programs using musl libc. ## Requirements -Building the target itself requires a RISC-V compiler that is supported by `cc-rs`. +This target requires: + +* Linux Kernel version 4.20 or later +* musl libc 1.2.5 or later + ## Building the target -The target can be built by enabling it for a `rustc` build. +This target is distributed through `rustup`, and otherwise requires no +special configuration. + +If you need to build your own Rust then the targets can be enabled in +`bootstrap.toml`. For example: ```toml [build] target = ["riscv64gc-unknown-linux-musl"] ``` -Make sure your C compiler is included in `$PATH`, then add it to the `bootstrap.toml`: - -```toml -[target.riscv64gc-unknown-linux-musl] -cc = "riscv64-linux-gnu-gcc" -cxx = "riscv64-linux-gnu-g++" -ar = "riscv64-linux-gnu-ar" -linker = "riscv64-linux-gnu-gcc" -``` ## Building Rust programs -This target are distributed through `rustup`, and otherwise require no -special configuration. +On a riscv64gc-unknown-linux-musl host, the `riscv64gc-unknown-linux-musl` +target should be automatically installed and used by default. + +On all other hosts, add the target: -## Cross-compilation +```bash +rustup target add riscv64gc-unknown-linux-musl +``` + +Then cross compile crates with: -This target can be cross-compiled from any host. +```bash +cargo build --target riscv64gc-unknown-linux-musl +``` ## Testing -This target can be tested as normal with `x.py` on a RISC-V host or via QEMU +The target can be tested as normal with `x.py` on a RISC-V host or via QEMU emulation. diff --git a/src/librustdoc/passes/propagate_doc_cfg.rs b/src/librustdoc/passes/propagate_doc_cfg.rs index 213b8060a8512..e15bb657b7867 100644 --- a/src/librustdoc/passes/propagate_doc_cfg.rs +++ b/src/librustdoc/passes/propagate_doc_cfg.rs @@ -1,8 +1,9 @@ //! Propagates [`#[doc(cfg(...))]`](https://github.com/rust-lang/rust/issues/43781) to child items. use rustc_data_structures::fx::FxHashMap; -use rustc_hir::Attribute; use rustc_hir::attrs::{AttributeKind, DocAttribute}; +use rustc_hir::{Attribute, find_attr}; +use rustc_span::{ExpnKind, MacroKind}; use crate::clean::inline::{load_attrs, merge_attrs}; use crate::clean::{CfgInfo, Crate, Item, ItemId, ItemKind}; @@ -133,8 +134,40 @@ impl DocFolder for CfgPropagator<'_, '_> { { self.cfg_info = cfg_info; } - if let ItemKind::PlaceholderImplItem = item.kind { + if let Some(impl_def_id) = item.item_id.as_def_id() { + let tcx = self.cx.tcx; + let expn_data = tcx.expn_that_defined(impl_def_id).expn_data(); + if matches!(expn_data.kind, ExpnKind::Macro(MacroKind::Derive, _)) + // This impl block comes from a `derive` expansion, so we want to retrieve + // the `cfg_attr` if any. + && let Some(self_ty_def_id) = tcx + .type_of(impl_def_id) + .instantiate_identity() + .skip_norm_wip() + .ty_adt_def() + .map(|adt| adt.did()) + && let self_ty_attrs = load_attrs(tcx, self_ty_def_id) + && let Some(cfgs_attr_trace) = + find_attr!(self_ty_attrs, CfgAttrTrace(cfgs) => cfgs) + && !cfgs_attr_trace.is_empty() + { + // We retrieve the `cfg_attr` of the `derive` this `impl` comes from. + let derive_span = expn_data.call_site; + let attrs_iter = Attribute::Parsed(AttributeKind::CfgTrace( + cfgs_attr_trace + .iter() + .filter(|(_, span)| span.contains(derive_span)) + .cloned() + .collect(), + )); + crate::clean::extract_cfg_from_attrs( + std::iter::once(&attrs_iter), + tcx, + &mut self.cfg_info, + ); + } + } // If we have a placeholder impl, we store the current `cfg` "context" to be used // on the actual impl later on (the impls are generated after we go through the whole // AST so they're stored in the `krate` object at the end). diff --git a/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs b/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs index 3e82ff4a69545..851d605c36be5 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs @@ -32,7 +32,7 @@ impl From<&AttrKind> for SimpleAttrKind { AttrKind::Synthetic(synthetic) => { match &**synthetic { SyntheticAttr::CfgTrace(_) => Self::CfgTrace, - SyntheticAttr::CfgAttrTrace => Self::CfgAttrTrace, + SyntheticAttr::CfgAttrTrace(_) => Self::CfgAttrTrace, } } AttrKind::DocComment(..) => Self::Doc, diff --git a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs index 99e7d202fe46f..cefb48046be47 100644 --- a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs +++ b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs @@ -270,5 +270,5 @@ impl<'tcx> LateLintPass<'tcx> for IncompatibleMsrv { fn is_under_cfg_attribute(cx: &LateContext<'_>, hir_id: HirId) -> bool { cx.tcx .hir_parent_id_iter(hir_id) - .any(|id| find_attr!(cx.tcx, id, CfgTrace(..) | CfgAttrTrace)) + .any(|id| find_attr!(cx.tcx, id, CfgTrace(..) | CfgAttrTrace(..))) } diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 426102e149d3f..82752b3d73766 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -2344,7 +2344,7 @@ pub fn is_hir_ty_cfg_dependant(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool { if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind && let Res::Def(_, def_id) = path.res { - return find_attr!(cx.tcx, def_id, CfgTrace(..) | CfgAttrTrace); + return find_attr!(cx.tcx, def_id, CfgTrace(..) | CfgAttrTrace(..)); } false } diff --git a/tests/run-make/macos-deployment-target-warning/rmake.rs b/tests/run-make/macos-deployment-target-warning/rmake.rs index 6aab525a7c8a4..47f9cd1cf5f2c 100644 --- a/tests/run-make/macos-deployment-target-warning/rmake.rs +++ b/tests/run-make/macos-deployment-target-warning/rmake.rs @@ -13,6 +13,7 @@ fn main() { let ld_prime_obj = r"ld: warning: object file \(.*\) was built for newer '.+' version \(\d+\.\d+\) than being linked \(\d+\.\d+\)"; let ld64_dylib = r"ld: warning: dylib \(.*\) was built for newer .+ version \(\d+\.\d+\) than being linked \(\d+\.\d+\)"; let ld_prime_dylib = r"ld: warning: building for [^ ,]+, but linking with dylib '[^']*' which was built for newer version [0-9.]+"; + let lld_obj = r"ld64\.lld: warning: .+ has version \d+\.\d+(\.\d+)?, which is newer than target minimum of \d+\.\d+(\.\d+)?"; // Test 1: static archive (object file mismatch) cc().arg("-c").arg("-mmacosx-version-min=15.5").output("foo.o").input("foo.c").run(); @@ -54,4 +55,24 @@ fn main() { .normalize(ld64_dylib, "NORMALIZED_DYLIB_DEPLOYMENT_MISMATCH_LINKER_WARNING") .normalize(ld_prime_dylib, "NORMALIZED_DYLIB_DEPLOYMENT_MISMATCH_LINKER_WARNING") .run(); + + // Test 3: static archive with lld (object file mismatch) + let lld_path = std::path::PathBuf::from(std::env::var("LLVM_BIN_DIR").unwrap()).join("lld"); + let ld64_lld = std::env::current_dir().unwrap().join("ld64.lld"); + std::os::unix::fs::symlink(&lld_path, &ld64_lld).expect("failed to create ld64.lld symlink"); + + let lld_warnings = rustc() + .arg("-lstatic=foo") + .link_arg("-mmacosx-version-min=11.2") + .link_arg(&format!("-fuse-ld={}", ld64_lld.display())) + .input("main.rs") + .crate_type("bin") + .run() + .stderr_utf8(); + + diff() + .expected_file("warnings.txt") + .actual_text("(rustc -W linker-info with lld)", &lld_warnings) + .normalize(lld_obj, "NORMALIZED_OBJECT_DEPLOYMENT_MISMATCH_LINKER_WARNING") + .run(); } diff --git a/tests/run-make/rmeta-unrelated-search-path-files/client.rs b/tests/run-make/rmeta-unrelated-search-path-files/client.rs new file mode 100644 index 0000000000000..a0fb04732fef1 --- /dev/null +++ b/tests/run-make/rmeta-unrelated-search-path-files/client.rs @@ -0,0 +1,5 @@ +//! [crate::Client] + +extern crate foo; + +pub struct Client; diff --git a/tests/run-make/rmeta-unrelated-search-path-files/foo.rs b/tests/run-make/rmeta-unrelated-search-path-files/foo.rs new file mode 100644 index 0000000000000..4a835673a596b --- /dev/null +++ b/tests/run-make/rmeta-unrelated-search-path-files/foo.rs @@ -0,0 +1 @@ +pub struct Foo; diff --git a/tests/run-make/rmeta-unrelated-search-path-files/foo_bar.rs b/tests/run-make/rmeta-unrelated-search-path-files/foo_bar.rs new file mode 100644 index 0000000000000..1c6a3b4c6cce8 --- /dev/null +++ b/tests/run-make/rmeta-unrelated-search-path-files/foo_bar.rs @@ -0,0 +1 @@ +pub struct FooBar; diff --git a/tests/run-make/rmeta-unrelated-search-path-files/rmake.rs b/tests/run-make/rmeta-unrelated-search-path-files/rmake.rs new file mode 100644 index 0000000000000..3bd402c5c6b79 --- /dev/null +++ b/tests/run-make/rmeta-unrelated-search-path-files/rmake.rs @@ -0,0 +1,30 @@ +//@ needs-target-std +// +// Regression test for . +// +// Ensures two builds of `client.rs` produce identical metadata +// even if there is an unrelated crate on the search path. + +use run_make_support::{rfs, rustc}; + +fn main() { + rustc().input("foo.rs").crate_type("rlib").run(); + rustc() + .input("client.rs") + .crate_type("rlib") + .emit("metadata") + .library_search_path(".") + .output("client1.rmeta") + .run(); + + rustc().input("foo_bar.rs").crate_type("rlib").run(); + rustc() + .input("client.rs") + .crate_type("rlib") + .emit("metadata") + .library_search_path(".") + .output("client2.rmeta") + .run(); + + assert_eq!(rfs::read("client1.rmeta"), rfs::read("client2.rmeta")); +} diff --git a/tests/rustdoc-html/doc-cfg/auxiliary/cfg-attr-proc-macro.rs b/tests/rustdoc-html/doc-cfg/auxiliary/cfg-attr-proc-macro.rs new file mode 100644 index 0000000000000..21db277833e05 --- /dev/null +++ b/tests/rustdoc-html/doc-cfg/auxiliary/cfg-attr-proc-macro.rs @@ -0,0 +1,24 @@ +//@ no-prefer-dynamic +//@ edition: 2024 + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::{TokenStream, TokenTree}; + +#[proc_macro_derive(Yop)] +pub fn derive_yop(input: TokenStream) -> TokenStream { + let mut iter = input.into_iter(); + + while let Some(token) = iter.next() { + if let TokenTree::Ident(ident) = token && + matches!(ident.to_string().as_str(), "struct" | "enum" | "union") + { + // Next token is the name. That's all we need! + let Some(TokenTree::Ident(ident)) = iter.next() else { panic!() }; + return format!("impl Trait for {ident} {{}}").parse().unwrap(); + } + } + panic!() +} diff --git a/tests/rustdoc-html/doc-cfg/cfg-attr-proc-macro.rs b/tests/rustdoc-html/doc-cfg/cfg-attr-proc-macro.rs new file mode 100644 index 0000000000000..d4f44a333bd25 --- /dev/null +++ b/tests/rustdoc-html/doc-cfg/cfg-attr-proc-macro.rs @@ -0,0 +1,14 @@ +//@ aux-build: cfg-attr-proc-macro.rs + +#![crate_name = "foo"] +#![feature(doc_cfg)] + +extern crate cfg_attr_proc_macro; + +pub trait Trait {} + +//@ has 'foo/struct.B.html' +//@ has - '//*[@id="impl-Trait-for-B"]/*[@class="item-info"]/*[@class="stab portability"]' \ +// 'Available on non-crate feature boop only.' +#[cfg_attr(not(feature = "boop"), derive(cfg_attr_proc_macro::Yop))] +pub struct B; diff --git a/tests/rustdoc-html/doc-cfg/cfg-attr.rs b/tests/rustdoc-html/doc-cfg/cfg-attr.rs new file mode 100644 index 0000000000000..96338d3c40c0e --- /dev/null +++ b/tests/rustdoc-html/doc-cfg/cfg-attr.rs @@ -0,0 +1,14 @@ +// This test ensures that the `cfg_attr` cfg predicates are correctly kept to be used +// by the `doc_cfg` feature. + +#![crate_name = "foo"] +#![feature(doc_cfg)] + +//@ has 'foo/struct.Test.html' +//@ has - '//*[@id="impl-Debug-for-Test"]/*[@class="item-info"]/*[@class="stab portability"]' \ +// 'Available on non-crate feature debug only.' +//@ has - '//*[@id="impl-Clone-for-Test"]/*[@class="item-info"]/*[@class="stab portability"]' \ +// 'Available on non-crate feature aa and non-crate feature bb only.' +#[cfg_attr(not(feature = "debug"), derive(Debug))] +#[cfg_attr(not(feature = "aa"), cfg_attr(not(feature = "bb"), derive(Clone)))] +pub struct Test; diff --git a/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs b/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs new file mode 100644 index 0000000000000..74f0618e4291f --- /dev/null +++ b/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs @@ -0,0 +1,17 @@ +//@ compile-flags: -Znext-solver=globally -Zassumptions-on-binders + +trait Trait {} + +trait Proj<'a> { + type Assoc; +} + +fn foo<'a, T>() +where + T: Proj<'a, Assoc = fn(::Assoc)>, + (): Trait<>::Assoc>, + //~^ ERROR the trait bound `(): Trait fn(>::Assoc))>` is not satisfied +{ +} + +fn main() {} diff --git a/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.stderr b/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.stderr new file mode 100644 index 0000000000000..5e8e131addd28 --- /dev/null +++ b/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.stderr @@ -0,0 +1,14 @@ +error[E0277]: the trait bound `(): Trait fn(>::Assoc))>` is not satisfied + --> $DIR/placeholder-assumptions-issue-157840.rs:12:9 + | +LL | (): Trait<>::Assoc>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait fn(>::Assoc))>` is not implemented for `()` + | +help: consider extending the `where` clause, but there might be an alternative better way to express this requirement + | +LL | (): Trait<>::Assoc>, (): Trait fn(>::Assoc))> + | +++++++++++++++++++++++++++++++++++++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/async-await/in-trait/bad-signatures.stderr b/tests/ui/async-await/in-trait/bad-signatures.stderr index 127a343a93016..1f2f0537af3d1 100644 --- a/tests/ui/async-await/in-trait/bad-signatures.stderr +++ b/tests/ui/async-await/in-trait/bad-signatures.stderr @@ -8,10 +8,13 @@ error: expected one of `:`, `@`, or `|`, found keyword `self` --> $DIR/bad-signatures.rs:5:23 | LL | async fn bar(&abc self); - | -----^^^^ - | | | - | | expected one of `:`, `@`, or `|` - | help: declare the type after the parameter binding: `: ` + | ^^^^ expected one of `:`, `@`, or `|` + | +help: declare the type after the parameter binding + | +LL - async fn bar(&abc self); +LL + async fn bar(: ); + | error: aborting due to 2 previous errors diff --git a/tests/ui/async-await/no-async-const.stderr b/tests/ui/async-await/no-async-const.stderr index d692ba8f47375..be02ba17dbe67 100644 --- a/tests/ui/async-await/no-async-const.stderr +++ b/tests/ui/async-await/no-async-const.stderr @@ -2,12 +2,14 @@ error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `const --> $DIR/no-async-const.rs:4:11 | LL | pub async const fn x() {} - | ------^^^^^ - | | | - | | expected one of `extern`, `fn`, `safe`, or `unsafe` - | help: `const` must come before `async`: `const async` + | ^^^^^ expected one of `extern`, `fn`, `safe`, or `unsafe` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `const` must come before `async` + | +LL - pub async const fn x() {} +LL + pub const async fn x() {} + | error: functions cannot be both `const` and `async` --> $DIR/no-async-const.rs:4:5 diff --git a/tests/ui/async-await/no-unsafe-async.stderr b/tests/ui/async-await/no-unsafe-async.stderr index 49b112f9313d4..8db98f3c75493 100644 --- a/tests/ui/async-await/no-unsafe-async.stderr +++ b/tests/ui/async-await/no-unsafe-async.stderr @@ -2,23 +2,27 @@ error: expected one of `extern` or `fn`, found keyword `async` --> $DIR/no-unsafe-async.rs:7:12 | LL | unsafe async fn g() {} - | -------^^^^^ - | | | - | | expected one of `extern` or `fn` - | help: `async` must come before `unsafe`: `async unsafe` + | ^^^^^ expected one of `extern` or `fn` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `async` must come before `unsafe` + | +LL - unsafe async fn g() {} +LL + async unsafe fn g() {} + | error: expected one of `extern` or `fn`, found keyword `async` --> $DIR/no-unsafe-async.rs:11:8 | LL | unsafe async fn f() {} - | -------^^^^^ - | | | - | | expected one of `extern` or `fn` - | help: `async` must come before `unsafe`: `async unsafe` + | ^^^^^ expected one of `extern` or `fn` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `async` must come before `unsafe` + | +LL - unsafe async fn f() {} +LL + async unsafe fn f() {} + | error: aborting due to 2 previous errors diff --git a/tests/ui/attributes/attr-bad-crate-attr.stderr b/tests/ui/attributes/attr-bad-crate-attr.stderr index 22522896bd1a9..885afa445efbd 100644 --- a/tests/ui/attributes/attr-bad-crate-attr.stderr +++ b/tests/ui/attributes/attr-bad-crate-attr.stderr @@ -2,7 +2,7 @@ error: expected item after attributes --> $DIR/attr-bad-crate-attr.rs:7:1 | LL | #[attr = "val"] // Unterminated - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ expected an item after this error: aborting due to 1 previous error diff --git a/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.rs b/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.rs deleted file mode 100644 index 74e0a36560b08..0000000000000 --- a/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.rs +++ /dev/null @@ -1,7 +0,0 @@ -const fn foo(a: i32) -> Vec { - vec![1, 2, 3] - //~^ ERROR cannot call non-const - //~| ERROR cannot call non-const -} - -fn main() {} diff --git a/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr b/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr deleted file mode 100644 index a7e8fdf37ae29..0000000000000 --- a/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0015]: cannot call non-const associated function `Box::<[i32; 3]>::new_uninit` in constant functions - --> $DIR/bad_const_fn_body_ice.rs:2:5 - | -LL | vec![1, 2, 3] - | ^^^^^^^^^^^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - -error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in constant functions - --> $DIR/bad_const_fn_body_ice.rs:2:5 - | -LL | vec![1, 2, 3] - | ^^^^^^^^^^^^^ - | -note: function `box_assume_init_into_vec_unsafe` is not const - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/eii/implementation-attribute-allowlist-issue-159015.rs b/tests/ui/eii/implementation-attribute-allowlist-issue-159015.rs new file mode 100644 index 0000000000000..d27ea2a833e0f --- /dev/null +++ b/tests/ui/eii/implementation-attribute-allowlist-issue-159015.rs @@ -0,0 +1,102 @@ +// EII implementations only accept attributes from a conservative allowlist. +// Regression test for #159015 + +//@ edition: 2024 +//@ needs-asm-support + +#![feature(coverage_attribute)] +#![feature(extern_item_impls)] +#![feature(optimize_attribute)] +#![feature(sanitize)] + +#[eii] +fn allowed(); + +/// Sugared and explicit documentation attributes are both allowed. +#[allowed] +#[allow(dead_code)] +#[warn(unreachable_code)] +#[deny(unused_mut)] +#[forbid(unsafe_code)] +#[expect(unused_variables)] +#[cfg(all())] +#[doc = "An allowed EII implementation."] +#[cold] +#[optimize(none)] +#[coverage(off)] +#[sanitize(address = "off")] +#[must_use] +#[deprecated] +fn allowed_impl() { + let unused = (); +} + +#[eii] +fn allowed_inline(); + +#[allowed_inline] +#[allow(unused_attributes)] +#[cfg_attr(all(), inline)] +fn allowed_inline_impl() {} + +#[eii] +fn foo(); + +#[foo] +#[unsafe(no_mangle)] +//~^ ERROR `#[foo]` is not allowed to have `#[no_mangle]` +fn bar() {} + +#[eii] +fn baz(); + +#[baz] +#[unsafe(export_name = "qux")] +//~^ ERROR `#[baz]` is not allowed to have `#[export_name]` +fn qux() {} + +#[eii] +fn quux(); + +#[quux] +#[unsafe(link_section = "__TEXT,__text")] +//~^ ERROR `#[quux]` is not allowed to have `#[link_section]` +fn corge() {} + +#[eii] +fn grault(); + +#[grault] +#[track_caller] +//~^ ERROR `#[grault]` is not allowed to have `#[track_caller]` +fn garply() {} + +#[eii] +extern "C" fn naked_attr(); + +#[naked_attr] +#[unsafe(naked)] +//~^ ERROR `#[naked_attr]` is not allowed to have `#[naked]` +extern "C" fn naked_attr_impl() { + core::arch::naked_asm!("") +} + +#[eii] +fn multiple_invalid_attrs(); + +#[multiple_invalid_attrs] +#[unsafe(no_mangle)] +//~^ ERROR `#[multiple_invalid_attrs]` is not allowed to have `#[no_mangle]` +#[track_caller] +//~^ ERROR `#[multiple_invalid_attrs]` is not allowed to have `#[track_caller]` +fn multiple_invalid_attrs_impl() {} + +#[eii(static_eii)] +static STATIC_EII: u8; + +#[static_eii] +#[used] +//~^ ERROR `#[static_eii]` is not allowed to have `#[used]` +static STATIC_EII_IMPL: u8 = 0; + +fn main() {} diff --git a/tests/ui/eii/implementation-attribute-allowlist-issue-159015.stderr b/tests/ui/eii/implementation-attribute-allowlist-issue-159015.stderr new file mode 100644 index 0000000000000..af9673099f20f --- /dev/null +++ b/tests/ui/eii/implementation-attribute-allowlist-issue-159015.stderr @@ -0,0 +1,67 @@ +error: `#[foo]` is not allowed to have `#[no_mangle]` + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:46:1 + | +LL | #[foo] + | ------ `#[foo]` is not allowed to have `#[no_mangle]` +LL | #[unsafe(no_mangle)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: `#[baz]` is not allowed to have `#[export_name]` + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:54:1 + | +LL | #[baz] + | ------ `#[baz]` is not allowed to have `#[export_name]` +LL | #[unsafe(export_name = "qux")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `#[quux]` is not allowed to have `#[link_section]` + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:62:1 + | +LL | #[quux] + | ------- `#[quux]` is not allowed to have `#[link_section]` +LL | #[unsafe(link_section = "__TEXT,__text")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `#[grault]` is not allowed to have `#[track_caller]` + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:70:1 + | +LL | #[grault] + | --------- `#[grault]` is not allowed to have `#[track_caller]` +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ + +error: `#[naked_attr]` is not allowed to have `#[naked]` + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:78:1 + | +LL | #[naked_attr] + | ------------- `#[naked_attr]` is not allowed to have `#[naked]` +LL | #[unsafe(naked)] + | ^^^^^^^^^^^^^^^^ + +error: `#[multiple_invalid_attrs]` is not allowed to have `#[no_mangle]` + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:88:1 + | +LL | #[multiple_invalid_attrs] + | ------------------------- `#[multiple_invalid_attrs]` is not allowed to have `#[no_mangle]` +LL | #[unsafe(no_mangle)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: `#[multiple_invalid_attrs]` is not allowed to have `#[track_caller]` + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:90:1 + | +LL | #[multiple_invalid_attrs] + | ------------------------- `#[multiple_invalid_attrs]` is not allowed to have `#[track_caller]` +... +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ + +error: `#[static_eii]` is not allowed to have `#[used]` + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:98:1 + | +LL | #[static_eii] + | ------------- `#[static_eii]` is not allowed to have `#[used]` +LL | #[used] + | ^^^^^^^ + +error: aborting due to 8 previous errors + diff --git a/tests/ui/eii/track_caller_errors.stderr b/tests/ui/eii/track_caller_errors.stderr index e096146b67830..356f86093d638 100644 --- a/tests/ui/eii/track_caller_errors.stderr +++ b/tests/ui/eii/track_caller_errors.stderr @@ -4,8 +4,7 @@ error: `#[decl1]` is not allowed to have `#[track_caller]` LL | #[track_caller] | ^^^^^^^^^^^^^^^ LL | #[decl1] -LL | fn impl1(x: u64) { - | ---------------- `#[decl1]` is not allowed to have `#[track_caller]` + | -------- `#[decl1]` is not allowed to have `#[track_caller]` error: aborting due to 1 previous error diff --git a/tests/ui/parser/attribute/attr-before-eof.stderr b/tests/ui/parser/attribute/attr-before-eof.stderr index 18a9d77bf719c..849d7881b4ed3 100644 --- a/tests/ui/parser/attribute/attr-before-eof.stderr +++ b/tests/ui/parser/attribute/attr-before-eof.stderr @@ -2,7 +2,7 @@ error: expected item after attributes --> $DIR/attr-before-eof.rs:3:1 | LL | #[derive(Debug)] - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ expected an item after this error: aborting due to 1 previous error diff --git a/tests/ui/parser/attribute/attr-dangling-in-mod.stderr b/tests/ui/parser/attribute/attr-dangling-in-mod.stderr index 22cc092109d1d..6ab08317a6690 100644 --- a/tests/ui/parser/attribute/attr-dangling-in-mod.stderr +++ b/tests/ui/parser/attribute/attr-dangling-in-mod.stderr @@ -2,7 +2,7 @@ error: expected item after attributes --> $DIR/attr-dangling-in-mod.rs:4:1 | LL | #[foo = "bar"] - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ expected an item after this error: aborting due to 1 previous error diff --git a/tests/ui/parser/attribute/attr-with-a-semicolon.stderr b/tests/ui/parser/attribute/attr-with-a-semicolon.stderr index b77f30fdb5934..3edc60a3cba5c 100644 --- a/tests/ui/parser/attribute/attr-with-a-semicolon.stderr +++ b/tests/ui/parser/attribute/attr-with-a-semicolon.stderr @@ -2,9 +2,9 @@ error: expected item after attributes --> $DIR/attr-with-a-semicolon.rs:1:1 | LL | #[derive(Debug, Clone)]; - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ expected an item after this | -help: consider removing this semicolon +help: remove the semicolon after the attribute | LL - #[derive(Debug, Clone)]; LL + #[derive(Debug, Clone)] diff --git a/tests/ui/parser/attribute/attrs-after-extern-mod.stderr b/tests/ui/parser/attribute/attrs-after-extern-mod.stderr index f2bafa54f8dfe..639c575438bf7 100644 --- a/tests/ui/parser/attribute/attrs-after-extern-mod.stderr +++ b/tests/ui/parser/attribute/attrs-after-extern-mod.stderr @@ -4,7 +4,7 @@ error: expected item after attributes LL | extern "C" { | - while parsing this item list starting here LL | #[cfg(stage37)] - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ expected an item after this LL | } | - the item list ends here diff --git a/tests/ui/parser/doc-before-attr.stderr b/tests/ui/parser/doc-before-attr.stderr index 0298b9b60d2f3..3111df9187d69 100644 --- a/tests/ui/parser/doc-before-attr.stderr +++ b/tests/ui/parser/doc-before-attr.stderr @@ -4,7 +4,7 @@ error: expected item after attributes LL | /// hi | ------ other attributes here LL | #[derive(Debug)] - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ expected an item after this error: aborting due to 1 previous error diff --git a/tests/ui/parser/duplicate-visibility.stderr b/tests/ui/parser/duplicate-visibility.stderr index e00ebe6a8cf6d..a7d5a36c58bfd 100644 --- a/tests/ui/parser/duplicate-visibility.stderr +++ b/tests/ui/parser/duplicate-visibility.stderr @@ -4,10 +4,7 @@ error: expected one of `(`, `async`, `const`, `default`, `extern`, `final`, `fn` LL | extern "C" { | - while parsing this item list starting here LL | pub pub fn foo(); - | ^^^ - | | - | expected one of 10 possible tokens - | help: there is already a visibility modifier, remove one + | ^^^ expected one of 10 possible tokens ... LL | } | - the item list ends here @@ -17,6 +14,11 @@ note: explicit visibility first seen here | LL | pub pub fn foo(); | ^^^ +help: there is already a visibility modifier, remove one + | +LL - pub pub fn foo(); +LL + pub fn foo(); + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/eq-less-to-less-eq.stderr b/tests/ui/parser/eq-less-to-less-eq.stderr index 4717d8287ff7b..efed3e2096f30 100644 --- a/tests/ui/parser/eq-less-to-less-eq.stderr +++ b/tests/ui/parser/eq-less-to-less-eq.stderr @@ -2,9 +2,13 @@ error: expected one of `!`, `(`, `+`, `::`, `<`, `>`, or `as`, found `{` --> $DIR/eq-less-to-less-eq.rs:4:15 | LL | if a =< b { - | -- ^ expected one of 7 possible tokens - | | - | help: did you mean: `<=` + | ^ expected one of 7 possible tokens + | +help: you might have meant to write a "less than or equal to" comparison + | +LL - if a =< b { +LL + if a <= b { + | error: expected one of `!`, `(`, `+`, `::`, `<`, `>`, or `as`, found `{` --> $DIR/eq-less-to-less-eq.rs:12:15 diff --git a/tests/ui/parser/inverted-parameters.stderr b/tests/ui/parser/inverted-parameters.stderr index 93b95a756087d..8eea01b19ccba 100644 --- a/tests/ui/parser/inverted-parameters.stderr +++ b/tests/ui/parser/inverted-parameters.stderr @@ -2,19 +2,25 @@ error: expected one of `:`, `@`, or `|`, found `bar` --> $DIR/inverted-parameters.rs:6:24 | LL | fn foo(&self, &str bar) {} - | -----^^^ - | | | - | | expected one of `:`, `@`, or `|` - | help: declare the type after the parameter binding: `: ` + | ^^^ expected one of `:`, `@`, or `|` + | +help: declare the type after the parameter binding + | +LL - fn foo(&self, &str bar) {} +LL + fn foo(&self, : ) {} + | error: expected one of `:`, `@`, or `|`, found `quux` --> $DIR/inverted-parameters.rs:12:10 | LL | fn baz(S quux, xyzzy: i32) {} - | --^^^^ - | | | - | | expected one of `:`, `@`, or `|` - | help: declare the type after the parameter binding: `: ` + | ^^^^ expected one of `:`, `@`, or `|` + | +help: declare the type after the parameter binding + | +LL - fn baz(S quux, xyzzy: i32) {} +LL + fn baz(: , xyzzy: i32) {} + | error: expected one of `:`, `@`, or `|`, found `a` --> $DIR/inverted-parameters.rs:17:12 @@ -47,10 +53,13 @@ error: expected one of `:`, `@`, or `|`, found `S` --> $DIR/inverted-parameters.rs:28:23 | LL | fn missing_colon(quux S) {} - | -----^ - | | | - | | expected one of `:`, `@`, or `|` - | help: declare the type after the parameter binding: `: ` + | ^ expected one of `:`, `@`, or `|` + | +help: declare the type after the parameter binding + | +LL - fn missing_colon(quux S) {} +LL + fn missing_colon(: ) {} + | error: aborting due to 6 previous errors diff --git a/tests/ui/parser/issues/issue-113342.stderr b/tests/ui/parser/issues/issue-113342.stderr index 6d9f22f6a7ce8..bc7aad3c03fbe 100644 --- a/tests/ui/parser/issues/issue-113342.stderr +++ b/tests/ui/parser/issues/issue-113342.stderr @@ -2,10 +2,13 @@ error: expected `fn`, found keyword `pub` --> $DIR/issue-113342.rs:7:12 | LL | extern "C" pub fn id(x: i32) -> i32 { x } - | -----------^^^ - | | | - | | expected `fn` - | help: visibility `pub` must come before `extern "C"`: `pub extern "C"` + | ^^^ expected `fn` + | +help: visibility `pub` must come before `extern "C"` + | +LL - extern "C" pub fn id(x: i32) -> i32 { x } +LL + pub extern "C" fn id(x: i32) -> i32 { x } + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-19398.stderr b/tests/ui/parser/issues/issue-19398.stderr index 2b97ec50c9172..3fd8bb40a0b8e 100644 --- a/tests/ui/parser/issues/issue-19398.stderr +++ b/tests/ui/parser/issues/issue-19398.stderr @@ -2,12 +2,14 @@ error: expected `fn`, found keyword `unsafe` --> $DIR/issue-19398.rs:2:19 | LL | extern "Rust" unsafe fn foo(); - | --------------^^^^^^ - | | | - | | expected `fn` - | help: `unsafe` must come before `extern "Rust"`: `unsafe extern "Rust"` + | ^^^^^^ expected `fn` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `unsafe` must come before `extern "Rust"` + | +LL - extern "Rust" unsafe fn foo(); +LL + unsafe extern "Rust" fn foo(); + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-20711-2.stderr b/tests/ui/parser/issues/issue-20711-2.stderr index 9fb7298955b38..738675999144f 100644 --- a/tests/ui/parser/issues/issue-20711-2.stderr +++ b/tests/ui/parser/issues/issue-20711-2.stderr @@ -5,7 +5,7 @@ LL | impl Foo { | - while parsing this item list starting here ... LL | #[stable(feature = "rust1", since = "1.0.0")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an item after this LL | LL | } | - the item list ends here diff --git a/tests/ui/parser/issues/issue-20711.stderr b/tests/ui/parser/issues/issue-20711.stderr index 256fb0ade7212..e5911c033ac9d 100644 --- a/tests/ui/parser/issues/issue-20711.stderr +++ b/tests/ui/parser/issues/issue-20711.stderr @@ -4,7 +4,7 @@ error: expected item after attributes LL | impl Foo { | - while parsing this item list starting here LL | #[stable(feature = "rust1", since = "1.0.0")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an item after this LL | LL | } | - the item list ends here diff --git a/tests/ui/parser/issues/issue-76437-async.stderr b/tests/ui/parser/issues/issue-76437-async.stderr index 483599135f566..4a02c045c7cf2 100644 --- a/tests/ui/parser/issues/issue-76437-async.stderr +++ b/tests/ui/parser/issues/issue-76437-async.stderr @@ -2,10 +2,13 @@ error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub` --> $DIR/issue-76437-async.rs:4:11 | LL | async pub fn t() {} - | ------^^^ - | | | - | | expected one of `extern`, `fn`, `safe`, or `unsafe` - | help: visibility `pub` must come before `async`: `pub async` + | ^^^ expected one of `extern`, `fn`, `safe`, or `unsafe` + | +help: visibility `pub` must come before `async` + | +LL - async pub fn t() {} +LL + pub async fn t() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-76437-const-async-unsafe.stderr b/tests/ui/parser/issues/issue-76437-const-async-unsafe.stderr index a703fc4e8a452..b296add2beb0a 100644 --- a/tests/ui/parser/issues/issue-76437-const-async-unsafe.stderr +++ b/tests/ui/parser/issues/issue-76437-const-async-unsafe.stderr @@ -2,10 +2,13 @@ error: expected one of `extern` or `fn`, found keyword `pub` --> $DIR/issue-76437-const-async-unsafe.rs:4:24 | LL | const async unsafe pub fn t() {} - | -------------------^^^ - | | | - | | expected one of `extern` or `fn` - | help: visibility `pub` must come before `const async unsafe`: `pub const async unsafe` + | ^^^ expected one of `extern` or `fn` + | +help: visibility `pub` must come before `const async unsafe` + | +LL - const async unsafe pub fn t() {} +LL + pub const async unsafe fn t() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-76437-const-async.stderr b/tests/ui/parser/issues/issue-76437-const-async.stderr index 81fa8a5f557e0..3d1fc4dc4fdd8 100644 --- a/tests/ui/parser/issues/issue-76437-const-async.stderr +++ b/tests/ui/parser/issues/issue-76437-const-async.stderr @@ -2,10 +2,13 @@ error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub` --> $DIR/issue-76437-const-async.rs:4:17 | LL | const async pub fn t() {} - | ------------^^^ - | | | - | | expected one of `extern`, `fn`, `safe`, or `unsafe` - | help: visibility `pub` must come before `const async`: `pub const async` + | ^^^ expected one of `extern`, `fn`, `safe`, or `unsafe` + | +help: visibility `pub` must come before `const async` + | +LL - const async pub fn t() {} +LL + pub const async fn t() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-76437-const.stderr b/tests/ui/parser/issues/issue-76437-const.stderr index 005a27b7c2498..2ebf2042ebd67 100644 --- a/tests/ui/parser/issues/issue-76437-const.stderr +++ b/tests/ui/parser/issues/issue-76437-const.stderr @@ -2,10 +2,13 @@ error: expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keywo --> $DIR/issue-76437-const.rs:4:11 | LL | const pub fn t() {} - | ------^^^ - | | | - | | expected one of `async`, `extern`, `fn`, `safe`, or `unsafe` - | help: visibility `pub` must come before `const`: `pub const` + | ^^^ expected one of `async`, `extern`, `fn`, `safe`, or `unsafe` + | +help: visibility `pub` must come before `const` + | +LL - const pub fn t() {} +LL + pub const fn t() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-76437-pub-crate-unsafe.stderr b/tests/ui/parser/issues/issue-76437-pub-crate-unsafe.stderr index 4ea76179be3f6..1cae371ae57ea 100644 --- a/tests/ui/parser/issues/issue-76437-pub-crate-unsafe.stderr +++ b/tests/ui/parser/issues/issue-76437-pub-crate-unsafe.stderr @@ -2,10 +2,13 @@ error: expected one of `extern` or `fn`, found keyword `pub` --> $DIR/issue-76437-pub-crate-unsafe.rs:4:12 | LL | unsafe pub(crate) fn t() {} - | -------^^^------- - | | | - | | expected one of `extern` or `fn` - | help: visibility `pub(crate)` must come before `unsafe`: `pub(crate) unsafe` + | ^^^ expected one of `extern` or `fn` + | +help: visibility `pub(crate)` must come before `unsafe` + | +LL - unsafe pub(crate) fn t() {} +LL + pub(crate) unsafe fn t() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-76437-unsafe.stderr b/tests/ui/parser/issues/issue-76437-unsafe.stderr index 69f7927750bf0..fb3abb7e9a669 100644 --- a/tests/ui/parser/issues/issue-76437-unsafe.stderr +++ b/tests/ui/parser/issues/issue-76437-unsafe.stderr @@ -2,10 +2,13 @@ error: expected one of `extern` or `fn`, found keyword `pub` --> $DIR/issue-76437-unsafe.rs:4:12 | LL | unsafe pub fn t() {} - | -------^^^ - | | | - | | expected one of `extern` or `fn` - | help: visibility `pub` must come before `unsafe`: `pub unsafe` + | ^^^ expected one of `extern` or `fn` + | +help: visibility `pub` must come before `unsafe` + | +LL - unsafe pub fn t() {} +LL + pub unsafe fn t() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr b/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr index ed2e4d8154929..692fbc0350953 100644 --- a/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr +++ b/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr @@ -2,16 +2,18 @@ error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `const --> $DIR/const-async-const.rs:5:13 | LL | const async const fn test() {} - | ^^^^^ - | | - | expected one of `extern`, `fn`, `safe`, or `unsafe` - | help: `const` already used earlier, remove this one + | ^^^^^ expected one of `extern`, `fn`, `safe`, or `unsafe` | note: `const` first seen here --> $DIR/const-async-const.rs:5:1 | LL | const async const fn test() {} | ^^^^^ +help: `const` already used earlier, remove this one + | +LL - const async const fn test() {} +LL + const async fn test() {} + | error: functions cannot be both `const` and `async` --> $DIR/const-async-const.rs:5:1 diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/recovery.stderr b/tests/ui/parser/issues/issue-87217-keyword-order/recovery.stderr index 3f504a9ebfc49..a1b3a29c2dd27 100644 --- a/tests/ui/parser/issues/issue-87217-keyword-order/recovery.stderr +++ b/tests/ui/parser/issues/issue-87217-keyword-order/recovery.stderr @@ -2,27 +2,31 @@ error: expected one of `extern` or `fn`, found keyword `const` --> $DIR/recovery.rs:6:12 | LL | unsafe const fn from_u32(val: u32) {} - | -------^^^^^ - | | | - | | expected one of `extern` or `fn` - | help: `const` must come before `unsafe`: `const unsafe` + | ^^^^^ expected one of `extern` or `fn` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `const` must come before `unsafe` + | +LL - unsafe const fn from_u32(val: u32) {} +LL + const unsafe fn from_u32(val: u32) {} + | error: expected one of `extern` or `fn`, found keyword `unsafe` --> $DIR/recovery.rs:14:12 | LL | unsafe unsafe fn from_u32(val: u32) {} - | ^^^^^^ - | | - | expected one of `extern` or `fn` - | help: `unsafe` already used earlier, remove this one + | ^^^^^^ expected one of `extern` or `fn` | note: `unsafe` first seen here --> $DIR/recovery.rs:14:5 | LL | unsafe unsafe fn from_u32(val: u32) {} | ^^^^^^ +help: `unsafe` already used earlier, remove this one + | +LL - unsafe unsafe fn from_u32(val: u32) {} +LL + unsafe fn from_u32(val: u32) {} + | error: aborting due to 2 previous errors diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.stderr b/tests/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.stderr index 489e8eefb052e..ccab054540691 100644 --- a/tests/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.stderr +++ b/tests/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.stderr @@ -2,12 +2,14 @@ error: expected one of `extern` or `fn`, found keyword `const` --> $DIR/several-kw-jump.rs:9:14 | LL | async unsafe const fn test() {} - | -------------^^^^^ - | | | - | | expected one of `extern` or `fn` - | help: `const` must come before `async unsafe`: `const async unsafe` + | ^^^^^ expected one of `extern` or `fn` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `const` must come before `async unsafe` + | +LL - async unsafe const fn test() {} +LL + const async unsafe fn test() {} + | error: functions cannot be both `const` and `async` --> $DIR/several-kw-jump.rs:9:1 diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-async.stderr b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-async.stderr index 74989502e7f5d..5423f72fc786b 100644 --- a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-async.stderr +++ b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-async.stderr @@ -2,12 +2,14 @@ error: expected one of `extern` or `fn`, found keyword `async` --> $DIR/wrong-async.rs:9:8 | LL | unsafe async fn test() {} - | -------^^^^^ - | | | - | | expected one of `extern` or `fn` - | help: `async` must come before `unsafe`: `async unsafe` + | ^^^^^ expected one of `extern` or `fn` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `async` must come before `unsafe` + | +LL - unsafe async fn test() {} +LL + async unsafe fn test() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-const.stderr b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-const.stderr index 5958f0c7d2ddd..9d68538ec804f 100644 --- a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-const.stderr +++ b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-const.stderr @@ -2,12 +2,14 @@ error: expected one of `extern` or `fn`, found keyword `const` --> $DIR/wrong-const.rs:9:8 | LL | unsafe const fn test() {} - | -------^^^^^ - | | | - | | expected one of `extern` or `fn` - | help: `const` must come before `unsafe`: `const unsafe` + | ^^^^^ expected one of `extern` or `fn` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `const` must come before `unsafe` + | +LL - unsafe const fn test() {} +LL + const unsafe fn test() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.stderr b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.stderr index 8ed037869c829..eee9b0b8b8270 100644 --- a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.stderr +++ b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.stderr @@ -2,12 +2,14 @@ error: expected `fn`, found keyword `unsafe` --> $DIR/wrong-unsafe-abi.rs:9:12 | LL | extern "C" unsafe fn test() {} - | -----------^^^^^^ - | | | - | | expected `fn` - | help: `unsafe` must come before `extern "C"`: `unsafe extern "C"` + | ^^^^^^ expected `fn` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `unsafe` must come before `extern "C"` + | +LL - extern "C" unsafe fn test() {} +LL + unsafe extern "C" fn test() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr index 232da9acef309..e6ea40f15ae8a 100644 --- a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr +++ b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr @@ -2,12 +2,14 @@ error: expected `fn`, found keyword `unsafe` --> $DIR/wrong-unsafe.rs:10:8 | LL | extern unsafe fn test() {} - | -------^^^^^^ - | | | - | | expected `fn` - | help: `unsafe` must come before `extern`: `unsafe extern` + | ^^^^^^ expected `fn` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `unsafe` must come before `extern` + | +LL - extern unsafe fn test() {} +LL + unsafe extern fn test() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-87694-duplicated-pub.stderr b/tests/ui/parser/issues/issue-87694-duplicated-pub.stderr index dd75f32f68ff2..50d58ffb2fb35 100644 --- a/tests/ui/parser/issues/issue-87694-duplicated-pub.stderr +++ b/tests/ui/parser/issues/issue-87694-duplicated-pub.stderr @@ -2,16 +2,18 @@ error: expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keywo --> $DIR/issue-87694-duplicated-pub.rs:1:11 | LL | pub const pub fn test() {} - | ^^^ - | | - | expected one of `async`, `extern`, `fn`, `safe`, or `unsafe` - | help: there is already a visibility modifier, remove one + | ^^^ expected one of `async`, `extern`, `fn`, `safe`, or `unsafe` | note: explicit visibility first seen here --> $DIR/issue-87694-duplicated-pub.rs:1:1 | LL | pub const pub fn test() {} | ^^^ +help: there is already a visibility modifier, remove one + | +LL - pub const pub fn test() {} +LL + pub const fn test() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-87694-misplaced-pub.stderr b/tests/ui/parser/issues/issue-87694-misplaced-pub.stderr index d35e09dceaf7f..fcdd07a91182c 100644 --- a/tests/ui/parser/issues/issue-87694-misplaced-pub.stderr +++ b/tests/ui/parser/issues/issue-87694-misplaced-pub.stderr @@ -2,10 +2,13 @@ error: expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keywo --> $DIR/issue-87694-misplaced-pub.rs:1:7 | LL | const pub fn test() {} - | ------^^^ - | | | - | | expected one of `async`, `extern`, `fn`, `safe`, or `unsafe` - | help: visibility `pub` must come before `const`: `pub const` + | ^^^ expected one of `async`, `extern`, `fn`, `safe`, or `unsafe` + | +help: visibility `pub` must come before `const` + | +LL - const pub fn test() {} +LL + pub const fn test() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-89396.stderr b/tests/ui/parser/issues/issue-89396.stderr index 41ce07050746a..8773a7516ff88 100644 --- a/tests/ui/parser/issues/issue-89396.stderr +++ b/tests/ui/parser/issues/issue-89396.stderr @@ -2,19 +2,24 @@ error: expected one of `=>`, `if`, or `|`, found `=` --> $DIR/issue-89396.rs:9:17 | LL | Some(_) = true, - | ^ - | | - | expected one of `=>`, `if`, or `|` - | help: use a fat arrow to start a match arm: `=>` + | ^ expected one of `=>`, `if`, or `|` + | +help: use a fat arrow to start a match arm + | +LL | Some(_) => true, + | + error: expected one of `=>`, `@`, `if`, or `|`, found `->` --> $DIR/issue-89396.rs:12:14 | LL | None -> false, - | ^^ - | | - | expected one of `=>`, `@`, `if`, or `|` - | help: use a fat arrow to start a match arm: `=>` + | ^^ expected one of `=>`, `@`, `if`, or `|` + | +help: use a fat arrow to start a match arm + | +LL - None -> false, +LL + None => false, + | error: aborting due to 2 previous errors diff --git a/tests/ui/parser/issues/recover-ge-as-fat-arrow.stderr b/tests/ui/parser/issues/recover-ge-as-fat-arrow.stderr index 997d080f1deed..2a8c78a776b9e 100644 --- a/tests/ui/parser/issues/recover-ge-as-fat-arrow.stderr +++ b/tests/ui/parser/issues/recover-ge-as-fat-arrow.stderr @@ -2,10 +2,13 @@ error: expected one of `...`, `..=`, `..`, `=>`, `if`, or `|`, found `>=` --> $DIR/recover-ge-as-fat-arrow.rs:4:11 | LL | 1 >= {} - | ^^ - | | - | expected one of `...`, `..=`, `..`, `=>`, `if`, or `|` - | help: use a fat arrow to start a match arm: `=>` + | ^^ expected one of `...`, `..=`, `..`, `=>`, `if`, or `|` + | +help: use a fat arrow to start a match arm + | +LL - 1 >= {} +LL + 1 => {} + | error[E0308]: mismatched types --> $DIR/recover-ge-as-fat-arrow.rs:5:29 diff --git a/tests/ui/parser/macro/kw-in-item-pos-recovery-151238.stderr b/tests/ui/parser/macro/kw-in-item-pos-recovery-151238.stderr index 81151edaf0c0c..3a7e4779aadfb 100644 --- a/tests/ui/parser/macro/kw-in-item-pos-recovery-151238.stderr +++ b/tests/ui/parser/macro/kw-in-item-pos-recovery-151238.stderr @@ -8,10 +8,13 @@ error: expected one of `:`, `@`, or `|`, found keyword `self` --> $DIR/kw-in-item-pos-recovery-151238.rs:7:28 | LL | trait MyTrait { fn bar(c self) } - | --^^^^ - | | | - | | expected one of `:`, `@`, or `|` - | help: declare the type after the parameter binding: `: ` + | ^^^^ expected one of `:`, `@`, or `|` + | +help: declare the type after the parameter binding + | +LL - trait MyTrait { fn bar(c self) } +LL + trait MyTrait { fn bar(: ) } + | error: expected one of `->`, `;`, `where`, or `{`, found `}` --> $DIR/kw-in-item-pos-recovery-151238.rs:7:34 diff --git a/tests/ui/parser/macro/misspelled-macro-rules.stderr b/tests/ui/parser/macro/misspelled-macro-rules.stderr index fc718d8556dfe..bf401caff318b 100644 --- a/tests/ui/parser/macro/misspelled-macro-rules.stderr +++ b/tests/ui/parser/macro/misspelled-macro-rules.stderr @@ -2,9 +2,13 @@ error: expected one of `(`, `[`, or `{`, found `thing` --> $DIR/misspelled-macro-rules.rs:7:14 | LL | marco_rules! thing { - | ----------- ^^^^^ expected one of `(`, `[`, or `{` - | | - | help: perhaps you meant to define a macro: `macro_rules` + | ^^^^^ expected one of `(`, `[`, or `{` + | +help: perhaps you meant to define a macro + | +LL - marco_rules! thing { +LL + macro_rules! thing { + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/range-exclusive-dotdotlt.stderr b/tests/ui/parser/range-exclusive-dotdotlt.stderr index af25e1df343de..9a38473b64403 100644 --- a/tests/ui/parser/range-exclusive-dotdotlt.stderr +++ b/tests/ui/parser/range-exclusive-dotdotlt.stderr @@ -2,17 +2,25 @@ error: expected type, found `10` --> $DIR/range-exclusive-dotdotlt.rs:2:17 | LL | let _ = 0..<10; - | -^^ expected type - | | - | help: remove the `<` to write an exclusive range + | ^^ expected type + | +help: remove the `<` to write an exclusive range + | +LL - let _ = 0..<10; +LL + let _ = 0..10; + | error: expected one of `!`, `(`, `+`, `::`, `<`, `>`, or `as`, found `;` --> $DIR/range-exclusive-dotdotlt.rs:8:20 | LL | let _ = 0.. $DIR/range-exclusive-dotdotlt.rs:14:18 @@ -24,17 +32,25 @@ error: expected type, found `1` --> $DIR/range-exclusive-dotdotlt.rs:19:26 | LL | let _ = [1, 2, 3][..<1]; - | -^ expected type - | | - | help: remove the `<` to write an exclusive range + | ^ expected type + | +help: remove the `<` to write an exclusive range + | +LL - let _ = [1, 2, 3][..<1]; +LL + let _ = [1, 2, 3][..1]; + | error: expected one of `!`, `(`, `+`, `::`, `<`, `>`, or `as`, found `]` --> $DIR/range-exclusive-dotdotlt.rs:25:29 | LL | let _ = [1, 2, 3][.. $DIR/range-exclusive-dotdotlt.rs:31:30 diff --git a/tests/ui/parser/raw/raw-byte-string-eof.stderr b/tests/ui/parser/raw/raw-byte-string-eof.stderr index 88fd53904c43f..96bc893a4d4cb 100644 --- a/tests/ui/parser/raw/raw-byte-string-eof.stderr +++ b/tests/ui/parser/raw/raw-byte-string-eof.stderr @@ -2,11 +2,13 @@ error[E0748]: unterminated raw string --> $DIR/raw-byte-string-eof.rs:2:5 | LL | br##"a"#; - | ^ - help: consider terminating the string here: `##` - | | - | unterminated raw string + | ^ unterminated raw string | = note: this raw string should be terminated with `"##` +help: consider terminating the string here + | +LL | br##"a"##; + | + error: aborting due to 1 previous error diff --git a/tests/ui/parser/raw/raw-str-unbalanced.stderr b/tests/ui/parser/raw/raw-str-unbalanced.stderr index eac8c06c1df5c..d957e555883b6 100644 --- a/tests/ui/parser/raw/raw-str-unbalanced.stderr +++ b/tests/ui/parser/raw/raw-str-unbalanced.stderr @@ -2,18 +2,30 @@ error: too many `#` when terminating raw string --> $DIR/raw-str-unbalanced.rs:2:10 | LL | r#""## - | -----^ help: remove the extra `#` + | -----^ | | | this raw string started with 1 `#` + | +help: remove the extra `#` + | +LL - r#""## +LL + r#""# + | error: too many `#` when terminating raw string --> $DIR/raw-str-unbalanced.rs:7:9 | LL | / r#" LL | | "#### - | | -^^^ help: remove the extra `#`s + | | -^^^ | |________| | this raw string started with 1 `#` + | +help: remove the extra `#`s + | +LL - "#### +LL + "# + | error: expected `;`, found `#` --> $DIR/raw-str-unbalanced.rs:10:28 @@ -28,9 +40,15 @@ error: too many `#` when terminating raw string --> $DIR/raw-str-unbalanced.rs:16:28 | LL | const B: &'static str = r""## - | ---^^ help: remove the extra `#`s + | ---^^ | | | this raw string started with 0 `#`s + | +help: remove the extra `#`s + | +LL - const B: &'static str = r""## +LL + const B: &'static str = r"" + | error: aborting due to 4 previous errors diff --git a/tests/ui/parser/raw/raw-string-2.stderr b/tests/ui/parser/raw/raw-string-2.stderr index 90dd9775e62e4..f390155904f69 100644 --- a/tests/ui/parser/raw/raw-string-2.stderr +++ b/tests/ui/parser/raw/raw-string-2.stderr @@ -2,9 +2,13 @@ error[E0748]: unterminated raw string --> $DIR/raw-string-2.rs:2:13 | LL | let x = r###"here's a long string"# "# "##; - | ^ unterminated raw string -- help: consider terminating the string here: `###` + | ^ unterminated raw string | = note: this raw string should be terminated with `"###` +help: consider terminating the string here + | +LL | let x = r###"here's a long string"# "# "###; + | + error: aborting due to 1 previous error diff --git a/tests/ui/parser/raw/raw-string.stderr b/tests/ui/parser/raw/raw-string.stderr index 6654ef7a75a42..07a664ef1aad3 100644 --- a/tests/ui/parser/raw/raw-string.stderr +++ b/tests/ui/parser/raw/raw-string.stderr @@ -2,11 +2,13 @@ error[E0748]: unterminated raw string --> $DIR/raw-string.rs:2:13 | LL | let x = r##"lol"#; - | ^ - help: consider terminating the string here: `##` - | | - | unterminated raw string + | ^ unterminated raw string | = note: this raw string should be terminated with `"##` +help: consider terminating the string here + | +LL | let x = r##"lol"##; + | + error: aborting due to 1 previous error diff --git a/tests/ui/parser/removed-syntax/removed-syntax-field-let-2.stderr b/tests/ui/parser/removed-syntax/removed-syntax-field-let-2.stderr index fda0919b9b647..e9d6630bd629f 100644 --- a/tests/ui/parser/removed-syntax/removed-syntax-field-let-2.stderr +++ b/tests/ui/parser/removed-syntax/removed-syntax-field-let-2.stderr @@ -2,25 +2,29 @@ error: expected identifier, found keyword `let` --> $DIR/removed-syntax-field-let-2.rs:2:5 | LL | let x: i32, - | ^^^- - | | - | expected identifier, found keyword - | help: remove this `let` keyword + | ^^^ expected identifier, found keyword | = note: the `let` keyword is not allowed in `struct` fields = note: see for more information +help: remove the `let` keyword + | +LL - let x: i32, +LL + x: i32, + | error: expected identifier, found keyword `let` --> $DIR/removed-syntax-field-let-2.rs:4:5 | LL | let y: i32, - | ^^^- - | | - | expected identifier, found keyword - | help: remove this `let` keyword + | ^^^ expected identifier, found keyword | = note: the `let` keyword is not allowed in `struct` fields = note: see for more information +help: remove the `let` keyword + | +LL - let y: i32, +LL + y: i32, + | error[E0063]: missing fields `x` and `y` in initializer of `Foo` --> $DIR/removed-syntax-field-let-2.rs:9:13 diff --git a/tests/ui/parser/removed-syntax/removed-syntax-field-let.stderr b/tests/ui/parser/removed-syntax/removed-syntax-field-let.stderr index 339d056e6360f..e470031207631 100644 --- a/tests/ui/parser/removed-syntax/removed-syntax-field-let.stderr +++ b/tests/ui/parser/removed-syntax/removed-syntax-field-let.stderr @@ -2,13 +2,15 @@ error: expected identifier, found keyword `let` --> $DIR/removed-syntax-field-let.rs:2:5 | LL | let foo: (), - | ^^^- - | | - | expected identifier, found keyword - | help: remove this `let` keyword + | ^^^ expected identifier, found keyword | = note: the `let` keyword is not allowed in `struct` fields = note: see for more information +help: remove the `let` keyword + | +LL - let foo: (), +LL + foo: (), + | error: aborting due to 1 previous error diff --git a/tests/ui/statics/check-values-constraints.rs b/tests/ui/statics/check-values-constraints.rs index c62abd75a304b..6f1635b761b07 100644 --- a/tests/ui/statics/check-values-constraints.rs +++ b/tests/ui/statics/check-values-constraints.rs @@ -1,5 +1,6 @@ // Verifies all possible restrictions for statics values. +#![feature(const_heap)] #![allow(warnings)] use std::marker; @@ -79,8 +80,6 @@ static STATIC10: UnsafeStruct = UnsafeStruct; struct MyOwned; static STATIC11: Vec = vec![MyOwned]; -//~^ ERROR cannot call non-const function -//~| ERROR cannot call non-const static mut STATIC12: UnsafeStruct = UnsafeStruct; @@ -93,29 +92,25 @@ static mut STATIC14: SafeStruct = SafeStruct { }; static STATIC15: &'static [Vec] = &[ - vec![MyOwned], //~ ERROR cannot call non-const function - //~| ERROR cannot call non-const - vec![MyOwned], //~ ERROR cannot call non-const function - //~| ERROR cannot call non-const + vec![MyOwned], + vec![MyOwned], ]; static STATIC16: (&'static Vec, &'static Vec) = ( - &vec![MyOwned], //~ ERROR cannot call non-const function - //~| ERROR cannot call non-const - &vec![MyOwned], //~ ERROR cannot call non-const function - //~| ERROR cannot call non-const + &vec![MyOwned], + &vec![MyOwned], ); static mut STATIC17: SafeEnum = SafeEnum::Variant1; static STATIC19: Vec = vec![3]; -//~^ ERROR cannot call non-const function -//~| ERROR cannot call non-const +//~^ ERROR encountered `const_allocate` pointer in final value that was not made global + pub fn main() { let y = { - static x: Vec = vec![3]; //~ ERROR cannot call non-const function - //~| ERROR cannot call non-const + static x: Vec = vec![3]; + //~^ ERROR encountered `const_allocate` pointer in final value that was not made global x //~^ ERROR cannot move out of static }; diff --git a/tests/ui/statics/check-values-constraints.stderr b/tests/ui/statics/check-values-constraints.stderr index 94d2b8ce80641..a3d49400703be 100644 --- a/tests/ui/statics/check-values-constraints.stderr +++ b/tests/ui/statics/check-values-constraints.stderr @@ -1,5 +1,5 @@ error[E0493]: destructor of `SafeStruct` cannot be evaluated at compile-time - --> $DIR/check-values-constraints.rs:64:7 + --> $DIR/check-values-constraints.rs:65:7 | LL | ..SafeStruct { | _______^ @@ -11,28 +11,8 @@ LL | | } LL | }; | - value is dropped here -error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics - --> $DIR/check-values-constraints.rs:81:33 - | -LL | static STATIC11: Vec = vec![MyOwned]; - | ^^^^^^^^^^^^^ - | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in statics - --> $DIR/check-values-constraints.rs:81:33 - | -LL | static STATIC11: Vec = vec![MyOwned]; - | ^^^^^^^^^^^^^ - | -note: function `box_assume_init_into_vec_unsafe` is not const - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - error[E0015]: cannot call non-const method `::to_string` in statics - --> $DIR/check-values-constraints.rs:92:38 + --> $DIR/check-values-constraints.rs:91:38 | LL | field2: SafeEnum::Variant4("str".to_string()), | ^^^^^^^^^^^ @@ -47,128 +27,24 @@ note: method `to_string` is not const because trait `ToString` is not const = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` -error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics - --> $DIR/check-values-constraints.rs:96:5 - | -LL | vec![MyOwned], - | ^^^^^^^^^^^^^ - | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in statics - --> $DIR/check-values-constraints.rs:96:5 - | -LL | vec![MyOwned], - | ^^^^^^^^^^^^^ - | -note: function `box_assume_init_into_vec_unsafe` is not const - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics - --> $DIR/check-values-constraints.rs:98:5 - | -LL | vec![MyOwned], - | ^^^^^^^^^^^^^ - | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in statics - --> $DIR/check-values-constraints.rs:98:5 - | -LL | vec![MyOwned], - | ^^^^^^^^^^^^^ - | -note: function `box_assume_init_into_vec_unsafe` is not const - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics - --> $DIR/check-values-constraints.rs:103:6 - | -LL | &vec![MyOwned], - | ^^^^^^^^^^^^^ - | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in statics - --> $DIR/check-values-constraints.rs:103:6 - | -LL | &vec![MyOwned], - | ^^^^^^^^^^^^^ - | -note: function `box_assume_init_into_vec_unsafe` is not const - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics - --> $DIR/check-values-constraints.rs:105:6 - | -LL | &vec![MyOwned], - | ^^^^^^^^^^^^^ - | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in statics - --> $DIR/check-values-constraints.rs:105:6 - | -LL | &vec![MyOwned], - | ^^^^^^^^^^^^^ - | -note: function `box_assume_init_into_vec_unsafe` is not const - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const associated function `Box::<[isize; 1]>::new_uninit` in statics - --> $DIR/check-values-constraints.rs:111:31 +error: encountered `const_allocate` pointer in final value that was not made global + --> $DIR/check-values-constraints.rs:106:1 | LL | static STATIC19: Vec = vec![3]; - | ^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in statics - --> $DIR/check-values-constraints.rs:111:31 - | -LL | static STATIC19: Vec = vec![3]; - | ^^^^^^^ - | -note: function `box_assume_init_into_vec_unsafe` is not const - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` + = note: use `const_make_global` to turn allocated pointers into immutable globals before returning -error[E0015]: cannot call non-const associated function `Box::<[isize; 1]>::new_uninit` in statics - --> $DIR/check-values-constraints.rs:117:32 +error: encountered `const_allocate` pointer in final value that was not made global + --> $DIR/check-values-constraints.rs:112:9 | LL | static x: Vec = vec![3]; - | ^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in statics - --> $DIR/check-values-constraints.rs:117:32 - | -LL | static x: Vec = vec![3]; - | ^^^^^^^ - | -note: function `box_assume_init_into_vec_unsafe` is not const - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` + = note: use `const_make_global` to turn allocated pointers into immutable globals before returning error[E0507]: cannot move out of static item `x` - --> $DIR/check-values-constraints.rs:119:9 + --> $DIR/check-values-constraints.rs:114:9 | LL | x | ^ move occurs because `x` has type `Vec`, which does not implement the `Copy` trait @@ -182,7 +58,7 @@ help: consider cloning the value if the performance cost is acceptable LL | x.clone() | ++++++++ -error: aborting due to 17 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0015, E0493, E0507. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/suggestions/suggest-add-self-issue-131084.stderr b/tests/ui/suggestions/suggest-add-self-issue-131084.stderr index a7f04395ea019..9fd70e02be47b 100644 --- a/tests/ui/suggestions/suggest-add-self-issue-131084.stderr +++ b/tests/ui/suggestions/suggest-add-self-issue-131084.stderr @@ -41,10 +41,13 @@ error: expected one of `:`, `@`, or `|`, found `s` --> $DIR/suggest-add-self-issue-131084.rs:21:32 | LL | fn type_before_name(String s) { - | -------^ - | | | - | | expected one of `:`, `@`, or `|` - | help: declare the type after the parameter binding: `: ` + | ^ expected one of `:`, `@`, or `|` + | +help: declare the type after the parameter binding + | +LL - fn type_before_name(String s) { +LL + fn type_before_name(: ) { + | error[E0424]: cannot find value `self` in this scope --> $DIR/suggest-add-self-issue-131084.rs:11:9 diff --git a/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr b/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr index d2eea3a805d99..6140de3974b00 100644 --- a/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr +++ b/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr @@ -2,12 +2,14 @@ error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `const --> $DIR/ice-120503-async-const-method.rs:6:11 | LL | async const fn bar(&self) { - | ------^^^^^ - | | | - | | expected one of `extern`, `fn`, `safe`, or `unsafe` - | help: `const` must come before `async`: `const async` + | ^^^^^ expected one of `extern`, `fn`, `safe`, or `unsafe` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `const` must come before `async` + | +LL - async const fn bar(&self) { +LL + const async fn bar(&self) { + | error[E0379]: functions in trait impls cannot be declared const --> $DIR/ice-120503-async-const-method.rs:6:11