Skip to content

Commit 500a686

Browse files
committed
Auto merge of rust-lang#137093 - matthiaskrgr:rollup-72j7mut, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#127581 (Fix crate name validation) - rust-lang#136490 (Do not allow attributes on struct field rest patterns) - rust-lang#136808 (Try to recover from path sep error in type parsing) - rust-lang#137055 (rustdoc: Properly restore search input placeholder) - rust-lang#137068 (fix(rustdoc): Fixed `Copy Item Path` in rust doc) - rust-lang#137070 (Do not generate invalid links in job summaries) - rust-lang#137074 (compiletest: add `{ignore,only}-rustc_abi-x86-sse2` directives) - rust-lang#137076 (triagebot.toml: ping me on changes to `tests/rustdoc-json`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents e72df78 + b3d5a77 commit 500a686

File tree

52 files changed

+408
-206
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+408
-206
lines changed

Diff for: compiler/rustc_driver_impl/src/lib.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -667,11 +667,12 @@ fn print_crate_info(
667667
return Compilation::Continue;
668668
};
669669
let t_outputs = rustc_interface::util::build_output_filenames(attrs, sess);
670-
let id = rustc_session::output::find_crate_name(sess, attrs);
670+
let crate_name = passes::get_crate_name(sess, attrs);
671671
let crate_types = collect_crate_types(sess, attrs);
672672
for &style in &crate_types {
673-
let fname =
674-
rustc_session::output::filename_for_input(sess, style, id, &t_outputs);
673+
let fname = rustc_session::output::filename_for_input(
674+
sess, style, crate_name, &t_outputs,
675+
);
675676
println_info!("{}", fname.as_path().file_name().unwrap().to_string_lossy());
676677
}
677678
}
@@ -680,8 +681,7 @@ fn print_crate_info(
680681
// no crate attributes, print out an error and exit
681682
return Compilation::Continue;
682683
};
683-
let id = rustc_session::output::find_crate_name(sess, attrs);
684-
println_info!("{id}");
684+
println_info!("{}", passes::get_crate_name(sess, attrs));
685685
}
686686
Cfg => {
687687
let mut cfgs = sess

Diff for: compiler/rustc_expand/src/module.rs

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

Diff for: compiler/rustc_incremental/src/persist/fs.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,9 @@ use rustc_data_structures::{base_n, flock};
117117
use rustc_fs_util::{LinkOrCopy, link_or_copy, try_canonicalize};
118118
use rustc_middle::bug;
119119
use rustc_session::config::CrateType;
120-
use rustc_session::output::{collect_crate_types, find_crate_name};
120+
use rustc_session::output::collect_crate_types;
121121
use rustc_session::{Session, StableCrateId};
122+
use rustc_span::Symbol;
122123
use tracing::debug;
123124

124125
use crate::errors;
@@ -211,7 +212,7 @@ pub fn in_incr_comp_dir(incr_comp_session_dir: &Path, file_name: &str) -> PathBu
211212
/// The garbage collection will take care of it.
212213
///
213214
/// [`rustc_interface::queries::dep_graph`]: ../../rustc_interface/struct.Queries.html#structfield.dep_graph
214-
pub(crate) fn prepare_session_directory(sess: &Session) {
215+
pub(crate) fn prepare_session_directory(sess: &Session, crate_name: Symbol) {
215216
if sess.opts.incremental.is_none() {
216217
return;
217218
}
@@ -221,7 +222,7 @@ pub(crate) fn prepare_session_directory(sess: &Session) {
221222
debug!("prepare_session_directory");
222223

223224
// {incr-comp-dir}/{crate-name-and-disambiguator}
224-
let crate_dir = crate_path(sess);
225+
let crate_dir = crate_path(sess, crate_name);
225226
debug!("crate-dir: {}", crate_dir.display());
226227
create_dir(sess, &crate_dir, "crate");
227228

@@ -594,10 +595,9 @@ fn string_to_timestamp(s: &str) -> Result<SystemTime, &'static str> {
594595
Ok(UNIX_EPOCH + duration)
595596
}
596597

597-
fn crate_path(sess: &Session) -> PathBuf {
598+
fn crate_path(sess: &Session, crate_name: Symbol) -> PathBuf {
598599
let incr_dir = sess.opts.incremental.as_ref().unwrap().clone();
599600

600-
let crate_name = find_crate_name(sess, &[]);
601601
let crate_types = collect_crate_types(sess, &[]);
602602
let stable_crate_id = StableCrateId::new(
603603
crate_name,

Diff for: compiler/rustc_incremental/src/persist/load.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustc_serialize::Decodable;
1111
use rustc_serialize::opaque::MemDecoder;
1212
use rustc_session::Session;
1313
use rustc_session::config::IncrementalStateAssertion;
14+
use rustc_span::Symbol;
1415
use tracing::{debug, warn};
1516

1617
use super::data::*;
@@ -203,9 +204,9 @@ pub fn load_query_result_cache(sess: &Session) -> Option<OnDiskCache> {
203204

204205
/// Setups the dependency graph by loading an existing graph from disk and set up streaming of a
205206
/// new graph to an incremental session directory.
206-
pub fn setup_dep_graph(sess: &Session) -> DepGraph {
207+
pub fn setup_dep_graph(sess: &Session, crate_name: Symbol) -> DepGraph {
207208
// `load_dep_graph` can only be called after `prepare_session_directory`.
208-
prepare_session_directory(sess);
209+
prepare_session_directory(sess, crate_name);
209210

210211
let res = sess.opts.build_dep_graph().then(|| load_dep_graph(sess));
211212

Diff for: compiler/rustc_interface/messages.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ interface_abi_required_feature_issue = for more information, see issue #116344 <
66
interface_cant_emit_mir =
77
could not emit MIR: {$error}
88
9+
interface_crate_name_does_not_match = `--crate-name` and `#[crate_name]` are required to match, but `{$crate_name}` != `{$attr_crate_name}`
10+
11+
interface_crate_name_invalid = crate names cannot start with a `-`, but `{$crate_name}` has a leading hyphen
12+
913
interface_emoji_identifier =
1014
identifiers cannot contain emoji: `{$ident}`
1115

Diff for: compiler/rustc_interface/src/errors.rs

+15
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,21 @@ use std::path::Path;
44
use rustc_macros::Diagnostic;
55
use rustc_span::{Span, Symbol};
66

7+
#[derive(Diagnostic)]
8+
#[diag(interface_crate_name_does_not_match)]
9+
pub(crate) struct CrateNameDoesNotMatch {
10+
#[primary_span]
11+
pub(crate) span: Span,
12+
pub(crate) crate_name: Symbol,
13+
pub(crate) attr_crate_name: Symbol,
14+
}
15+
16+
#[derive(Diagnostic)]
17+
#[diag(interface_crate_name_invalid)]
18+
pub(crate) struct CrateNameInvalid<'a> {
19+
pub(crate) crate_name: &'a str,
20+
}
21+
722
#[derive(Diagnostic)]
823
#[diag(interface_ferris_identifier)]
924
pub struct FerrisIdentifier {

Diff for: compiler/rustc_interface/src/passes.rs

+84-21
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ use rustc_passes::{abi_test, input_stats, layout_test};
2828
use rustc_resolve::Resolver;
2929
use rustc_session::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType};
3030
use rustc_session::cstore::Untracked;
31-
use rustc_session::output::{collect_crate_types, filename_for_input, find_crate_name};
31+
use rustc_session::output::{collect_crate_types, filename_for_input};
3232
use rustc_session::search_paths::PathKind;
3333
use rustc_session::{Limit, Session};
34-
use rustc_span::{ErrorGuaranteed, FileName, SourceFileHash, SourceFileHashAlgorithm, Symbol, sym};
34+
use rustc_span::{
35+
ErrorGuaranteed, FileName, SourceFileHash, SourceFileHashAlgorithm, Span, Symbol, sym,
36+
};
3537
use rustc_target::spec::PanicStrategy;
3638
use rustc_trait_selection::traits;
3739
use tracing::{info, instrument};
@@ -725,8 +727,7 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
725727

726728
let pre_configured_attrs = rustc_expand::config::pre_configure_attrs(sess, &krate.attrs);
727729

728-
// parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches.
729-
let crate_name = find_crate_name(sess, &pre_configured_attrs);
730+
let crate_name = get_crate_name(sess, &pre_configured_attrs);
730731
let crate_types = collect_crate_types(sess, &pre_configured_attrs);
731732
let stable_crate_id = StableCrateId::new(
732733
crate_name,
@@ -735,7 +736,7 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
735736
sess.cfg_version,
736737
);
737738
let outputs = util::build_output_filenames(&pre_configured_attrs, sess);
738-
let dep_graph = setup_dep_graph(sess);
739+
let dep_graph = setup_dep_graph(sess, crate_name);
739740

740741
let cstore =
741742
FreezeLock::new(Box::new(CStore::new(compiler.codegen_backend.metadata_loader())) as _);
@@ -1080,23 +1081,85 @@ pub(crate) fn start_codegen<'tcx>(
10801081
codegen
10811082
}
10821083

1083-
fn get_recursion_limit(krate_attrs: &[ast::Attribute], sess: &Session) -> Limit {
1084-
if let Some(attr) = krate_attrs
1085-
.iter()
1086-
.find(|attr| attr.has_name(sym::recursion_limit) && attr.value_str().is_none())
1084+
/// Compute and validate the crate name.
1085+
pub fn get_crate_name(sess: &Session, krate_attrs: &[ast::Attribute]) -> Symbol {
1086+
// We validate *all* occurrences of `#![crate_name]`, pick the first find and
1087+
// if a crate name was passed on the command line via `--crate-name` we enforce
1088+
// that they match.
1089+
// We perform the validation step here instead of later to ensure it gets run
1090+
// in all code paths that require the crate name very early on, namely before
1091+
// macro expansion.
1092+
1093+
let attr_crate_name =
1094+
validate_and_find_value_str_builtin_attr(sym::crate_name, sess, krate_attrs);
1095+
1096+
let validate = |name, span| {
1097+
rustc_session::output::validate_crate_name(sess, name, span);
1098+
name
1099+
};
1100+
1101+
if let Some(crate_name) = &sess.opts.crate_name {
1102+
let crate_name = Symbol::intern(crate_name);
1103+
if let Some((attr_crate_name, span)) = attr_crate_name
1104+
&& attr_crate_name != crate_name
1105+
{
1106+
sess.dcx().emit_err(errors::CrateNameDoesNotMatch {
1107+
span,
1108+
crate_name,
1109+
attr_crate_name,
1110+
});
1111+
}
1112+
return validate(crate_name, None);
1113+
}
1114+
1115+
if let Some((crate_name, span)) = attr_crate_name {
1116+
return validate(crate_name, Some(span));
1117+
}
1118+
1119+
if let Input::File(ref path) = sess.io.input
1120+
&& let Some(file_stem) = path.file_stem().and_then(|s| s.to_str())
10871121
{
1088-
// This is here mainly to check for using a macro, such as
1089-
// #![recursion_limit = foo!()]. That is not supported since that
1090-
// would require expanding this while in the middle of expansion,
1091-
// which needs to know the limit before expanding. Otherwise,
1092-
// validation would normally be caught in AstValidator (via
1093-
// `check_builtin_attribute`), but by the time that runs the macro
1094-
// is expanded, and it doesn't give an error.
1095-
validate_attr::emit_fatal_malformed_builtin_attribute(
1096-
&sess.psess,
1097-
attr,
1098-
sym::recursion_limit,
1099-
);
1122+
if file_stem.starts_with('-') {
1123+
sess.dcx().emit_err(errors::CrateNameInvalid { crate_name: file_stem });
1124+
} else {
1125+
return validate(Symbol::intern(&file_stem.replace('-', "_")), None);
1126+
}
11001127
}
1128+
1129+
sym::rust_out
1130+
}
1131+
1132+
fn get_recursion_limit(krate_attrs: &[ast::Attribute], sess: &Session) -> Limit {
1133+
// We don't permit macro calls inside of the attribute (e.g., #![recursion_limit = `expand!()`])
1134+
// because that would require expanding this while in the middle of expansion, which needs to
1135+
// know the limit before expanding.
1136+
let _ = validate_and_find_value_str_builtin_attr(sym::recursion_limit, sess, krate_attrs);
11011137
rustc_middle::middle::limits::get_recursion_limit(krate_attrs, sess)
11021138
}
1139+
1140+
/// Validate *all* occurrences of the given "[value-str]" built-in attribute and return the first find.
1141+
///
1142+
/// This validator is intended for built-in attributes whose value needs to be known very early
1143+
/// during compilation (namely, before macro expansion) and it mainly exists to reject macro calls
1144+
/// inside of the attributes, such as in `#![name = expand!()]`. Normal attribute validation happens
1145+
/// during semantic analysis via [`TyCtxt::check_mod_attrs`] which happens *after* macro expansion
1146+
/// when such macro calls (here: `expand`) have already been expanded and we can no longer check for
1147+
/// their presence.
1148+
///
1149+
/// [value-str]: ast::Attribute::value_str
1150+
fn validate_and_find_value_str_builtin_attr(
1151+
name: Symbol,
1152+
sess: &Session,
1153+
krate_attrs: &[ast::Attribute],
1154+
) -> Option<(Symbol, Span)> {
1155+
let mut result = None;
1156+
// Validate *all* relevant attributes, not just the first occurrence.
1157+
for attr in ast::attr::filter_by_name(krate_attrs, name) {
1158+
let Some(value) = attr.value_str() else {
1159+
validate_attr::emit_fatal_malformed_builtin_attribute(&sess.psess, attr, name)
1160+
};
1161+
// Choose the first occurrence as our result.
1162+
result.get_or_insert((value, attr.span));
1163+
}
1164+
result
1165+
}

Diff for: compiler/rustc_interface/src/util.rs

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

Diff for: compiler/rustc_parse/messages.ftl

-3
Original file line numberDiff line numberDiff line change
@@ -743,9 +743,6 @@ parse_single_colon_import_path = expected `::`, found `:`
743743
.suggestion = use double colon
744744
.note = import paths are delimited using `::`
745745
746-
parse_single_colon_struct_type = found single colon in a struct field type path
747-
.suggestion = write a path separator here
748-
749746
parse_static_with_generics = static items may not have generic parameters
750747
751748
parse_struct_literal_body_without_path =

Diff for: compiler/rustc_parse/src/errors.rs

-8
Original file line numberDiff line numberDiff line change
@@ -3071,14 +3071,6 @@ pub(crate) struct BadItemKind {
30713071
pub help: bool,
30723072
}
30733073

3074-
#[derive(Diagnostic)]
3075-
#[diag(parse_single_colon_struct_type)]
3076-
pub(crate) struct SingleColonStructType {
3077-
#[primary_span]
3078-
#[suggestion(code = "::", applicability = "maybe-incorrect", style = "verbose")]
3079-
pub span: Span,
3080-
}
3081-
30823074
#[derive(Diagnostic)]
30833075
#[diag(parse_macro_rules_missing_bang)]
30843076
pub(crate) struct MacroRulesMissingBang {

Diff for: compiler/rustc_parse/src/parser/item.rs

-3
Original file line numberDiff line numberDiff line change
@@ -2043,9 +2043,6 @@ impl<'a> Parser<'a> {
20432043
}
20442044
self.expect_field_ty_separator()?;
20452045
let ty = self.parse_ty()?;
2046-
if self.token == token::Colon && self.look_ahead(1, |t| *t != token::Colon) {
2047-
self.dcx().emit_err(errors::SingleColonStructType { span: self.token.span });
2048-
}
20492046
let default = if self.token == token::Eq {
20502047
self.bump();
20512048
let const_expr = self.parse_expr_anon_const()?;

Diff for: compiler/rustc_parse/src/parser/pat.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -1472,17 +1472,6 @@ impl<'a> Parser<'a> {
14721472
let mut last_non_comma_dotdot_span = None;
14731473

14741474
while self.token != token::CloseDelim(Delimiter::Brace) {
1475-
let attrs = match self.parse_outer_attributes() {
1476-
Ok(attrs) => attrs,
1477-
Err(err) => {
1478-
if let Some(delayed) = delayed_err {
1479-
delayed.emit();
1480-
}
1481-
return Err(err);
1482-
}
1483-
};
1484-
let lo = self.token.span;
1485-
14861475
// check that a comma comes after every field
14871476
if !ate_comma {
14881477
let err = if self.token == token::At {
@@ -1585,6 +1574,17 @@ impl<'a> Parser<'a> {
15851574
}
15861575
}
15871576

1577+
let attrs = match self.parse_outer_attributes() {
1578+
Ok(attrs) => attrs,
1579+
Err(err) => {
1580+
if let Some(delayed) = delayed_err {
1581+
delayed.emit();
1582+
}
1583+
return Err(err);
1584+
}
1585+
};
1586+
let lo = self.token.span;
1587+
15881588
let field = self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
15891589
let field = match this.parse_pat_field(lo, attrs) {
15901590
Ok(field) => Ok(field),

Diff for: compiler/rustc_parse/src/parser/path.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,19 @@ impl<'a> Parser<'a> {
246246
segments.push(segment);
247247

248248
if self.is_import_coupler() || !self.eat_path_sep() {
249-
if style == PathStyle::Expr
250-
&& self.may_recover()
249+
let ok_for_recovery = self.may_recover()
250+
&& match style {
251+
PathStyle::Expr => true,
252+
PathStyle::Type if let Some((ident, _)) = self.prev_token.ident() => {
253+
self.token == token::Colon
254+
&& ident.as_str().chars().all(|c| c.is_lowercase())
255+
&& self.token.span.lo() == self.prev_token.span.hi()
256+
&& self
257+
.look_ahead(1, |token| self.token.span.hi() == token.span.lo())
258+
}
259+
_ => false,
260+
};
261+
if ok_for_recovery
251262
&& self.token == token::Colon
252263
&& self.look_ahead(1, |token| token.is_ident() && !token.is_reserved_ident())
253264
{

0 commit comments

Comments
 (0)