Auto merge of #137093 - matthiaskrgr:rollup-72j7mut, r=matthiaskrgr

Rollup of 8 pull requests

Successful merges:

 - #127581 (Fix crate name validation)
 - #136490 (Do not allow attributes on struct field rest patterns)
 - #136808 (Try to recover from path sep error in type parsing)
 - #137055 (rustdoc: Properly restore search input placeholder)
 - #137068 (fix(rustdoc): Fixed `Copy Item Path` in rust doc)
 - #137070 (Do not generate invalid links in job summaries)
 - #137074 (compiletest: add `{ignore,only}-rustc_abi-x86-sse2` directives)
 - #137076 (triagebot.toml: ping me on changes to `tests/rustdoc-json`)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-02-16 01:29:09 +00:00
commit 500a686ba8
52 changed files with 411 additions and 209 deletions

View File

@ -667,11 +667,12 @@ fn print_crate_info(
return Compilation::Continue;
};
let t_outputs = rustc_interface::util::build_output_filenames(attrs, sess);
let id = rustc_session::output::find_crate_name(sess, attrs);
let crate_name = passes::get_crate_name(sess, attrs);
let crate_types = collect_crate_types(sess, attrs);
for &style in &crate_types {
let fname =
rustc_session::output::filename_for_input(sess, style, id, &t_outputs);
let fname = rustc_session::output::filename_for_input(
sess, style, crate_name, &t_outputs,
);
println_info!("{}", fname.as_path().file_name().unwrap().to_string_lossy());
}
}
@ -680,8 +681,7 @@ fn print_crate_info(
// no crate attributes, print out an error and exit
return Compilation::Continue;
};
let id = rustc_session::output::find_crate_name(sess, attrs);
println_info!("{id}");
println_info!("{}", passes::get_crate_name(sess, attrs));
}
Cfg => {
let mut cfgs = sess

View File

@ -183,12 +183,12 @@ pub(crate) fn mod_file_path_from_attr(
let first_path = attrs.iter().find(|at| at.has_name(sym::path))?;
let Some(path_sym) = first_path.value_str() else {
// This check is here mainly to catch attempting to use a macro,
// such as #[path = concat!(...)]. This isn't currently supported
// because otherwise the InvocationCollector would need to defer
// loading a module until the #[path] attribute was expanded, and
// it doesn't support that (and would likely add a bit of
// complexity). Usually bad forms are checked in AstValidator (via
// `check_builtin_attribute`), but by the time that runs the macro
// such as `#[path = concat!(...)]`. This isn't supported because
// otherwise the `InvocationCollector` would need to defer loading
// a module until the `#[path]` attribute was expanded, and it
// doesn't support that (and would likely add a bit of complexity).
// Usually bad forms are checked during semantic analysis via
// `TyCtxt::check_mod_attrs`), but by the time that runs the macro
// is expanded, and it doesn't give an error.
validate_attr::emit_fatal_malformed_builtin_attribute(&sess.psess, first_path, sym::path);
};

View File

@ -117,8 +117,9 @@ use rustc_data_structures::{base_n, flock};
use rustc_fs_util::{LinkOrCopy, link_or_copy, try_canonicalize};
use rustc_middle::bug;
use rustc_session::config::CrateType;
use rustc_session::output::{collect_crate_types, find_crate_name};
use rustc_session::output::collect_crate_types;
use rustc_session::{Session, StableCrateId};
use rustc_span::Symbol;
use tracing::debug;
use crate::errors;
@ -211,7 +212,7 @@ pub fn in_incr_comp_dir(incr_comp_session_dir: &Path, file_name: &str) -> PathBu
/// The garbage collection will take care of it.
///
/// [`rustc_interface::queries::dep_graph`]: ../../rustc_interface/struct.Queries.html#structfield.dep_graph
pub(crate) fn prepare_session_directory(sess: &Session) {
pub(crate) fn prepare_session_directory(sess: &Session, crate_name: Symbol) {
if sess.opts.incremental.is_none() {
return;
}
@ -221,7 +222,7 @@ pub(crate) fn prepare_session_directory(sess: &Session) {
debug!("prepare_session_directory");
// {incr-comp-dir}/{crate-name-and-disambiguator}
let crate_dir = crate_path(sess);
let crate_dir = crate_path(sess, crate_name);
debug!("crate-dir: {}", crate_dir.display());
create_dir(sess, &crate_dir, "crate");
@ -594,10 +595,9 @@ fn string_to_timestamp(s: &str) -> Result<SystemTime, &'static str> {
Ok(UNIX_EPOCH + duration)
}
fn crate_path(sess: &Session) -> PathBuf {
fn crate_path(sess: &Session, crate_name: Symbol) -> PathBuf {
let incr_dir = sess.opts.incremental.as_ref().unwrap().clone();
let crate_name = find_crate_name(sess, &[]);
let crate_types = collect_crate_types(sess, &[]);
let stable_crate_id = StableCrateId::new(
crate_name,

View File

@ -11,6 +11,7 @@ use rustc_serialize::Decodable;
use rustc_serialize::opaque::MemDecoder;
use rustc_session::Session;
use rustc_session::config::IncrementalStateAssertion;
use rustc_span::Symbol;
use tracing::{debug, warn};
use super::data::*;
@ -203,9 +204,9 @@ pub fn load_query_result_cache(sess: &Session) -> Option<OnDiskCache> {
/// Setups the dependency graph by loading an existing graph from disk and set up streaming of a
/// new graph to an incremental session directory.
pub fn setup_dep_graph(sess: &Session) -> DepGraph {
pub fn setup_dep_graph(sess: &Session, crate_name: Symbol) -> DepGraph {
// `load_dep_graph` can only be called after `prepare_session_directory`.
prepare_session_directory(sess);
prepare_session_directory(sess, crate_name);
let res = sess.opts.build_dep_graph().then(|| load_dep_graph(sess));

View File

@ -6,6 +6,10 @@ interface_abi_required_feature_issue = for more information, see issue #116344 <
interface_cant_emit_mir =
could not emit MIR: {$error}
interface_crate_name_does_not_match = `--crate-name` and `#[crate_name]` are required to match, but `{$crate_name}` != `{$attr_crate_name}`
interface_crate_name_invalid = crate names cannot start with a `-`, but `{$crate_name}` has a leading hyphen
interface_emoji_identifier =
identifiers cannot contain emoji: `{$ident}`

View File

@ -4,6 +4,21 @@ use std::path::Path;
use rustc_macros::Diagnostic;
use rustc_span::{Span, Symbol};
#[derive(Diagnostic)]
#[diag(interface_crate_name_does_not_match)]
pub(crate) struct CrateNameDoesNotMatch {
#[primary_span]
pub(crate) span: Span,
pub(crate) crate_name: Symbol,
pub(crate) attr_crate_name: Symbol,
}
#[derive(Diagnostic)]
#[diag(interface_crate_name_invalid)]
pub(crate) struct CrateNameInvalid<'a> {
pub(crate) crate_name: &'a str,
}
#[derive(Diagnostic)]
#[diag(interface_ferris_identifier)]
pub struct FerrisIdentifier {

View File

@ -28,10 +28,12 @@ use rustc_passes::{abi_test, input_stats, layout_test};
use rustc_resolve::Resolver;
use rustc_session::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType};
use rustc_session::cstore::Untracked;
use rustc_session::output::{collect_crate_types, filename_for_input, find_crate_name};
use rustc_session::output::{collect_crate_types, filename_for_input};
use rustc_session::search_paths::PathKind;
use rustc_session::{Limit, Session};
use rustc_span::{ErrorGuaranteed, FileName, SourceFileHash, SourceFileHashAlgorithm, Symbol, sym};
use rustc_span::{
ErrorGuaranteed, FileName, SourceFileHash, SourceFileHashAlgorithm, Span, Symbol, sym,
};
use rustc_target::spec::PanicStrategy;
use rustc_trait_selection::traits;
use tracing::{info, instrument};
@ -725,8 +727,7 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
let pre_configured_attrs = rustc_expand::config::pre_configure_attrs(sess, &krate.attrs);
// parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches.
let crate_name = find_crate_name(sess, &pre_configured_attrs);
let crate_name = get_crate_name(sess, &pre_configured_attrs);
let crate_types = collect_crate_types(sess, &pre_configured_attrs);
let stable_crate_id = StableCrateId::new(
crate_name,
@ -735,7 +736,7 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
sess.cfg_version,
);
let outputs = util::build_output_filenames(&pre_configured_attrs, sess);
let dep_graph = setup_dep_graph(sess);
let dep_graph = setup_dep_graph(sess, crate_name);
let cstore =
FreezeLock::new(Box::new(CStore::new(compiler.codegen_backend.metadata_loader())) as _);
@ -1080,23 +1081,85 @@ pub(crate) fn start_codegen<'tcx>(
codegen
}
fn get_recursion_limit(krate_attrs: &[ast::Attribute], sess: &Session) -> Limit {
if let Some(attr) = krate_attrs
.iter()
.find(|attr| attr.has_name(sym::recursion_limit) && attr.value_str().is_none())
{
// This is here mainly to check for using a macro, such as
// #![recursion_limit = foo!()]. That is not supported since that
// would require expanding this while in the middle of expansion,
// which needs to know the limit before expanding. Otherwise,
// validation would normally be caught in AstValidator (via
// `check_builtin_attribute`), but by the time that runs the macro
// is expanded, and it doesn't give an error.
validate_attr::emit_fatal_malformed_builtin_attribute(
&sess.psess,
attr,
sym::recursion_limit,
);
/// Compute and validate the crate name.
pub fn get_crate_name(sess: &Session, krate_attrs: &[ast::Attribute]) -> Symbol {
// We validate *all* occurrences of `#![crate_name]`, pick the first find and
// if a crate name was passed on the command line via `--crate-name` we enforce
// that they match.
// We perform the validation step here instead of later to ensure it gets run
// in all code paths that require the crate name very early on, namely before
// macro expansion.
let attr_crate_name =
validate_and_find_value_str_builtin_attr(sym::crate_name, sess, krate_attrs);
let validate = |name, span| {
rustc_session::output::validate_crate_name(sess, name, span);
name
};
if let Some(crate_name) = &sess.opts.crate_name {
let crate_name = Symbol::intern(crate_name);
if let Some((attr_crate_name, span)) = attr_crate_name
&& attr_crate_name != crate_name
{
sess.dcx().emit_err(errors::CrateNameDoesNotMatch {
span,
crate_name,
attr_crate_name,
});
}
return validate(crate_name, None);
}
if let Some((crate_name, span)) = attr_crate_name {
return validate(crate_name, Some(span));
}
if let Input::File(ref path) = sess.io.input
&& let Some(file_stem) = path.file_stem().and_then(|s| s.to_str())
{
if file_stem.starts_with('-') {
sess.dcx().emit_err(errors::CrateNameInvalid { crate_name: file_stem });
} else {
return validate(Symbol::intern(&file_stem.replace('-', "_")), None);
}
}
sym::rust_out
}
fn get_recursion_limit(krate_attrs: &[ast::Attribute], sess: &Session) -> Limit {
// We don't permit macro calls inside of the attribute (e.g., #![recursion_limit = `expand!()`])
// because that would require expanding this while in the middle of expansion, which needs to
// know the limit before expanding.
let _ = validate_and_find_value_str_builtin_attr(sym::recursion_limit, sess, krate_attrs);
rustc_middle::middle::limits::get_recursion_limit(krate_attrs, sess)
}
/// Validate *all* occurrences of the given "[value-str]" built-in attribute and return the first find.
///
/// This validator is intended for built-in attributes whose value needs to be known very early
/// during compilation (namely, before macro expansion) and it mainly exists to reject macro calls
/// inside of the attributes, such as in `#![name = expand!()]`. Normal attribute validation happens
/// during semantic analysis via [`TyCtxt::check_mod_attrs`] which happens *after* macro expansion
/// when such macro calls (here: `expand`) have already been expanded and we can no longer check for
/// their presence.
///
/// [value-str]: ast::Attribute::value_str
fn validate_and_find_value_str_builtin_attr(
name: Symbol,
sess: &Session,
krate_attrs: &[ast::Attribute],
) -> Option<(Symbol, Span)> {
let mut result = None;
// Validate *all* relevant attributes, not just the first occurrence.
for attr in ast::attr::filter_by_name(krate_attrs, name) {
let Some(value) = attr.value_str() else {
validate_attr::emit_fatal_malformed_builtin_attribute(&sess.psess, attr, name)
};
// Choose the first occurrence as our result.
result.get_or_insert((value, attr.span));
}
result
}

View File

@ -433,11 +433,11 @@ pub(crate) fn check_attr_crate_type(
}
} else {
// This is here mainly to check for using a macro, such as
// #![crate_type = foo!()]. That is not supported since the
// `#![crate_type = foo!()]`. That is not supported since the
// crate type needs to be known very early in compilation long
// before expansion. Otherwise, validation would normally be
// caught in AstValidator (via `check_builtin_attribute`), but
// by the time that runs the macro is expanded, and it doesn't
// caught during semantic analysis via `TyCtxt::check_mod_attrs`,
// but by the time that runs the macro is expanded, and it doesn't
// give an error.
validate_attr::emit_fatal_malformed_builtin_attribute(
&sess.psess,

View File

@ -743,9 +743,6 @@ parse_single_colon_import_path = expected `::`, found `:`
.suggestion = use double colon
.note = import paths are delimited using `::`
parse_single_colon_struct_type = found single colon in a struct field type path
.suggestion = write a path separator here
parse_static_with_generics = static items may not have generic parameters
parse_struct_literal_body_without_path =

View File

@ -3071,14 +3071,6 @@ pub(crate) struct BadItemKind {
pub help: bool,
}
#[derive(Diagnostic)]
#[diag(parse_single_colon_struct_type)]
pub(crate) struct SingleColonStructType {
#[primary_span]
#[suggestion(code = "::", applicability = "maybe-incorrect", style = "verbose")]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(parse_macro_rules_missing_bang)]
pub(crate) struct MacroRulesMissingBang {

View File

@ -2043,9 +2043,6 @@ impl<'a> Parser<'a> {
}
self.expect_field_ty_separator()?;
let ty = self.parse_ty()?;
if self.token == token::Colon && self.look_ahead(1, |t| *t != token::Colon) {
self.dcx().emit_err(errors::SingleColonStructType { span: self.token.span });
}
let default = if self.token == token::Eq {
self.bump();
let const_expr = self.parse_expr_anon_const()?;

View File

@ -1472,17 +1472,6 @@ impl<'a> Parser<'a> {
let mut last_non_comma_dotdot_span = None;
while self.token != token::CloseDelim(Delimiter::Brace) {
let attrs = match self.parse_outer_attributes() {
Ok(attrs) => attrs,
Err(err) => {
if let Some(delayed) = delayed_err {
delayed.emit();
}
return Err(err);
}
};
let lo = self.token.span;
// check that a comma comes after every field
if !ate_comma {
let err = if self.token == token::At {
@ -1585,6 +1574,17 @@ impl<'a> Parser<'a> {
}
}
let attrs = match self.parse_outer_attributes() {
Ok(attrs) => attrs,
Err(err) => {
if let Some(delayed) = delayed_err {
delayed.emit();
}
return Err(err);
}
};
let lo = self.token.span;
let field = self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
let field = match this.parse_pat_field(lo, attrs) {
Ok(field) => Ok(field),

View File

@ -246,8 +246,19 @@ impl<'a> Parser<'a> {
segments.push(segment);
if self.is_import_coupler() || !self.eat_path_sep() {
if style == PathStyle::Expr
&& self.may_recover()
let ok_for_recovery = self.may_recover()
&& match style {
PathStyle::Expr => true,
PathStyle::Type if let Some((ident, _)) = self.prev_token.ident() => {
self.token == token::Colon
&& ident.as_str().chars().all(|c| c.is_lowercase())
&& self.token.span.lo() == self.prev_token.span.hi()
&& self
.look_ahead(1, |token| self.token.span.hi() == token.span.lo())
}
_ => false,
};
if ok_for_recovery
&& self.token == token::Colon
&& self.look_ahead(1, |token| token.is_ident() && !token.is_reserved_ident())
{

View File

@ -8,12 +8,8 @@ session_cannot_mix_and_match_sanitizers = `-Zsanitizer={$first}` is incompatible
session_cli_feature_diagnostic_help =
add `-Zcrate-attr="feature({$feature})"` to the command-line options to enable
session_crate_name_does_not_match = `--crate-name` and `#[crate_name]` are required to match, but `{$s}` != `{$name}`
session_crate_name_empty = crate name must not be empty
session_crate_name_invalid = crate names cannot start with a `-`, but `{$s}` has a leading hyphen
session_embed_source_insufficient_dwarf_version = `-Zembed-source=y` requires at least `-Z dwarf-version=5` but DWARF version is {$dwarf_version}
session_embed_source_requires_debug_info = `-Zembed-source=y` requires debug information to be enabled
@ -52,8 +48,8 @@ session_instrumentation_not_supported = {$us} instrumentation is not supported f
session_int_literal_too_large = integer literal is too large
.note = value exceeds limit of `{$limit}`
session_invalid_character_in_create_name = invalid character `{$character}` in crate name: `{$crate_name}`
session_invalid_character_in_create_name_help = you can either pass `--crate-name` on the command line or add `#![crate_name="…"]` to set the crate name
session_invalid_character_in_crate_name = invalid character {$character} in crate name: `{$crate_name}`
.help = you can either pass `--crate-name` on the command line or add `#![crate_name = "…"]` to set the crate name
session_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float literal
.label = invalid suffix `{$suffix}`

View File

@ -212,21 +212,6 @@ pub(crate) struct FileWriteFail<'a> {
pub(crate) err: String,
}
#[derive(Diagnostic)]
#[diag(session_crate_name_does_not_match)]
pub(crate) struct CrateNameDoesNotMatch {
#[primary_span]
pub(crate) span: Span,
pub(crate) s: Symbol,
pub(crate) name: Symbol,
}
#[derive(Diagnostic)]
#[diag(session_crate_name_invalid)]
pub(crate) struct CrateNameInvalid<'a> {
pub(crate) s: &'a str,
}
#[derive(Diagnostic)]
#[diag(session_crate_name_empty)]
pub(crate) struct CrateNameEmpty {
@ -235,20 +220,14 @@ pub(crate) struct CrateNameEmpty {
}
#[derive(Diagnostic)]
#[diag(session_invalid_character_in_create_name)]
#[diag(session_invalid_character_in_crate_name)]
pub(crate) struct InvalidCharacterInCrateName {
#[primary_span]
pub(crate) span: Option<Span>,
pub(crate) character: char,
pub(crate) crate_name: Symbol,
#[subdiagnostic]
pub(crate) crate_name_help: Option<InvalidCrateNameHelp>,
}
#[derive(Subdiagnostic)]
pub(crate) enum InvalidCrateNameHelp {
#[help(session_invalid_character_in_create_name_help)]
AddCrateName,
#[help]
pub(crate) help: Option<()>,
}
#[derive(Subdiagnostic)]

View File

@ -2,15 +2,12 @@
use std::path::Path;
use rustc_ast::{self as ast, attr};
use rustc_ast as ast;
use rustc_span::{Span, Symbol, sym};
use crate::Session;
use crate::config::{self, CrateType, Input, OutFileName, OutputFilenames, OutputType};
use crate::errors::{
self, CrateNameDoesNotMatch, CrateNameEmpty, CrateNameInvalid, FileIsNotWriteable,
InvalidCharacterInCrateName, InvalidCrateNameHelp,
};
use crate::config::{self, CrateType, OutFileName, OutputFilenames, OutputType};
use crate::errors::{self, CrateNameEmpty, FileIsNotWriteable, InvalidCharacterInCrateName};
pub fn out_filename(
sess: &Session,
@ -49,69 +46,31 @@ fn is_writeable(p: &Path) -> bool {
}
}
pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute]) -> Symbol {
let validate = |s: Symbol, span: Option<Span>| {
validate_crate_name(sess, s, span);
s
};
// Look in attributes 100% of the time to make sure the attribute is marked
// as used. After doing this, however, we still prioritize a crate name from
// the command line over one found in the #[crate_name] attribute. If we
// find both we ensure that they're the same later on as well.
let attr_crate_name =
attr::find_by_name(attrs, sym::crate_name).and_then(|at| at.value_str().map(|s| (at, s)));
if let Some(ref s) = sess.opts.crate_name {
let s = Symbol::intern(s);
if let Some((attr, name)) = attr_crate_name {
if name != s {
sess.dcx().emit_err(CrateNameDoesNotMatch { span: attr.span, s, name });
}
}
return validate(s, None);
}
if let Some((attr, s)) = attr_crate_name {
return validate(s, Some(attr.span));
}
if let Input::File(ref path) = sess.io.input {
if let Some(s) = path.file_stem().and_then(|s| s.to_str()) {
if s.starts_with('-') {
sess.dcx().emit_err(CrateNameInvalid { s });
} else {
return validate(Symbol::intern(&s.replace('-', "_")), None);
}
}
}
sym::rust_out
}
pub fn validate_crate_name(sess: &Session, s: Symbol, sp: Option<Span>) {
/// Validate the given crate name.
///
/// Note that this validation is more permissive than identifier parsing. It considers
/// non-empty sequences of alphanumeric and underscore characters to be valid crate names.
/// Most notably, it accepts names starting with a numeric character like `0`!
///
/// Furthermore, this shouldn't be taken as the canonical crate name validator.
/// Other places may use a more restrictive grammar (e.g., identifier or ASCII identifier).
pub fn validate_crate_name(sess: &Session, crate_name: Symbol, span: Option<Span>) {
let mut guar = None;
{
if s.is_empty() {
guar = Some(sess.dcx().emit_err(CrateNameEmpty { span: sp }));
}
for c in s.as_str().chars() {
if c.is_alphanumeric() {
continue;
}
if c == '_' {
continue;
}
guar = Some(sess.dcx().emit_err(InvalidCharacterInCrateName {
span: sp,
character: c,
crate_name: s,
crate_name_help: if sp.is_none() {
Some(InvalidCrateNameHelp::AddCrateName)
} else {
None
},
}));
if crate_name.is_empty() {
guar = Some(sess.dcx().emit_err(CrateNameEmpty { span }));
}
for c in crate_name.as_str().chars() {
if c.is_alphanumeric() || c == '_' {
continue;
}
guar = Some(sess.dcx().emit_err(InvalidCharacterInCrateName {
span,
character: c,
crate_name,
help: span.is_none().then_some(()),
}));
}
if let Some(guar) = guar {

View File

@ -52,10 +52,15 @@ access_url="https://ci-artifacts.rust-lang.org/${deploy_dir}/$(ciCommit)"
# to make them easily accessible.
if [ -n "${GITHUB_STEP_SUMMARY}" ]
then
echo "# CI artifacts" >> "${GITHUB_STEP_SUMMARY}"
archives=($(find "${upload_dir}" -maxdepth 1 -name "*.xz"))
for filename in "${upload_dir}"/*.xz; do
filename=$(basename "${filename}")
echo "- [${filename}](${access_url}/${filename})" >> "${GITHUB_STEP_SUMMARY}"
done
# Avoid generating an invalid "*.xz" file if there are no archives
if [ ${#archives[@]} -gt 0 ]; then
echo "# CI artifacts" >> "${GITHUB_STEP_SUMMARY}"
for filename in "${upload_dir}"/*.xz; do
filename=$(basename "${filename}")
echo "- [${filename}](${access_url}/${filename})" >> "${GITHUB_STEP_SUMMARY}"
done
fi
fi

View File

@ -154,6 +154,7 @@ Some examples of `X` in `ignore-X` or `only-X`:
`ignore-coverage-map`, `ignore-coverage-run`
- When testing a dist toolchain: `dist`
- This needs to be enabled with `COMPILETEST_ENABLE_DIST_TESTS=1`
- The `rustc_abi` of the target: e.g. `rustc_abi-x86_64-sse2`
The following directives will check rustc build settings and target
settings:

View File

@ -2039,7 +2039,10 @@ function preLoadCss(cssUrl) {
// Most page titles are '<Item> in <path::to::module> - Rust', except
// modules (which don't have the first part) and keywords/primitives
// (which don't have a module path)
const [item, module] = document.title.split(" in ");
const titleElement = document.querySelector("title");
const title = titleElement && titleElement.textContent ?
titleElement.textContent.replace(" - Rust", "") : "";
const [item, module] = title.split(" in ");
const path = [item];
if (module !== undefined) {
path.unshift(module);

View File

@ -5318,8 +5318,9 @@ function registerSearchEvents() {
// @ts-expect-error
searchState.input.addEventListener("blur", () => {
// @ts-expect-error
searchState.input.placeholder = searchState.input.origPlaceholder;
if (window.searchState.input) {
window.searchState.input.placeholder = window.searchState.origPlaceholder;
}
});
// Push and pop states are used to add search results to the browser

View File

@ -517,6 +517,7 @@ pub struct TargetCfgs {
pub all_abis: HashSet<String>,
pub all_families: HashSet<String>,
pub all_pointer_widths: HashSet<String>,
pub all_rustc_abis: HashSet<String>,
}
impl TargetCfgs {
@ -536,6 +537,9 @@ impl TargetCfgs {
let mut all_abis = HashSet::new();
let mut all_families = HashSet::new();
let mut all_pointer_widths = HashSet::new();
// NOTE: for distinction between `abi` and `rustc_abi`, see comment on
// `TargetCfg::rustc_abi`.
let mut all_rustc_abis = HashSet::new();
// If current target is not included in the `--print=all-target-specs-json` output,
// we check whether it is a custom target from the user or a synthetic target from bootstrap.
@ -576,7 +580,9 @@ impl TargetCfgs {
all_families.insert(family.clone());
}
all_pointer_widths.insert(format!("{}bit", cfg.pointer_width));
if let Some(rustc_abi) = &cfg.rustc_abi {
all_rustc_abis.insert(rustc_abi.clone());
}
all_targets.insert(target.clone());
}
@ -590,6 +596,7 @@ impl TargetCfgs {
all_abis,
all_families,
all_pointer_widths,
all_rustc_abis,
}
}
@ -676,6 +683,10 @@ pub struct TargetCfg {
pub(crate) xray: bool,
#[serde(default = "default_reloc_model")]
pub(crate) relocation_model: String,
// NOTE: `rustc_abi` should not be confused with `abi`. `rustc_abi` was introduced in #137037 to
// make SSE2 *required* by the ABI (kind of a hack to make a target feature *required* via the
// target spec).
pub(crate) rustc_abi: Option<String>,
// Not present in target cfg json output, additional derived information.
#[serde(skip)]

View File

@ -87,6 +87,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
"ignore-remote",
"ignore-riscv64",
"ignore-rustc-debug-assertions",
"ignore-rustc_abi-x86-sse2",
"ignore-s390x",
"ignore-sgx",
"ignore-sparc64",
@ -198,6 +199,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
"only-nvptx64",
"only-powerpc",
"only-riscv64",
"only-rustc_abi-x86-sse2",
"only-s390x",
"only-sparc",
"only-sparc64",

View File

@ -234,6 +234,14 @@ fn parse_cfg_name_directive<'a>(
allowed_names: ["coverage-map", "coverage-run"],
message: "when the test mode is {name}",
}
condition! {
name: target_cfg.rustc_abi.as_ref().map(|abi| format!("rustc_abi-{abi}")).unwrap_or_default(),
allowed_names: ContainsPrefixed {
prefix: "rustc_abi-",
inner: target_cfgs.all_rustc_abis.clone(),
},
message: "when the target `rustc_abi` is {name}",
}
condition! {
name: "dist",

View File

@ -889,3 +889,17 @@ fn test_needs_target_has_atomic() {
assert!(!check_ignore(&config, "//@ needs-target-has-atomic: 8, ptr"));
assert!(check_ignore(&config, "//@ needs-target-has-atomic: 8, ptr, 128"));
}
#[test]
// FIXME: this test will fail against stage 0 until #137037 changes reach beta.
#[cfg_attr(bootstrap, ignore)]
fn test_rustc_abi() {
let config = cfg().target("i686-unknown-linux-gnu").build();
assert_eq!(config.target_cfg().rustc_abi, Some("x86-sse2".to_string()));
assert!(check_ignore(&config, "//@ ignore-rustc_abi-x86-sse2"));
assert!(!check_ignore(&config, "//@ only-rustc_abi-x86-sse2"));
let config = cfg().target("x86_64-unknown-linux-gnu").build();
assert_eq!(config.target_cfg().rustc_abi, None);
assert!(!check_ignore(&config, "//@ ignore-rustc_abi-x86-sse2"));
assert!(check_ignore(&config, "//@ only-rustc_abi-x86-sse2"));
}

View File

@ -0,0 +1,6 @@
// issue: rust-lang/rust#122001
// Ensure we reject macro calls inside `#![crate_name]` as their result wouldn't get honored anyway.
#![crate_name = concat!("my", "crate")] //~ ERROR malformed `crate_name` attribute input
fn main() {}

View File

@ -0,0 +1,8 @@
error: malformed `crate_name` attribute input
--> $DIR/crate-name-macro-call.rs:4:1
|
LL | #![crate_name = concat!("my", "crate")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![crate_name = "name"]`
error: aborting due to 1 previous error

View File

@ -1,5 +1,5 @@
error: malformed `crate_type` attribute input
--> $DIR/invalid_crate_type_syntax.rs:2:1
--> $DIR/crate-type-delimited.rs:2:1
|
LL | #![crate_type(lib)]
| ^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![crate_type = "bin|lib|..."]`

View File

@ -1,5 +1,5 @@
error: malformed `crate_type` attribute input
--> $DIR/no_crate_type.rs:2:1
--> $DIR/crate-type-empty.rs:2:1
|
LL | #![crate_type]
| ^^^^^^^^^^^^^^ help: must be of the form: `#![crate_type = "bin|lib|..."]`

View File

@ -1,5 +1,5 @@
error: malformed `crate_type` attribute input
--> $DIR/invalid-crate-type-macro.rs:1:1
--> $DIR/crate-type-macro-call.rs:1:1
|
LL | #![crate_type = foo!()]
| ^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![crate_type = "bin|lib|..."]`

View File

@ -1,6 +0,0 @@
error: invalid character `'$'` in crate name: `need_crate_arg_ignore_tidy$x`
|
= help: you can either pass `--crate-name` on the command line or add `#![crate_name="…"]` to set the crate name
error: aborting due to 1 previous error

View File

@ -1,8 +1,6 @@
error: path separator must be a double colon
--> $DIR/single-colon-path-not-const-generics.rs:8:18
|
LL | pub struct Foo {
| --- while parsing this struct
LL | a: Vec<foo::bar:A>,
| ^
|
@ -10,7 +8,7 @@ LL | a: Vec<foo::bar:A>,
help: use a double colon instead
|
LL | a: Vec<foo::bar::A>,
| +
| +
error: aborting due to 1 previous error

View File

@ -0,0 +1,6 @@
error: invalid character '$' in crate name: `need_crate_arg_ignore_tidy$x`
|
= help: you can either pass `--crate-name` on the command line or add `#![crate_name = "…"]` to set the crate name
error: aborting due to 1 previous error

View File

@ -0,0 +1,5 @@
// Ensure we validate `#![crate_name]` on print requests and reject macro calls inside of it.
// See also <https://github.com/rust-lang/rust/issues/122001>.
//@ compile-flags: --print=crate-name
#![crate_name = concat!("wrapped")] //~ ERROR malformed `crate_name` attribute input

View File

@ -0,0 +1,8 @@
error: malformed `crate_name` attribute input
--> $DIR/print-crate-name-request-malformed-crate-name.rs:5:1
|
LL | #![crate_name = concat!("wrapped")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![crate_name = "name"]`
error: aborting due to 1 previous error

View File

@ -0,0 +1,4 @@
// Ensure we validate `#![crate_name]` on print requests.
//@ compile-flags: --print=file-names
#![crate_name] //~ ERROR malformed `crate_name` attribute input

View File

@ -0,0 +1,8 @@
error: malformed `crate_name` attribute input
--> $DIR/print-file-names-request-malformed-crate-name-1.rs:4:1
|
LL | #![crate_name]
| ^^^^^^^^^^^^^^ help: must be of the form: `#![crate_name = "name"]`
error: aborting due to 1 previous error

View File

@ -0,0 +1,7 @@
// Ensure that we validate *all* `#![crate_name]`s on print requests, not just the first,
// and that we reject macro calls inside of them.
// See also <https://github.com/rust-lang/rust/issues/122001>.
//@ compile-flags: --print=file-names
#![crate_name = "this_one_is_okay"]
#![crate_name = concat!("this_one_is_not")] //~ ERROR malformed `crate_name` attribute input

View File

@ -0,0 +1,8 @@
error: malformed `crate_name` attribute input
--> $DIR/print-file-names-request-malformed-crate-name-2.rs:7:1
|
LL | #![crate_name = concat!("this_one_is_not")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![crate_name = "name"]`
error: aborting due to 1 previous error

View File

@ -0,0 +1,5 @@
// Ensure we validate `#![crate_name]` on print requests and reject macro calls inside of it.
// See also <https://github.com/rust-lang/rust/issues/122001>.
//@ compile-flags: --print=file-names
#![crate_name = concat!("wrapped")] //~ ERROR malformed `crate_name` attribute input

View File

@ -0,0 +1,8 @@
error: malformed `crate_name` attribute input
--> $DIR/print-file-names-request-malformed-crate-name.rs:5:1
|
LL | #![crate_name = concat!("wrapped")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![crate_name = "name"]`
error: aborting due to 1 previous error

View File

@ -0,0 +1,8 @@
// #81282: Attributes are not allowed on struct field rest patterns (the ..).
struct S {}
fn main() {
let S { #[cfg(any())] .. } = S {};
//~^ ERROR expected identifier, found `..`
}

View File

@ -0,0 +1,10 @@
error: expected identifier, found `..`
--> $DIR/attr-pat-struct-rest.rs:6:27
|
LL | let S { #[cfg(any())] .. } = S {};
| - ^^ expected identifier
| |
| while parsing the fields for this pattern
error: aborting due to 1 previous error

View File

@ -0,0 +1,15 @@
//@ run-rustfix
use std::fmt;
struct Hello;
impl fmt::Display for Hello {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { //~ ERROR path separator must be a double colon
write!(f, "hello")
}
}
fn main() {
let _ = Hello;
}

View File

@ -0,0 +1,15 @@
//@ run-rustfix
use std::fmt;
struct Hello;
impl fmt::Display for Hello {
fn fmt(&self, f: &mut fmt:Formatter) -> fmt::Result { //~ ERROR path separator must be a double colon
write!(f, "hello")
}
}
fn main() {
let _ = Hello;
}

View File

@ -0,0 +1,14 @@
error: path separator must be a double colon
--> $DIR/argument-list-from-path-sep-error-129273.rs:8:30
|
LL | fn fmt(&self, f: &mut fmt:Formatter) -> fmt::Result {
| ^
|
= note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>
help: use a double colon instead
|
LL | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
| +
error: aborting due to 1 previous error

View File

@ -7,14 +7,14 @@ mod foo {
struct Foo {
a: foo:A,
//~^ ERROR found single colon in a struct field type path
//~| expected `,`, or `}`, found `:`
//~^ ERROR path separator must be a double colon
//~| ERROR struct `A` is private
}
struct Bar {
b: foo::bar:B,
//~^ ERROR found single colon in a struct field type path
//~| expected `,`, or `}`, found `:`
//~^ ERROR path separator must be a double colon
//~| ERROR module `bar` is private
}
fn main() {}

View File

@ -1,40 +1,53 @@
error: found single colon in a struct field type path
error: path separator must be a double colon
--> $DIR/struct-field-type-including-single-colon.rs:9:11
|
LL | a: foo:A,
| ^
|
help: write a path separator here
= note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>
help: use a double colon instead
|
LL | a: foo::A,
| +
error: expected `,`, or `}`, found `:`
--> $DIR/struct-field-type-including-single-colon.rs:9:11
|
LL | struct Foo {
| --- while parsing this struct
LL | a: foo:A,
| ^
error: found single colon in a struct field type path
error: path separator must be a double colon
--> $DIR/struct-field-type-including-single-colon.rs:15:16
|
LL | b: foo::bar:B,
| ^
|
help: write a path separator here
= note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>
help: use a double colon instead
|
LL | b: foo::bar::B,
| +
error: expected `,`, or `}`, found `:`
--> $DIR/struct-field-type-including-single-colon.rs:15:16
error[E0603]: struct `A` is private
--> $DIR/struct-field-type-including-single-colon.rs:9:12
|
LL | a: foo:A,
| ^ private struct
|
note: the struct `A` is defined here
--> $DIR/struct-field-type-including-single-colon.rs:2:5
|
LL | struct A;
| ^^^^^^^^^
error[E0603]: module `bar` is private
--> $DIR/struct-field-type-including-single-colon.rs:15:13
|
LL | struct Bar {
| --- while parsing this struct
LL | b: foo::bar:B,
| ^
| ^^^ - struct `B` is not publicly re-exported
| |
| private module
|
note: the module `bar` is defined here
--> $DIR/struct-field-type-including-single-colon.rs:3:5
|
LL | mod bar {
| ^^^^^^^
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0603`.

View File

@ -962,6 +962,9 @@ message = "This PR changes how LLVM is built. Consider updating src/bootstrap/do
[mentions."test/crashes"]
message = "This PR changes a file inside `tests/crashes`. If a crash was fixed, please move into the corresponding `ui` subdir and add 'Fixes #<issueNr>' to the PR description to autoclose the issue upon merge."
[mentions."tests/rustdoc-json"]
cc = ["@aDotInTheVoid"]
[mentions."tests/ui/deriving/deriving-all-codegen.stdout"]
message = "Changes to the code generated for builtin derived traits."
cc = ["@nnethercote"]