| author | bors <bors@rust-lang.org> 2026-03-20 07:22:03 UTC |
| committer | bors <bors@rust-lang.org> 2026-03-20 07:22:03 UTC |
| log | 86c839ffb36d0e21405dee5ab38e3f85c5b63699 |
| tree | bfa3f1d205177439941f7e0ac8227e2432eac1fe |
| parent | 76be1cc4eef94daeab731ed9395a317b34d89d63 |
| parent | ffe94f0bcbe7f974e0970965fedec2e4a806324d |
Rollup of 15 pull requests
Successful merges:
- rust-lang/rust#152909 (sess: `-Zbranch-protection` is a target modifier)
- rust-lang/rust#153556 (`impl` restriction lowering)
- rust-lang/rust#154048 (Don't emit rustdoc `missing_doc_code_examples` lint on impl items)
- rust-lang/rust#150935 (Introduce #[diagnostic::on_move(message)])
- rust-lang/rust#152973 (remove -Csoft-float)
- rust-lang/rust#153862 (Rename `cycle_check` to `find_cycle`)
- rust-lang/rust#153992 (bootstrap: Optionally print a backtrace if a command fails)
- rust-lang/rust#154019 (two smaller feature cleanups)
- rust-lang/rust#154059 (tests: Activate `must_not_suspend` test for `MutexGuard` dropped before `await`)
- rust-lang/rust#154075 (Rewrite `query_ensure_result`.)
- rust-lang/rust#154082 (Updates derive_where and removes workaround)
- rust-lang/rust#154084 (Preserve braces around `self` in use tree pretty printing)
- rust-lang/rust#154086 (Insert space after float literal ending with `.` in pretty printer)
- rust-lang/rust#154087 (Fix whitespace after fragment specifiers in macro pretty printing)
- rust-lang/rust#154109 (tests: Add regression test for async closures involving HRTBs)77 files changed, 1564 insertions(+), 170 deletions(-)
Cargo.lock+2-2| ... | ... | @@ -1140,9 +1140,9 @@ version = "0.1.96" |
| 1140 | 1140 | |
| 1141 | 1141 | [[package]] |
| 1142 | 1142 | name = "derive-where" |
| 1143 | version = "1.6.0" | |
| 1143 | version = "1.6.1" | |
| 1144 | 1144 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1145 | checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f" | |
| 1145 | checksum = "d08b3a0bcc0d079199cd476b2cae8435016ec11d1c0986c6901c5ac223041534" | |
| 1146 | 1146 | dependencies = [ |
| 1147 | 1147 | "proc-macro2", |
| 1148 | 1148 | "quote", |
compiler/rustc_ast_pretty/src/pprust/state.rs+20| ... | ... | @@ -329,6 +329,19 @@ fn print_crate_inner<'a>( |
| 329 | 329 | /// - #63896: `#[allow(unused,` must be printed rather than `#[allow(unused ,` |
| 330 | 330 | /// - #73345: `#[allow(unused)]` must be printed rather than `# [allow(unused)]` |
| 331 | 331 | /// |
| 332 | /// Returns `true` if both token trees are identifier-like tokens that would | |
| 333 | /// merge into a single token if printed without a space between them. | |
| 334 | /// E.g. `ident` + `where` would merge into `identwhere`. | |
| 335 | fn idents_would_merge(tt1: &TokenTree, tt2: &TokenTree) -> bool { | |
| 336 | fn is_ident_like(tt: &TokenTree) -> bool { | |
| 337 | matches!( | |
| 338 | tt, | |
| 339 | TokenTree::Token(Token { kind: token::Ident(..) | token::NtIdent(..), .. }, _,) | |
| 340 | ) | |
| 341 | } | |
| 342 | is_ident_like(tt1) && is_ident_like(tt2) | |
| 343 | } | |
| 344 | ||
| 332 | 345 | fn space_between(tt1: &TokenTree, tt2: &TokenTree) -> bool { |
| 333 | 346 | use Delimiter::*; |
| 334 | 347 | use TokenTree::{Delimited as Del, Token as Tok}; |
| ... | ... | @@ -811,6 +824,13 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere |
| 811 | 824 | if let Some(next) = iter.peek() { |
| 812 | 825 | if spacing == Spacing::Alone && space_between(tt, next) { |
| 813 | 826 | self.space(); |
| 827 | } else if spacing != Spacing::Alone && idents_would_merge(tt, next) { | |
| 828 | // When tokens from macro `tt` captures preserve their | |
| 829 | // original `Joint`/`JointHidden` spacing, adjacent | |
| 830 | // identifier-like tokens can be concatenated without a | |
| 831 | // space (e.g. `$x:identwhere`). Insert a space to | |
| 832 | // prevent this. | |
| 833 | self.space(); | |
| 814 | 834 | } |
| 815 | 835 | } |
| 816 | 836 | } |
compiler/rustc_ast_pretty/src/pprust/state/expr.rs+37-11| ... | ... | @@ -260,12 +260,15 @@ impl<'a> State<'a> { |
| 260 | 260 | // |
| 261 | 261 | // loop { break x; }.method(); |
| 262 | 262 | // |
| 263 | self.print_expr_cond_paren( | |
| 264 | receiver, | |
| 265 | receiver.precedence() < ExprPrecedence::Unambiguous, | |
| 266 | fixup.leftmost_subexpression_with_dot(), | |
| 267 | ); | |
| 263 | let needs_paren = receiver.precedence() < ExprPrecedence::Unambiguous; | |
| 264 | self.print_expr_cond_paren(receiver, needs_paren, fixup.leftmost_subexpression_with_dot()); | |
| 268 | 265 | |
| 266 | // If the receiver is an unsuffixed float literal like `0.`, insert | |
| 267 | // a space so the `.` of the method call doesn't merge with the | |
| 268 | // trailing dot: `0. .method()` instead of `0..method()`. | |
| 269 | if !needs_paren && expr_ends_with_dot(receiver) { | |
| 270 | self.word(" "); | |
| 271 | } | |
| 269 | 272 | self.word("."); |
| 270 | 273 | self.print_ident(segment.ident); |
| 271 | 274 | if let Some(args) = &segment.args { |
| ... | ... | @@ -658,11 +661,15 @@ impl<'a> State<'a> { |
| 658 | 661 | ); |
| 659 | 662 | } |
| 660 | 663 | ast::ExprKind::Field(expr, ident) => { |
| 664 | let needs_paren = expr.precedence() < ExprPrecedence::Unambiguous; | |
| 661 | 665 | self.print_expr_cond_paren( |
| 662 | 666 | expr, |
| 663 | expr.precedence() < ExprPrecedence::Unambiguous, | |
| 667 | needs_paren, | |
| 664 | 668 | fixup.leftmost_subexpression_with_dot(), |
| 665 | 669 | ); |
| 670 | if !needs_paren && expr_ends_with_dot(expr) { | |
| 671 | self.word(" "); | |
| 672 | } | |
| 666 | 673 | self.word("."); |
| 667 | 674 | self.print_ident(*ident); |
| 668 | 675 | } |
| ... | ... | @@ -685,11 +692,15 @@ impl<'a> State<'a> { |
| 685 | 692 | let fake_prec = ExprPrecedence::LOr; |
| 686 | 693 | if let Some(e) = start { |
| 687 | 694 | let start_fixup = fixup.leftmost_subexpression_with_operator(true); |
| 688 | self.print_expr_cond_paren( | |
| 689 | e, | |
| 690 | start_fixup.precedence(e) < fake_prec, | |
| 691 | start_fixup, | |
| 692 | ); | |
| 695 | let needs_paren = start_fixup.precedence(e) < fake_prec; | |
| 696 | self.print_expr_cond_paren(e, needs_paren, start_fixup); | |
| 697 | // If the start expression is a float literal ending with | |
| 698 | // `.`, we need a space before `..` or `..=` so that the | |
| 699 | // dots don't merge. E.g. `0. ..45.` must not become | |
| 700 | // `0...45.`. | |
| 701 | if !needs_paren && expr_ends_with_dot(e) { | |
| 702 | self.word(" "); | |
| 703 | } | |
| 693 | 704 | } |
| 694 | 705 | match limits { |
| 695 | 706 | ast::RangeLimits::HalfOpen => self.word(".."), |
| ... | ... | @@ -1025,3 +1036,18 @@ fn reconstruct_format_args_template_string(pieces: &[FormatArgsPiece]) -> String |
| 1025 | 1036 | template.push('"'); |
| 1026 | 1037 | template |
| 1027 | 1038 | } |
| 1039 | ||
| 1040 | /// Returns `true` if the printed representation of this expression ends with | |
| 1041 | /// a `.` character — specifically, an unsuffixed float literal like `0.` or | |
| 1042 | /// `45.`. This is used to insert whitespace before range operators (`..`, | |
| 1043 | /// `..=`) so that the dots don't merge (e.g. `0. ..45.` instead of `0...45.`). | |
| 1044 | fn expr_ends_with_dot(expr: &ast::Expr) -> bool { | |
| 1045 | match &expr.kind { | |
| 1046 | ast::ExprKind::Lit(token_lit) => { | |
| 1047 | token_lit.kind == token::Float | |
| 1048 | && token_lit.suffix.is_none() | |
| 1049 | && token_lit.symbol.as_str().ends_with('.') | |
| 1050 | } | |
| 1051 | _ => false, | |
| 1052 | } | |
| 1053 | } |
compiler/rustc_ast_pretty/src/pprust/state/item.rs+7-1| ... | ... | @@ -881,7 +881,13 @@ impl<'a> State<'a> { |
| 881 | 881 | } |
| 882 | 882 | if items.is_empty() { |
| 883 | 883 | self.word("{}"); |
| 884 | } else if let [(item, _)] = items.as_slice() { | |
| 884 | } else if let [(item, _)] = items.as_slice() | |
| 885 | && !item | |
| 886 | .prefix | |
| 887 | .segments | |
| 888 | .first() | |
| 889 | .is_some_and(|seg| seg.ident.name == rustc_span::symbol::kw::SelfLower) | |
| 890 | { | |
| 885 | 891 | self.print_use_tree(item); |
| 886 | 892 | } else { |
| 887 | 893 | let cb = self.cbox(INDENT_UNIT); |
compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs+11-1| ... | ... | @@ -22,6 +22,7 @@ use crate::parser::{ArgParser, MetaItemListParser, MetaItemOrLitParser, MetaItem |
| 22 | 22 | |
| 23 | 23 | pub(crate) mod do_not_recommend; |
| 24 | 24 | pub(crate) mod on_const; |
| 25 | pub(crate) mod on_move; | |
| 25 | 26 | pub(crate) mod on_unimplemented; |
| 26 | 27 | |
| 27 | 28 | #[derive(Copy, Clone)] |
| ... | ... | @@ -32,6 +33,8 @@ pub(crate) enum Mode { |
| 32 | 33 | DiagnosticOnUnimplemented, |
| 33 | 34 | /// `#[diagnostic::on_const]` |
| 34 | 35 | DiagnosticOnConst, |
| 36 | /// `#[diagnostic::on_move]` | |
| 37 | DiagnosticOnMove, | |
| 35 | 38 | } |
| 36 | 39 | |
| 37 | 40 | fn merge_directives<S: Stage>( |
| ... | ... | @@ -113,6 +116,13 @@ fn parse_directive_items<'p, S: Stage>( |
| 113 | 116 | span, |
| 114 | 117 | ); |
| 115 | 118 | } |
| 119 | Mode::DiagnosticOnMove => { | |
| 120 | cx.emit_lint( | |
| 121 | MALFORMED_DIAGNOSTIC_ATTRIBUTES, | |
| 122 | AttributeLintKind::MalformedOnMoveAttr { span }, | |
| 123 | span, | |
| 124 | ); | |
| 125 | } | |
| 116 | 126 | } |
| 117 | 127 | continue; |
| 118 | 128 | }} |
| ... | ... | @@ -132,7 +142,7 @@ fn parse_directive_items<'p, S: Stage>( |
| 132 | 142 | Mode::RustcOnUnimplemented => { |
| 133 | 143 | cx.emit_err(NoValueInOnUnimplemented { span: item.span() }); |
| 134 | 144 | } |
| 135 | Mode::DiagnosticOnUnimplemented |Mode::DiagnosticOnConst => { | |
| 145 | Mode::DiagnosticOnUnimplemented |Mode::DiagnosticOnConst | Mode::DiagnosticOnMove => { | |
| 136 | 146 | cx.emit_lint( |
| 137 | 147 | MALFORMED_DIAGNOSTIC_ATTRIBUTES, |
| 138 | 148 | AttributeLintKind::IgnoredDiagnosticOption { |
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs created+72| ... | ... | @@ -0,0 +1,72 @@ |
| 1 | use rustc_feature::template; | |
| 2 | use rustc_hir::attrs::AttributeKind; | |
| 3 | use rustc_hir::lints::AttributeLintKind; | |
| 4 | use rustc_session::lint::builtin::MALFORMED_DIAGNOSTIC_ATTRIBUTES; | |
| 5 | use rustc_span::sym; | |
| 6 | ||
| 7 | use crate::attributes::diagnostic::*; | |
| 8 | use crate::attributes::prelude::*; | |
| 9 | use crate::context::{AcceptContext, Stage}; | |
| 10 | use crate::parser::ArgParser; | |
| 11 | use crate::target_checking::{ALL_TARGETS, AllowedTargets}; | |
| 12 | ||
| 13 | #[derive(Default)] | |
| 14 | pub(crate) struct OnMoveParser { | |
| 15 | span: Option<Span>, | |
| 16 | directive: Option<(Span, Directive)>, | |
| 17 | } | |
| 18 | ||
| 19 | impl OnMoveParser { | |
| 20 | fn parse<'sess, S: Stage>( | |
| 21 | &mut self, | |
| 22 | cx: &mut AcceptContext<'_, 'sess, S>, | |
| 23 | args: &ArgParser, | |
| 24 | mode: Mode, | |
| 25 | ) { | |
| 26 | if !cx.features().diagnostic_on_move() { | |
| 27 | return; | |
| 28 | } | |
| 29 | ||
| 30 | let span = cx.attr_span; | |
| 31 | self.span = Some(span); | |
| 32 | let Some(list) = args.list() else { | |
| 33 | cx.emit_lint( | |
| 34 | MALFORMED_DIAGNOSTIC_ATTRIBUTES, | |
| 35 | AttributeLintKind::MissingOptionsForOnMove, | |
| 36 | span, | |
| 37 | ); | |
| 38 | return; | |
| 39 | }; | |
| 40 | ||
| 41 | if list.is_empty() { | |
| 42 | cx.emit_lint( | |
| 43 | MALFORMED_DIAGNOSTIC_ATTRIBUTES, | |
| 44 | AttributeLintKind::OnMoveMalformedAttrExpectedLiteralOrDelimiter, | |
| 45 | list.span, | |
| 46 | ); | |
| 47 | return; | |
| 48 | } | |
| 49 | ||
| 50 | if let Some(directive) = parse_directive_items(cx, mode, list.mixed(), true) { | |
| 51 | merge_directives(cx, &mut self.directive, (span, directive)); | |
| 52 | } | |
| 53 | } | |
| 54 | } | |
| 55 | impl<S: Stage> AttributeParser<S> for OnMoveParser { | |
| 56 | const ATTRIBUTES: AcceptMapping<Self, S> = &[( | |
| 57 | &[sym::diagnostic, sym::on_move], | |
| 58 | template!(List: &[r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#]), | |
| 59 | |this, cx, args| { | |
| 60 | this.parse(cx, args, Mode::DiagnosticOnMove); | |
| 61 | }, | |
| 62 | )]; | |
| 63 | const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); | |
| 64 | ||
| 65 | fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> { | |
| 66 | if let Some(span) = self.span { | |
| 67 | Some(AttributeKind::OnMove { span, directive: self.directive.map(|d| Box::new(d.1)) }) | |
| 68 | } else { | |
| 69 | None | |
| 70 | } | |
| 71 | } | |
| 72 | } |
compiler/rustc_attr_parsing/src/context.rs+2| ... | ... | @@ -29,6 +29,7 @@ use crate::attributes::debugger::*; |
| 29 | 29 | use crate::attributes::deprecation::*; |
| 30 | 30 | use crate::attributes::diagnostic::do_not_recommend::*; |
| 31 | 31 | use crate::attributes::diagnostic::on_const::*; |
| 32 | use crate::attributes::diagnostic::on_move::*; | |
| 32 | 33 | use crate::attributes::diagnostic::on_unimplemented::*; |
| 33 | 34 | use crate::attributes::doc::*; |
| 34 | 35 | use crate::attributes::dummy::*; |
| ... | ... | @@ -149,6 +150,7 @@ attribute_parsers!( |
| 149 | 150 | MacroUseParser, |
| 150 | 151 | NakedParser, |
| 151 | 152 | OnConstParser, |
| 153 | OnMoveParser, | |
| 152 | 154 | OnUnimplementedParser, |
| 153 | 155 | RustcAlignParser, |
| 154 | 156 | RustcAlignStaticParser, |
compiler/rustc_borrowck/src/borrowck_errors.rs+15-10| ... | ... | @@ -324,18 +324,23 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { |
| 324 | 324 | verb: &str, |
| 325 | 325 | optional_adverb_for_moved: &str, |
| 326 | 326 | moved_path: Option<String>, |
| 327 | primary_message: Option<String>, | |
| 327 | 328 | ) -> Diag<'infcx> { |
| 328 | let moved_path = moved_path.map(|mp| format!(": `{mp}`")).unwrap_or_default(); | |
| 329 | if let Some(primary_message) = primary_message { | |
| 330 | struct_span_code_err!(self.dcx(), use_span, E0382, "{}", primary_message) | |
| 331 | } else { | |
| 332 | let moved_path = moved_path.map(|mp| format!(": `{mp}`")).unwrap_or_default(); | |
| 329 | 333 | |
| 330 | struct_span_code_err!( | |
| 331 | self.dcx(), | |
| 332 | use_span, | |
| 333 | E0382, | |
| 334 | "{} of {}moved value{}", | |
| 335 | verb, | |
| 336 | optional_adverb_for_moved, | |
| 337 | moved_path, | |
| 338 | ) | |
| 334 | struct_span_code_err!( | |
| 335 | self.dcx(), | |
| 336 | use_span, | |
| 337 | E0382, | |
| 338 | "{} of {}moved value{}", | |
| 339 | verb, | |
| 340 | optional_adverb_for_moved, | |
| 341 | moved_path, | |
| 342 | ) | |
| 343 | } | |
| 339 | 344 | } |
| 340 | 345 | |
| 341 | 346 | pub(crate) fn cannot_borrow_path_as_mutable_because( |
compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs+50-7| ... | ... | @@ -6,12 +6,16 @@ use std::ops::ControlFlow; |
| 6 | 6 | use either::Either; |
| 7 | 7 | use hir::{ClosureKind, Path}; |
| 8 | 8 | use rustc_data_structures::fx::FxIndexSet; |
| 9 | use rustc_data_structures::thin_vec::ThinVec; | |
| 9 | 10 | use rustc_errors::codes::*; |
| 10 | 11 | use rustc_errors::{Applicability, Diag, MultiSpan, struct_span_code_err}; |
| 11 | 12 | use rustc_hir as hir; |
| 13 | use rustc_hir::attrs::diagnostic::FormatArgs; | |
| 12 | 14 | use rustc_hir::def::{DefKind, Res}; |
| 13 | 15 | use rustc_hir::intravisit::{Visitor, walk_block, walk_expr}; |
| 14 | use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, LangItem, PatField}; | |
| 16 | use rustc_hir::{ | |
| 17 | CoroutineDesugaring, CoroutineKind, CoroutineSource, LangItem, PatField, find_attr, | |
| 18 | }; | |
| 15 | 19 | use rustc_middle::bug; |
| 16 | 20 | use rustc_middle::hir::nested_filter::OnlyBodies; |
| 17 | 21 | use rustc_middle::mir::{ |
| ... | ... | @@ -138,6 +142,36 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { |
| 138 | 142 | let partial_str = if is_partial_move { "partial " } else { "" }; |
| 139 | 143 | let partially_str = if is_partial_move { "partially " } else { "" }; |
| 140 | 144 | |
| 145 | let (on_move_message, on_move_label, on_move_notes) = if let ty::Adt(item_def, args) = | |
| 146 | self.body.local_decls[moved_place.local].ty.kind() | |
| 147 | && let Some(Some(directive)) = find_attr!(self.infcx.tcx, item_def.did(), OnMove { directive, .. } => directive) | |
| 148 | { | |
| 149 | let item_name = self.infcx.tcx.item_name(item_def.did()).to_string(); | |
| 150 | let mut generic_args: Vec<_> = self | |
| 151 | .infcx | |
| 152 | .tcx | |
| 153 | .generics_of(item_def.did()) | |
| 154 | .own_params | |
| 155 | .iter() | |
| 156 | .filter_map(|param| Some((param.name, args[param.index as usize].to_string()))) | |
| 157 | .collect(); | |
| 158 | generic_args.push((kw::SelfUpper, item_name)); | |
| 159 | ||
| 160 | let args = FormatArgs { | |
| 161 | this: String::new(), | |
| 162 | trait_sugared: String::new(), | |
| 163 | item_context: "", | |
| 164 | generic_args, | |
| 165 | }; | |
| 166 | ( | |
| 167 | directive.message.as_ref().map(|e| e.1.format(&args)), | |
| 168 | directive.label.as_ref().map(|e| e.1.format(&args)), | |
| 169 | directive.notes.iter().map(|e| e.format(&args)).collect(), | |
| 170 | ) | |
| 171 | } else { | |
| 172 | (None, None, ThinVec::new()) | |
| 173 | }; | |
| 174 | ||
| 141 | 175 | let mut err = self.cannot_act_on_moved_value( |
| 142 | 176 | span, |
| 143 | 177 | desired_action.as_noun(), |
| ... | ... | @@ -146,8 +180,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { |
| 146 | 180 | moved_place, |
| 147 | 181 | DescribePlaceOpt { including_downcast: true, including_tuple_field: true }, |
| 148 | 182 | ), |
| 183 | on_move_message, | |
| 149 | 184 | ); |
| 150 | 185 | |
| 186 | for note in on_move_notes { | |
| 187 | err.note(note); | |
| 188 | } | |
| 189 | ||
| 151 | 190 | let reinit_spans = maybe_reinitialized_locations |
| 152 | 191 | .iter() |
| 153 | 192 | .take(3) |
| ... | ... | @@ -275,12 +314,16 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { |
| 275 | 314 | if needs_note { |
| 276 | 315 | if let Some(local) = place.as_local() { |
| 277 | 316 | let span = self.body.local_decls[local].source_info.span; |
| 278 | err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { | |
| 279 | is_partial_move, | |
| 280 | ty, | |
| 281 | place: &note_msg, | |
| 282 | span, | |
| 283 | }); | |
| 317 | if let Some(on_move_label) = on_move_label { | |
| 318 | err.span_label(span, on_move_label); | |
| 319 | } else { | |
| 320 | err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { | |
| 321 | is_partial_move, | |
| 322 | ty, | |
| 323 | place: &note_msg, | |
| 324 | span, | |
| 325 | }); | |
| 326 | } | |
| 284 | 327 | } else { |
| 285 | 328 | err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Note { |
| 286 | 329 | is_partial_move, |
compiler/rustc_codegen_llvm/src/back/write.rs+2-10| ... | ... | @@ -23,9 +23,7 @@ use rustc_middle::ty::TyCtxt; |
| 23 | 23 | use rustc_session::Session; |
| 24 | 24 | use rustc_session::config::{self, Lto, OutputType, Passes, SplitDwarfKind, SwitchWithOptPath}; |
| 25 | 25 | use rustc_span::{BytePos, InnerSpan, Pos, RemapPathScopeComponents, SpanData, SyntaxContext, sym}; |
| 26 | use rustc_target::spec::{ | |
| 27 | Arch, CodeModel, FloatAbi, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel, | |
| 28 | }; | |
| 26 | use rustc_target::spec::{CodeModel, FloatAbi, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel}; | |
| 29 | 27 | use tracing::{debug, trace}; |
| 30 | 28 | |
| 31 | 29 | use crate::back::lto::{Buffer, ModuleBuffer}; |
| ... | ... | @@ -206,13 +204,7 @@ pub(crate) fn target_machine_factory( |
| 206 | 204 | let reloc_model = to_llvm_relocation_model(sess.relocation_model()); |
| 207 | 205 | |
| 208 | 206 | let (opt_level, _) = to_llvm_opt_settings(optlvl); |
| 209 | let float_abi = if sess.target.arch == Arch::Arm && sess.opts.cg.soft_float { | |
| 210 | llvm::FloatAbi::Soft | |
| 211 | } else { | |
| 212 | // `validate_commandline_args_with_session_available` has already warned about this being | |
| 213 | // ignored. Let's make sure LLVM doesn't suddenly start using this flag on more targets. | |
| 214 | to_llvm_float_abi(sess.target.llvm_floatabi) | |
| 215 | }; | |
| 207 | let float_abi = to_llvm_float_abi(sess.target.llvm_floatabi); | |
| 216 | 208 | |
| 217 | 209 | let ffunction_sections = |
| 218 | 210 | sess.opts.unstable_opts.function_sections.unwrap_or(sess.target.function_sections); |
compiler/rustc_feature/src/builtin_attrs.rs+1| ... | ... | @@ -1587,6 +1587,7 @@ pub fn is_stable_diagnostic_attribute(sym: Symbol, features: &Features) -> bool |
| 1587 | 1587 | match sym { |
| 1588 | 1588 | sym::on_unimplemented | sym::do_not_recommend => true, |
| 1589 | 1589 | sym::on_const => features.diagnostic_on_const(), |
| 1590 | sym::on_move => features.diagnostic_on_move(), | |
| 1590 | 1591 | _ => false, |
| 1591 | 1592 | } |
| 1592 | 1593 | } |
compiler/rustc_feature/src/unstable.rs+2| ... | ... | @@ -472,6 +472,8 @@ declare_features! ( |
| 472 | 472 | (unstable, derive_from, "1.91.0", Some(144889)), |
| 473 | 473 | /// Allows giving non-const impls custom diagnostic messages if attempted to be used as const |
| 474 | 474 | (unstable, diagnostic_on_const, "1.93.0", Some(143874)), |
| 475 | /// Allows giving on-move borrowck custom diagnostic messages for a type | |
| 476 | (unstable, diagnostic_on_move, "CURRENT_RUSTC_VERSION", Some(150935)), | |
| 475 | 477 | /// Allows `#[doc(cfg(...))]`. |
| 476 | 478 | (unstable, doc_cfg, "1.21.0", Some(43781)), |
| 477 | 479 | /// Allows `#[doc(masked)]`. |
compiler/rustc_hir/src/attrs/data_structures.rs+6-1| ... | ... | @@ -1180,13 +1180,18 @@ pub enum AttributeKind { |
| 1180 | 1180 | directive: Option<Box<Directive>>, |
| 1181 | 1181 | }, |
| 1182 | 1182 | |
| 1183 | /// Represents `#[diagnostic::on_move]` | |
| 1184 | OnMove { | |
| 1185 | span: Span, | |
| 1186 | directive: Option<Box<Directive>>, | |
| 1187 | }, | |
| 1188 | ||
| 1183 | 1189 | /// Represents `#[rustc_on_unimplemented]` and `#[diagnostic::on_unimplemented]`. |
| 1184 | 1190 | OnUnimplemented { |
| 1185 | 1191 | span: Span, |
| 1186 | 1192 | /// None if the directive was malformed in some way. |
| 1187 | 1193 | directive: Option<Box<Directive>>, |
| 1188 | 1194 | }, |
| 1189 | ||
| 1190 | 1195 | /// Represents `#[optimize(size|speed)]` |
| 1191 | 1196 | Optimize(OptimizeAttr, Span), |
| 1192 | 1197 |
compiler/rustc_hir/src/attrs/encode_cross_crate.rs+1| ... | ... | @@ -77,6 +77,7 @@ impl AttributeKind { |
| 77 | 77 | NoStd(..) => No, |
| 78 | 78 | NonExhaustive(..) => Yes, // Needed for rustdoc |
| 79 | 79 | OnConst { .. } => Yes, |
| 80 | OnMove { .. } => Yes, | |
| 80 | 81 | OnUnimplemented { .. } => Yes, |
| 81 | 82 | Optimize(..) => No, |
| 82 | 83 | PanicRuntime => No, |
compiler/rustc_interface/src/tests.rs-1| ... | ... | @@ -637,7 +637,6 @@ fn test_codegen_options_tracking_hash() { |
| 637 | 637 | tracked!(profile_use, Some(PathBuf::from("abc"))); |
| 638 | 638 | tracked!(relocation_model, Some(RelocModel::Pic)); |
| 639 | 639 | tracked!(relro_level, Some(RelroLevel::Full)); |
| 640 | tracked!(soft_float, true); | |
| 641 | 640 | tracked!(split_debuginfo, Some(SplitDebuginfo::Packed)); |
| 642 | 641 | tracked!(symbol_mangling_version, Some(SymbolManglingVersion::V0)); |
| 643 | 642 | tracked!(target_cpu, Some(String::from("abc"))); |
compiler/rustc_lint/src/early/diagnostics.rs+12| ... | ... | @@ -498,6 +498,18 @@ impl<'a> Diagnostic<'a, ()> for DecorateAttrLint<'_, '_, '_> { |
| 498 | 498 | &AttributeLintKind::MissingOptionsForOnConst => { |
| 499 | 499 | lints::MissingOptionsForOnConstAttr.into_diag(dcx, level) |
| 500 | 500 | } |
| 501 | &AttributeLintKind::MalformedOnMoveAttr { span } => { | |
| 502 | lints::MalformedOnMoveAttrLint { span }.into_diag(dcx, level) | |
| 503 | } | |
| 504 | &AttributeLintKind::OnMoveMalformedFormatLiterals { name } => { | |
| 505 | lints::OnMoveMalformedFormatLiterals { name }.into_diag(dcx, level) | |
| 506 | } | |
| 507 | &AttributeLintKind::OnMoveMalformedAttrExpectedLiteralOrDelimiter => { | |
| 508 | lints::OnMoveMalformedAttrExpectedLiteralOrDelimiter.into_diag(dcx, level) | |
| 509 | } | |
| 510 | &AttributeLintKind::MissingOptionsForOnMove => { | |
| 511 | lints::MissingOptionsForOnMoveAttr.into_diag(dcx, level) | |
| 512 | } | |
| 501 | 513 | } |
| 502 | 514 | } |
| 503 | 515 | } |
compiler/rustc_lint/src/lints.rs+29| ... | ... | @@ -3953,6 +3953,11 @@ pub(crate) struct MissingOptionsForOnUnimplementedAttr; |
| 3953 | 3953 | #[help("at least one of the `message`, `note` and `label` options are expected")] |
| 3954 | 3954 | pub(crate) struct MissingOptionsForOnConstAttr; |
| 3955 | 3955 | |
| 3956 | #[derive(Diagnostic)] | |
| 3957 | #[diag("missing options for `on_move` attribute")] | |
| 3958 | #[help("at least one of the `message`, `note` and `label` options are expected")] | |
| 3959 | pub(crate) struct MissingOptionsForOnMoveAttr; | |
| 3960 | ||
| 3956 | 3961 | #[derive(Diagnostic)] |
| 3957 | 3962 | #[diag("malformed `on_unimplemented` attribute")] |
| 3958 | 3963 | #[help("only `message`, `note` and `label` are allowed as options")] |
| ... | ... | @@ -3973,3 +3978,27 @@ pub(crate) struct MalformedOnConstAttrLint { |
| 3973 | 3978 | #[diag("`Eq::assert_receiver_is_total_eq` should never be implemented by hand")] |
| 3974 | 3979 | #[note("this method was used to add checks to the `Eq` derive macro")] |
| 3975 | 3980 | pub(crate) struct EqInternalMethodImplemented; |
| 3981 | ||
| 3982 | #[derive(Diagnostic)] | |
| 3983 | #[diag("unknown or malformed `on_move` attribute")] | |
| 3984 | #[help( | |
| 3985 | "only `message`, `note` and `label` are allowed as options. Their values must be string literals" | |
| 3986 | )] | |
| 3987 | pub(crate) struct MalformedOnMoveAttrLint { | |
| 3988 | #[label("invalid option found here")] | |
| 3989 | pub span: Span, | |
| 3990 | } | |
| 3991 | ||
| 3992 | #[derive(Diagnostic)] | |
| 3993 | #[diag("unknown parameter `{$name}`")] | |
| 3994 | #[help("expect `Self` as format argument")] | |
| 3995 | pub(crate) struct OnMoveMalformedFormatLiterals { | |
| 3996 | pub name: Symbol, | |
| 3997 | } | |
| 3998 | ||
| 3999 | #[derive(Diagnostic)] | |
| 4000 | #[diag("expected a literal or missing delimiter")] | |
| 4001 | #[help( | |
| 4002 | "only literals are allowed as values for the `message`, `note` and `label` options. These options must be separated by a comma" | |
| 4003 | )] | |
| 4004 | pub(crate) struct OnMoveMalformedAttrExpectedLiteralOrDelimiter; |
compiler/rustc_lint_defs/src/lib.rs+8| ... | ... | @@ -840,6 +840,9 @@ pub enum AttributeLintKind { |
| 840 | 840 | MalformedOnConstAttr { |
| 841 | 841 | span: Span, |
| 842 | 842 | }, |
| 843 | MalformedOnMoveAttr { | |
| 844 | span: Span, | |
| 845 | }, | |
| 843 | 846 | MalformedDiagnosticFormat { |
| 844 | 847 | warning: FormatWarning, |
| 845 | 848 | }, |
| ... | ... | @@ -855,6 +858,11 @@ pub enum AttributeLintKind { |
| 855 | 858 | }, |
| 856 | 859 | MissingOptionsForOnUnimplemented, |
| 857 | 860 | MissingOptionsForOnConst, |
| 861 | MissingOptionsForOnMove, | |
| 862 | OnMoveMalformedFormatLiterals { | |
| 863 | name: Symbol, | |
| 864 | }, | |
| 865 | OnMoveMalformedAttrExpectedLiteralOrDelimiter, | |
| 858 | 866 | } |
| 859 | 867 | |
| 860 | 868 | #[derive(Debug, Clone, HashStable_Generic)] |
compiler/rustc_middle/src/query/inner.rs+27-16| ... | ... | @@ -77,23 +77,34 @@ where |
| 77 | 77 | C: QueryCache<Value = Erased<Result<T, ErrorGuaranteed>>>, |
| 78 | 78 | Result<T, ErrorGuaranteed>: Erasable, |
| 79 | 79 | { |
| 80 | let convert = |value: Erased<Result<T, ErrorGuaranteed>>| -> Result<(), ErrorGuaranteed> { | |
| 81 | match erase::restore_val(value) { | |
| 82 | Ok(_) => Ok(()), | |
| 83 | Err(guar) => Err(guar), | |
| 84 | } | |
| 85 | }; | |
| 86 | ||
| 80 | 87 | match try_get_cached(tcx, &query.cache, key) { |
| 81 | Some(value) => erase::restore_val(value).map(drop), | |
| 82 | None => (query.execute_query_fn)( | |
| 83 | tcx, | |
| 84 | DUMMY_SP, | |
| 85 | key, | |
| 86 | QueryMode::Ensure { ensure_mode: EnsureMode::Ok }, | |
| 87 | ) | |
| 88 | .map(erase::restore_val) | |
| 89 | .map(|value| value.map(drop)) | |
| 90 | // Either we actually executed the query, which means we got a full `Result`, | |
| 91 | // or we can just assume the query succeeded, because it was green in the | |
| 92 | // incremental cache. If it is green, that means that the previous compilation | |
| 93 | // that wrote to the incremental cache compiles successfully. That is only | |
| 94 | // possible if the cache entry was `Ok(())`, so we emit that here, without | |
| 95 | // actually encoding the `Result` in the cache or loading it from there. | |
| 96 | .unwrap_or(Ok(())), | |
| 88 | Some(value) => convert(value), | |
| 89 | None => { | |
| 90 | match (query.execute_query_fn)( | |
| 91 | tcx, | |
| 92 | DUMMY_SP, | |
| 93 | key, | |
| 94 | QueryMode::Ensure { ensure_mode: EnsureMode::Ok }, | |
| 95 | ) { | |
| 96 | // We executed the query. Convert the successful result. | |
| 97 | Some(res) => convert(res), | |
| 98 | ||
| 99 | // Reaching here means we didn't execute the query, but we can just assume the | |
| 100 | // query succeeded, because it was green in the incremental cache. If it is green, | |
| 101 | // that means that the previous compilation that wrote to the incremental cache | |
| 102 | // compiles successfully. That is only possible if the cache entry was `Ok(())`, so | |
| 103 | // we emit that here, without actually encoding the `Result` in the cache or | |
| 104 | // loading it from there. | |
| 105 | None => Ok(()), | |
| 106 | } | |
| 107 | } | |
| 97 | 108 | } |
| 98 | 109 | } |
| 99 | 110 |
compiler/rustc_passes/src/check_attr.rs+57| ... | ... | @@ -74,6 +74,10 @@ struct DiagnosticOnConstOnlyForNonConstTraitImpls { |
| 74 | 74 | item_span: Span, |
| 75 | 75 | } |
| 76 | 76 | |
| 77 | #[derive(Diagnostic)] | |
| 78 | #[diag("`#[diagnostic::on_move]` can only be applied to enums, structs or unions")] | |
| 79 | struct DiagnosticOnMoveOnlyForAdt; | |
| 80 | ||
| 77 | 81 | fn target_from_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item: &hir::ImplItem<'_>) -> Target { |
| 78 | 82 | match impl_item.kind { |
| 79 | 83 | hir::ImplItemKind::Const(..) => Target::AssocConst, |
| ... | ... | @@ -233,6 +237,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { |
| 233 | 237 | Attribute::Parsed(AttributeKind::DoNotRecommend{attr_span}) => {self.check_do_not_recommend(*attr_span, hir_id, target, item)}, |
| 234 | 238 | Attribute::Parsed(AttributeKind::OnUnimplemented{span, directive}) => {self.check_diagnostic_on_unimplemented(*span, hir_id, target,directive.as_deref())}, |
| 235 | 239 | Attribute::Parsed(AttributeKind::OnConst{span, ..}) => {self.check_diagnostic_on_const(*span, hir_id, target, item)} |
| 240 | Attribute::Parsed(AttributeKind::OnMove { span, directive }) => { | |
| 241 | self.check_diagnostic_on_move(*span, hir_id, target, directive.as_deref()) | |
| 242 | }, | |
| 236 | 243 | Attribute::Parsed( |
| 237 | 244 | // tidy-alphabetical-start |
| 238 | 245 | AttributeKind::RustcAllowIncoherentImpl(..) |
| ... | ... | @@ -684,6 +691,56 @@ impl<'tcx> CheckAttrVisitor<'tcx> { |
| 684 | 691 | // The traits' or the impls'? |
| 685 | 692 | } |
| 686 | 693 | |
| 694 | /// Checks if `#[diagnostic::on_move]` is applied to an ADT definition | |
| 695 | fn check_diagnostic_on_move( | |
| 696 | &self, | |
| 697 | attr_span: Span, | |
| 698 | hir_id: HirId, | |
| 699 | target: Target, | |
| 700 | directive: Option<&Directive>, | |
| 701 | ) { | |
| 702 | if !matches!(target, Target::Enum | Target::Struct | Target::Union) { | |
| 703 | self.tcx.emit_node_span_lint( | |
| 704 | MISPLACED_DIAGNOSTIC_ATTRIBUTES, | |
| 705 | hir_id, | |
| 706 | attr_span, | |
| 707 | DiagnosticOnMoveOnlyForAdt, | |
| 708 | ); | |
| 709 | } | |
| 710 | ||
| 711 | if let Some(directive) = directive { | |
| 712 | if let Node::Item(Item { | |
| 713 | kind: | |
| 714 | ItemKind::Struct(_, generics, _) | |
| 715 | | ItemKind::Enum(_, generics, _) | |
| 716 | | ItemKind::Union(_, generics, _), | |
| 717 | .. | |
| 718 | }) = self.tcx.hir_node(hir_id) | |
| 719 | { | |
| 720 | directive.visit_params(&mut |argument_name, span| { | |
| 721 | let has_generic = generics.params.iter().any(|p| { | |
| 722 | if !matches!(p.kind, GenericParamKind::Lifetime { .. }) | |
| 723 | && let ParamName::Plain(name) = p.name | |
| 724 | && name.name == argument_name | |
| 725 | { | |
| 726 | true | |
| 727 | } else { | |
| 728 | false | |
| 729 | } | |
| 730 | }); | |
| 731 | if !has_generic { | |
| 732 | self.tcx.emit_node_span_lint( | |
| 733 | MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, | |
| 734 | hir_id, | |
| 735 | span, | |
| 736 | errors::OnMoveMalformedFormatLiterals { name: argument_name }, | |
| 737 | ) | |
| 738 | } | |
| 739 | }); | |
| 740 | } | |
| 741 | } | |
| 742 | } | |
| 743 | ||
| 687 | 744 | /// Checks if an `#[inline]` is applied to a function or a closure. |
| 688 | 745 | fn check_inline(&self, hir_id: HirId, attr_span: Span, kind: &InlineAttr, target: Target) { |
| 689 | 746 | match target { |
compiler/rustc_passes/src/errors.rs+7| ... | ... | @@ -1432,3 +1432,10 @@ pub(crate) struct UnknownFormatParameterForOnUnimplementedAttr { |
| 1432 | 1432 | #[help(r#"expect either a generic argument name or {"`{Self}`"} as format argument"#)] |
| 1433 | 1433 | pub help: bool, |
| 1434 | 1434 | } |
| 1435 | ||
| 1436 | #[derive(Diagnostic)] | |
| 1437 | #[diag("unknown parameter `{$name}`")] | |
| 1438 | #[help(r#"expect either a generic argument name or {"`{Self}`"} as format argument"#)] | |
| 1439 | pub(crate) struct OnMoveMalformedFormatLiterals { | |
| 1440 | pub name: Symbol, | |
| 1441 | } |
compiler/rustc_query_impl/src/job.rs+6-6| ... | ... | @@ -155,11 +155,11 @@ fn abstracted_waiters_of(job_map: &QueryJobMap<'_>, query: QueryJobId) -> Vec<Ab |
| 155 | 155 | result |
| 156 | 156 | } |
| 157 | 157 | |
| 158 | /// Look for query cycles by doing a depth first search starting at `query`. | |
| 158 | /// Looks for a query cycle by doing a depth first search starting at `query`. | |
| 159 | 159 | /// `span` is the reason for the `query` to execute. This is initially DUMMY_SP. |
| 160 | 160 | /// If a cycle is detected, this initial value is replaced with the span causing |
| 161 | /// the cycle. | |
| 162 | fn cycle_check<'tcx>( | |
| 161 | /// the cycle. `stack` will contain just the cycle on return if detected. | |
| 162 | fn find_cycle<'tcx>( | |
| 163 | 163 | job_map: &QueryJobMap<'tcx>, |
| 164 | 164 | query: QueryJobId, |
| 165 | 165 | span: Span, |
| ... | ... | @@ -190,7 +190,7 @@ fn cycle_check<'tcx>( |
| 190 | 190 | continue; |
| 191 | 191 | }; |
| 192 | 192 | if let ControlFlow::Break(maybe_resumable) = |
| 193 | cycle_check(job_map, parent, abstracted_waiter.span, stack, visited) | |
| 193 | find_cycle(job_map, parent, abstracted_waiter.span, stack, visited) | |
| 194 | 194 | { |
| 195 | 195 | // Return the resumable waiter in `waiter.resumable` if present |
| 196 | 196 | return ControlFlow::Break(abstracted_waiter.resumable.or(maybe_resumable)); |
| ... | ... | @@ -232,7 +232,7 @@ fn connected_to_root<'tcx>( |
| 232 | 232 | false |
| 233 | 233 | } |
| 234 | 234 | |
| 235 | /// Looks for query cycles starting from the last query in `jobs`. | |
| 235 | /// Looks for a query cycle using the last query in `jobs`. | |
| 236 | 236 | /// If a cycle is found, all queries in the cycle is removed from `jobs` and |
| 237 | 237 | /// the function return true. |
| 238 | 238 | /// If a cycle was not found, the starting query is removed from `jobs` and |
| ... | ... | @@ -246,7 +246,7 @@ fn remove_cycle<'tcx>( |
| 246 | 246 | let mut stack = Vec::new(); |
| 247 | 247 | // Look for a cycle starting with the last query in `jobs` |
| 248 | 248 | if let ControlFlow::Break(resumable) = |
| 249 | cycle_check(job_map, jobs.pop().unwrap(), DUMMY_SP, &mut stack, &mut visited) | |
| 249 | find_cycle(job_map, jobs.pop().unwrap(), DUMMY_SP, &mut stack, &mut visited) | |
| 250 | 250 | { |
| 251 | 251 | // The stack is a vector of pairs of spans and queries; reverse it so that |
| 252 | 252 | // the earlier entries require later entries |
compiler/rustc_resolve/src/errors.rs+4| ... | ... | @@ -560,6 +560,10 @@ pub(crate) struct ExpectedModuleFound { |
| 560 | 560 | #[diag("cannot determine resolution for the visibility", code = E0578)] |
| 561 | 561 | pub(crate) struct Indeterminate(#[primary_span] pub(crate) Span); |
| 562 | 562 | |
| 563 | #[derive(Diagnostic)] | |
| 564 | #[diag("trait implementation can only be restricted to ancestor modules")] | |
| 565 | pub(crate) struct RestrictionAncestorOnly(#[primary_span] pub(crate) Span); | |
| 566 | ||
| 563 | 567 | #[derive(Diagnostic)] |
| 564 | 568 | #[diag("cannot use a tool module through an import")] |
| 565 | 569 | pub(crate) struct ToolModuleImported { |
compiler/rustc_resolve/src/late.rs+39-4| ... | ... | @@ -452,6 +452,8 @@ pub(crate) enum PathSource<'a, 'ast, 'ra> { |
| 452 | 452 | DefineOpaques, |
| 453 | 453 | /// Resolving a macro |
| 454 | 454 | Macro, |
| 455 | /// Paths for module or crate root. Used for restrictions. | |
| 456 | Module, | |
| 455 | 457 | } |
| 456 | 458 | |
| 457 | 459 | impl PathSource<'_, '_, '_> { |
| ... | ... | @@ -460,7 +462,8 @@ impl PathSource<'_, '_, '_> { |
| 460 | 462 | PathSource::Type |
| 461 | 463 | | PathSource::Trait(_) |
| 462 | 464 | | PathSource::Struct(_) |
| 463 | | PathSource::DefineOpaques => TypeNS, | |
| 465 | | PathSource::DefineOpaques | |
| 466 | | PathSource::Module => TypeNS, | |
| 464 | 467 | PathSource::Expr(..) |
| 465 | 468 | | PathSource::Pat |
| 466 | 469 | | PathSource::TupleStruct(..) |
| ... | ... | @@ -485,7 +488,8 @@ impl PathSource<'_, '_, '_> { |
| 485 | 488 | | PathSource::DefineOpaques |
| 486 | 489 | | PathSource::Delegation |
| 487 | 490 | | PathSource::PreciseCapturingArg(..) |
| 488 | | PathSource::Macro => false, | |
| 491 | | PathSource::Macro | |
| 492 | | PathSource::Module => false, | |
| 489 | 493 | } |
| 490 | 494 | } |
| 491 | 495 | |
| ... | ... | @@ -528,6 +532,7 @@ impl PathSource<'_, '_, '_> { |
| 528 | 532 | PathSource::ReturnTypeNotation | PathSource::Delegation => "function", |
| 529 | 533 | PathSource::PreciseCapturingArg(..) => "type or const parameter", |
| 530 | 534 | PathSource::Macro => "macro", |
| 535 | PathSource::Module => "module", | |
| 531 | 536 | } |
| 532 | 537 | } |
| 533 | 538 | |
| ... | ... | @@ -626,6 +631,7 @@ impl PathSource<'_, '_, '_> { |
| 626 | 631 | ), |
| 627 | 632 | PathSource::PreciseCapturingArg(MacroNS) => false, |
| 628 | 633 | PathSource::Macro => matches!(res, Res::Def(DefKind::Macro(_), _)), |
| 634 | PathSource::Module => matches!(res, Res::Def(DefKind::Mod, _)), | |
| 629 | 635 | } |
| 630 | 636 | } |
| 631 | 637 | |
| ... | ... | @@ -646,6 +652,12 @@ impl PathSource<'_, '_, '_> { |
| 646 | 652 | (PathSource::PreciseCapturingArg(..), true) => E0799, |
| 647 | 653 | (PathSource::PreciseCapturingArg(..), false) => E0800, |
| 648 | 654 | (PathSource::Macro, _) => E0425, |
| 655 | // FIXME: There is no dedicated error code for this case yet. | |
| 656 | // E0577 already covers the same situation for visibilities, | |
| 657 | // so we reuse it here for now. It may make sense to generalize | |
| 658 | // it for restrictions in the future. | |
| 659 | (PathSource::Module, true) => E0577, | |
| 660 | (PathSource::Module, false) => E0433, | |
| 649 | 661 | } |
| 650 | 662 | } |
| 651 | 663 | } |
| ... | ... | @@ -2174,7 +2186,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |
| 2174 | 2186 | | PathSource::Type |
| 2175 | 2187 | | PathSource::PreciseCapturingArg(..) |
| 2176 | 2188 | | PathSource::ReturnTypeNotation |
| 2177 | | PathSource::Macro => false, | |
| 2189 | | PathSource::Macro | |
| 2190 | | PathSource::Module => false, | |
| 2178 | 2191 | PathSource::Expr(..) |
| 2179 | 2192 | | PathSource::Pat |
| 2180 | 2193 | | PathSource::Struct(_) |
| ... | ... | @@ -2800,7 +2813,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |
| 2800 | 2813 | self.diag_metadata.current_impl_items = None; |
| 2801 | 2814 | } |
| 2802 | 2815 | |
| 2803 | ItemKind::Trait(box Trait { generics, bounds, items, .. }) => { | |
| 2816 | ItemKind::Trait(box Trait { generics, bounds, items, impl_restriction, .. }) => { | |
| 2817 | // resolve paths for `impl` restrictions | |
| 2818 | self.resolve_impl_restriction_path(impl_restriction); | |
| 2819 | ||
| 2804 | 2820 | // Create a new rib for the trait-wide type parameters. |
| 2805 | 2821 | self.with_generic_param_rib( |
| 2806 | 2822 | &generics.params, |
| ... | ... | @@ -4389,6 +4405,25 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |
| 4389 | 4405 | } |
| 4390 | 4406 | } |
| 4391 | 4407 | |
| 4408 | fn resolve_impl_restriction_path(&mut self, restriction: &'ast ast::ImplRestriction) { | |
| 4409 | match &restriction.kind { | |
| 4410 | ast::RestrictionKind::Unrestricted => (), | |
| 4411 | ast::RestrictionKind::Restricted { path, id, shorthand: _ } => { | |
| 4412 | self.smart_resolve_path(*id, &None, path, PathSource::Module); | |
| 4413 | if let Some(res) = self.r.partial_res_map[&id].full_res() | |
| 4414 | && let Some(def_id) = res.opt_def_id() | |
| 4415 | { | |
| 4416 | if !self.r.is_accessible_from( | |
| 4417 | Visibility::Restricted(def_id), | |
| 4418 | self.parent_scope.module, | |
| 4419 | ) { | |
| 4420 | self.r.dcx().create_err(errors::RestrictionAncestorOnly(path.span)).emit(); | |
| 4421 | } | |
| 4422 | } | |
| 4423 | } | |
| 4424 | } | |
| 4425 | } | |
| 4426 | ||
| 4392 | 4427 | // High-level and context dependent path resolution routine. |
| 4393 | 4428 | // Resolves the path and records the resolution into definition map. |
| 4394 | 4429 | // If resolution fails tries several techniques to find likely |
compiler/rustc_resolve/src/macros.rs+1-1| ... | ... | @@ -707,7 +707,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 707 | 707 | } |
| 708 | 708 | |
| 709 | 709 | const DIAG_ATTRS: &[Symbol] = |
| 710 | &[sym::on_unimplemented, sym::do_not_recommend, sym::on_const]; | |
| 710 | &[sym::on_unimplemented, sym::do_not_recommend, sym::on_const, sym::on_move]; | |
| 711 | 711 | |
| 712 | 712 | if res == Res::NonMacroAttr(NonMacroAttrKind::Tool) |
| 713 | 713 | && let [namespace, attribute, ..] = &*path.segments |
compiler/rustc_session/src/errors.rs-11| ... | ... | @@ -517,17 +517,6 @@ pub(crate) struct FailedToCreateProfiler { |
| 517 | 517 | pub(crate) err: String, |
| 518 | 518 | } |
| 519 | 519 | |
| 520 | #[derive(Diagnostic)] | |
| 521 | #[diag("`-Csoft-float` is ignored on this target; it only has an effect on *eabihf targets")] | |
| 522 | #[note("this may become a hard error in a future version of Rust")] | |
| 523 | pub(crate) struct SoftFloatIgnored; | |
| 524 | ||
| 525 | #[derive(Diagnostic)] | |
| 526 | #[diag("`-Csoft-float` is unsound and deprecated; use a corresponding *eabi target instead")] | |
| 527 | #[note("it will be removed or ignored in a future version of Rust")] | |
| 528 | #[note("see issue #129893 <https://github.com/rust-lang/rust/issues/129893> for more information")] | |
| 529 | pub(crate) struct SoftFloatDeprecated; | |
| 530 | ||
| 531 | 520 | #[derive(Diagnostic)] |
| 532 | 521 | #[diag("unexpected `--cfg {$cfg}` flag")] |
| 533 | 522 | #[note("config `{$cfg_name}` is only supposed to be controlled by `{$controlled_by}`")] |
compiler/rustc_session/src/lib.rs+2| ... | ... | @@ -1,5 +1,7 @@ |
| 1 | 1 | // tidy-alphabetical-start |
| 2 | 2 | #![allow(internal_features)] |
| 3 | #![feature(const_option_ops)] | |
| 4 | #![feature(const_trait_impl)] | |
| 3 | 5 | #![feature(default_field_values)] |
| 4 | 6 | #![feature(iter_intersperse)] |
| 5 | 7 | #![feature(macro_derive)] |
compiler/rustc_session/src/options.rs+35-19| ... | ... | @@ -611,7 +611,7 @@ macro_rules! options { |
| 611 | 611 | $parse:ident, |
| 612 | 612 | [$dep_tracking_marker:ident $( $tmod:ident )?], |
| 613 | 613 | $desc:expr |
| 614 | $(, is_deprecated_and_do_nothing: $dnn:literal )?) | |
| 614 | $(, removed: $removed:ident )?) | |
| 615 | 615 | ),* ,) => |
| 616 | 616 | ( |
| 617 | 617 | #[derive(Clone)] |
| ... | ... | @@ -667,7 +667,7 @@ macro_rules! options { |
| 667 | 667 | |
| 668 | 668 | pub const $stat: OptionDescrs<$struct_name> = |
| 669 | 669 | &[ $( OptionDesc{ name: stringify!($opt), setter: $optmod::$opt, |
| 670 | type_desc: desc::$parse, desc: $desc, is_deprecated_and_do_nothing: false $( || $dnn )?, | |
| 670 | type_desc: desc::$parse, desc: $desc, removed: None $( .or(Some(RemovedOption::$removed)) )?, | |
| 671 | 671 | tmod: tmod_enum_opt!($struct_name, $tmod_enum_name, $opt, $($tmod),*) } ),* ]; |
| 672 | 672 | |
| 673 | 673 | mod $optmod { |
| ... | ... | @@ -705,6 +705,12 @@ macro_rules! redirect_field { |
| 705 | 705 | type OptionSetter<O> = fn(&mut O, v: Option<&str>) -> bool; |
| 706 | 706 | type OptionDescrs<O> = &'static [OptionDesc<O>]; |
| 707 | 707 | |
| 708 | /// Indicates whether a removed option should warn or error. | |
| 709 | enum RemovedOption { | |
| 710 | Warn, | |
| 711 | Err, | |
| 712 | } | |
| 713 | ||
| 708 | 714 | pub struct OptionDesc<O> { |
| 709 | 715 | name: &'static str, |
| 710 | 716 | setter: OptionSetter<O>, |
| ... | ... | @@ -712,7 +718,7 @@ pub struct OptionDesc<O> { |
| 712 | 718 | type_desc: &'static str, |
| 713 | 719 | // description for option from options table |
| 714 | 720 | desc: &'static str, |
| 715 | is_deprecated_and_do_nothing: bool, | |
| 721 | removed: Option<RemovedOption>, | |
| 716 | 722 | tmod: Option<OptionsTargetModifiers>, |
| 717 | 723 | } |
| 718 | 724 | |
| ... | ... | @@ -743,18 +749,18 @@ fn build_options<O: Default>( |
| 743 | 749 | |
| 744 | 750 | let option_to_lookup = key.replace('-', "_"); |
| 745 | 751 | match descrs.iter().find(|opt_desc| opt_desc.name == option_to_lookup) { |
| 746 | Some(OptionDesc { | |
| 747 | name: _, | |
| 748 | setter, | |
| 749 | type_desc, | |
| 750 | desc, | |
| 751 | is_deprecated_and_do_nothing, | |
| 752 | tmod, | |
| 753 | }) => { | |
| 754 | if *is_deprecated_and_do_nothing { | |
| 752 | Some(OptionDesc { name: _, setter, type_desc, desc, removed, tmod }) => { | |
| 753 | if let Some(removed) = removed { | |
| 755 | 754 | // deprecation works for prefixed options only |
| 756 | 755 | assert!(!prefix.is_empty()); |
| 757 | early_dcx.early_warn(format!("`-{prefix} {key}`: {desc}")); | |
| 756 | match removed { | |
| 757 | RemovedOption::Warn => { | |
| 758 | early_dcx.early_warn(format!("`-{prefix} {key}`: {desc}")) | |
| 759 | } | |
| 760 | RemovedOption::Err => { | |
| 761 | early_dcx.early_fatal(format!("`-{prefix} {key}`: {desc}")) | |
| 762 | } | |
| 763 | } | |
| 758 | 764 | } |
| 759 | 765 | if !setter(&mut op, value) { |
| 760 | 766 | match value { |
| ... | ... | @@ -783,6 +789,7 @@ fn build_options<O: Default>( |
| 783 | 789 | |
| 784 | 790 | #[allow(non_upper_case_globals)] |
| 785 | 791 | mod desc { |
| 792 | pub(crate) const parse_ignore: &str = "<ignored>"; // should not be user-visible | |
| 786 | 793 | pub(crate) const parse_no_value: &str = "no value"; |
| 787 | 794 | pub(crate) const parse_bool: &str = |
| 788 | 795 | "one of: `y`, `yes`, `on`, `true`, `n`, `no`, `off` or `false`"; |
| ... | ... | @@ -889,6 +896,12 @@ pub mod parse { |
| 889 | 896 | pub(crate) use super::*; |
| 890 | 897 | pub(crate) const MAX_THREADS_CAP: usize = 256; |
| 891 | 898 | |
| 899 | /// Ignore the value. Used for removed options where we don't actually want to store | |
| 900 | /// anything in the session. | |
| 901 | pub(crate) fn parse_ignore(_slot: &mut (), _v: Option<&str>) -> bool { | |
| 902 | true | |
| 903 | } | |
| 904 | ||
| 892 | 905 | /// This is for boolean options that don't take a value, and are true simply |
| 893 | 906 | /// by existing on the command-line. |
| 894 | 907 | /// |
| ... | ... | @@ -2059,7 +2072,7 @@ options! { |
| 2059 | 2072 | #[rustc_lint_opt_deny_field_access("documented to do nothing")] |
| 2060 | 2073 | ar: String = (String::new(), parse_string, [UNTRACKED], |
| 2061 | 2074 | "this option is deprecated and does nothing", |
| 2062 | is_deprecated_and_do_nothing: true), | |
| 2075 | removed: Warn), | |
| 2063 | 2076 | #[rustc_lint_opt_deny_field_access("use `Session::code_model` instead of this field")] |
| 2064 | 2077 | code_model: Option<CodeModel> = (None, parse_code_model, [TRACKED], |
| 2065 | 2078 | "choose the code model to use (`rustc --print code-models` for details)"), |
| ... | ... | @@ -2098,7 +2111,7 @@ options! { |
| 2098 | 2111 | inline_threshold: Option<u32> = (None, parse_opt_number, [UNTRACKED], |
| 2099 | 2112 | "this option is deprecated and does nothing \ |
| 2100 | 2113 | (consider using `-Cllvm-args=--inline-threshold=...`)", |
| 2101 | is_deprecated_and_do_nothing: true), | |
| 2114 | removed: Warn), | |
| 2102 | 2115 | #[rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field")] |
| 2103 | 2116 | instrument_coverage: InstrumentCoverage = (InstrumentCoverage::No, parse_instrument_coverage, [TRACKED], |
| 2104 | 2117 | "instrument the generated code to support LLVM source-based code coverage reports \ |
| ... | ... | @@ -2139,7 +2152,7 @@ options! { |
| 2139 | 2152 | #[rustc_lint_opt_deny_field_access("documented to do nothing")] |
| 2140 | 2153 | no_stack_check: bool = (false, parse_no_value, [UNTRACKED], |
| 2141 | 2154 | "this option is deprecated and does nothing", |
| 2142 | is_deprecated_and_do_nothing: true), | |
| 2155 | removed: Warn), | |
| 2143 | 2156 | no_vectorize_loops: bool = (false, parse_no_value, [TRACKED], |
| 2144 | 2157 | "disable loop vectorization optimization passes"), |
| 2145 | 2158 | no_vectorize_slp: bool = (false, parse_no_value, [TRACKED], |
| ... | ... | @@ -2173,8 +2186,11 @@ options! { |
| 2173 | 2186 | "set rpath values in libs/exes (default: no)"), |
| 2174 | 2187 | save_temps: bool = (false, parse_bool, [UNTRACKED], |
| 2175 | 2188 | "save all temporary output files during compilation (default: no)"), |
| 2176 | soft_float: bool = (false, parse_bool, [TRACKED], | |
| 2177 | "deprecated option: use soft float ABI (*eabihf targets only) (default: no)"), | |
| 2189 | #[rustc_lint_opt_deny_field_access("documented to do nothing")] | |
| 2190 | soft_float: () = ((), parse_ignore, [UNTRACKED], | |
| 2191 | "this option has been removed \ | |
| 2192 | (use a corresponding *eabi target instead)", | |
| 2193 | removed: Err), | |
| 2178 | 2194 | #[rustc_lint_opt_deny_field_access("use `Session::split_debuginfo` instead of this field")] |
| 2179 | 2195 | split_debuginfo: Option<SplitDebuginfo> = (None, parse_split_debuginfo, [TRACKED], |
| 2180 | 2196 | "how to handle split-debuginfo, a platform-specific option"), |
| ... | ... | @@ -2240,7 +2256,7 @@ options! { |
| 2240 | 2256 | (default: no)"), |
| 2241 | 2257 | box_noalias: bool = (true, parse_bool, [TRACKED], |
| 2242 | 2258 | "emit noalias metadata for box (default: yes)"), |
| 2243 | branch_protection: Option<BranchProtection> = (None, parse_branch_protection, [TRACKED], | |
| 2259 | branch_protection: Option<BranchProtection> = (None, parse_branch_protection, [TRACKED TARGET_MODIFIER], | |
| 2244 | 2260 | "set options for branch target identification and pointer authentication on AArch64"), |
| 2245 | 2261 | build_sdylib_interface: bool = (false, parse_bool, [UNTRACKED], |
| 2246 | 2262 | "whether the stable interface is being built"), |
compiler/rustc_session/src/session.rs-10| ... | ... | @@ -1360,16 +1360,6 @@ fn validate_commandline_args_with_session_available(sess: &Session) { |
| 1360 | 1360 | } |
| 1361 | 1361 | } |
| 1362 | 1362 | } |
| 1363 | ||
| 1364 | if sess.opts.cg.soft_float { | |
| 1365 | if sess.target.arch == Arch::Arm { | |
| 1366 | sess.dcx().emit_warn(errors::SoftFloatDeprecated); | |
| 1367 | } else { | |
| 1368 | // All `use_softfp` does is the equivalent of `-mfloat-abi` in GCC/clang, which only exists on ARM targets. | |
| 1369 | // We document this flag to only affect `*eabihf` targets, so let's show a warning for all other targets. | |
| 1370 | sess.dcx().emit_warn(errors::SoftFloatIgnored); | |
| 1371 | } | |
| 1372 | } | |
| 1373 | 1363 | } |
| 1374 | 1364 | |
| 1375 | 1365 | /// Holds data on the current incremental compilation session, if there is one. |
compiler/rustc_span/src/symbol.rs+2| ... | ... | @@ -797,6 +797,7 @@ symbols! { |
| 797 | 797 | diagnostic, |
| 798 | 798 | diagnostic_namespace, |
| 799 | 799 | diagnostic_on_const, |
| 800 | diagnostic_on_move, | |
| 800 | 801 | dialect, |
| 801 | 802 | direct, |
| 802 | 803 | discriminant_kind, |
| ... | ... | @@ -1407,6 +1408,7 @@ symbols! { |
| 1407 | 1408 | omit_gdb_pretty_printer_section, |
| 1408 | 1409 | on, |
| 1409 | 1410 | on_const, |
| 1411 | on_move, | |
| 1410 | 1412 | on_unimplemented, |
| 1411 | 1413 | opaque, |
| 1412 | 1414 | opaque_generic_const_args, |
compiler/rustc_type_ir/Cargo.toml+1-1| ... | ... | @@ -7,7 +7,7 @@ edition = "2024" |
| 7 | 7 | # tidy-alphabetical-start |
| 8 | 8 | arrayvec = { version = "0.7", default-features = false } |
| 9 | 9 | bitflags = "2.4.1" |
| 10 | derive-where = "1.2.7" | |
| 10 | derive-where = "1.6.1" | |
| 11 | 11 | ena = "0.14.4" |
| 12 | 12 | indexmap = "2.0.0" |
| 13 | 13 | rustc-hash = "2.0.0" |
compiler/rustc_type_ir/src/binder.rs+3-17| ... | ... | @@ -26,11 +26,7 @@ use crate::{self as ty, DebruijnIndex, Interner, UniverseIndex}; |
| 26 | 26 | /// for more details. |
| 27 | 27 | /// |
| 28 | 28 | /// `Decodable` and `Encodable` are implemented for `Binder<T>` using the `impl_binder_encode_decode!` macro. |
| 29 | // FIXME(derive-where#136): Need to use separate `derive_where` for | |
| 30 | // `Copy` and `Ord` to prevent the emitted `Clone` and `PartialOrd` | |
| 31 | // impls from incorrectly relying on `T: Copy` and `T: Ord`. | |
| 32 | #[derive_where(Copy; I: Interner, T: Copy)] | |
| 33 | #[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, T)] | |
| 29 | #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner, T)] | |
| 34 | 30 | #[derive(GenericTypeVisitable)] |
| 35 | 31 | #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] |
| 36 | 32 | pub struct Binder<I: Interner, T> { |
| ... | ... | @@ -365,12 +361,7 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> { |
| 365 | 361 | /// `instantiate`. |
| 366 | 362 | /// |
| 367 | 363 | /// See <https://rustc-dev-guide.rust-lang.org/ty_module/early_binder.html> for more details. |
| 368 | // FIXME(derive-where#136): Need to use separate `derive_where` for | |
| 369 | // `Copy` and `Ord` to prevent the emitted `Clone` and `PartialOrd` | |
| 370 | // impls from incorrectly relying on `T: Copy` and `T: Ord`. | |
| 371 | #[derive_where(Ord; I: Interner, T: Ord)] | |
| 372 | #[derive_where(Copy; I: Interner, T: Copy)] | |
| 373 | #[derive_where(Clone, PartialOrd, PartialEq, Hash, Debug; I: Interner, T)] | |
| 364 | #[derive_where(Clone, Copy, PartialOrd, Ord, PartialEq, Hash, Debug; I: Interner, T)] | |
| 374 | 365 | #[derive(GenericTypeVisitable)] |
| 375 | 366 | #[cfg_attr( |
| 376 | 367 | feature = "nightly", |
| ... | ... | @@ -964,12 +955,7 @@ pub enum BoundVarIndexKind { |
| 964 | 955 | /// The "placeholder index" fully defines a placeholder region, type, or const. Placeholders are |
| 965 | 956 | /// identified by both a universe, as well as a name residing within that universe. Distinct bound |
| 966 | 957 | /// regions/types/consts within the same universe simply have an unknown relationship to one |
| 967 | // FIXME(derive-where#136): Need to use separate `derive_where` for | |
| 968 | // `Copy` and `Ord` to prevent the emitted `Clone` and `PartialOrd` | |
| 969 | // impls from incorrectly relying on `T: Copy` and `T: Ord`. | |
| 970 | #[derive_where(Ord; I: Interner, T: Ord)] | |
| 971 | #[derive_where(Copy; I: Interner, T: Copy)] | |
| 972 | #[derive_where(Clone, PartialOrd, PartialEq, Eq, Hash; I: Interner, T)] | |
| 958 | #[derive_where(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash; I: Interner, T)] | |
| 973 | 959 | #[derive(TypeVisitable_Generic, TypeFoldable_Generic)] |
| 974 | 960 | #[cfg_attr( |
| 975 | 961 | feature = "nightly", |
library/core/src/lib.rs+1-2| ... | ... | @@ -107,8 +107,6 @@ |
| 107 | 107 | #![feature(core_intrinsics)] |
| 108 | 108 | #![feature(coverage_attribute)] |
| 109 | 109 | #![feature(disjoint_bitor)] |
| 110 | #![feature(internal_impls_macro)] | |
| 111 | #![feature(link_cfg)] | |
| 112 | 110 | #![feature(offset_of_enum)] |
| 113 | 111 | #![feature(panic_internals)] |
| 114 | 112 | #![feature(pattern_type_macro)] |
| ... | ... | @@ -144,6 +142,7 @@ |
| 144 | 142 | #![feature(intra_doc_pointers)] |
| 145 | 143 | #![feature(intrinsics)] |
| 146 | 144 | #![feature(lang_items)] |
| 145 | #![feature(link_cfg)] | |
| 147 | 146 | #![feature(link_llvm_intrinsics)] |
| 148 | 147 | #![feature(macro_metavar_expr)] |
| 149 | 148 | #![feature(macro_metavar_expr_concat)] |
library/core/src/marker.rs-3| ... | ... | @@ -52,9 +52,6 @@ use crate::pin::UnsafePinned; |
| 52 | 52 | /// u32, |
| 53 | 53 | /// } |
| 54 | 54 | /// ``` |
| 55 | #[unstable(feature = "internal_impls_macro", issue = "none")] | |
| 56 | // Allow implementations of `UnsizedConstParamTy` even though std cannot use that feature. | |
| 57 | #[allow_internal_unstable(const_param_ty_trait)] | |
| 58 | 55 | macro marker_impls { |
| 59 | 56 | ( $(#[$($meta:tt)*])* $Trait:ident for $({$($bounds:tt)*})? $T:ty $(, $($rest:tt)*)? ) => { |
| 60 | 57 | $(#[$($meta)*])* impl< $($($bounds)*)? > $Trait for $T {} |
library/std/src/lib.rs+8-8| ... | ... | @@ -275,9 +275,7 @@ |
| 275 | 275 | #![feature(cfg_sanitizer_cfi)] |
| 276 | 276 | #![feature(cfg_target_thread_local)] |
| 277 | 277 | #![feature(cfi_encoding)] |
| 278 | #![feature(const_default)] | |
| 279 | 278 | #![feature(const_trait_impl)] |
| 280 | #![feature(core_float_math)] | |
| 281 | 279 | #![feature(decl_macro)] |
| 282 | 280 | #![feature(deprecated_suggestion)] |
| 283 | 281 | #![feature(doc_cfg)] |
| ... | ... | @@ -287,16 +285,11 @@ |
| 287 | 285 | #![feature(f16)] |
| 288 | 286 | #![feature(f128)] |
| 289 | 287 | #![feature(ffi_const)] |
| 290 | #![feature(formatting_options)] | |
| 291 | #![feature(funnel_shifts)] | |
| 292 | 288 | #![feature(intra_doc_pointers)] |
| 293 | #![feature(iter_advance_by)] | |
| 294 | #![feature(iter_next_chunk)] | |
| 295 | 289 | #![feature(lang_items)] |
| 296 | 290 | #![feature(link_cfg)] |
| 297 | 291 | #![feature(linkage)] |
| 298 | 292 | #![feature(macro_metavar_expr_concat)] |
| 299 | #![feature(maybe_uninit_fill)] | |
| 300 | 293 | #![feature(min_specialization)] |
| 301 | 294 | #![feature(must_not_suspend)] |
| 302 | 295 | #![feature(needs_panic_runtime)] |
| ... | ... | @@ -314,7 +307,6 @@ |
| 314 | 307 | #![feature(try_blocks)] |
| 315 | 308 | #![feature(try_trait_v2)] |
| 316 | 309 | #![feature(type_alias_impl_trait)] |
| 317 | #![feature(uint_carryless_mul)] | |
| 318 | 310 | // tidy-alphabetical-end |
| 319 | 311 | // |
| 320 | 312 | // Library features (core): |
| ... | ... | @@ -325,6 +317,8 @@ |
| 325 | 317 | #![feature(char_internals)] |
| 326 | 318 | #![feature(clone_to_uninit)] |
| 327 | 319 | #![feature(const_convert)] |
| 320 | #![feature(const_default)] | |
| 321 | #![feature(core_float_math)] | |
| 328 | 322 | #![feature(core_intrinsics)] |
| 329 | 323 | #![feature(core_io_borrowed_buf)] |
| 330 | 324 | #![feature(cstr_display)] |
| ... | ... | @@ -340,13 +334,18 @@ |
| 340 | 334 | #![feature(float_minimum_maximum)] |
| 341 | 335 | #![feature(fmt_internals)] |
| 342 | 336 | #![feature(fn_ptr_trait)] |
| 337 | #![feature(formatting_options)] | |
| 338 | #![feature(funnel_shifts)] | |
| 343 | 339 | #![feature(generic_atomic)] |
| 344 | 340 | #![feature(hasher_prefixfree_extras)] |
| 345 | 341 | #![feature(hashmap_internals)] |
| 346 | 342 | #![feature(hint_must_use)] |
| 347 | 343 | #![feature(int_from_ascii)] |
| 348 | 344 | #![feature(ip)] |
| 345 | #![feature(iter_advance_by)] | |
| 346 | #![feature(iter_next_chunk)] | |
| 349 | 347 | #![feature(maybe_uninit_array_assume_init)] |
| 348 | #![feature(maybe_uninit_fill)] | |
| 350 | 349 | #![feature(panic_can_unwind)] |
| 351 | 350 | #![feature(panic_internals)] |
| 352 | 351 | #![feature(pin_coerce_unsized_trait)] |
| ... | ... | @@ -364,6 +363,7 @@ |
| 364 | 363 | #![feature(sync_unsafe_cell)] |
| 365 | 364 | #![feature(temporary_niche_types)] |
| 366 | 365 | #![feature(ub_checks)] |
| 366 | #![feature(uint_carryless_mul)] | |
| 367 | 367 | #![feature(used_with_arg)] |
| 368 | 368 | // tidy-alphabetical-end |
| 369 | 369 | // |
src/bootstrap/src/utils/exec.rs+11| ... | ... | @@ -7,6 +7,7 @@ |
| 7 | 7 | //! relevant to command execution in the bootstrap process. This includes settings such as |
| 8 | 8 | //! dry-run mode, verbosity level, and failure behavior. |
| 9 | 9 | |
| 10 | use std::backtrace::{Backtrace, BacktraceStatus}; | |
| 10 | 11 | use std::collections::HashMap; |
| 11 | 12 | use std::ffi::{OsStr, OsString}; |
| 12 | 13 | use std::fmt::{Debug, Formatter}; |
| ... | ... | @@ -930,6 +931,16 @@ Executed at: {executed_at}"#, |
| 930 | 931 | if stderr.captures() { |
| 931 | 932 | writeln!(error_message, "\n--- STDERR vvv\n{}", output.stderr().trim()).unwrap(); |
| 932 | 933 | } |
| 934 | let backtrace = if exec_ctx.verbosity > 1 { | |
| 935 | Backtrace::force_capture() | |
| 936 | } else if matches!(command.failure_behavior, BehaviorOnFailure::Ignore) { | |
| 937 | Backtrace::disabled() | |
| 938 | } else { | |
| 939 | Backtrace::capture() | |
| 940 | }; | |
| 941 | if matches!(backtrace.status(), BacktraceStatus::Captured) { | |
| 942 | writeln!(error_message, "\n--- BACKTRACE vvv\n{backtrace}").unwrap(); | |
| 943 | } | |
| 933 | 944 | |
| 934 | 945 | match command.failure_behavior { |
| 935 | 946 | BehaviorOnFailure::DelayFail => { |
src/librustdoc/passes/check_doc_test_visibility.rs+1-2| ... | ... | @@ -79,8 +79,7 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) - |
| 79 | 79 | | clean::ProvidedAssocConstItem(..) |
| 80 | 80 | | clean::ImplAssocConstItem(..) |
| 81 | 81 | | clean::RequiredAssocTypeItem(..) |
| 82 | // check for trait impl | |
| 83 | | clean::ImplItem(box clean::Impl { trait_: Some(_), .. }) | |
| 82 | | clean::ImplItem(_) | |
| 84 | 83 | ) |
| 85 | 84 | { |
| 86 | 85 | return false; |
src/tools/tidy/src/issues.txt-1| ... | ... | @@ -1475,7 +1475,6 @@ ui/lint/issue-97094.rs |
| 1475 | 1475 | ui/lint/issue-99387.rs |
| 1476 | 1476 | ui/lint/let_underscore/issue-119696-err-on-fn.rs |
| 1477 | 1477 | ui/lint/let_underscore/issue-119697-extra-let.rs |
| 1478 | ui/lint/must_not_suspend/issue-89562.rs | |
| 1479 | 1478 | ui/lint/unused/issue-103320-must-use-ops.rs |
| 1480 | 1479 | ui/lint/unused/issue-104397.rs |
| 1481 | 1480 | ui/lint/unused/issue-105061-array-lint.rs |
tests/assembly-llvm/naked-functions/aarch64-naked-fn-no-bti-prolog.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | //@ compile-flags: -C no-prepopulate-passes -Zbranch-protection=bti | |
| 1 | //@ compile-flags: -C no-prepopulate-passes -Zbranch-protection=bti -Cunsafe-allow-abi-mismatch=branch-protection | |
| 2 | 2 | //@ assembly-output: emit-asm |
| 3 | 3 | //@ needs-asm-support |
| 4 | 4 | //@ only-aarch64 |
tests/pretty/float-trailing-dot.rs created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | //@ pp-exact | |
| 2 | ||
| 3 | fn main() { | |
| 4 | let _ = 0. ..45.; | |
| 5 | let _ = 0. ..=360.; | |
| 6 | let _ = 0. ..; | |
| 7 | let _ = 0. .to_string(); | |
| 8 | } |
tests/pretty/macro-fragment-specifier-whitespace.pp created+24| ... | ... | @@ -0,0 +1,24 @@ |
| 1 | #![feature(prelude_import)] | |
| 2 | #![no_std] | |
| 3 | extern crate std; | |
| 4 | #[prelude_import] | |
| 5 | use ::std::prelude::rust_2015::*; | |
| 6 | //@ pretty-mode:expanded | |
| 7 | //@ pp-exact:macro-fragment-specifier-whitespace.pp | |
| 8 | ||
| 9 | // Test that fragment specifier names in macro definitions are properly | |
| 10 | // separated from the following keyword/identifier token when pretty-printed. | |
| 11 | // This is a regression test for a bug where `$x:ident` followed by `where` | |
| 12 | // was pretty-printed as `$x:identwhere` (an invalid fragment specifier). | |
| 13 | ||
| 14 | macro_rules! outer { | |
| 15 | ($d:tt $($params:tt)*) => | |
| 16 | { | |
| 17 | #[macro_export] macro_rules! inner | |
| 18 | { ($($params)* where $d($rest:tt)*) => {}; } | |
| 19 | }; | |
| 20 | } | |
| 21 | #[macro_export] | |
| 22 | macro_rules! inner { ($x:ident where $ ($rest : tt)*) => {}; } | |
| 23 | ||
| 24 | fn main() {} |
tests/pretty/macro-fragment-specifier-whitespace.rs created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | //@ pretty-mode:expanded | |
| 2 | //@ pp-exact:macro-fragment-specifier-whitespace.pp | |
| 3 | ||
| 4 | // Test that fragment specifier names in macro definitions are properly | |
| 5 | // separated from the following keyword/identifier token when pretty-printed. | |
| 6 | // This is a regression test for a bug where `$x:ident` followed by `where` | |
| 7 | // was pretty-printed as `$x:identwhere` (an invalid fragment specifier). | |
| 8 | ||
| 9 | macro_rules! outer { | |
| 10 | ($d:tt $($params:tt)*) => { | |
| 11 | #[macro_export] | |
| 12 | macro_rules! inner { | |
| 13 | ($($params)* where $d($rest:tt)*) => {}; | |
| 14 | } | |
| 15 | }; | |
| 16 | } | |
| 17 | outer!($ $x:ident); | |
| 18 | ||
| 19 | fn main() {} |
tests/pretty/use-self-braces.rs created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | //@ pp-exact | |
| 2 | //@ edition:2021 | |
| 3 | ||
| 4 | #![allow(unused_imports)] | |
| 5 | ||
| 6 | // Braces around `self` must be preserved, because `use foo::self` is not valid Rust. | |
| 7 | use std::io::{self}; | |
| 8 | use std::fmt::{self, Debug}; | |
| 9 | ||
| 10 | fn main() {} |
tests/run-make/pointer-auth-link-with-c-lto-clang/rmake.rs+1| ... | ... | @@ -32,6 +32,7 @@ fn main() { |
| 32 | 32 | .opt_level("2") |
| 33 | 33 | .linker(&env_var("CLANG")) |
| 34 | 34 | .link_arg("-fuse-ld=lld") |
| 35 | .arg("-Cunsafe-allow-abi-mismatch=branch-protection") | |
| 35 | 36 | .arg("-Zbranch-protection=bti,gcs,pac-ret,leaf") |
| 36 | 37 | .input("test.rs") |
| 37 | 38 | .output("test.bin") |
tests/run-make/pointer-auth-link-with-c/rmake.rs+15-3| ... | ... | @@ -15,7 +15,11 @@ use run_make_support::{build_native_static_lib, cc, is_windows_msvc, llvm_ar, ru |
| 15 | 15 | |
| 16 | 16 | fn main() { |
| 17 | 17 | build_native_static_lib("test"); |
| 18 | rustc().arg("-Zbranch-protection=bti,gcs,pac-ret,leaf").input("test.rs").run(); | |
| 18 | rustc() | |
| 19 | .arg("-Cunsafe-allow-abi-mismatch=branch-protection") | |
| 20 | .arg("-Zbranch-protection=bti,gcs,pac-ret,leaf") | |
| 21 | .input("test.rs") | |
| 22 | .run(); | |
| 19 | 23 | run("test"); |
| 20 | 24 | cc().arg("-v") |
| 21 | 25 | .arg("-c") |
| ... | ... | @@ -25,7 +29,11 @@ fn main() { |
| 25 | 29 | .run(); |
| 26 | 30 | let obj_file = if is_windows_msvc() { "test.obj" } else { "test" }; |
| 27 | 31 | llvm_ar().obj_to_ar().output_input("libtest.a", &obj_file).run(); |
| 28 | rustc().arg("-Zbranch-protection=bti,gcs,pac-ret,leaf").input("test.rs").run(); | |
| 32 | rustc() | |
| 33 | .arg("-Cunsafe-allow-abi-mismatch=branch-protection") | |
| 34 | .arg("-Zbranch-protection=bti,gcs,pac-ret,leaf") | |
| 35 | .input("test.rs") | |
| 36 | .run(); | |
| 29 | 37 | run("test"); |
| 30 | 38 | |
| 31 | 39 | // FIXME: +pc was only recently added to LLVM |
| ... | ... | @@ -37,6 +45,10 @@ fn main() { |
| 37 | 45 | // .run(); |
| 38 | 46 | // let obj_file = if is_windows_msvc() { "test.obj" } else { "test" }; |
| 39 | 47 | // llvm_ar().obj_to_ar().output_input("libtest.a", &obj_file).run(); |
| 40 | // rustc().arg("-Zbranch-protection=bti,pac-ret,pc,leaf").input("test.rs").run(); | |
| 48 | // rustc() | |
| 49 | // .arg("-Cunsafe-allow-abi-mismatch=branch-protection") | |
| 50 | // .arg("-Zbranch-protection=bti,pac-ret,pc,leaf") | |
| 51 | // .input("test.rs") | |
| 52 | // .run(); | |
| 41 | 53 | // run("test"); |
| 42 | 54 | } |
tests/rustdoc-ui/lints/lint-missing-doc-code-example.rs+5-1| ... | ... | @@ -78,7 +78,11 @@ impl Clone for Struct { |
| 78 | 78 | } |
| 79 | 79 | } |
| 80 | 80 | |
| 81 | ||
| 81 | impl Struct { // No doc or code example and it's fine! | |
| 82 | pub fn bar() {} | |
| 83 | //~^ ERROR missing code example in this documentation | |
| 84 | //~| ERROR missing documentation for an associated function | |
| 85 | } | |
| 82 | 86 | |
| 83 | 87 | /// doc |
| 84 | 88 | /// |
tests/rustdoc-ui/lints/lint-missing-doc-code-example.stderr+19-1| ... | ... | @@ -1,3 +1,15 @@ |
| 1 | error: missing documentation for an associated function | |
| 2 | --> $DIR/lint-missing-doc-code-example.rs:82:5 | |
| 3 | | | |
| 4 | LL | pub fn bar() {} | |
| 5 | | ^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | note: the lint level is defined here | |
| 8 | --> $DIR/lint-missing-doc-code-example.rs:2:9 | |
| 9 | | | |
| 10 | LL | #![deny(missing_docs)] | |
| 11 | | ^^^^^^^^^^^^ | |
| 12 | ||
| 1 | 13 | error: missing code example in this documentation |
| 2 | 14 | --> $DIR/lint-missing-doc-code-example.rs:38:3 |
| 3 | 15 | | |
| ... | ... | @@ -28,5 +40,11 @@ error: missing code example in this documentation |
| 28 | 40 | LL | /// Doc |
| 29 | 41 | | ^^^^^^^ |
| 30 | 42 | |
| 31 | error: aborting due to 4 previous errors | |
| 43 | error: missing code example in this documentation | |
| 44 | --> $DIR/lint-missing-doc-code-example.rs:82:5 | |
| 45 | | | |
| 46 | LL | pub fn bar() {} | |
| 47 | | ^^^^^^^^^^^^^^^ | |
| 48 | ||
| 49 | error: aborting due to 6 previous errors | |
| 32 | 50 |
tests/ui/async-await/async-closures/unifying-function-types-involving-hrtb.rs created+33| ... | ... | @@ -0,0 +1,33 @@ |
| 1 | //! Regresssion test for <https://github.com/rust-lang/rust/issues/59337>. | |
| 2 | ||
| 3 | //@ edition:2018 | |
| 4 | //@ check-pass | |
| 5 | ||
| 6 | use std::future::Future; | |
| 7 | ||
| 8 | trait Foo<'a> { | |
| 9 | type Future: Future<Output = u8> + 'a; | |
| 10 | ||
| 11 | fn start(self, f: &'a u8) -> Self::Future; | |
| 12 | } | |
| 13 | ||
| 14 | impl<'a, Fn, Fut> Foo<'a> for Fn | |
| 15 | where | |
| 16 | Fn: FnOnce(&'a u8) -> Fut, | |
| 17 | Fut: Future<Output = u8> + 'a, | |
| 18 | { | |
| 19 | type Future = Fut; | |
| 20 | ||
| 21 | fn start(self, f: &'a u8) -> Self::Future { (self)(f) } | |
| 22 | } | |
| 23 | ||
| 24 | fn foo<F>(f: F) where F: for<'a> Foo<'a> { | |
| 25 | let bar = 5; | |
| 26 | f.start(&bar); | |
| 27 | } | |
| 28 | ||
| 29 | fn main() { | |
| 30 | foo(async move | f: &u8 | { *f }); | |
| 31 | ||
| 32 | foo({ async fn baz(f: &u8) -> u8 { *f } baz }); | |
| 33 | } |
tests/ui/diagnostic_namespace/on_move/auxiliary/other.rs created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | #![feature(diagnostic_on_move)] | |
| 2 | ||
| 3 | #[diagnostic::on_move( | |
| 4 | message = "Foo", | |
| 5 | label = "Bar", | |
| 6 | )] | |
| 7 | #[derive(Debug)] | |
| 8 | pub struct Foo; |
tests/ui/diagnostic_namespace/on_move/error_is_shown_in_downstream_crates.rs created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | //@ aux-build:other.rs | |
| 2 | ||
| 3 | extern crate other; | |
| 4 | ||
| 5 | use other::Foo; | |
| 6 | ||
| 7 | fn takes_foo(_: Foo) {} | |
| 8 | ||
| 9 | fn main() { | |
| 10 | let foo = Foo; | |
| 11 | takes_foo(foo); | |
| 12 | let bar = foo; | |
| 13 | //~^ERROR Foo | |
| 14 | } |
tests/ui/diagnostic_namespace/on_move/error_is_shown_in_downstream_crates.stderr created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | error[E0382]: Foo | |
| 2 | --> $DIR/error_is_shown_in_downstream_crates.rs:12:15 | |
| 3 | | | |
| 4 | LL | let foo = Foo; | |
| 5 | | --- Bar | |
| 6 | LL | takes_foo(foo); | |
| 7 | | --- value moved here | |
| 8 | LL | let bar = foo; | |
| 9 | | ^^^ value used here after move | |
| 10 | | | |
| 11 | note: consider changing this parameter type in function `takes_foo` to borrow instead if owning the value isn't necessary | |
| 12 | --> $DIR/error_is_shown_in_downstream_crates.rs:7:17 | |
| 13 | | | |
| 14 | LL | fn takes_foo(_: Foo) {} | |
| 15 | | --------- ^^^ this parameter takes ownership of the value | |
| 16 | | | | |
| 17 | | in this function | |
| 18 | ||
| 19 | error: aborting due to 1 previous error | |
| 20 | ||
| 21 | For more information about this error, try `rustc --explain E0382`. |
tests/ui/diagnostic_namespace/on_move/on_move_simple.rs created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | #![feature(diagnostic_on_move)] | |
| 2 | ||
| 3 | #[diagnostic::on_move( | |
| 4 | message = "Foo", | |
| 5 | label = "Bar", | |
| 6 | )] | |
| 7 | #[derive(Debug)] | |
| 8 | struct Foo; | |
| 9 | ||
| 10 | fn takes_foo(_: Foo) {} | |
| 11 | ||
| 12 | fn main() { | |
| 13 | let foo = Foo; | |
| 14 | takes_foo(foo); | |
| 15 | let bar = foo; | |
| 16 | //~^ERROR Foo | |
| 17 | } |
tests/ui/diagnostic_namespace/on_move/on_move_simple.stderr created+29| ... | ... | @@ -0,0 +1,29 @@ |
| 1 | error[E0382]: Foo | |
| 2 | --> $DIR/on_move_simple.rs:15:15 | |
| 3 | | | |
| 4 | LL | let foo = Foo; | |
| 5 | | --- Bar | |
| 6 | LL | takes_foo(foo); | |
| 7 | | --- value moved here | |
| 8 | LL | let bar = foo; | |
| 9 | | ^^^ value used here after move | |
| 10 | | | |
| 11 | note: consider changing this parameter type in function `takes_foo` to borrow instead if owning the value isn't necessary | |
| 12 | --> $DIR/on_move_simple.rs:10:17 | |
| 13 | | | |
| 14 | LL | fn takes_foo(_: Foo) {} | |
| 15 | | --------- ^^^ this parameter takes ownership of the value | |
| 16 | | | | |
| 17 | | in this function | |
| 18 | note: if `Foo` implemented `Clone`, you could clone the value | |
| 19 | --> $DIR/on_move_simple.rs:8:1 | |
| 20 | | | |
| 21 | LL | struct Foo; | |
| 22 | | ^^^^^^^^^^ consider implementing `Clone` for this type | |
| 23 | ... | |
| 24 | LL | takes_foo(foo); | |
| 25 | | --- you could clone this value | |
| 26 | ||
| 27 | error: aborting due to 1 previous error | |
| 28 | ||
| 29 | For more information about this error, try `rustc --explain E0382`. |
tests/ui/diagnostic_namespace/on_move/on_move_with_format.rs created+32| ... | ... | @@ -0,0 +1,32 @@ |
| 1 | #![feature(diagnostic_on_move)] | |
| 2 | ||
| 3 | #[diagnostic::on_move( | |
| 4 | message = "Foo for {Self}", | |
| 5 | label = "Bar for {Self}", | |
| 6 | )] | |
| 7 | #[derive(Debug)] | |
| 8 | struct Foo; | |
| 9 | ||
| 10 | #[diagnostic::on_move( | |
| 11 | message="Foo for {X}", | |
| 12 | label="Bar for {X}", | |
| 13 | )] | |
| 14 | struct MyType<X> { | |
| 15 | _x: X, | |
| 16 | } | |
| 17 | ||
| 18 | fn takes_foo(_: Foo) {} | |
| 19 | ||
| 20 | fn takes_mytype<X>(_: MyType<X>) {} | |
| 21 | ||
| 22 | fn main() { | |
| 23 | let foo = Foo; | |
| 24 | takes_foo(foo); | |
| 25 | let bar = foo; | |
| 26 | //~^ERROR Foo for Foo | |
| 27 | ||
| 28 | let mytype = MyType { _x: 0 }; | |
| 29 | takes_mytype(mytype); | |
| 30 | let baz = mytype; | |
| 31 | //~^ERROR Foo for i32 | |
| 32 | } |
tests/ui/diagnostic_namespace/on_move/on_move_with_format.stderr created+55| ... | ... | @@ -0,0 +1,55 @@ |
| 1 | error[E0382]: Foo for Foo | |
| 2 | --> $DIR/on_move_with_format.rs:25:15 | |
| 3 | | | |
| 4 | LL | let foo = Foo; | |
| 5 | | --- Bar for Foo | |
| 6 | LL | takes_foo(foo); | |
| 7 | | --- value moved here | |
| 8 | LL | let bar = foo; | |
| 9 | | ^^^ value used here after move | |
| 10 | | | |
| 11 | note: consider changing this parameter type in function `takes_foo` to borrow instead if owning the value isn't necessary | |
| 12 | --> $DIR/on_move_with_format.rs:18:17 | |
| 13 | | | |
| 14 | LL | fn takes_foo(_: Foo) {} | |
| 15 | | --------- ^^^ this parameter takes ownership of the value | |
| 16 | | | | |
| 17 | | in this function | |
| 18 | note: if `Foo` implemented `Clone`, you could clone the value | |
| 19 | --> $DIR/on_move_with_format.rs:8:1 | |
| 20 | | | |
| 21 | LL | struct Foo; | |
| 22 | | ^^^^^^^^^^ consider implementing `Clone` for this type | |
| 23 | ... | |
| 24 | LL | takes_foo(foo); | |
| 25 | | --- you could clone this value | |
| 26 | ||
| 27 | error[E0382]: Foo for i32 | |
| 28 | --> $DIR/on_move_with_format.rs:30:15 | |
| 29 | | | |
| 30 | LL | let mytype = MyType { _x: 0 }; | |
| 31 | | ------ Bar for i32 | |
| 32 | LL | takes_mytype(mytype); | |
| 33 | | ------ value moved here | |
| 34 | LL | let baz = mytype; | |
| 35 | | ^^^^^^ value used here after move | |
| 36 | | | |
| 37 | note: consider changing this parameter type in function `takes_mytype` to borrow instead if owning the value isn't necessary | |
| 38 | --> $DIR/on_move_with_format.rs:20:23 | |
| 39 | | | |
| 40 | LL | fn takes_mytype<X>(_: MyType<X>) {} | |
| 41 | | ------------ ^^^^^^^^^ this parameter takes ownership of the value | |
| 42 | | | | |
| 43 | | in this function | |
| 44 | note: if `MyType<i32>` implemented `Clone`, you could clone the value | |
| 45 | --> $DIR/on_move_with_format.rs:14:1 | |
| 46 | | | |
| 47 | LL | struct MyType<X> { | |
| 48 | | ^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type | |
| 49 | ... | |
| 50 | LL | takes_mytype(mytype); | |
| 51 | | ------ you could clone this value | |
| 52 | ||
| 53 | error: aborting due to 2 previous errors | |
| 54 | ||
| 55 | For more information about this error, try `rustc --explain E0382`. |
tests/ui/diagnostic_namespace/on_move/report_warning_on_duplicated_options.rs created+22| ... | ... | @@ -0,0 +1,22 @@ |
| 1 | #![feature(diagnostic_on_move)] | |
| 2 | ||
| 3 | #[diagnostic::on_move( | |
| 4 | message = "first message", | |
| 5 | label = "first label", | |
| 6 | )] | |
| 7 | #[diagnostic::on_move( | |
| 8 | message = "second message", | |
| 9 | //~^ WARN `message` is ignored due to previous definition of `message` [malformed_diagnostic_attributes] | |
| 10 | label = "second label", | |
| 11 | //~^ WARN `label` is ignored due to previous definition of `label` [malformed_diagnostic_attributes] | |
| 12 | )] | |
| 13 | struct Foo; | |
| 14 | ||
| 15 | fn takes_foo(_: Foo) {} | |
| 16 | ||
| 17 | fn main() { | |
| 18 | let foo = Foo; | |
| 19 | takes_foo(foo); | |
| 20 | let bar = foo; | |
| 21 | //~^ERROR first message | |
| 22 | } |
tests/ui/diagnostic_namespace/on_move/report_warning_on_duplicated_options.stderr created+49| ... | ... | @@ -0,0 +1,49 @@ |
| 1 | warning: `message` is ignored due to previous definition of `message` | |
| 2 | --> $DIR/report_warning_on_duplicated_options.rs:8:5 | |
| 3 | | | |
| 4 | LL | message = "first message", | |
| 5 | | ------------------------- `message` is first declared here | |
| 6 | ... | |
| 7 | LL | message = "second message", | |
| 8 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `message` is later redundantly declared here | |
| 9 | | | |
| 10 | = note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default | |
| 11 | ||
| 12 | warning: `label` is ignored due to previous definition of `label` | |
| 13 | --> $DIR/report_warning_on_duplicated_options.rs:10:5 | |
| 14 | | | |
| 15 | LL | label = "first label", | |
| 16 | | --------------------- `label` is first declared here | |
| 17 | ... | |
| 18 | LL | label = "second label", | |
| 19 | | ^^^^^^^^^^^^^^^^^^^^^^ `label` is later redundantly declared here | |
| 20 | ||
| 21 | error[E0382]: first message | |
| 22 | --> $DIR/report_warning_on_duplicated_options.rs:20:15 | |
| 23 | | | |
| 24 | LL | let foo = Foo; | |
| 25 | | --- first label | |
| 26 | LL | takes_foo(foo); | |
| 27 | | --- value moved here | |
| 28 | LL | let bar = foo; | |
| 29 | | ^^^ value used here after move | |
| 30 | | | |
| 31 | note: consider changing this parameter type in function `takes_foo` to borrow instead if owning the value isn't necessary | |
| 32 | --> $DIR/report_warning_on_duplicated_options.rs:15:17 | |
| 33 | | | |
| 34 | LL | fn takes_foo(_: Foo) {} | |
| 35 | | --------- ^^^ this parameter takes ownership of the value | |
| 36 | | | | |
| 37 | | in this function | |
| 38 | note: if `Foo` implemented `Clone`, you could clone the value | |
| 39 | --> $DIR/report_warning_on_duplicated_options.rs:13:1 | |
| 40 | | | |
| 41 | LL | struct Foo; | |
| 42 | | ^^^^^^^^^^ consider implementing `Clone` for this type | |
| 43 | ... | |
| 44 | LL | takes_foo(foo); | |
| 45 | | --- you could clone this value | |
| 46 | ||
| 47 | error: aborting due to 1 previous error; 2 warnings emitted | |
| 48 | ||
| 49 | For more information about this error, try `rustc --explain E0382`. |
tests/ui/diagnostic_namespace/on_move/report_warning_on_invalid_formats.rs created+18| ... | ... | @@ -0,0 +1,18 @@ |
| 1 | #![feature(diagnostic_on_move)] | |
| 2 | ||
| 3 | #[diagnostic::on_move( | |
| 4 | message = "Foo {Baz}", | |
| 5 | //~^WARN unknown parameter `Baz` | |
| 6 | label = "Bar", | |
| 7 | )] | |
| 8 | #[derive(Debug)] | |
| 9 | struct Foo; | |
| 10 | ||
| 11 | fn takes_foo(_: Foo) {} | |
| 12 | ||
| 13 | fn main() { | |
| 14 | let foo = Foo; | |
| 15 | takes_foo(foo); | |
| 16 | let bar = foo; | |
| 17 | //~^ERROR Foo | |
| 18 | } |
tests/ui/diagnostic_namespace/on_move/report_warning_on_invalid_formats.stderr created+38| ... | ... | @@ -0,0 +1,38 @@ |
| 1 | warning: unknown parameter `Baz` | |
| 2 | --> $DIR/report_warning_on_invalid_formats.rs:4:21 | |
| 3 | | | |
| 4 | LL | message = "Foo {Baz}", | |
| 5 | | ^^^ | |
| 6 | | | |
| 7 | = help: expect either a generic argument name or `{Self}` as format argument | |
| 8 | = note: `#[warn(malformed_diagnostic_format_literals)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default | |
| 9 | ||
| 10 | error[E0382]: Foo {Baz} | |
| 11 | --> $DIR/report_warning_on_invalid_formats.rs:16:15 | |
| 12 | | | |
| 13 | LL | let foo = Foo; | |
| 14 | | --- Bar | |
| 15 | LL | takes_foo(foo); | |
| 16 | | --- value moved here | |
| 17 | LL | let bar = foo; | |
| 18 | | ^^^ value used here after move | |
| 19 | | | |
| 20 | note: consider changing this parameter type in function `takes_foo` to borrow instead if owning the value isn't necessary | |
| 21 | --> $DIR/report_warning_on_invalid_formats.rs:11:17 | |
| 22 | | | |
| 23 | LL | fn takes_foo(_: Foo) {} | |
| 24 | | --------- ^^^ this parameter takes ownership of the value | |
| 25 | | | | |
| 26 | | in this function | |
| 27 | note: if `Foo` implemented `Clone`, you could clone the value | |
| 28 | --> $DIR/report_warning_on_invalid_formats.rs:9:1 | |
| 29 | | | |
| 30 | LL | struct Foo; | |
| 31 | | ^^^^^^^^^^ consider implementing `Clone` for this type | |
| 32 | ... | |
| 33 | LL | takes_foo(foo); | |
| 34 | | --- you could clone this value | |
| 35 | ||
| 36 | error: aborting due to 1 previous error; 1 warning emitted | |
| 37 | ||
| 38 | For more information about this error, try `rustc --explain E0382`. |
tests/ui/diagnostic_namespace/on_move/report_warning_on_invalid_meta_item_syntax.rs created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | #![feature(diagnostic_on_move)] | |
| 2 | ||
| 3 | #[diagnostic::on_move = "foo"] | |
| 4 | //~^WARN missing options for `on_move` attribute [malformed_diagnostic_attributes] | |
| 5 | struct Foo; | |
| 6 | ||
| 7 | fn takes_foo(_: Foo) {} | |
| 8 | ||
| 9 | fn main() { | |
| 10 | let foo = Foo; | |
| 11 | takes_foo(foo); | |
| 12 | let bar = foo; | |
| 13 | //~^ERROR use of moved value: `foo` | |
| 14 | } |
tests/ui/diagnostic_namespace/on_move/report_warning_on_invalid_meta_item_syntax.stderr created+38| ... | ... | @@ -0,0 +1,38 @@ |
| 1 | warning: missing options for `on_move` attribute | |
| 2 | --> $DIR/report_warning_on_invalid_meta_item_syntax.rs:3:1 | |
| 3 | | | |
| 4 | LL | #[diagnostic::on_move = "foo"] | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | = help: at least one of the `message`, `note` and `label` options are expected | |
| 8 | = note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default | |
| 9 | ||
| 10 | error[E0382]: use of moved value: `foo` | |
| 11 | --> $DIR/report_warning_on_invalid_meta_item_syntax.rs:12:15 | |
| 12 | | | |
| 13 | LL | let foo = Foo; | |
| 14 | | --- move occurs because `foo` has type `Foo`, which does not implement the `Copy` trait | |
| 15 | LL | takes_foo(foo); | |
| 16 | | --- value moved here | |
| 17 | LL | let bar = foo; | |
| 18 | | ^^^ value used here after move | |
| 19 | | | |
| 20 | note: consider changing this parameter type in function `takes_foo` to borrow instead if owning the value isn't necessary | |
| 21 | --> $DIR/report_warning_on_invalid_meta_item_syntax.rs:7:17 | |
| 22 | | | |
| 23 | LL | fn takes_foo(_: Foo) {} | |
| 24 | | --------- ^^^ this parameter takes ownership of the value | |
| 25 | | | | |
| 26 | | in this function | |
| 27 | note: if `Foo` implemented `Clone`, you could clone the value | |
| 28 | --> $DIR/report_warning_on_invalid_meta_item_syntax.rs:5:1 | |
| 29 | | | |
| 30 | LL | struct Foo; | |
| 31 | | ^^^^^^^^^^ consider implementing `Clone` for this type | |
| 32 | ... | |
| 33 | LL | takes_foo(foo); | |
| 34 | | --- you could clone this value | |
| 35 | ||
| 36 | error: aborting due to 1 previous error; 1 warning emitted | |
| 37 | ||
| 38 | For more information about this error, try `rustc --explain E0382`. |
tests/ui/diagnostic_namespace/on_move/report_warning_on_malformed_options_without_delimiters.rs created+18| ... | ... | @@ -0,0 +1,18 @@ |
| 1 | #![feature(diagnostic_on_move)] | |
| 2 | ||
| 3 | #[diagnostic::on_move( | |
| 4 | //~^ WARN expected a literal or missing delimiter [malformed_diagnostic_attributes] | |
| 5 | //~| HELP only literals are allowed as values for the `message`, `note` and `label` options. These options must be separated by a comma | |
| 6 | message = "Foo" | |
| 7 | label = "Bar", | |
| 8 | )] | |
| 9 | struct Foo; | |
| 10 | ||
| 11 | fn takes_foo(_: Foo) {} | |
| 12 | ||
| 13 | fn main() { | |
| 14 | let foo = Foo; | |
| 15 | takes_foo(foo); | |
| 16 | let bar = foo; | |
| 17 | //~^ERROR use of moved value: `foo` | |
| 18 | } |
tests/ui/diagnostic_namespace/on_move/report_warning_on_malformed_options_without_delimiters.stderr created+44| ... | ... | @@ -0,0 +1,44 @@ |
| 1 | warning: expected a literal or missing delimiter | |
| 2 | --> $DIR/report_warning_on_malformed_options_without_delimiters.rs:3:22 | |
| 3 | | | |
| 4 | LL | #[diagnostic::on_move( | |
| 5 | | ______________________^ | |
| 6 | LL | | | |
| 7 | LL | | | |
| 8 | LL | | message = "Foo" | |
| 9 | LL | | label = "Bar", | |
| 10 | LL | | )] | |
| 11 | | |_^ | |
| 12 | | | |
| 13 | = help: only literals are allowed as values for the `message`, `note` and `label` options. These options must be separated by a comma | |
| 14 | = note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default | |
| 15 | ||
| 16 | error[E0382]: use of moved value: `foo` | |
| 17 | --> $DIR/report_warning_on_malformed_options_without_delimiters.rs:16:15 | |
| 18 | | | |
| 19 | LL | let foo = Foo; | |
| 20 | | --- move occurs because `foo` has type `Foo`, which does not implement the `Copy` trait | |
| 21 | LL | takes_foo(foo); | |
| 22 | | --- value moved here | |
| 23 | LL | let bar = foo; | |
| 24 | | ^^^ value used here after move | |
| 25 | | | |
| 26 | note: consider changing this parameter type in function `takes_foo` to borrow instead if owning the value isn't necessary | |
| 27 | --> $DIR/report_warning_on_malformed_options_without_delimiters.rs:11:17 | |
| 28 | | | |
| 29 | LL | fn takes_foo(_: Foo) {} | |
| 30 | | --------- ^^^ this parameter takes ownership of the value | |
| 31 | | | | |
| 32 | | in this function | |
| 33 | note: if `Foo` implemented `Clone`, you could clone the value | |
| 34 | --> $DIR/report_warning_on_malformed_options_without_delimiters.rs:9:1 | |
| 35 | | | |
| 36 | LL | struct Foo; | |
| 37 | | ^^^^^^^^^^ consider implementing `Clone` for this type | |
| 38 | ... | |
| 39 | LL | takes_foo(foo); | |
| 40 | | --- you could clone this value | |
| 41 | ||
| 42 | error: aborting due to 1 previous error; 1 warning emitted | |
| 43 | ||
| 44 | For more information about this error, try `rustc --explain E0382`. |
tests/ui/diagnostic_namespace/on_move/report_warning_on_malformed_options_without_literals.rs created+18| ... | ... | @@ -0,0 +1,18 @@ |
| 1 | #![feature(diagnostic_on_move)] | |
| 2 | ||
| 3 | #[diagnostic::on_move( | |
| 4 | //~^ WARN expected a literal or missing delimiter [malformed_diagnostic_attributes] | |
| 5 | //~| HELP only literals are allowed as values for the `message`, `note` and `label` options. These options must be separated by a comma | |
| 6 | message = Foo, | |
| 7 | label = "Bar", | |
| 8 | )] | |
| 9 | struct Foo; | |
| 10 | ||
| 11 | fn takes_foo(_: Foo) {} | |
| 12 | ||
| 13 | fn main() { | |
| 14 | let foo = Foo; | |
| 15 | takes_foo(foo); | |
| 16 | let bar = foo; | |
| 17 | //~^ERROR use of moved value: `foo` | |
| 18 | } |
tests/ui/diagnostic_namespace/on_move/report_warning_on_malformed_options_without_literals.stderr created+44| ... | ... | @@ -0,0 +1,44 @@ |
| 1 | warning: expected a literal or missing delimiter | |
| 2 | --> $DIR/report_warning_on_malformed_options_without_literals.rs:3:22 | |
| 3 | | | |
| 4 | LL | #[diagnostic::on_move( | |
| 5 | | ______________________^ | |
| 6 | LL | | | |
| 7 | LL | | | |
| 8 | LL | | message = Foo, | |
| 9 | LL | | label = "Bar", | |
| 10 | LL | | )] | |
| 11 | | |_^ | |
| 12 | | | |
| 13 | = help: only literals are allowed as values for the `message`, `note` and `label` options. These options must be separated by a comma | |
| 14 | = note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default | |
| 15 | ||
| 16 | error[E0382]: use of moved value: `foo` | |
| 17 | --> $DIR/report_warning_on_malformed_options_without_literals.rs:16:15 | |
| 18 | | | |
| 19 | LL | let foo = Foo; | |
| 20 | | --- move occurs because `foo` has type `Foo`, which does not implement the `Copy` trait | |
| 21 | LL | takes_foo(foo); | |
| 22 | | --- value moved here | |
| 23 | LL | let bar = foo; | |
| 24 | | ^^^ value used here after move | |
| 25 | | | |
| 26 | note: consider changing this parameter type in function `takes_foo` to borrow instead if owning the value isn't necessary | |
| 27 | --> $DIR/report_warning_on_malformed_options_without_literals.rs:11:17 | |
| 28 | | | |
| 29 | LL | fn takes_foo(_: Foo) {} | |
| 30 | | --------- ^^^ this parameter takes ownership of the value | |
| 31 | | | | |
| 32 | | in this function | |
| 33 | note: if `Foo` implemented `Clone`, you could clone the value | |
| 34 | --> $DIR/report_warning_on_malformed_options_without_literals.rs:9:1 | |
| 35 | | | |
| 36 | LL | struct Foo; | |
| 37 | | ^^^^^^^^^^ consider implementing `Clone` for this type | |
| 38 | ... | |
| 39 | LL | takes_foo(foo); | |
| 40 | | --- you could clone this value | |
| 41 | ||
| 42 | error: aborting due to 1 previous error; 1 warning emitted | |
| 43 | ||
| 44 | For more information about this error, try `rustc --explain E0382`. |
tests/ui/diagnostic_namespace/on_move/report_warning_on_missing_options.rs created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | #![feature(diagnostic_on_move)] | |
| 2 | ||
| 3 | #[diagnostic::on_move] | |
| 4 | //~^WARN missing options for `on_move` attribute [malformed_diagnostic_attributes] | |
| 5 | struct Foo; | |
| 6 | ||
| 7 | fn takes_foo(_: Foo) {} | |
| 8 | ||
| 9 | fn main() { | |
| 10 | let foo = Foo; | |
| 11 | takes_foo(foo); | |
| 12 | let bar = foo; | |
| 13 | //~^ERROR use of moved value: `foo` | |
| 14 | } |
tests/ui/diagnostic_namespace/on_move/report_warning_on_missing_options.stderr created+38| ... | ... | @@ -0,0 +1,38 @@ |
| 1 | warning: missing options for `on_move` attribute | |
| 2 | --> $DIR/report_warning_on_missing_options.rs:3:1 | |
| 3 | | | |
| 4 | LL | #[diagnostic::on_move] | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | = help: at least one of the `message`, `note` and `label` options are expected | |
| 8 | = note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default | |
| 9 | ||
| 10 | error[E0382]: use of moved value: `foo` | |
| 11 | --> $DIR/report_warning_on_missing_options.rs:12:15 | |
| 12 | | | |
| 13 | LL | let foo = Foo; | |
| 14 | | --- move occurs because `foo` has type `Foo`, which does not implement the `Copy` trait | |
| 15 | LL | takes_foo(foo); | |
| 16 | | --- value moved here | |
| 17 | LL | let bar = foo; | |
| 18 | | ^^^ value used here after move | |
| 19 | | | |
| 20 | note: consider changing this parameter type in function `takes_foo` to borrow instead if owning the value isn't necessary | |
| 21 | --> $DIR/report_warning_on_missing_options.rs:7:17 | |
| 22 | | | |
| 23 | LL | fn takes_foo(_: Foo) {} | |
| 24 | | --------- ^^^ this parameter takes ownership of the value | |
| 25 | | | | |
| 26 | | in this function | |
| 27 | note: if `Foo` implemented `Clone`, you could clone the value | |
| 28 | --> $DIR/report_warning_on_missing_options.rs:5:1 | |
| 29 | | | |
| 30 | LL | struct Foo; | |
| 31 | | ^^^^^^^^^^ consider implementing `Clone` for this type | |
| 32 | ... | |
| 33 | LL | takes_foo(foo); | |
| 34 | | --- you could clone this value | |
| 35 | ||
| 36 | error: aborting due to 1 previous error; 1 warning emitted | |
| 37 | ||
| 38 | For more information about this error, try `rustc --explain E0382`. |
tests/ui/diagnostic_namespace/on_move/report_warning_on_non_adt.rs created+23| ... | ... | @@ -0,0 +1,23 @@ |
| 1 | #![feature(diagnostic_on_move)] | |
| 2 | ||
| 3 | #[diagnostic::on_move( | |
| 4 | message = "Foo", | |
| 5 | label = "Bar", | |
| 6 | )] | |
| 7 | struct Foo; | |
| 8 | ||
| 9 | #[diagnostic::on_move( | |
| 10 | //~^WARN `#[diagnostic::on_move]` can only be applied to enums, structs or unions | |
| 11 | message = "Foo", | |
| 12 | label = "Bar", | |
| 13 | )] | |
| 14 | trait MyTrait {} | |
| 15 | ||
| 16 | fn takes_foo(_: Foo) {} | |
| 17 | ||
| 18 | fn main() { | |
| 19 | let foo = Foo; | |
| 20 | takes_foo(foo); | |
| 21 | let bar = foo; | |
| 22 | //~^ERROR Foo | |
| 23 | } |
tests/ui/diagnostic_namespace/on_move/report_warning_on_non_adt.stderr created+41| ... | ... | @@ -0,0 +1,41 @@ |
| 1 | warning: `#[diagnostic::on_move]` can only be applied to enums, structs or unions | |
| 2 | --> $DIR/report_warning_on_non_adt.rs:9:1 | |
| 3 | | | |
| 4 | LL | / #[diagnostic::on_move( | |
| 5 | LL | | | |
| 6 | LL | | message = "Foo", | |
| 7 | LL | | label = "Bar", | |
| 8 | LL | | )] | |
| 9 | | |__^ | |
| 10 | | | |
| 11 | = note: `#[warn(misplaced_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default | |
| 12 | ||
| 13 | error[E0382]: Foo | |
| 14 | --> $DIR/report_warning_on_non_adt.rs:21:15 | |
| 15 | | | |
| 16 | LL | let foo = Foo; | |
| 17 | | --- Bar | |
| 18 | LL | takes_foo(foo); | |
| 19 | | --- value moved here | |
| 20 | LL | let bar = foo; | |
| 21 | | ^^^ value used here after move | |
| 22 | | | |
| 23 | note: consider changing this parameter type in function `takes_foo` to borrow instead if owning the value isn't necessary | |
| 24 | --> $DIR/report_warning_on_non_adt.rs:16:17 | |
| 25 | | | |
| 26 | LL | fn takes_foo(_: Foo) {} | |
| 27 | | --------- ^^^ this parameter takes ownership of the value | |
| 28 | | | | |
| 29 | | in this function | |
| 30 | note: if `Foo` implemented `Clone`, you could clone the value | |
| 31 | --> $DIR/report_warning_on_non_adt.rs:7:1 | |
| 32 | | | |
| 33 | LL | struct Foo; | |
| 34 | | ^^^^^^^^^^ consider implementing `Clone` for this type | |
| 35 | ... | |
| 36 | LL | takes_foo(foo); | |
| 37 | | --- you could clone this value | |
| 38 | ||
| 39 | error: aborting due to 1 previous error; 1 warning emitted | |
| 40 | ||
| 41 | For more information about this error, try `rustc --explain E0382`. |
tests/ui/diagnostic_namespace/on_move/report_warning_on_unknown_options.rs created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | #![feature(diagnostic_on_move)] | |
| 2 | ||
| 3 | #[diagnostic::on_move( | |
| 4 | message = "Foo", | |
| 5 | label = "Bar", | |
| 6 | baz="Baz" | |
| 7 | //~^WARN unknown or malformed `on_move` attribute | |
| 8 | //~|HELP only `message`, `note` and `label` are allowed as options. Their values must be string literals | |
| 9 | )] | |
| 10 | struct Foo; | |
| 11 | ||
| 12 | fn takes_foo(_: Foo) {} | |
| 13 | ||
| 14 | fn main() { | |
| 15 | let foo = Foo; | |
| 16 | takes_foo(foo); | |
| 17 | let bar = foo; | |
| 18 | //~^ERROR Foo | |
| 19 | } |
tests/ui/diagnostic_namespace/on_move/report_warning_on_unknown_options.stderr created+38| ... | ... | @@ -0,0 +1,38 @@ |
| 1 | warning: unknown or malformed `on_move` attribute | |
| 2 | --> $DIR/report_warning_on_unknown_options.rs:6:5 | |
| 3 | | | |
| 4 | LL | baz="Baz" | |
| 5 | | ^^^^^^^^^ invalid option found here | |
| 6 | | | |
| 7 | = help: only `message`, `note` and `label` are allowed as options. Their values must be string literals | |
| 8 | = note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default | |
| 9 | ||
| 10 | error[E0382]: Foo | |
| 11 | --> $DIR/report_warning_on_unknown_options.rs:17:15 | |
| 12 | | | |
| 13 | LL | let foo = Foo; | |
| 14 | | --- Bar | |
| 15 | LL | takes_foo(foo); | |
| 16 | | --- value moved here | |
| 17 | LL | let bar = foo; | |
| 18 | | ^^^ value used here after move | |
| 19 | | | |
| 20 | note: consider changing this parameter type in function `takes_foo` to borrow instead if owning the value isn't necessary | |
| 21 | --> $DIR/report_warning_on_unknown_options.rs:12:17 | |
| 22 | | | |
| 23 | LL | fn takes_foo(_: Foo) {} | |
| 24 | | --------- ^^^ this parameter takes ownership of the value | |
| 25 | | | | |
| 26 | | in this function | |
| 27 | note: if `Foo` implemented `Clone`, you could clone the value | |
| 28 | --> $DIR/report_warning_on_unknown_options.rs:10:1 | |
| 29 | | | |
| 30 | LL | struct Foo; | |
| 31 | | ^^^^^^^^^^ consider implementing `Clone` for this type | |
| 32 | ... | |
| 33 | LL | takes_foo(foo); | |
| 34 | | --- you could clone this value | |
| 35 | ||
| 36 | error: aborting due to 1 previous error; 1 warning emitted | |
| 37 | ||
| 38 | For more information about this error, try `rustc --explain E0382`. |
tests/ui/feature-gates/feature-gate-diagnostic-on-move.rs created+18| ... | ... | @@ -0,0 +1,18 @@ |
| 1 | //! This is an unusual feature gate test, as it doesn't test the feature | |
| 2 | //! gate, but the fact that not adding the feature gate will cause the | |
| 3 | //! diagnostic to not emit the custom diagnostic message | |
| 4 | //! | |
| 5 | #[diagnostic::on_move( | |
| 6 | message = "Foo" | |
| 7 | )] | |
| 8 | #[derive(Debug)] | |
| 9 | struct Foo; | |
| 10 | ||
| 11 | fn takes_foo(_: Foo) {} | |
| 12 | ||
| 13 | fn main() { | |
| 14 | let foo = Foo; | |
| 15 | takes_foo(foo); | |
| 16 | let bar = foo; | |
| 17 | //~^ERROR use of moved value: `foo` | |
| 18 | } |
tests/ui/feature-gates/feature-gate-diagnostic-on-move.stderr created+29| ... | ... | @@ -0,0 +1,29 @@ |
| 1 | error[E0382]: use of moved value: `foo` | |
| 2 | --> $DIR/feature-gate-diagnostic-on-move.rs:16:15 | |
| 3 | | | |
| 4 | LL | let foo = Foo; | |
| 5 | | --- move occurs because `foo` has type `Foo`, which does not implement the `Copy` trait | |
| 6 | LL | takes_foo(foo); | |
| 7 | | --- value moved here | |
| 8 | LL | let bar = foo; | |
| 9 | | ^^^ value used here after move | |
| 10 | | | |
| 11 | note: consider changing this parameter type in function `takes_foo` to borrow instead if owning the value isn't necessary | |
| 12 | --> $DIR/feature-gate-diagnostic-on-move.rs:11:17 | |
| 13 | | | |
| 14 | LL | fn takes_foo(_: Foo) {} | |
| 15 | | --------- ^^^ this parameter takes ownership of the value | |
| 16 | | | | |
| 17 | | in this function | |
| 18 | note: if `Foo` implemented `Clone`, you could clone the value | |
| 19 | --> $DIR/feature-gate-diagnostic-on-move.rs:9:1 | |
| 20 | | | |
| 21 | LL | struct Foo; | |
| 22 | | ^^^^^^^^^^ consider implementing `Clone` for this type | |
| 23 | ... | |
| 24 | LL | takes_foo(foo); | |
| 25 | | --- you could clone this value | |
| 26 | ||
| 27 | error: aborting due to 1 previous error | |
| 28 | ||
| 29 | For more information about this error, try `rustc --explain E0382`. |
tests/ui/impl-restriction/restriction_resolution_errors.rs created+85| ... | ... | @@ -0,0 +1,85 @@ |
| 1 | #![feature(impl_restriction)] | |
| 2 | #![expect(incomplete_features)] | |
| 3 | ||
| 4 | pub mod a { | |
| 5 | pub enum E {} | |
| 6 | pub mod d {} | |
| 7 | pub mod b { | |
| 8 | pub mod c {} | |
| 9 | ||
| 10 | // We do not use crate-relative paths here, since we follow the | |
| 11 | // "uniform paths" approach used for type/expression paths. | |
| 12 | pub impl(in a::b) trait T1 {} //~ ERROR cannot find module or crate `a` in this scope [E0433] | |
| 13 | ||
| 14 | pub impl(in ::std) trait T2 {} //~ ERROR trait implementation can only be restricted to ancestor modules | |
| 15 | ||
| 16 | pub impl(in self::c) trait T3 {} //~ ERROR trait implementation can only be restricted to ancestor modules | |
| 17 | ||
| 18 | pub impl(in super::d) trait T4 {} //~ ERROR trait implementation can only be restricted to ancestor modules | |
| 19 | ||
| 20 | pub impl(in crate::c) trait T5 {} //~ ERROR cannot find module `c` in the crate root [E0433] | |
| 21 | ||
| 22 | pub impl(in super::E) trait T6 {} //~ ERROR expected module, found enum `super::E` [E0577] | |
| 23 | ||
| 24 | pub impl(in super::super::super) trait T7 {} //~ ERROR too many leading `super` keywords [E0433] | |
| 25 | ||
| 26 | // OK paths | |
| 27 | pub impl(crate) trait T8 {} | |
| 28 | pub impl(self) trait T9 {} | |
| 29 | pub impl(super) trait T10 {} | |
| 30 | pub impl(in crate::a) trait T11 {} | |
| 31 | pub impl(in super::super) trait T12 {} | |
| 32 | ||
| 33 | // Check if we can resolve paths referring to modules declared later. | |
| 34 | pub impl(in self::f) trait L1 {} //~ ERROR trait implementation can only be restricted to ancestor modules | |
| 35 | ||
| 36 | pub impl(in super::G) trait L2 {} //~ ERROR expected module, found enum `super::G` [E0577] | |
| 37 | ||
| 38 | pub impl(in super::h) trait L3 {} //~ ERROR trait implementation can only be restricted to ancestor modules | |
| 39 | ||
| 40 | pub mod f {} | |
| 41 | } | |
| 42 | ||
| 43 | pub enum G {} | |
| 44 | pub mod h {} | |
| 45 | } | |
| 46 | ||
| 47 | pub impl(in crate::a) trait T13 {} //~ ERROR trait implementation can only be restricted to ancestor modules | |
| 48 | ||
| 49 | pub impl(in crate::a::E) trait T14 {} //~ ERROR expected module, found enum `crate::a::E` [E0577] | |
| 50 | ||
| 51 | pub impl(crate) trait T15 {} | |
| 52 | pub impl(self) trait T16 {} | |
| 53 | ||
| 54 | pub impl(super) trait T17 {} //~ ERROR too many leading `super` keywords [E0433] | |
| 55 | ||
| 56 | // Check if we can resolve paths referring to modules declared later. | |
| 57 | pub impl(in crate::j) trait L4 {} //~ ERROR trait implementation can only be restricted to ancestor modules | |
| 58 | ||
| 59 | pub impl(in crate::I) trait L5 {} //~ ERROR expected module, found enum `crate::I` [E0577] | |
| 60 | ||
| 61 | pub enum I {} | |
| 62 | pub mod j {} | |
| 63 | ||
| 64 | // Check if we can resolve `use`d paths. | |
| 65 | mod m1 { | |
| 66 | pub impl(in crate::m2) trait U1 {} // OK | |
| 67 | } | |
| 68 | ||
| 69 | use m1 as m2; | |
| 70 | ||
| 71 | mod m3 { | |
| 72 | mod m4 { | |
| 73 | pub impl(in crate::m2) trait U2 {} //~ ERROR trait implementation can only be restricted to ancestor modules | |
| 74 | pub impl(in m6) trait U3 {} // OK | |
| 75 | pub impl(in m6::m5) trait U4 {} //~ ERROR trait implementation can only be restricted to ancestor modules | |
| 76 | pub impl(in m7) trait U5 {} //~ ERROR expected module, found enum `m7` [E0577] | |
| 77 | ||
| 78 | use crate::m3 as m6; | |
| 79 | use crate::m3::E as m7; | |
| 80 | } | |
| 81 | mod m5 {} | |
| 82 | pub enum E {} | |
| 83 | } | |
| 84 | ||
| 85 | fn main() {} |
tests/ui/impl-restriction/restriction_resolution_errors.stderr created+140| ... | ... | @@ -0,0 +1,140 @@ |
| 1 | error: trait implementation can only be restricted to ancestor modules | |
| 2 | --> $DIR/restriction_resolution_errors.rs:14:21 | |
| 3 | | | |
| 4 | LL | pub impl(in ::std) trait T2 {} | |
| 5 | | ^^^^^ | |
| 6 | ||
| 7 | error: trait implementation can only be restricted to ancestor modules | |
| 8 | --> $DIR/restriction_resolution_errors.rs:16:21 | |
| 9 | | | |
| 10 | LL | pub impl(in self::c) trait T3 {} | |
| 11 | | ^^^^^^^ | |
| 12 | ||
| 13 | error: trait implementation can only be restricted to ancestor modules | |
| 14 | --> $DIR/restriction_resolution_errors.rs:18:21 | |
| 15 | | | |
| 16 | LL | pub impl(in super::d) trait T4 {} | |
| 17 | | ^^^^^^^^ | |
| 18 | ||
| 19 | error[E0433]: too many leading `super` keywords | |
| 20 | --> $DIR/restriction_resolution_errors.rs:24:35 | |
| 21 | | | |
| 22 | LL | pub impl(in super::super::super) trait T7 {} | |
| 23 | | ^^^^^ there are too many leading `super` keywords | |
| 24 | ||
| 25 | error: trait implementation can only be restricted to ancestor modules | |
| 26 | --> $DIR/restriction_resolution_errors.rs:34:21 | |
| 27 | | | |
| 28 | LL | pub impl(in self::f) trait L1 {} | |
| 29 | | ^^^^^^^ | |
| 30 | ||
| 31 | error: trait implementation can only be restricted to ancestor modules | |
| 32 | --> $DIR/restriction_resolution_errors.rs:38:21 | |
| 33 | | | |
| 34 | LL | pub impl(in super::h) trait L3 {} | |
| 35 | | ^^^^^^^^ | |
| 36 | ||
| 37 | error: trait implementation can only be restricted to ancestor modules | |
| 38 | --> $DIR/restriction_resolution_errors.rs:47:13 | |
| 39 | | | |
| 40 | LL | pub impl(in crate::a) trait T13 {} | |
| 41 | | ^^^^^^^^ | |
| 42 | ||
| 43 | error[E0433]: too many leading `super` keywords | |
| 44 | --> $DIR/restriction_resolution_errors.rs:54:10 | |
| 45 | | | |
| 46 | LL | pub impl(super) trait T17 {} | |
| 47 | | ^^^^^ there are too many leading `super` keywords | |
| 48 | ||
| 49 | error: trait implementation can only be restricted to ancestor modules | |
| 50 | --> $DIR/restriction_resolution_errors.rs:57:13 | |
| 51 | | | |
| 52 | LL | pub impl(in crate::j) trait L4 {} | |
| 53 | | ^^^^^^^^ | |
| 54 | ||
| 55 | error: trait implementation can only be restricted to ancestor modules | |
| 56 | --> $DIR/restriction_resolution_errors.rs:73:21 | |
| 57 | | | |
| 58 | LL | pub impl(in crate::m2) trait U2 {} | |
| 59 | | ^^^^^^^^^ | |
| 60 | ||
| 61 | error: trait implementation can only be restricted to ancestor modules | |
| 62 | --> $DIR/restriction_resolution_errors.rs:75:21 | |
| 63 | | | |
| 64 | LL | pub impl(in m6::m5) trait U4 {} | |
| 65 | | ^^^^^^ | |
| 66 | ||
| 67 | error[E0433]: cannot find module or crate `a` in this scope | |
| 68 | --> $DIR/restriction_resolution_errors.rs:12:21 | |
| 69 | | | |
| 70 | LL | pub impl(in a::b) trait T1 {} | |
| 71 | | ^ use of unresolved module or unlinked crate `a` | |
| 72 | | | |
| 73 | help: there is a crate or module with a similar name | |
| 74 | | | |
| 75 | LL - pub impl(in a::b) trait T1 {} | |
| 76 | LL + pub impl(in c::b) trait T1 {} | |
| 77 | | | |
| 78 | help: consider importing this module | |
| 79 | | | |
| 80 | LL + use a; | |
| 81 | | | |
| 82 | ||
| 83 | error[E0433]: cannot find module `c` in the crate root | |
| 84 | --> $DIR/restriction_resolution_errors.rs:20:28 | |
| 85 | | | |
| 86 | LL | pub impl(in crate::c) trait T5 {} | |
| 87 | | ^ not found in the crate root | |
| 88 | ||
| 89 | error[E0577]: expected module, found enum `super::E` | |
| 90 | --> $DIR/restriction_resolution_errors.rs:22:21 | |
| 91 | | | |
| 92 | LL | pub impl(in super::E) trait T6 {} | |
| 93 | | ^^^^^^^^ not a module | |
| 94 | ||
| 95 | error[E0577]: expected module, found enum `super::G` | |
| 96 | --> $DIR/restriction_resolution_errors.rs:36:21 | |
| 97 | | | |
| 98 | LL | pub impl(in super::G) trait L2 {} | |
| 99 | | ^^^^^^^^ not a module | |
| 100 | ||
| 101 | error[E0577]: expected module, found enum `crate::a::E` | |
| 102 | --> $DIR/restriction_resolution_errors.rs:49:13 | |
| 103 | | | |
| 104 | LL | pub mod b { | |
| 105 | | --------- similarly named module `b` defined here | |
| 106 | ... | |
| 107 | LL | pub impl(in crate::a::E) trait T14 {} | |
| 108 | | ^^^^^^^^^^^ | |
| 109 | | | |
| 110 | help: a module with a similar name exists | |
| 111 | | | |
| 112 | LL - pub impl(in crate::a::E) trait T14 {} | |
| 113 | LL + pub impl(in crate::a::b) trait T14 {} | |
| 114 | | | |
| 115 | ||
| 116 | error[E0577]: expected module, found enum `crate::I` | |
| 117 | --> $DIR/restriction_resolution_errors.rs:59:13 | |
| 118 | | | |
| 119 | LL | pub mod a { | |
| 120 | | --------- similarly named module `a` defined here | |
| 121 | ... | |
| 122 | LL | pub impl(in crate::I) trait L5 {} | |
| 123 | | ^^^^^^^^ | |
| 124 | | | |
| 125 | help: a module with a similar name exists | |
| 126 | | | |
| 127 | LL - pub impl(in crate::I) trait L5 {} | |
| 128 | LL + pub impl(in crate::a) trait L5 {} | |
| 129 | | | |
| 130 | ||
| 131 | error[E0577]: expected module, found enum `m7` | |
| 132 | --> $DIR/restriction_resolution_errors.rs:76:21 | |
| 133 | | | |
| 134 | LL | pub impl(in m7) trait U5 {} | |
| 135 | | ^^ not a module | |
| 136 | ||
| 137 | error: aborting due to 18 previous errors | |
| 138 | ||
| 139 | Some errors have detailed explanations: E0433, E0577. | |
| 140 | For more information about an error, try `rustc --explain E0433`. |
tests/ui/lint/must_not_suspend/issue-89562.rs deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | //@ edition:2018 | |
| 2 | //@ run-pass | |
| 3 | ||
| 4 | use std::sync::Mutex; | |
| 5 | ||
| 6 | // Copied from the issue. Allow-by-default for now, so run-pass | |
| 7 | pub async fn foo() { | |
| 8 | let foo = Mutex::new(1); | |
| 9 | let lock = foo.lock().unwrap(); | |
| 10 | ||
| 11 | // Prevent mutex lock being held across `.await` point. | |
| 12 | drop(lock); | |
| 13 | ||
| 14 | bar().await; | |
| 15 | } | |
| 16 | ||
| 17 | async fn bar() {} | |
| 18 | ||
| 19 | fn main() {} |
tests/ui/lint/must_not_suspend/mutex-guard-dropped-before-await.rs created+23| ... | ... | @@ -0,0 +1,23 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/89562> | |
| 2 | ||
| 3 | //@ edition:2018 | |
| 4 | //@ run-pass | |
| 5 | ||
| 6 | #![feature(must_not_suspend)] | |
| 7 | #![deny(must_not_suspend)] | |
| 8 | ||
| 9 | use std::sync::Mutex; | |
| 10 | ||
| 11 | pub async fn foo() { | |
| 12 | let foo = Mutex::new(1); | |
| 13 | let lock = foo.lock().unwrap(); | |
| 14 | ||
| 15 | // Prevent mutex lock being held across `.await` point. | |
| 16 | drop(lock); | |
| 17 | ||
| 18 | bar().await; | |
| 19 | } | |
| 20 | ||
| 21 | async fn bar() {} | |
| 22 | ||
| 23 | fn main() {} |