diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs index 0f1ab02fca251..d37915b1b80b2 100644 --- a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs @@ -1,4 +1,4 @@ -use rustc_hir::attrs::MacroUseArgs; +use rustc_hir::attrs::{CollapseMacroDebuginfo, MacroUseArgs}; use rustc_session::lint::builtin::INVALID_MACRO_EXPORT_ARGUMENTS; use super::prelude::*; @@ -163,3 +163,46 @@ impl SingleAttributeParser for MacroExportParser { Some(AttributeKind::MacroExport { span: cx.attr_span, local_inner_macros }) } } + +pub(crate) struct CollapseDebugInfoParser; + +impl SingleAttributeParser for CollapseDebugInfoParser { + const PATH: &[Symbol] = &[sym::collapse_debuginfo]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const TEMPLATE: AttributeTemplate = template!( + List: &["no", "external", "yes"], + "https://doc.rust-lang.org/reference/attributes/debugger.html#the-collapse_debuginfo-attribute" + ); + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::MacroDef)]); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { + let Some(list) = args.list() else { + cx.expected_list(cx.attr_span, args); + return None; + }; + let Some(single) = list.single() else { + cx.expected_single_argument(list.span); + return None; + }; + let Some(mi) = single.meta_item() else { + cx.unexpected_literal(single.span()); + return None; + }; + if let Err(err) = mi.args().no_args() { + cx.expected_no_args(err); + } + let path = mi.path().word_sym(); + let info = match path { + Some(sym::yes) => CollapseMacroDebuginfo::Yes, + Some(sym::no) => CollapseMacroDebuginfo::No, + Some(sym::external) => CollapseMacroDebuginfo::External, + _ => { + cx.expected_specific_argument(mi.span(), &[sym::yes, sym::no, sym::external]); + return None; + } + }; + + Some(AttributeKind::CollapseDebugInfo(info)) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 732bf111b2568..835bf8ae5c9c4 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -48,7 +48,8 @@ use crate::attributes::lint_helpers::{ }; use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser}; use crate::attributes::macro_attrs::{ - AllowInternalUnsafeParser, MacroEscapeParser, MacroExportParser, MacroUseParser, + AllowInternalUnsafeParser, CollapseDebugInfoParser, MacroEscapeParser, MacroExportParser, + MacroUseParser, }; use crate::attributes::must_use::MustUseParser; use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser; @@ -191,6 +192,7 @@ attribute_parsers!( // tidy-alphabetical-start Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index e38fffa6587cf..7602e3c4598a3 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -442,7 +442,17 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { /// Returns whether there is a parser for an attribute with this name pub fn is_parsed_attribute(path: &[Symbol]) -> bool { - Late::parsers().accepters.contains_key(path) || EARLY_PARSED_ATTRIBUTES.contains(&path) + /// The list of attributes that are parsed attributes, + /// even though they don't have a parser in `Late::parsers()` + const SPECIAL_ATTRIBUTES: &[&[Symbol]] = &[ + // Cfg attrs are removed after being early-parsed, so don't need to be in the parser list + &[sym::cfg], + &[sym::cfg_attr], + ]; + + Late::parsers().accepters.contains_key(path) + || EARLY_PARSED_ATTRIBUTES.contains(&path) + || SPECIAL_ATTRIBUTES.contains(&path) } fn lower_attr_args(&self, args: &ast::AttrArgs, lower_span: impl Fn(Span) -> Span) -> AttrArgs { diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs index 0ebd3dc826d48..a5009b3bfa52f 100644 --- a/compiler/rustc_builtin_macros/src/eii.rs +++ b/compiler/rustc_builtin_macros/src/eii.rs @@ -108,7 +108,7 @@ fn eii_( let mut return_items = Vec::new(); if func.body.is_some() { - return_items.push(Box::new(generate_default_impl( + return_items.push(generate_default_impl( ecx, &func, impl_unsafe, @@ -116,25 +116,25 @@ fn eii_( eii_attr_span, item_span, foreign_item_name, - ))) + )) } - return_items.push(Box::new(generate_foreign_item( + return_items.push(generate_foreign_item( ecx, eii_attr_span, item_span, func, vis, &attrs_from_decl, - ))); - return_items.push(Box::new(generate_attribute_macro_to_implement( + )); + return_items.push(generate_attribute_macro_to_implement( ecx, eii_attr_span, macro_name, foreign_item_name, impl_unsafe, &attrs_from_decl, - ))); + )); return_items.into_iter().map(wrap_item).collect() } @@ -194,7 +194,7 @@ fn generate_default_impl( eii_attr_span: Span, item_span: Span, foreign_item_name: Ident, -) -> ast::Item { +) -> Box { // FIXME: re-add some original attrs let attrs = ThinVec::new(); @@ -211,124 +211,72 @@ fn generate_default_impl( span: eii_attr_span, is_default: true, known_eii_macro_resolution: Some(ast::EiiExternTarget { - extern_item_path: ast::Path { - span: foreign_item_name.span, - segments: thin_vec![ - ast::PathSegment { - ident: Ident::from_str_and_span("super", foreign_item_name.span,), - id: DUMMY_NODE_ID, - args: None - }, - ast::PathSegment { ident: foreign_item_name, id: DUMMY_NODE_ID, args: None }, - ], - tokens: None, - }, + extern_item_path: ecx.path( + foreign_item_name.span, + // prefix super to escape the `dflt` module generated below + vec![Ident::from_str_and_span("super", foreign_item_name.span), foreign_item_name], + ), impl_unsafe, }), }); - ast::Item { - attrs: ThinVec::new(), - id: ast::DUMMY_NODE_ID, - span: eii_attr_span, - vis: ast::Visibility { - span: eii_attr_span, - kind: ast::VisibilityKind::Inherited, - tokens: None, - }, - kind: ast::ItemKind::Const(Box::new(ast::ConstItem { - ident: Ident { name: kw::Underscore, span: eii_attr_span }, - defaultness: ast::Defaultness::Final, - generics: ast::Generics::default(), - ty: Box::new(ast::Ty { - id: DUMMY_NODE_ID, - kind: ast::TyKind::Tup(ThinVec::new()), - span: eii_attr_span, - tokens: None, - }), - rhs: Some(ast::ConstItemRhs::Body(Box::new(ast::Expr { - id: DUMMY_NODE_ID, - kind: ast::ExprKind::Block( - Box::new(ast::Block { - stmts: thin_vec![ast::Stmt { - id: DUMMY_NODE_ID, - kind: ast::StmtKind::Item(Box::new(ast::Item { - attrs: ThinVec::new(), - id: DUMMY_NODE_ID, - span: item_span, - vis: ast::Visibility { - span: item_span, - kind: ast::VisibilityKind::Inherited, - tokens: None - }, - kind: ItemKind::Mod( - ast::Safety::Default, - Ident::from_str_and_span("dflt", item_span), - ast::ModKind::Loaded( - thin_vec![ - Box::new(ast::Item { - attrs: thin_vec![ecx.attr_nested_word( - sym::allow, - sym::unused_imports, - item_span - ),], - id: DUMMY_NODE_ID, - span: item_span, - vis: ast::Visibility { - span: eii_attr_span, - kind: ast::VisibilityKind::Inherited, - tokens: None - }, - kind: ItemKind::Use(ast::UseTree { - prefix: ast::Path::from_ident( - Ident::from_str_and_span( - "super", item_span, - ) - ), - kind: ast::UseTreeKind::Glob, - span: item_span, - }), - tokens: None, - }), - Box::new(ast::Item { - attrs, - id: DUMMY_NODE_ID, - span: item_span, - vis: ast::Visibility { - span: eii_attr_span, - kind: ast::VisibilityKind::Inherited, - tokens: None - }, - kind: ItemKind::Fn(Box::new(default_func)), - tokens: None, - }), - ], - ast::Inline::Yes, - ast::ModSpans { - inner_span: item_span, - inject_use_span: item_span, - } - ) - ), - tokens: None, - })), - span: eii_attr_span, - }], - id: DUMMY_NODE_ID, - rules: ast::BlockCheckMode::Default, - span: eii_attr_span, - tokens: None, - }), - None, + let item_mod = |span: Span, name: Ident, items: ThinVec>| { + ecx.item( + item_span, + ThinVec::new(), + ItemKind::Mod( + ast::Safety::Default, + name, + ast::ModKind::Loaded( + items, + ast::Inline::Yes, + ast::ModSpans { inner_span: span, inject_use_span: span }, ), - span: eii_attr_span, - attrs: ThinVec::new(), - tokens: None, - }))), - define_opaque: None, - })), - tokens: None, - } + ), + ) + }; + + let anon_mod = |span: Span, stmts: ThinVec| { + let unit = ecx.ty(item_span, ast::TyKind::Tup(ThinVec::new())); + let underscore = Ident::new(kw::Underscore, item_span); + ecx.item_const( + span, + underscore, + unit, + ast::ConstItemRhs::Body(ecx.expr_block(ecx.block(span, stmts))), + ) + }; + + // const _: () = { + // mod dflt { + // use super::*; + // + // } + // } + anon_mod( + item_span, + thin_vec![ecx.stmt_item( + item_span, + item_mod( + item_span, + Ident::from_str_and_span("dflt", item_span), + thin_vec![ + ecx.item( + item_span, + thin_vec![ecx.attr_nested_word(sym::allow, sym::unused_imports, item_span)], + ItemKind::Use(ast::UseTree { + prefix: ast::Path::from_ident(Ident::from_str_and_span( + "super", item_span, + )), + kind: ast::UseTreeKind::Glob, + span: item_span, + }) + ), + ecx.item(item_span, attrs, ItemKind::Fn(Box::new(default_func))) + ] + ) + ),], + ) } /// Generates a foreign item, like @@ -343,7 +291,7 @@ fn generate_foreign_item( mut func: ast::Fn, vis: Visibility, attrs_from_decl: &[Attribute], -) -> ast::Item { +) -> Box { let mut foreign_item_attrs = ThinVec::new(); foreign_item_attrs.extend_from_slice(attrs_from_decl); @@ -375,16 +323,10 @@ fn generate_foreign_item( func.sig.header.safety = ast::Safety::Safe(func.sig.span); } - ast::Item { - attrs: ast::AttrVec::default(), - id: ast::DUMMY_NODE_ID, - span: eii_attr_span, - vis: ast::Visibility { - span: eii_attr_span, - kind: ast::VisibilityKind::Inherited, - tokens: None, - }, - kind: ast::ItemKind::ForeignMod(ast::ForeignMod { + ecx.item( + eii_attr_span, + ThinVec::new(), + ast::ItemKind::ForeignMod(ast::ForeignMod { extern_span: eii_attr_span, safety: ast::Safety::Unsafe(eii_attr_span), abi, @@ -397,8 +339,7 @@ fn generate_foreign_item( tokens: None, })]), }), - tokens: None, - } + ) } /// Generate a stub macro (a bit like in core) that will roughly look like: @@ -418,7 +359,7 @@ fn generate_attribute_macro_to_implement( foreign_item_name: Ident, impl_unsafe: bool, attrs_from_decl: &[Attribute], -) -> ast::Item { +) -> Box { let mut macro_attrs = ThinVec::new(); // To avoid e.g. `error: attribute macro has missing stability attribute` @@ -428,7 +369,8 @@ fn generate_attribute_macro_to_implement( // #[builtin_macro(eii_shared_macro)] macro_attrs.push(ecx.attr_nested_word(sym::rustc_builtin_macro, sym::eii_shared_macro, span)); - ast::Item { + // cant use ecx methods here to construct item since we need it to be public + Box::new(ast::Item { attrs: macro_attrs, id: ast::DUMMY_NODE_ID, span, @@ -467,7 +409,7 @@ fn generate_attribute_macro_to_implement( }, ), tokens: None, - } + }) } pub(crate) fn eii_extern_target( diff --git a/compiler/rustc_expand/messages.ftl b/compiler/rustc_expand/messages.ftl index 6c23320a1b112..851d78e0b1051 100644 --- a/compiler/rustc_expand/messages.ftl +++ b/compiler/rustc_expand/messages.ftl @@ -5,9 +5,6 @@ expand_attributes_on_expressions_experimental = expand_cfg_attr_no_attributes = `#[cfg_attr]` does not expand to any attributes -expand_collapse_debuginfo_illegal = - illegal value for attribute #[collapse_debuginfo(no|external|yes)] - expand_count_repetition_misplaced = `count` can not be placed inside the innermost repetition diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 946f17943fe3d..bf653fac52535 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -6,7 +6,7 @@ use std::path::{Path, PathBuf}; use std::rc::Rc; use std::sync::Arc; -use rustc_ast::attr::{AttributeExt, MarkedAttrs}; +use rustc_ast::attr::MarkedAttrs; use rustc_ast::token::MetaVarKind; use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{AssocCtxt, Visitor}; @@ -16,7 +16,7 @@ use rustc_data_structures::sync; use rustc_errors::{BufferedEarlyLint, DiagCtxtHandle, ErrorGuaranteed, PResult}; use rustc_feature::Features; use rustc_hir as hir; -use rustc_hir::attrs::{AttributeKind, CfgEntry, Deprecation}; +use rustc_hir::attrs::{AttributeKind, CfgEntry, CollapseMacroDebuginfo, Deprecation}; use rustc_hir::def::MacroKinds; use rustc_hir::limit::Limit; use rustc_hir::{Stability, find_attr}; @@ -24,7 +24,6 @@ use rustc_lint_defs::RegisteredTools; use rustc_parse::MACRO_ARGUMENTS; use rustc_parse::parser::{ForceCollect, Parser}; use rustc_session::Session; -use rustc_session::config::CollapseMacroDebuginfo; use rustc_session::parse::ParseSess; use rustc_span::def_id::{CrateNum, DefId, LocalDefId}; use rustc_span::edition::Edition; @@ -34,7 +33,6 @@ use rustc_span::{DUMMY_SP, FileName, Ident, Span, Symbol, kw, sym}; use smallvec::{SmallVec, smallvec}; use thin_vec::ThinVec; -use crate::base::ast::MetaItemInner; use crate::errors; use crate::expand::{self, AstFragment, Invocation}; use crate::mbe::macro_rules::ParserAnyMacro; @@ -887,25 +885,6 @@ impl SyntaxExtension { } } - fn collapse_debuginfo_by_name( - attr: &impl AttributeExt, - ) -> Result { - let list = attr.meta_item_list(); - let Some([MetaItemInner::MetaItem(item)]) = list.as_deref() else { - return Err(attr.span()); - }; - if !item.is_word() { - return Err(item.span); - } - - match item.name() { - Some(sym::no) => Ok(CollapseMacroDebuginfo::No), - Some(sym::external) => Ok(CollapseMacroDebuginfo::External), - Some(sym::yes) => Ok(CollapseMacroDebuginfo::Yes), - _ => Err(item.path.span), - } - } - /// if-ext - if macro from different crate (related to callsite code) /// | cmd \ attr | no | (unspecified) | external | yes | /// | no | no | no | no | no | @@ -914,21 +893,15 @@ impl SyntaxExtension { /// | yes | yes | yes | yes | yes | fn get_collapse_debuginfo(sess: &Session, attrs: &[hir::Attribute], ext: bool) -> bool { let flag = sess.opts.cg.collapse_macro_debuginfo; - let attr = ast::attr::find_by_name(attrs, sym::collapse_debuginfo) - .and_then(|attr| { - Self::collapse_debuginfo_by_name(attr) - .map_err(|span| { - sess.dcx().emit_err(errors::CollapseMacroDebuginfoIllegal { span }) - }) - .ok() - }) - .unwrap_or_else(|| { - if find_attr!(attrs, AttributeKind::RustcBuiltinMacro { .. }) { - CollapseMacroDebuginfo::Yes - } else { - CollapseMacroDebuginfo::Unspecified - } - }); + let attr = + if let Some(info) = find_attr!(attrs, AttributeKind::CollapseDebugInfo(info) => info) { + info.clone() + } else if find_attr!(attrs, AttributeKind::RustcBuiltinMacro { .. }) { + CollapseMacroDebuginfo::Yes + } else { + CollapseMacroDebuginfo::Unspecified + }; + #[rustfmt::skip] let collapse_table = [ [false, false, false, false], diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs index 6bae16b3bba15..9f9764e060d1b 100644 --- a/compiler/rustc_expand/src/errors.rs +++ b/compiler/rustc_expand/src/errors.rs @@ -78,13 +78,6 @@ pub(crate) struct ResolveRelativePath { pub path: String, } -#[derive(Diagnostic)] -#[diag(expand_collapse_debuginfo_illegal)] -pub(crate) struct CollapseMacroDebuginfoIllegal { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(expand_macro_const_stability)] pub(crate) struct MacroConstStability { diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index c791f54902d13..a5ecfa45fb408 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -568,6 +568,26 @@ impl rustc_serialize::Encodable for DocAttribute } } +/// How to perform collapse macros debug info +/// if-ext - if macro from different crate (related to callsite code) +/// | cmd \ attr | no | (unspecified) | external | yes | +/// | no | no | no | no | no | +/// | (unspecified) | no | no | if-ext | yes | +/// | external | no | if-ext | if-ext | yes | +/// | yes | yes | yes | yes | yes | +#[derive(Copy, Clone, Debug, Hash, PartialEq)] +#[derive(HashStable_Generic, Encodable, Decodable, PrintAttribute)] +pub enum CollapseMacroDebuginfo { + /// Don't collapse debuginfo for the macro + No = 0, + /// Unspecified value + Unspecified = 1, + /// Collapse debuginfo if the macro comes from a different crate + External = 2, + /// Collapse debuginfo for the macro + Yes = 3, +} + /// Represents parsed *built-in* inert attributes. /// /// ## Overview @@ -664,6 +684,9 @@ pub enum AttributeKind { /// Represents `#[cold]`. Cold(Span), + /// Represents `#[collapse_debuginfo]`. + CollapseDebugInfo(CollapseMacroDebuginfo), + /// Represents `#[rustc_confusables]`. Confusables { symbols: ThinVec, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 4e1e9a074e665..efdb4f2f22b2e 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -31,6 +31,7 @@ impl AttributeKind { CfiEncoding { .. } => Yes, Coinductive(..) => No, Cold(..) => No, + CollapseDebugInfo(..) => Yes, Confusables { .. } => Yes, ConstContinue(..) => No, ConstStability { .. } => Yes, diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index d075f94ef8502..a78b0e8e1ed81 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -8,14 +8,14 @@ use rustc_abi::Align; use rustc_data_structures::profiling::TimePassesFormat; use rustc_errors::emitter::HumanReadableErrorType; use rustc_errors::{ColorConfig, registry}; -use rustc_hir::attrs::NativeLibKind; +use rustc_hir::attrs::{CollapseMacroDebuginfo, NativeLibKind}; use rustc_session::config::{ - AnnotateMoves, AutoDiff, BranchProtection, CFGuard, Cfg, CollapseMacroDebuginfo, CoverageLevel, - CoverageOptions, DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, - Externs, FmtDebug, FunctionReturn, InliningThreshold, Input, InstrumentCoverage, - InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirIncludeSpans, - NextSolverConfig, Offload, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, - Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, + AnnotateMoves, AutoDiff, BranchProtection, CFGuard, Cfg, CoverageLevel, CoverageOptions, + DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, Externs, + FmtDebug, FunctionReturn, InliningThreshold, Input, InstrumentCoverage, InstrumentXRay, + LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirIncludeSpans, NextSolverConfig, + Offload, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, Passes, + PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, build_configuration, build_session_options, rustc_optgroups, }; diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 747895c804697..1331d99c01ead 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -967,6 +967,7 @@ parse_unknown_start_of_token = unknown start of token: {$escaped} .sugg_quotes = Unicode characters '“' (Left Double Quotation Mark) and '”' (Right Double Quotation Mark) look like '{$ascii_str}' ({$ascii_name}), but are not .sugg_other = Unicode character '{$ch}' ({$u_name}) looks like '{$ascii_str}' ({$ascii_name}), but it is not .help_null = source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used + .help_invisible_char = invisible characters like '{$escaped}' are not usually visible in text editors .note_repeats = character appears {$repeats -> [one] once more *[other] {$repeats} more times diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 3b72c9802afd3..60e4a240c85e9 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2369,6 +2369,8 @@ pub(crate) struct UnknownTokenStart { pub null: Option, #[subdiagnostic] pub repeat: Option, + #[subdiagnostic] + pub invisible: Option, } #[derive(Subdiagnostic)] @@ -2409,6 +2411,10 @@ pub(crate) struct UnknownTokenRepeat { pub repeats: usize, } +#[derive(Subdiagnostic)] +#[help(parse_help_invisible_char)] +pub(crate) struct InvisibleCharacter; + #[derive(Subdiagnostic)] #[help(parse_help_null)] pub(crate) struct UnknownTokenNull; diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 94ae35c195821..7c969dd7f9f48 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -36,6 +36,10 @@ use unescape_error_reporting::{emit_unescape_error, escaped_char}; #[cfg(target_pointer_width = "64")] rustc_data_structures::static_assert_size!(rustc_lexer::Token, 12); +const INVISIBLE_CHARACTERS: [char; 8] = [ + '\u{200b}', '\u{200c}', '\u{2060}', '\u{2061}', '\u{2062}', '\u{00ad}', '\u{034f}', '\u{061c}', +]; + #[derive(Clone, Debug)] pub(crate) struct UnmatchedDelim { pub found_delim: Option, @@ -456,6 +460,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { escaped: escaped_char(c), sugg, null: if c == '\x00' { Some(errors::UnknownTokenNull) } else { None }, + invisible: if INVISIBLE_CHARACTERS.contains(&c) { Some(errors::InvisibleCharacter) } else { None }, repeat: if repeats > 0 { swallow_next_invalid = repeats; Some(errors::UnknownTokenRepeat { repeats }) diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index ba44aa3a35ab8..39ad541ee85a9 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -55,10 +55,6 @@ passes_change_fields_to_be_of_unit_type = *[other] fields } -passes_collapse_debuginfo = - `collapse_debuginfo` attribute should be applied to macro definitions - .label = not a macro definition - passes_const_continue_attr = `#[const_continue]` should be applied to a break expression .label = not a break expression diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 360feacac0e96..717a0e54d0c6e 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -229,6 +229,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::BodyStability { .. } | AttributeKind::ConstStabilityIndirect | AttributeKind::MacroTransparency(_) + | AttributeKind::CollapseDebugInfo(..) | AttributeKind::CfgTrace(..) | AttributeKind::Pointee(..) | AttributeKind::Dummy @@ -324,7 +325,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | [sym::rustc_dirty, ..] | [sym::rustc_if_this_changed, ..] | [sym::rustc_then_this_would_need, ..] => self.check_rustc_dirty_clean(attr), - [sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target), [sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target), [sym::autodiff_forward, ..] | [sym::autodiff_reverse, ..] => { self.check_autodiff(hir_id, attr, span, target) @@ -336,8 +336,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::warn | sym::deny | sym::forbid - | sym::cfg - | sym::cfg_attr // need to be fixed | sym::patchable_function_entry // FIXME(patchable_function_entry) | sym::deprecated_safe // FIXME(deprecated_safe) @@ -346,7 +344,54 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::panic_handler | sym::lang | sym::needs_allocator - | sym::default_lib_allocator, + | sym::default_lib_allocator + | sym::rustc_diagnostic_item + | sym::rustc_no_mir_inline + | sym::rustc_insignificant_dtor + | sym::rustc_nonnull_optimization_guaranteed + | sym::rustc_intrinsic + | sym::rustc_inherit_overflow_checks + | sym::rustc_intrinsic_const_stable_indirect + | sym::rustc_trivial_field_reads + | sym::rustc_on_unimplemented + | sym::rustc_do_not_const_check + | sym::rustc_reservation_impl + | sym::rustc_doc_primitive + | sym::rustc_allocator + | sym::rustc_deallocator + | sym::rustc_reallocator + | sym::rustc_conversion_suggestion + | sym::rustc_allocator_zeroed + | sym::rustc_allocator_zeroed_variant + | sym::rustc_deprecated_safe_2024 + | sym::rustc_test_marker + | sym::rustc_abi + | sym::rustc_layout + | sym::rustc_proc_macro_decls + | sym::rustc_dump_def_parents + | sym::rustc_never_type_options + | sym::rustc_autodiff + | sym::rustc_capture_analysis + | sym::rustc_regions + | sym::rustc_strict_coherence + | sym::rustc_dump_predicates + | sym::rustc_variance + | sym::rustc_variance_of_opaques + | sym::rustc_hidden_type_of_opaques + | sym::rustc_mir + | sym::rustc_dump_user_args + | sym::rustc_effective_visibility + | sym::rustc_outlives + | sym::rustc_symbol_name + | sym::rustc_evaluate_where_clauses + | sym::rustc_dump_vtable + | sym::rustc_delayed_bug_from_inside_query + | sym::rustc_dump_item_bounds + | sym::rustc_def_path + | sym::rustc_partition_reused + | sym::rustc_partition_codegened + | sym::rustc_expected_cgu_reuse + | sym::rustc_nounwind, .. ] => {} [name, rest@..] => { @@ -361,15 +406,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> { continue } - // FIXME: differentiate between unstable and internal attributes just - // like we do with features instead of just accepting `rustc_` - // attributes by name. That should allow trimming the above list, too. - if !name.as_str().starts_with("rustc_") { - span_bug!( - attr.span(), - "builtin attribute {name:?} not handled by `CheckAttrVisitor`" - ) - } + span_bug!( + attr.span(), + "builtin attribute {name:?} not handled by `CheckAttrVisitor`" + ) } None => (), } @@ -716,18 +756,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } } - /// Checks if `#[collapse_debuginfo]` is applied to a macro. - fn check_collapse_debuginfo(&self, attr: &Attribute, span: Span, target: Target) { - match target { - Target::MacroDef => {} - _ => { - self.tcx.dcx().emit_err(errors::CollapseDebuginfo { - attr_span: attr.span(), - defn_span: span, - }); - } - } - } /// Checks if a `#[track_caller]` is applied to a function. fn check_track_caller( diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 14555765e4234..ace738c559a42 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -375,15 +375,6 @@ pub(crate) struct UnusedMultiple { pub name: Symbol, } -#[derive(Diagnostic)] -#[diag(passes_collapse_debuginfo)] -pub(crate) struct CollapseDebuginfo { - #[primary_span] - pub attr_span: Span, - #[label] - pub defn_span: Span, -} - #[derive(LintDiagnostic)] #[diag(passes_deprecated_annotation_has_no_effect)] pub(crate) struct DeprecatedAnnotationHasNoEffect { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 8c492fcf8f15d..f0dc5b9ac48c5 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -3065,6 +3065,7 @@ pub(crate) mod dep_tracking { use rustc_errors::LanguageIdentifier; use rustc_feature::UnstableFeatures; use rustc_hashes::Hash64; + use rustc_hir::attrs::CollapseMacroDebuginfo; use rustc_span::edition::Edition; use rustc_span::{RealFileName, RemapPathScopeComponents}; use rustc_target::spec::{ @@ -3074,13 +3075,12 @@ pub(crate) mod dep_tracking { }; use super::{ - AnnotateMoves, AutoDiff, BranchProtection, CFGuard, CFProtection, CollapseMacroDebuginfo, - CoverageOptions, CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, - FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, - LocationDetail, LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OptLevel, - OutFileName, OutputType, OutputTypes, PatchableFunctionEntry, Polonius, ResolveDocLinks, - SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, - WasiExecModel, + AnnotateMoves, AutoDiff, BranchProtection, CFGuard, CFProtection, CoverageOptions, + CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, FunctionReturn, + InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail, + LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OptLevel, OutFileName, OutputType, + OutputTypes, PatchableFunctionEntry, Polonius, ResolveDocLinks, SourceFileHashAlgorithm, + SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, }; use crate::lint; use crate::utils::NativeLib; @@ -3299,25 +3299,6 @@ pub enum ProcMacroExecutionStrategy { CrossThread, } -/// How to perform collapse macros debug info -/// if-ext - if macro from different crate (related to callsite code) -/// | cmd \ attr | no | (unspecified) | external | yes | -/// | no | no | no | no | no | -/// | (unspecified) | no | no | if-ext | yes | -/// | external | no | if-ext | if-ext | yes | -/// | yes | yes | yes | yes | yes | -#[derive(Clone, Copy, PartialEq, Hash, Debug)] -pub enum CollapseMacroDebuginfo { - /// Don't collapse debuginfo for the macro - No = 0, - /// Unspecified value - Unspecified = 1, - /// Collapse debuginfo if the macro comes from a different crate - External = 2, - /// Collapse debuginfo for the macro - Yes = 3, -} - /// Which format to use for `-Z dump-mono-stats` #[derive(Clone, Copy, PartialEq, Hash, Debug)] pub enum DumpMonoStatsFormat { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 21fa3321a30ad..99ab134038124 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -10,6 +10,7 @@ use rustc_data_structures::stable_hasher::StableHasher; use rustc_errors::{ColorConfig, LanguageIdentifier, TerminalUrl}; use rustc_feature::UnstableFeatures; use rustc_hashes::Hash64; +use rustc_hir::attrs::CollapseMacroDebuginfo; use rustc_macros::{BlobDecodable, Encodable}; use rustc_span::edition::Edition; use rustc_span::{RealFileName, RemapPathScopeComponents, SourceFileHashAlgorithm}; diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 8113e1824f27d..a2d3fa401b625 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -9,6 +9,7 @@ use crate::clone::TrivialClone; use crate::cmp::Ordering::{self, Equal, Greater, Less}; use crate::intrinsics::{exact_div, unchecked_sub}; +use crate::marker::Destruct; use crate::mem::{self, MaybeUninit, SizedTypeProperties}; use crate::num::NonZero; use crate::ops::{OneSidedRange, OneSidedRangeBound, Range, RangeBounds, RangeInclusive}; @@ -4036,9 +4037,10 @@ impl [T] { /// [`split_at_mut`]: slice::split_at_mut #[stable(feature = "clone_from_slice", since = "1.7.0")] #[track_caller] - pub fn clone_from_slice(&mut self, src: &[T]) + #[rustc_const_unstable(feature = "const_clone", issue = "142757")] + pub const fn clone_from_slice(&mut self, src: &[T]) where - T: Clone, + T: [const] Clone + [const] Destruct, { self.spec_clone_from(src); } @@ -5367,13 +5369,17 @@ const unsafe fn copy_from_slice_impl(dest: &mut [T], src: &[T]) { } } -trait CloneFromSpec { - fn spec_clone_from(&mut self, src: &[T]); +#[rustc_const_unstable(feature = "const_clone", issue = "142757")] +const trait CloneFromSpec { + fn spec_clone_from(&mut self, src: &[T]) + where + T: [const] Destruct; } -impl CloneFromSpec for [T] +#[rustc_const_unstable(feature = "const_clone", issue = "142757")] +impl const CloneFromSpec for [T] where - T: Clone, + T: [const] Clone + [const] Destruct, { #[track_caller] default fn spec_clone_from(&mut self, src: &[T]) { @@ -5383,15 +5389,19 @@ where // But since it can't be relied on we also have an explicit specialization for T: Copy. let len = self.len(); let src = &src[..len]; - for i in 0..len { - self[i].clone_from(&src[i]); + // FIXME(const_hack): make this a `for idx in 0..self.len()` loop. + let mut idx = 0; + while idx < self.len() { + self[idx].clone_from(&src[idx]); + idx += 1; } } } -impl CloneFromSpec for [T] +#[rustc_const_unstable(feature = "const_clone", issue = "142757")] +impl const CloneFromSpec for [T] where - T: TrivialClone, + T: [const] TrivialClone + [const] Destruct, { #[track_caller] fn spec_clone_from(&mut self, src: &[T]) { diff --git a/library/coretests/tests/clone.rs b/library/coretests/tests/clone.rs index 054b1d3d4986c..68871dbccf07b 100644 --- a/library/coretests/tests/clone.rs +++ b/library/coretests/tests/clone.rs @@ -121,3 +121,74 @@ fn cstr_metadata_is_length_with_nul() { let bytes: *const [u8] = p as *const [u8]; assert_eq!(s.to_bytes_with_nul().len(), bytes.len()); } + +#[test] +fn test_const_clone() { + const { + let bool: bool = Default::default(); + let char: char = Default::default(); + let ascii_char: std::ascii::Char = Default::default(); + let usize: usize = Default::default(); + let u8: u8 = Default::default(); + let u16: u16 = Default::default(); + let u32: u32 = Default::default(); + let u64: u64 = Default::default(); + let u128: u128 = Default::default(); + let i8: i8 = Default::default(); + let i16: i16 = Default::default(); + let i32: i32 = Default::default(); + let i64: i64 = Default::default(); + let i128: i128 = Default::default(); + let f16: f16 = Default::default(); + let f32: f32 = Default::default(); + let f64: f64 = Default::default(); + let f128: f128 = Default::default(); + + let bool_clone: bool = bool.clone(); + let char_clone: char = char.clone(); + let ascii_char_clone: std::ascii::Char = ascii_char.clone(); + + let usize_clone: usize = usize.clone(); + let u8_clone: u8 = u8.clone(); + let u16_clone: u16 = u16.clone(); + let u32_clone: u32 = u32.clone(); + let u64_clone: u64 = u64.clone(); + let u128_clone: u128 = u128.clone(); + let i8_clone: i8 = i8.clone(); + let i16_clone: i16 = i16.clone(); + let i32_clone: i32 = i32.clone(); + let i64_clone: i64 = i64.clone(); + let i128_clone: i128 = i128.clone(); + let f16_clone: f16 = f16.clone(); + let f32_clone: f32 = f32.clone(); + let f64_clone: f64 = f64.clone(); + let f128_clone: f128 = f128.clone(); + + assert!(bool == bool_clone); + assert!(char == char_clone); + assert!(ascii_char == ascii_char_clone); + assert!(usize == usize_clone); + assert!(u8 == u8_clone); + assert!(u16 == u16_clone); + assert!(u32 == u32_clone); + assert!(u64 == u64_clone); + assert!(u128 == u128_clone); + assert!(i8 == i8_clone); + assert!(i16 == i16_clone); + assert!(i32 == i32_clone); + assert!(i64 == i64_clone); + assert!(i128 == i128_clone); + assert!(f16 == f16_clone); + assert!(f32 == f32_clone); + assert!(f64 == f64_clone); + assert!(f128 == f128_clone); + + let src: [i32; 4] = [1, 2, 3, 4]; + let mut dst: [i32; 2] = [0, 0]; + + dst.clone_from_slice(&src[2..]); + + assert!(src == [1, 2, 3, 4]); + assert!(dst == [3, 4]); + } +} diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 6a8b6d9ba154f..ff4fc4c892afe 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -19,11 +19,14 @@ #![feature(clone_to_uninit)] #![feature(const_array)] #![feature(const_cell_traits)] +#![feature(const_clone)] #![feature(const_cmp)] #![feature(const_convert)] +#![feature(const_default)] #![feature(const_destruct)] #![feature(const_drop_in_place)] #![feature(const_eval_select)] +#![feature(const_index)] #![feature(const_ops)] #![feature(const_option_ops)] #![feature(const_ref_cell)] diff --git a/library/std/src/os/windows/fs.rs b/library/std/src/os/windows/fs.rs index c544bf485a252..73f3e589e2432 100644 --- a/library/std/src/os/windows/fs.rs +++ b/library/std/src/os/windows/fs.rs @@ -305,6 +305,18 @@ pub trait OpenOptionsExt { /// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-security_impersonation_level #[stable(feature = "open_options_ext", since = "1.10.0")] fn security_qos_flags(&mut self, flags: u32) -> &mut Self; + + /// If set to `true`, prevent the "last access time" of the file from being changed. + /// + /// Default to `false`. + #[unstable(feature = "windows_freeze_file_times", issue = "149715")] + fn freeze_last_access_time(&mut self, freeze: bool) -> &mut Self; + + /// If set to `true`, prevent the "last write time" of the file from being changed. + /// + /// Default to `false`. + #[unstable(feature = "windows_freeze_file_times", issue = "149715")] + fn freeze_last_write_time(&mut self, freeze: bool) -> &mut Self; } #[stable(feature = "open_options_ext", since = "1.10.0")] @@ -333,6 +345,16 @@ impl OpenOptionsExt for OpenOptions { self.as_inner_mut().security_qos_flags(flags); self } + + fn freeze_last_access_time(&mut self, freeze: bool) -> &mut Self { + self.as_inner_mut().freeze_last_access_time(freeze); + self + } + + fn freeze_last_write_time(&mut self, freeze: bool) -> &mut Self { + self.as_inner_mut().freeze_last_write_time(freeze); + self + } } /// Windows-specific extensions to [`fs::Metadata`]. diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index 8061068e447a5..a1bb0c6e828bd 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -6,7 +6,7 @@ use crate::fs::TryLockError; use crate::hash::Hash; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::path::{Path, PathBuf}; -pub use crate::sys::fs::common::{Dir, remove_dir_all}; +pub use crate::sys::fs::common::{Dir, copy, remove_dir_all}; use crate::sys::pal::{helpers, unsupported}; use crate::sys::time::SystemTime; @@ -541,10 +541,6 @@ pub fn canonicalize(p: &Path) -> io::Result { crate::path::absolute(p) } -pub fn copy(_from: &Path, _to: &Path) -> io::Result { - unsupported() -} - fn set_perm_inner(f: &uefi_fs::File, perm: FilePermissions) -> io::Result<()> { let mut file_info = f.file_info()?; diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs index 2e3d50aa0e087..fc8aec2f3f7c4 100644 --- a/library/std/src/sys/fs/windows.rs +++ b/library/std/src/sys/fs/windows.rs @@ -82,6 +82,8 @@ pub struct OpenOptions { share_mode: u32, security_qos_flags: u32, inherit_handle: bool, + freeze_last_access_time: bool, + freeze_last_write_time: bool, } #[derive(Clone, PartialEq, Eq, Debug)] @@ -205,6 +207,8 @@ impl OpenOptions { attributes: 0, security_qos_flags: 0, inherit_handle: false, + freeze_last_access_time: false, + freeze_last_write_time: false, } } @@ -247,6 +251,12 @@ impl OpenOptions { pub fn inherit_handle(&mut self, inherit: bool) { self.inherit_handle = inherit; } + pub fn freeze_last_access_time(&mut self, freeze: bool) { + self.freeze_last_access_time = freeze; + } + pub fn freeze_last_write_time(&mut self, freeze: bool) { + self.freeze_last_write_time = freeze; + } fn get_access_mode(&self) -> io::Result { match (self.read, self.write, self.append, self.access_mode) { @@ -352,6 +362,18 @@ impl File { }; let handle = unsafe { HandleOrInvalid::from_raw_handle(handle) }; if let Ok(handle) = OwnedHandle::try_from(handle) { + if opts.freeze_last_access_time || opts.freeze_last_write_time { + let file_time = + c::FILETIME { dwLowDateTime: 0xFFFFFFFF, dwHighDateTime: 0xFFFFFFFF }; + cvt(unsafe { + c::SetFileTime( + handle.as_raw_handle(), + core::ptr::null(), + if opts.freeze_last_access_time { &file_time } else { core::ptr::null() }, + if opts.freeze_last_write_time { &file_time } else { core::ptr::null() }, + ) + })?; + } // Manual truncation. See #115745. if opts.truncate && creation == c::OPEN_ALWAYS diff --git a/src/doc/rustc/src/platform-support/m68k-unknown-none-elf.md b/src/doc/rustc/src/platform-support/m68k-unknown-none-elf.md index e390ba0aee96b..0a9bdc7e1c984 100644 --- a/src/doc/rustc/src/platform-support/m68k-unknown-none-elf.md +++ b/src/doc/rustc/src/platform-support/m68k-unknown-none-elf.md @@ -12,6 +12,7 @@ Bare metal Motorola 680x0 This target requires an m68k build environment for cross-compilation which is available on Debian, Debian-based systems, openSUSE, and other distributions. +The gnu linker is currently required, as `lld` has no support for the `m68k` architecture On Debian-based systems, it should be sufficient to install a g++ cross-compiler for the m68k architecture which will automatically pull in additional dependencies such as @@ -29,43 +30,9 @@ binaries: # apt install qemu-user-static ``` -To run more complex programs, it will be necessary to set up a Debian/m68k chroot with -the help of the command `debootstrap`: - -```text -# apt install debootstrap debian-ports-archive-keyring -# debootstrap --keyring=/usr/share/keyrings/debian-ports-archive-keyring.gpg --arch=m68k unstable debian-68k http://ftp.ports.debian.org/debian-ports -``` - -This chroot can then seamlessly entered using the normal `chroot` command thanks to -QEMU user emulation: - -```text -# chroot /path/to/debian-68k -``` - -To get started with native builds, which are currently untested, a native Debian/m68k -system can be installed either on real hardware such as 68k-based Commodore Amiga or -Atari systems or emulated environments such as QEMU version 4.2 or newer or ARAnyM. - -ISO images for installation are provided by the Debian Ports team and can be obtained -from the Debian CD image server available at: - -[https://cdimage.debian.org/cdimage/ports/current](https://cdimage.debian.org/cdimage/ports/current/) - -Documentation for Debian/m68k is available on the Debian Wiki at: - -[https://wiki.debian.org/M68k](https://wiki.debian.org/M68k) - -Support is available either through the `debian-68k` mailing list: - -[https://lists.debian.org/debian-68k/](https://lists.debian.org/debian-68k/) - -or the `#debian-68k` IRC channel on OFTC network. - ## Building -At least llvm version `19.1.5` is required to build `core` and `alloc` for this target, and currently the gnu linker is required, as `lld` has no support for the `m68k` architecture +At least llvm version `19.1.5` is required to build `core` and `alloc` for this target. ## Cross-compilation @@ -105,4 +72,4 @@ Very simple programs can be run using the `qemu-m68k-static` program: qemu-m68k-static your-code ``` -For more complex applications, a chroot or native m68k system is required for testing. +For more complex applications, a native (or emulated) m68k system is required for testing. diff --git a/tests/ui/attributes/collapse-debuginfo-invalid.rs b/tests/ui/attributes/collapse-debuginfo-invalid.rs index ccf11df2eb0d7..e467c72f52c0e 100644 --- a/tests/ui/attributes/collapse-debuginfo-invalid.rs +++ b/tests/ui/attributes/collapse-debuginfo-invalid.rs @@ -5,80 +5,80 @@ // Test that the `#[collapse_debuginfo]` attribute can only be used on macro definitions. #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on extern crate std; #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on use std::collections::HashMap; #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on static FOO: u32 = 3; #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on const BAR: u32 = 3; #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on fn foo() { let _ = #[collapse_debuginfo(yes)] || { }; - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on #[collapse_debuginfo(yes)] - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on let _ = 3; let _ = #[collapse_debuginfo(yes)] 3; - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on match (3, 4) { #[collapse_debuginfo(yes)] - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on _ => (), } } #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on mod bar { } #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on type Map = HashMap; #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on enum Foo { #[collapse_debuginfo(yes)] - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on Variant, } #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on struct Bar { #[collapse_debuginfo(yes)] - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on field: u32, } #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on union Qux { a: u32, b: u16 } #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on trait Foobar { #[collapse_debuginfo(yes)] - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on type Bar; } #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on type AFoobar = impl Foobar; impl Foobar for Bar { @@ -91,14 +91,14 @@ fn constraining() -> AFoobar { } #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on impl Bar { #[collapse_debuginfo(yes)] - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on const FOO: u32 = 3; #[collapse_debuginfo(yes)] - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on fn bar(&self) {} } diff --git a/tests/ui/attributes/collapse-debuginfo-invalid.stderr b/tests/ui/attributes/collapse-debuginfo-invalid.stderr index 081e4445a8695..d66e334c993ca 100644 --- a/tests/ui/attributes/collapse-debuginfo-invalid.stderr +++ b/tests/ui/attributes/collapse-debuginfo-invalid.stderr @@ -1,221 +1,178 @@ -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on extern crates --> $DIR/collapse-debuginfo-invalid.rs:7:1 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | extern crate std; - | ----------------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on use statements --> $DIR/collapse-debuginfo-invalid.rs:11:1 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | use std::collections::HashMap; - | ------------------------------ not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on statics --> $DIR/collapse-debuginfo-invalid.rs:15:1 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | static FOO: u32 = 3; - | -------------------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on constants --> $DIR/collapse-debuginfo-invalid.rs:19:1 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | const BAR: u32 = 3; - | ------------------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on functions --> $DIR/collapse-debuginfo-invalid.rs:23:1 | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / fn foo() { -LL | | let _ = #[collapse_debuginfo(yes)] || { }; -LL | | -LL | | #[collapse_debuginfo(yes)] -... | -LL | | } - | |_- not a macro definition - -error: `collapse_debuginfo` attribute should be applied to macro definitions +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs + +error: `#[collapse_debuginfo]` attribute cannot be used on closures --> $DIR/collapse-debuginfo-invalid.rs:26:13 | LL | let _ = #[collapse_debuginfo(yes)] || { }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ------ not a macro definition + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on statements --> $DIR/collapse-debuginfo-invalid.rs:28:5 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | let _ = 3; - | ---------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on expressions --> $DIR/collapse-debuginfo-invalid.rs:31:13 | LL | let _ = #[collapse_debuginfo(yes)] 3; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - not a macro definition + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on match arms --> $DIR/collapse-debuginfo-invalid.rs:34:9 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | _ => (), - | ------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on modules --> $DIR/collapse-debuginfo-invalid.rs:40:1 | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / mod bar { -LL | | } - | |_- not a macro definition +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on type aliases --> $DIR/collapse-debuginfo-invalid.rs:45:1 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | type Map = HashMap; - | ----------------------------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on enums --> $DIR/collapse-debuginfo-invalid.rs:49:1 | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / enum Foo { -LL | | #[collapse_debuginfo(yes)] -LL | | -LL | | Variant, -LL | | } - | |_- not a macro definition - -error: `collapse_debuginfo` attribute should be applied to macro definitions +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs + +error: `#[collapse_debuginfo]` attribute cannot be used on enum variants --> $DIR/collapse-debuginfo-invalid.rs:52:5 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | Variant, - | ------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on structs --> $DIR/collapse-debuginfo-invalid.rs:57:1 | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / struct Bar { -LL | | #[collapse_debuginfo(yes)] -LL | | -LL | | field: u32, -LL | | } - | |_- not a macro definition - -error: `collapse_debuginfo` attribute should be applied to macro definitions +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs + +error: `#[collapse_debuginfo]` attribute cannot be used on struct fields --> $DIR/collapse-debuginfo-invalid.rs:60:5 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | field: u32, - | ---------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on unions --> $DIR/collapse-debuginfo-invalid.rs:65:1 | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / union Qux { -LL | | a: u32, -LL | | b: u16 -LL | | } - | |_- not a macro definition +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on traits --> $DIR/collapse-debuginfo-invalid.rs:72:1 | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / trait Foobar { -LL | | #[collapse_debuginfo(yes)] -LL | | -LL | | type Bar; -LL | | } - | |_- not a macro definition - -error: `collapse_debuginfo` attribute should be applied to macro definitions +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs + +error: `#[collapse_debuginfo]` attribute cannot be used on associated types + --> $DIR/collapse-debuginfo-invalid.rs:75:5 + | +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs + +error: `#[collapse_debuginfo]` attribute cannot be used on type aliases --> $DIR/collapse-debuginfo-invalid.rs:80:1 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | type AFoobar = impl Foobar; - | --------------------------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on inherent impl blocks --> $DIR/collapse-debuginfo-invalid.rs:93:1 | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / impl Bar { -LL | | #[collapse_debuginfo(yes)] -LL | | -LL | | const FOO: u32 = 3; -... | -LL | | fn bar(&self) {} -LL | | } - | |_- not a macro definition - -error: `collapse_debuginfo` attribute should be applied to macro definitions - --> $DIR/collapse-debuginfo-invalid.rs:75:5 +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | type Bar; - | --------- not a macro definition + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on associated consts --> $DIR/collapse-debuginfo-invalid.rs:96:5 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | const FOO: u32 = 3; - | ------------------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on inherent methods --> $DIR/collapse-debuginfo-invalid.rs:100:5 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | fn bar(&self) {} - | ---------------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs error: aborting due to 22 previous errors diff --git a/tests/ui/const-generics/associated-const-bindings/normalization-via-param-env.rs b/tests/ui/const-generics/associated-const-bindings/normalization-via-param-env.rs new file mode 100644 index 0000000000000..c7bb5bccedb3a --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/normalization-via-param-env.rs @@ -0,0 +1,18 @@ +//@ check-pass +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] + +// Regression test for normalizing const projections +// with associated const equality bounds. + +trait Trait { + #[type_const] + const C: usize; +} + +fn f>() { + // This must normalize ::C to 1 + let _: [(); T::C] = [()]; +} + +fn main() {} diff --git a/tests/ui/lexer/lex-invisible-characters.rs b/tests/ui/lexer/lex-invisible-characters.rs new file mode 100644 index 0000000000000..2db72b8475dc5 --- /dev/null +++ b/tests/ui/lexer/lex-invisible-characters.rs @@ -0,0 +1,6 @@ +// Provide extra help when a user has an invisible character in their code + +fn main​() { + //~^ ERROR unknown start of token: \u{200b} + //~| HELP invisible characters like '\u{200b}' are not usually visible in text editors +} diff --git a/tests/ui/lexer/lex-invisible-characters.stderr b/tests/ui/lexer/lex-invisible-characters.stderr new file mode 100644 index 0000000000000..ddac0f4e9325c --- /dev/null +++ b/tests/ui/lexer/lex-invisible-characters.stderr @@ -0,0 +1,10 @@ +error: unknown start of token: \u{200b} + --> $DIR/lex-invisible-characters.rs:3:8 + | +LL | fn main​() { + | ^ + | + = help: invisible characters like '\u{200b}' are not usually visible in text editors + +error: aborting due to 1 previous error +