diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-07 05:48:48 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-07 05:48:48 +0000 |
commit | ef24de24a82fe681581cc130f342363c47c0969a (patch) | |
tree | 0d494f7e1a38b95c92426f58fe6eaa877303a86c /compiler/rustc_expand | |
parent | Releasing progress-linux version 1.74.1+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-ef24de24a82fe681581cc130f342363c47c0969a.tar.xz rustc-ef24de24a82fe681581cc130f342363c47c0969a.zip |
Merging upstream version 1.75.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_expand')
-rw-r--r-- | compiler/rustc_expand/Cargo.toml | 6 | ||||
-rw-r--r-- | compiler/rustc_expand/messages.ftl | 1 | ||||
-rw-r--r-- | compiler/rustc_expand/src/config.rs | 211 | ||||
-rw-r--r-- | compiler/rustc_expand/src/errors.rs | 1 | ||||
-rw-r--r-- | compiler/rustc_expand/src/lib.rs | 2 | ||||
-rw-r--r-- | compiler/rustc_expand/src/mbe/macro_rules.rs | 24 | ||||
-rw-r--r-- | compiler/rustc_expand/src/mbe/metavar_expr.rs | 14 | ||||
-rw-r--r-- | compiler/rustc_expand/src/module.rs | 4 | ||||
-rw-r--r-- | compiler/rustc_expand/src/placeholders.rs | 2 | ||||
-rw-r--r-- | compiler/rustc_expand/src/proc_macro_server.rs | 5 | ||||
-rw-r--r-- | compiler/rustc_expand/src/tests.rs | 4 |
11 files changed, 140 insertions, 134 deletions
diff --git a/compiler/rustc_expand/Cargo.toml b/compiler/rustc_expand/Cargo.toml index 02da5b5dc..9189a501a 100644 --- a/compiler/rustc_expand/Cargo.toml +++ b/compiler/rustc_expand/Cargo.toml @@ -8,9 +8,10 @@ build = false doctest = false [dependencies] +# tidy-alphabetical-start crossbeam-channel = "0.5.0" -rustc_ast_passes = { path = "../rustc_ast_passes" } rustc_ast = { path = "../rustc_ast" } +rustc_ast_passes = { path = "../rustc_ast_passes" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_attr = { path = "../rustc_attr" } rustc_data_structures = { path = "../rustc_data_structures" } @@ -25,6 +26,7 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } +termcolor = "1.2" thin-vec = "0.2.12" tracing = "0.1" -termcolor = "1.2" +# tidy-alphabetical-end diff --git a/compiler/rustc_expand/messages.ftl b/compiler/rustc_expand/messages.ftl index 6c7e68246..8b9382962 100644 --- a/compiler/rustc_expand/messages.ftl +++ b/compiler/rustc_expand/messages.ftl @@ -86,6 +86,7 @@ expand_module_circular = expand_module_file_not_found = file not found for module `{$name}` .help = to create the module `{$name}`, create file "{$default_path}" or "{$secondary_path}" + .note = if there is a `mod {$name}` elsewhere in the crate already, import it with `use crate::...` instead expand_module_in_block = cannot declare a non-inline module inside a block unless it has a path attribute diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 8658cea13..bef487659 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -13,17 +13,16 @@ use rustc_ast::NodeId; use rustc_ast::{self as ast, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem}; use rustc_attr as attr; use rustc_data_structures::flat_map_in_place::FlatMapInPlace; -use rustc_data_structures::fx::FxHashMap; -use rustc_feature::{Feature, Features, State as FeatureState}; -use rustc_feature::{ - ACCEPTED_FEATURES, ACTIVE_FEATURES, REMOVED_FEATURES, STABLE_REMOVED_FEATURES, -}; +use rustc_data_structures::fx::FxHashSet; +use rustc_feature::Features; +use rustc_feature::{ACCEPTED_FEATURES, REMOVED_FEATURES, UNSTABLE_FEATURES}; use rustc_parse::validate_attr; use rustc_session::parse::feature_err; use rustc_session::Session; -use rustc_span::edition::{Edition, ALL_EDITIONS}; +use rustc_span::edition::ALL_EDITIONS; use rustc_span::symbol::{sym, Symbol}; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::Span; +use thin_vec::ThinVec; /// A folder that strips out items that do not belong in the current configuration. pub struct StripUnconfigured<'a> { @@ -36,85 +35,56 @@ pub struct StripUnconfigured<'a> { pub lint_node_id: NodeId, } -pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features { - fn feature_removed(sess: &Session, span: Span, reason: Option<&str>) { - sess.emit_err(FeatureRemoved { - span, - reason: reason.map(|reason| FeatureRemovedReason { reason }), - }); - } - - fn active_features_up_to(edition: Edition) -> impl Iterator<Item = &'static Feature> { - ACTIVE_FEATURES.iter().filter(move |feature| { - if let Some(feature_edition) = feature.edition { - feature_edition <= edition - } else { - false - } - }) +pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -> Features { + fn feature_list(attr: &Attribute) -> ThinVec<ast::NestedMetaItem> { + if attr.has_name(sym::feature) + && let Some(list) = attr.meta_item_list() + { + list + } else { + ThinVec::new() + } } let mut features = Features::default(); - let mut edition_enabled_features = FxHashMap::default(); - let crate_edition = sess.edition(); - - for &edition in ALL_EDITIONS { - if edition <= crate_edition { - // The `crate_edition` implies its respective umbrella feature-gate - // (i.e., `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX). - edition_enabled_features.insert(edition.feature_name(), edition); - } - } - for feature in active_features_up_to(crate_edition) { - feature.set(&mut features, DUMMY_SP); - edition_enabled_features.insert(feature.name, crate_edition); - } + // The edition from `--edition`. + let crate_edition = sess.edition(); - // Process the edition umbrella feature-gates first, to ensure - // `edition_enabled_features` is completed before it's queried. + // The maximum of (a) the edition from `--edition` and (b) any edition + // umbrella feature-gates declared in the code. + // - E.g. if `crate_edition` is 2015 but `rust_2018_preview` is present, + // `feature_edition` is 2018 + let mut features_edition = crate_edition; for attr in krate_attrs { - if !attr.has_name(sym::feature) { - continue; - } - - let Some(list) = attr.meta_item_list() else { - continue; - }; - - for mi in list { - if !mi.is_word() { - continue; - } - - let name = mi.name_or_empty(); - - let edition = ALL_EDITIONS.iter().find(|e| name == e.feature_name()).copied(); - if let Some(edition) = edition { - if edition <= crate_edition { - continue; - } - - for feature in active_features_up_to(edition) { - // FIXME(Manishearth) there is currently no way to set - // lib features by edition - feature.set(&mut features, DUMMY_SP); - edition_enabled_features.insert(feature.name, edition); + for mi in feature_list(attr) { + if mi.is_word() { + let name = mi.name_or_empty(); + let edition = ALL_EDITIONS.iter().find(|e| name == e.feature_name()).copied(); + if let Some(edition) = edition + && edition > features_edition + { + features_edition = edition; } } } } - for attr in krate_attrs { - if !attr.has_name(sym::feature) { - continue; + // Enable edition-dependent features based on `features_edition`. + // - E.g. enable `test_2018_feature` if `features_edition` is 2018 or higher + let mut edition_enabled_features = FxHashSet::default(); + for f in UNSTABLE_FEATURES { + if let Some(edition) = f.feature.edition && edition <= features_edition { + // FIXME(Manishearth) there is currently no way to set lib features by + // edition. + edition_enabled_features.insert(f.feature.name); + (f.set_enabled)(&mut features); } + } - let Some(list) = attr.meta_item_list() else { - continue; - }; - - for mi in list { + // Process all features declared in the code. + for attr in krate_attrs { + for mi in feature_list(attr) { let name = match mi.ident() { Some(ident) if mi.is_word() => ident.name, Some(ident) => { @@ -136,38 +106,57 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features { } }; - if let Some(&edition) = edition_enabled_features.get(&name) { + // If the declared feature is an edition umbrella feature-gate, + // warn if it was redundant w.r.t. `crate_edition`. + // - E.g. warn if `rust_2018_preview` is declared when + // `crate_edition` is 2018 + // - E.g. don't warn if `rust_2018_preview` is declared when + // `crate_edition` is 2015. + if let Some(&edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) { + if edition <= crate_edition { + sess.emit_warning(FeatureIncludedInEdition { + span: mi.span(), + feature: name, + edition, + }); + } + features.set_declared_lang_feature(name, mi.span(), None); + continue; + } + + // If the declared feature is edition-dependent and was already + // enabled due to `feature_edition`, give a warning. + // - E.g. warn if `test_2018_feature` is declared when + // `feature_edition` is 2018 or higher. + if edition_enabled_features.contains(&name) { sess.emit_warning(FeatureIncludedInEdition { span: mi.span(), feature: name, - edition, + edition: features_edition, }); + features.set_declared_lang_feature(name, mi.span(), None); continue; } - if ALL_EDITIONS.iter().any(|e| name == e.feature_name()) { - // Handled in the separate loop above. + // If the declared feature has been removed, issue an error. + if let Some(f) = REMOVED_FEATURES.iter().find(|f| name == f.feature.name) { + sess.emit_err(FeatureRemoved { + span: mi.span(), + reason: f.reason.map(|reason| FeatureRemovedReason { reason }), + }); continue; } - let removed = REMOVED_FEATURES.iter().find(|f| name == f.name); - let stable_removed = STABLE_REMOVED_FEATURES.iter().find(|f| name == f.name); - if let Some(Feature { state, .. }) = removed.or(stable_removed) { - if let FeatureState::Removed { reason } | FeatureState::Stabilized { reason } = - state - { - feature_removed(sess, mi.span(), *reason); - continue; - } - } - - if let Some(Feature { since, .. }) = ACCEPTED_FEATURES.iter().find(|f| name == f.name) { - let since = Some(Symbol::intern(since)); - features.declared_lang_features.push((name, mi.span(), since)); - features.active_features.insert(name); + // If the declared feature is stable, record it. + if let Some(f) = ACCEPTED_FEATURES.iter().find(|f| name == f.name) { + let since = Some(Symbol::intern(f.since)); + features.set_declared_lang_feature(name, mi.span(), since); continue; } + // If `-Z allow-features` is used and the declared feature is + // unstable and not also listed as one of the allowed features, + // issue an error. if let Some(allowed) = sess.opts.unstable_opts.allow_features.as_ref() { if allowed.iter().all(|f| name.as_str() != f) { sess.emit_err(FeatureNotAllowed { span: mi.span(), name }); @@ -175,15 +164,25 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features { } } - if let Some(f) = ACTIVE_FEATURES.iter().find(|f| name == f.name) { - f.set(&mut features, mi.span()); - features.declared_lang_features.push((name, mi.span(), None)); - features.active_features.insert(name); + // If the declared feature is unstable, record it. + if let Some(f) = UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name) { + (f.set_enabled)(&mut features); + // When the ICE comes from core, alloc or std (approximation of the standard library), there's a chance + // that the person hitting the ICE may be using -Zbuild-std or similar with an untested target. + // The bug is probably in the standard library and not the compiler in that case, but that doesn't + // really matter - we want a bug report. + if features.internal(name) + && ![sym::core, sym::alloc, sym::std].contains(&crate_name) + { + sess.using_internal_features.store(true, std::sync::atomic::Ordering::Relaxed); + } + features.set_declared_lang_feature(name, mi.span(), None); continue; } - features.declared_lib_features.push((name, mi.span())); - features.active_features.insert(name); + // Otherwise, the feature is unknown. Record it as a lib feature. + // It will be checked later. + features.set_declared_lib_feature(name, mi.span()); } } @@ -252,7 +251,8 @@ impl<'a> StripUnconfigured<'a> { let trees: Vec<_> = stream .0 .iter() - .flat_map(|tree| match tree.clone() { + .flat_map(|tree| { + match tree.clone() { AttrTokenTree::Attributes(mut data) => { data.attrs.flat_map_in_place(|attr| self.process_cfg_attr(&attr)); @@ -267,18 +267,17 @@ impl<'a> StripUnconfigured<'a> { } AttrTokenTree::Delimited(sp, delim, mut inner) => { inner = self.configure_tokens(&inner); - Some(AttrTokenTree::Delimited(sp, delim, inner)) - .into_iter() + Some(AttrTokenTree::Delimited(sp, delim, inner)).into_iter() } - AttrTokenTree::Token(ref token, _) if let TokenKind::Interpolated(nt) = &token.kind => { - panic!( - "Nonterminal should have been flattened at {:?}: {:?}", - token.span, nt - ); + AttrTokenTree::Token(ref token, _) + if let TokenKind::Interpolated(nt) = &token.kind => + { + panic!("Nonterminal should have been flattened at {:?}: {:?}", token.span, nt); } AttrTokenTree::Token(token, spacing) => { Some(AttrTokenTree::Token(token, spacing)).into_iter() } + } }) .collect(); AttrTokenStream::new(trees) diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs index e3a0ae357..d86632c47 100644 --- a/compiler/rustc_expand/src/errors.rs +++ b/compiler/rustc_expand/src/errors.rs @@ -350,6 +350,7 @@ pub(crate) struct ModuleInBlockName { #[derive(Diagnostic)] #[diag(expand_module_file_not_found, code = "E0583")] #[help] +#[note] pub(crate) struct ModuleFileNotFound { #[primary_span] pub span: Span, diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 8b1fc5b90..5a774164a 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -1,3 +1,5 @@ +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![feature(array_windows)] #![feature(associated_type_bounds)] #![feature(associated_type_defaults)] diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index a5959d68f..ebdd3cb54 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -716,18 +716,18 @@ fn has_compile_error_macro(rhs: &mbe::TokenTree) -> bool { match rhs { mbe::TokenTree::Delimited(_sp, d) => { let has_compile_error = d.tts.array_windows::<3>().any(|[ident, bang, args]| { - if let mbe::TokenTree::Token(ident) = ident && - let TokenKind::Ident(ident, _) = ident.kind && - ident == sym::compile_error && - let mbe::TokenTree::Token(bang) = bang && - let TokenKind::Not = bang.kind && - let mbe::TokenTree::Delimited(_, del) = args && - del.delim != Delimiter::Invisible - { - true - } else { - false - } + if let mbe::TokenTree::Token(ident) = ident + && let TokenKind::Ident(ident, _) = ident.kind + && ident == sym::compile_error + && let mbe::TokenTree::Token(bang) = bang + && let TokenKind::Not = bang.kind + && let mbe::TokenTree::Delimited(_, del) = args + && del.delim != Delimiter::Invisible + { + true + } else { + false + } }); if has_compile_error { true } else { d.tts.iter().any(has_compile_error_macro) } } diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs index 7c37aadc6..7cb279a98 100644 --- a/compiler/rustc_expand/src/mbe/metavar_expr.rs +++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs @@ -124,8 +124,7 @@ fn parse_depth<'sess>( && let Ok(n_usize) = usize::try_from(n_u128) { Ok(n_usize) - } - else { + } else { let msg = "only unsuffixes integer literals are supported in meta-variable expressions"; Err(sess.span_diagnostic.struct_span_err(span, msg)) } @@ -137,15 +136,16 @@ fn parse_ident<'sess>( sess: &'sess ParseSess, span: Span, ) -> PResult<'sess, Ident> { - if let Some(tt) = iter.next() && let TokenTree::Token(token, _) = tt { + if let Some(tt) = iter.next() + && let TokenTree::Token(token, _) = tt + { if let Some((elem, false)) = token.ident() { return Ok(elem); } let token_str = pprust::token_to_string(token); - let mut err = sess.span_diagnostic.struct_span_err( - span, - format!("expected identifier, found `{}`", &token_str) - ); + let mut err = sess + .span_diagnostic + .struct_span_err(span, format!("expected identifier, found `{}`", &token_str)); err.span_suggestion( token.span, format!("try removing `{}`", &token_str), diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs index 3779af19e..df6bdc695 100644 --- a/compiler/rustc_expand/src/module.rs +++ b/compiler/rustc_expand/src/module.rs @@ -91,7 +91,9 @@ pub(crate) fn mod_dir_path( inline: Inline, ) -> (PathBuf, DirOwnership) { match inline { - Inline::Yes if let Some(file_path) = mod_file_path_from_attr(sess, attrs, &module.dir_path) => { + Inline::Yes + if let Some(file_path) = mod_file_path_from_attr(sess, attrs, &module.dir_path) => + { // For inline modules file path from `#[path]` is actually the directory path // for historical reasons, so we don't pop the last segment here. (file_path, DirOwnership::Owned { relative: None }) diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index 82cac2292..1292a8552 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -4,8 +4,8 @@ use rustc_ast::mut_visit::*; use rustc_ast::ptr::P; use rustc_ast::token::Delimiter; use rustc_data_structures::fx::FxHashMap; -use rustc_span::source_map::DUMMY_SP; use rustc_span::symbol::Ident; +use rustc_span::DUMMY_SP; use smallvec::{smallvec, SmallVec}; use thin_vec::ThinVec; diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 2dc9b51a3..aa4c7a531 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -226,9 +226,8 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre })); } - Interpolated(nt) if let NtIdent(ident, is_raw) = *nt => { - trees.push(TokenTree::Ident(Ident { sym: ident.name, is_raw, span: ident.span })) - } + Interpolated(nt) if let NtIdent(ident, is_raw) = *nt => trees + .push(TokenTree::Ident(Ident { sym: ident.name, is_raw, span: ident.span })), Interpolated(nt) => { let stream = TokenStream::from_nonterminal_ast(&nt); diff --git a/compiler/rustc_expand/src/tests.rs b/compiler/rustc_expand/src/tests.rs index 8e3219c13..9f52669e1 100644 --- a/compiler/rustc_expand/src/tests.rs +++ b/compiler/rustc_expand/src/tests.rs @@ -2,7 +2,7 @@ use rustc_ast as ast; use rustc_ast::tokenstream::TokenStream; use rustc_parse::{new_parser_from_source_str, parser::Parser, source_file_to_stream}; use rustc_session::parse::ParseSess; -use rustc_span::create_default_session_if_not_set_then; +use rustc_span::create_default_session_globals_then; use rustc_span::source_map::{FilePathMapping, SourceMap}; use rustc_span::{BytePos, Span}; @@ -181,7 +181,7 @@ impl<T: Write> Write for Shared<T> { } fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: &str) { - create_default_session_if_not_set_then(|_| { + create_default_session_globals_then(|| { let (handler, source_map, output) = create_test_handler(); source_map.new_source_file(Path::new("test.rs").to_owned().into(), file_text.to_owned()); |