authorbors <bors@rust-lang.org> 2026-03-20 07:22:03 UTC
committerbors <bors@rust-lang.org> 2026-03-20 07:22:03 UTC
log86c839ffb36d0e21405dee5ab38e3f85c5b63699
treebfa3f1d205177439941f7e0ac8227e2432eac1fe
parent76be1cc4eef94daeab731ed9395a317b34d89d63
parentffe94f0bcbe7f974e0970965fedec2e4a806324d

Auto merge of #154123 - Zalathar:rollup-MUEvgV7, r=Zalathar

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"
11401140
11411141[[package]]
11421142name = "derive-where"
1143version = "1.6.0"
1143version = "1.6.1"
11441144source = "registry+https://github.com/rust-lang/crates.io-index"
1145checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f"
1145checksum = "d08b3a0bcc0d079199cd476b2cae8435016ec11d1c0986c6901c5ac223041534"
11461146dependencies = [
11471147 "proc-macro2",
11481148 "quote",
compiler/rustc_ast_pretty/src/pprust/state.rs+20
......@@ -329,6 +329,19 @@ fn print_crate_inner<'a>(
329329/// - #63896: `#[allow(unused,` must be printed rather than `#[allow(unused ,`
330330/// - #73345: `#[allow(unused)]` must be printed rather than `# [allow(unused)]`
331331///
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`.
335fn 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
332345fn space_between(tt1: &TokenTree, tt2: &TokenTree) -> bool {
333346 use Delimiter::*;
334347 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
811824 if let Some(next) = iter.peek() {
812825 if spacing == Spacing::Alone && space_between(tt, next) {
813826 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();
814834 }
815835 }
816836 }
compiler/rustc_ast_pretty/src/pprust/state/expr.rs+37-11
......@@ -260,12 +260,15 @@ impl<'a> State<'a> {
260260 //
261261 // loop { break x; }.method();
262262 //
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());
268265
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 }
269272 self.word(".");
270273 self.print_ident(segment.ident);
271274 if let Some(args) = &segment.args {
......@@ -658,11 +661,15 @@ impl<'a> State<'a> {
658661 );
659662 }
660663 ast::ExprKind::Field(expr, ident) => {
664 let needs_paren = expr.precedence() < ExprPrecedence::Unambiguous;
661665 self.print_expr_cond_paren(
662666 expr,
663 expr.precedence() < ExprPrecedence::Unambiguous,
667 needs_paren,
664668 fixup.leftmost_subexpression_with_dot(),
665669 );
670 if !needs_paren && expr_ends_with_dot(expr) {
671 self.word(" ");
672 }
666673 self.word(".");
667674 self.print_ident(*ident);
668675 }
......@@ -685,11 +692,15 @@ impl<'a> State<'a> {
685692 let fake_prec = ExprPrecedence::LOr;
686693 if let Some(e) = start {
687694 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 }
693704 }
694705 match limits {
695706 ast::RangeLimits::HalfOpen => self.word(".."),
......@@ -1025,3 +1036,18 @@ fn reconstruct_format_args_template_string(pieces: &[FormatArgsPiece]) -> String
10251036 template.push('"');
10261037 template
10271038}
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.`).
1044fn 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> {
881881 }
882882 if items.is_empty() {
883883 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 {
885891 self.print_use_tree(item);
886892 } else {
887893 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
2222
2323pub(crate) mod do_not_recommend;
2424pub(crate) mod on_const;
25pub(crate) mod on_move;
2526pub(crate) mod on_unimplemented;
2627
2728#[derive(Copy, Clone)]
......@@ -32,6 +33,8 @@ pub(crate) enum Mode {
3233 DiagnosticOnUnimplemented,
3334 /// `#[diagnostic::on_const]`
3435 DiagnosticOnConst,
36 /// `#[diagnostic::on_move]`
37 DiagnosticOnMove,
3538}
3639
3740fn merge_directives<S: Stage>(
......@@ -113,6 +116,13 @@ fn parse_directive_items<'p, S: Stage>(
113116 span,
114117 );
115118 }
119 Mode::DiagnosticOnMove => {
120 cx.emit_lint(
121 MALFORMED_DIAGNOSTIC_ATTRIBUTES,
122 AttributeLintKind::MalformedOnMoveAttr { span },
123 span,
124 );
125 }
116126 }
117127 continue;
118128 }}
......@@ -132,7 +142,7 @@ fn parse_directive_items<'p, S: Stage>(
132142 Mode::RustcOnUnimplemented => {
133143 cx.emit_err(NoValueInOnUnimplemented { span: item.span() });
134144 }
135 Mode::DiagnosticOnUnimplemented |Mode::DiagnosticOnConst => {
145 Mode::DiagnosticOnUnimplemented |Mode::DiagnosticOnConst | Mode::DiagnosticOnMove => {
136146 cx.emit_lint(
137147 MALFORMED_DIAGNOSTIC_ATTRIBUTES,
138148 AttributeLintKind::IgnoredDiagnosticOption {
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs created+72
......@@ -0,0 +1,72 @@
1use rustc_feature::template;
2use rustc_hir::attrs::AttributeKind;
3use rustc_hir::lints::AttributeLintKind;
4use rustc_session::lint::builtin::MALFORMED_DIAGNOSTIC_ATTRIBUTES;
5use rustc_span::sym;
6
7use crate::attributes::diagnostic::*;
8use crate::attributes::prelude::*;
9use crate::context::{AcceptContext, Stage};
10use crate::parser::ArgParser;
11use crate::target_checking::{ALL_TARGETS, AllowedTargets};
12
13#[derive(Default)]
14pub(crate) struct OnMoveParser {
15 span: Option<Span>,
16 directive: Option<(Span, Directive)>,
17}
18
19impl 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}
55impl<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::*;
2929use crate::attributes::deprecation::*;
3030use crate::attributes::diagnostic::do_not_recommend::*;
3131use crate::attributes::diagnostic::on_const::*;
32use crate::attributes::diagnostic::on_move::*;
3233use crate::attributes::diagnostic::on_unimplemented::*;
3334use crate::attributes::doc::*;
3435use crate::attributes::dummy::*;
......@@ -149,6 +150,7 @@ attribute_parsers!(
149150 MacroUseParser,
150151 NakedParser,
151152 OnConstParser,
153 OnMoveParser,
152154 OnUnimplementedParser,
153155 RustcAlignParser,
154156 RustcAlignStaticParser,
compiler/rustc_borrowck/src/borrowck_errors.rs+15-10
......@@ -324,18 +324,23 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> {
324324 verb: &str,
325325 optional_adverb_for_moved: &str,
326326 moved_path: Option<String>,
327 primary_message: Option<String>,
327328 ) -> 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();
329333
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 }
339344 }
340345
341346 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;
66use either::Either;
77use hir::{ClosureKind, Path};
88use rustc_data_structures::fx::FxIndexSet;
9use rustc_data_structures::thin_vec::ThinVec;
910use rustc_errors::codes::*;
1011use rustc_errors::{Applicability, Diag, MultiSpan, struct_span_code_err};
1112use rustc_hir as hir;
13use rustc_hir::attrs::diagnostic::FormatArgs;
1214use rustc_hir::def::{DefKind, Res};
1315use rustc_hir::intravisit::{Visitor, walk_block, walk_expr};
14use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, LangItem, PatField};
16use rustc_hir::{
17 CoroutineDesugaring, CoroutineKind, CoroutineSource, LangItem, PatField, find_attr,
18};
1519use rustc_middle::bug;
1620use rustc_middle::hir::nested_filter::OnlyBodies;
1721use rustc_middle::mir::{
......@@ -138,6 +142,36 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
138142 let partial_str = if is_partial_move { "partial " } else { "" };
139143 let partially_str = if is_partial_move { "partially " } else { "" };
140144
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
141175 let mut err = self.cannot_act_on_moved_value(
142176 span,
143177 desired_action.as_noun(),
......@@ -146,8 +180,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
146180 moved_place,
147181 DescribePlaceOpt { including_downcast: true, including_tuple_field: true },
148182 ),
183 on_move_message,
149184 );
150185
186 for note in on_move_notes {
187 err.note(note);
188 }
189
151190 let reinit_spans = maybe_reinitialized_locations
152191 .iter()
153192 .take(3)
......@@ -275,12 +314,16 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
275314 if needs_note {
276315 if let Some(local) = place.as_local() {
277316 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 }
284327 } else {
285328 err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Note {
286329 is_partial_move,
compiler/rustc_codegen_llvm/src/back/write.rs+2-10
......@@ -23,9 +23,7 @@ use rustc_middle::ty::TyCtxt;
2323use rustc_session::Session;
2424use rustc_session::config::{self, Lto, OutputType, Passes, SplitDwarfKind, SwitchWithOptPath};
2525use rustc_span::{BytePos, InnerSpan, Pos, RemapPathScopeComponents, SpanData, SyntaxContext, sym};
26use rustc_target::spec::{
27 Arch, CodeModel, FloatAbi, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel,
28};
26use rustc_target::spec::{CodeModel, FloatAbi, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel};
2927use tracing::{debug, trace};
3028
3129use crate::back::lto::{Buffer, ModuleBuffer};
......@@ -206,13 +204,7 @@ pub(crate) fn target_machine_factory(
206204 let reloc_model = to_llvm_relocation_model(sess.relocation_model());
207205
208206 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);
216208
217209 let ffunction_sections =
218210 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
15871587 match sym {
15881588 sym::on_unimplemented | sym::do_not_recommend => true,
15891589 sym::on_const => features.diagnostic_on_const(),
1590 sym::on_move => features.diagnostic_on_move(),
15901591 _ => false,
15911592 }
15921593}
compiler/rustc_feature/src/unstable.rs+2
......@@ -472,6 +472,8 @@ declare_features! (
472472 (unstable, derive_from, "1.91.0", Some(144889)),
473473 /// Allows giving non-const impls custom diagnostic messages if attempted to be used as const
474474 (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)),
475477 /// Allows `#[doc(cfg(...))]`.
476478 (unstable, doc_cfg, "1.21.0", Some(43781)),
477479 /// Allows `#[doc(masked)]`.
compiler/rustc_hir/src/attrs/data_structures.rs+6-1
......@@ -1180,13 +1180,18 @@ pub enum AttributeKind {
11801180 directive: Option<Box<Directive>>,
11811181 },
11821182
1183 /// Represents `#[diagnostic::on_move]`
1184 OnMove {
1185 span: Span,
1186 directive: Option<Box<Directive>>,
1187 },
1188
11831189 /// Represents `#[rustc_on_unimplemented]` and `#[diagnostic::on_unimplemented]`.
11841190 OnUnimplemented {
11851191 span: Span,
11861192 /// None if the directive was malformed in some way.
11871193 directive: Option<Box<Directive>>,
11881194 },
1189
11901195 /// Represents `#[optimize(size|speed)]`
11911196 Optimize(OptimizeAttr, Span),
11921197
compiler/rustc_hir/src/attrs/encode_cross_crate.rs+1
......@@ -77,6 +77,7 @@ impl AttributeKind {
7777 NoStd(..) => No,
7878 NonExhaustive(..) => Yes, // Needed for rustdoc
7979 OnConst { .. } => Yes,
80 OnMove { .. } => Yes,
8081 OnUnimplemented { .. } => Yes,
8182 Optimize(..) => No,
8283 PanicRuntime => No,
compiler/rustc_interface/src/tests.rs-1
......@@ -637,7 +637,6 @@ fn test_codegen_options_tracking_hash() {
637637 tracked!(profile_use, Some(PathBuf::from("abc")));
638638 tracked!(relocation_model, Some(RelocModel::Pic));
639639 tracked!(relro_level, Some(RelroLevel::Full));
640 tracked!(soft_float, true);
641640 tracked!(split_debuginfo, Some(SplitDebuginfo::Packed));
642641 tracked!(symbol_mangling_version, Some(SymbolManglingVersion::V0));
643642 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<'_, '_, '_> {
498498 &AttributeLintKind::MissingOptionsForOnConst => {
499499 lints::MissingOptionsForOnConstAttr.into_diag(dcx, level)
500500 }
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 }
501513 }
502514 }
503515}
compiler/rustc_lint/src/lints.rs+29
......@@ -3953,6 +3953,11 @@ pub(crate) struct MissingOptionsForOnUnimplementedAttr;
39533953#[help("at least one of the `message`, `note` and `label` options are expected")]
39543954pub(crate) struct MissingOptionsForOnConstAttr;
39553955
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")]
3959pub(crate) struct MissingOptionsForOnMoveAttr;
3960
39563961#[derive(Diagnostic)]
39573962#[diag("malformed `on_unimplemented` attribute")]
39583963#[help("only `message`, `note` and `label` are allowed as options")]
......@@ -3973,3 +3978,27 @@ pub(crate) struct MalformedOnConstAttrLint {
39733978#[diag("`Eq::assert_receiver_is_total_eq` should never be implemented by hand")]
39743979#[note("this method was used to add checks to the `Eq` derive macro")]
39753980pub(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)]
3987pub(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")]
3995pub(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)]
4004pub(crate) struct OnMoveMalformedAttrExpectedLiteralOrDelimiter;
compiler/rustc_lint_defs/src/lib.rs+8
......@@ -840,6 +840,9 @@ pub enum AttributeLintKind {
840840 MalformedOnConstAttr {
841841 span: Span,
842842 },
843 MalformedOnMoveAttr {
844 span: Span,
845 },
843846 MalformedDiagnosticFormat {
844847 warning: FormatWarning,
845848 },
......@@ -855,6 +858,11 @@ pub enum AttributeLintKind {
855858 },
856859 MissingOptionsForOnUnimplemented,
857860 MissingOptionsForOnConst,
861 MissingOptionsForOnMove,
862 OnMoveMalformedFormatLiterals {
863 name: Symbol,
864 },
865 OnMoveMalformedAttrExpectedLiteralOrDelimiter,
858866}
859867
860868#[derive(Debug, Clone, HashStable_Generic)]
compiler/rustc_middle/src/query/inner.rs+27-16
......@@ -77,23 +77,34 @@ where
7777 C: QueryCache<Value = Erased<Result<T, ErrorGuaranteed>>>,
7878 Result<T, ErrorGuaranteed>: Erasable,
7979{
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
8087 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 }
97108 }
98109}
99110
compiler/rustc_passes/src/check_attr.rs+57
......@@ -74,6 +74,10 @@ struct DiagnosticOnConstOnlyForNonConstTraitImpls {
7474 item_span: Span,
7575}
7676
77#[derive(Diagnostic)]
78#[diag("`#[diagnostic::on_move]` can only be applied to enums, structs or unions")]
79struct DiagnosticOnMoveOnlyForAdt;
80
7781fn target_from_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item: &hir::ImplItem<'_>) -> Target {
7882 match impl_item.kind {
7983 hir::ImplItemKind::Const(..) => Target::AssocConst,
......@@ -233,6 +237,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
233237 Attribute::Parsed(AttributeKind::DoNotRecommend{attr_span}) => {self.check_do_not_recommend(*attr_span, hir_id, target, item)},
234238 Attribute::Parsed(AttributeKind::OnUnimplemented{span, directive}) => {self.check_diagnostic_on_unimplemented(*span, hir_id, target,directive.as_deref())},
235239 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 },
236243 Attribute::Parsed(
237244 // tidy-alphabetical-start
238245 AttributeKind::RustcAllowIncoherentImpl(..)
......@@ -684,6 +691,56 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
684691 // The traits' or the impls'?
685692 }
686693
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
687744 /// Checks if an `#[inline]` is applied to a function or a closure.
688745 fn check_inline(&self, hir_id: HirId, attr_span: Span, kind: &InlineAttr, target: Target) {
689746 match target {
compiler/rustc_passes/src/errors.rs+7
......@@ -1432,3 +1432,10 @@ pub(crate) struct UnknownFormatParameterForOnUnimplementedAttr {
14321432 #[help(r#"expect either a generic argument name or {"`{Self}`"} as format argument"#)]
14331433 pub help: bool,
14341434}
1435
1436#[derive(Diagnostic)]
1437#[diag("unknown parameter `{$name}`")]
1438#[help(r#"expect either a generic argument name or {"`{Self}`"} as format argument"#)]
1439pub(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
155155 result
156156}
157157
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`.
159159/// `span` is the reason for the `query` to execute. This is initially DUMMY_SP.
160160/// If a cycle is detected, this initial value is replaced with the span causing
161/// the cycle.
162fn cycle_check<'tcx>(
161/// the cycle. `stack` will contain just the cycle on return if detected.
162fn find_cycle<'tcx>(
163163 job_map: &QueryJobMap<'tcx>,
164164 query: QueryJobId,
165165 span: Span,
......@@ -190,7 +190,7 @@ fn cycle_check<'tcx>(
190190 continue;
191191 };
192192 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)
194194 {
195195 // Return the resumable waiter in `waiter.resumable` if present
196196 return ControlFlow::Break(abstracted_waiter.resumable.or(maybe_resumable));
......@@ -232,7 +232,7 @@ fn connected_to_root<'tcx>(
232232 false
233233}
234234
235/// Looks for query cycles starting from the last query in `jobs`.
235/// Looks for a query cycle using the last query in `jobs`.
236236/// If a cycle is found, all queries in the cycle is removed from `jobs` and
237237/// the function return true.
238238/// If a cycle was not found, the starting query is removed from `jobs` and
......@@ -246,7 +246,7 @@ fn remove_cycle<'tcx>(
246246 let mut stack = Vec::new();
247247 // Look for a cycle starting with the last query in `jobs`
248248 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)
250250 {
251251 // The stack is a vector of pairs of spans and queries; reverse it so that
252252 // the earlier entries require later entries
compiler/rustc_resolve/src/errors.rs+4
......@@ -560,6 +560,10 @@ pub(crate) struct ExpectedModuleFound {
560560#[diag("cannot determine resolution for the visibility", code = E0578)]
561561pub(crate) struct Indeterminate(#[primary_span] pub(crate) Span);
562562
563#[derive(Diagnostic)]
564#[diag("trait implementation can only be restricted to ancestor modules")]
565pub(crate) struct RestrictionAncestorOnly(#[primary_span] pub(crate) Span);
566
563567#[derive(Diagnostic)]
564568#[diag("cannot use a tool module through an import")]
565569pub(crate) struct ToolModuleImported {
compiler/rustc_resolve/src/late.rs+39-4
......@@ -452,6 +452,8 @@ pub(crate) enum PathSource<'a, 'ast, 'ra> {
452452 DefineOpaques,
453453 /// Resolving a macro
454454 Macro,
455 /// Paths for module or crate root. Used for restrictions.
456 Module,
455457}
456458
457459impl PathSource<'_, '_, '_> {
......@@ -460,7 +462,8 @@ impl PathSource<'_, '_, '_> {
460462 PathSource::Type
461463 | PathSource::Trait(_)
462464 | PathSource::Struct(_)
463 | PathSource::DefineOpaques => TypeNS,
465 | PathSource::DefineOpaques
466 | PathSource::Module => TypeNS,
464467 PathSource::Expr(..)
465468 | PathSource::Pat
466469 | PathSource::TupleStruct(..)
......@@ -485,7 +488,8 @@ impl PathSource<'_, '_, '_> {
485488 | PathSource::DefineOpaques
486489 | PathSource::Delegation
487490 | PathSource::PreciseCapturingArg(..)
488 | PathSource::Macro => false,
491 | PathSource::Macro
492 | PathSource::Module => false,
489493 }
490494 }
491495
......@@ -528,6 +532,7 @@ impl PathSource<'_, '_, '_> {
528532 PathSource::ReturnTypeNotation | PathSource::Delegation => "function",
529533 PathSource::PreciseCapturingArg(..) => "type or const parameter",
530534 PathSource::Macro => "macro",
535 PathSource::Module => "module",
531536 }
532537 }
533538
......@@ -626,6 +631,7 @@ impl PathSource<'_, '_, '_> {
626631 ),
627632 PathSource::PreciseCapturingArg(MacroNS) => false,
628633 PathSource::Macro => matches!(res, Res::Def(DefKind::Macro(_), _)),
634 PathSource::Module => matches!(res, Res::Def(DefKind::Mod, _)),
629635 }
630636 }
631637
......@@ -646,6 +652,12 @@ impl PathSource<'_, '_, '_> {
646652 (PathSource::PreciseCapturingArg(..), true) => E0799,
647653 (PathSource::PreciseCapturingArg(..), false) => E0800,
648654 (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,
649661 }
650662 }
651663}
......@@ -2174,7 +2186,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
21742186 | PathSource::Type
21752187 | PathSource::PreciseCapturingArg(..)
21762188 | PathSource::ReturnTypeNotation
2177 | PathSource::Macro => false,
2189 | PathSource::Macro
2190 | PathSource::Module => false,
21782191 PathSource::Expr(..)
21792192 | PathSource::Pat
21802193 | PathSource::Struct(_)
......@@ -2800,7 +2813,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
28002813 self.diag_metadata.current_impl_items = None;
28012814 }
28022815
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
28042820 // Create a new rib for the trait-wide type parameters.
28052821 self.with_generic_param_rib(
28062822 &generics.params,
......@@ -4389,6 +4405,25 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
43894405 }
43904406 }
43914407
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
43924427 // High-level and context dependent path resolution routine.
43934428 // Resolves the path and records the resolution into definition map.
43944429 // 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> {
707707 }
708708
709709 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];
711711
712712 if res == Res::NonMacroAttr(NonMacroAttrKind::Tool)
713713 && let [namespace, attribute, ..] = &*path.segments
compiler/rustc_session/src/errors.rs-11
......@@ -517,17 +517,6 @@ pub(crate) struct FailedToCreateProfiler {
517517 pub(crate) err: String,
518518}
519519
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")]
523pub(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")]
529pub(crate) struct SoftFloatDeprecated;
530
531520#[derive(Diagnostic)]
532521#[diag("unexpected `--cfg {$cfg}` flag")]
533522#[note("config `{$cfg_name}` is only supposed to be controlled by `{$controlled_by}`")]
compiler/rustc_session/src/lib.rs+2
......@@ -1,5 +1,7 @@
11// tidy-alphabetical-start
22#![allow(internal_features)]
3#![feature(const_option_ops)]
4#![feature(const_trait_impl)]
35#![feature(default_field_values)]
46#![feature(iter_intersperse)]
57#![feature(macro_derive)]
compiler/rustc_session/src/options.rs+35-19
......@@ -611,7 +611,7 @@ macro_rules! options {
611611 $parse:ident,
612612 [$dep_tracking_marker:ident $( $tmod:ident )?],
613613 $desc:expr
614 $(, is_deprecated_and_do_nothing: $dnn:literal )?)
614 $(, removed: $removed:ident )?)
615615 ),* ,) =>
616616(
617617 #[derive(Clone)]
......@@ -667,7 +667,7 @@ macro_rules! options {
667667
668668 pub const $stat: OptionDescrs<$struct_name> =
669669 &[ $( 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)) )?,
671671 tmod: tmod_enum_opt!($struct_name, $tmod_enum_name, $opt, $($tmod),*) } ),* ];
672672
673673 mod $optmod {
......@@ -705,6 +705,12 @@ macro_rules! redirect_field {
705705type OptionSetter<O> = fn(&mut O, v: Option<&str>) -> bool;
706706type OptionDescrs<O> = &'static [OptionDesc<O>];
707707
708/// Indicates whether a removed option should warn or error.
709enum RemovedOption {
710 Warn,
711 Err,
712}
713
708714pub struct OptionDesc<O> {
709715 name: &'static str,
710716 setter: OptionSetter<O>,
......@@ -712,7 +718,7 @@ pub struct OptionDesc<O> {
712718 type_desc: &'static str,
713719 // description for option from options table
714720 desc: &'static str,
715 is_deprecated_and_do_nothing: bool,
721 removed: Option<RemovedOption>,
716722 tmod: Option<OptionsTargetModifiers>,
717723}
718724
......@@ -743,18 +749,18 @@ fn build_options<O: Default>(
743749
744750 let option_to_lookup = key.replace('-', "_");
745751 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 {
755754 // deprecation works for prefixed options only
756755 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 }
758764 }
759765 if !setter(&mut op, value) {
760766 match value {
......@@ -783,6 +789,7 @@ fn build_options<O: Default>(
783789
784790#[allow(non_upper_case_globals)]
785791mod desc {
792 pub(crate) const parse_ignore: &str = "<ignored>"; // should not be user-visible
786793 pub(crate) const parse_no_value: &str = "no value";
787794 pub(crate) const parse_bool: &str =
788795 "one of: `y`, `yes`, `on`, `true`, `n`, `no`, `off` or `false`";
......@@ -889,6 +896,12 @@ pub mod parse {
889896 pub(crate) use super::*;
890897 pub(crate) const MAX_THREADS_CAP: usize = 256;
891898
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
892905 /// This is for boolean options that don't take a value, and are true simply
893906 /// by existing on the command-line.
894907 ///
......@@ -2059,7 +2072,7 @@ options! {
20592072 #[rustc_lint_opt_deny_field_access("documented to do nothing")]
20602073 ar: String = (String::new(), parse_string, [UNTRACKED],
20612074 "this option is deprecated and does nothing",
2062 is_deprecated_and_do_nothing: true),
2075 removed: Warn),
20632076 #[rustc_lint_opt_deny_field_access("use `Session::code_model` instead of this field")]
20642077 code_model: Option<CodeModel> = (None, parse_code_model, [TRACKED],
20652078 "choose the code model to use (`rustc --print code-models` for details)"),
......@@ -2098,7 +2111,7 @@ options! {
20982111 inline_threshold: Option<u32> = (None, parse_opt_number, [UNTRACKED],
20992112 "this option is deprecated and does nothing \
21002113 (consider using `-Cllvm-args=--inline-threshold=...`)",
2101 is_deprecated_and_do_nothing: true),
2114 removed: Warn),
21022115 #[rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field")]
21032116 instrument_coverage: InstrumentCoverage = (InstrumentCoverage::No, parse_instrument_coverage, [TRACKED],
21042117 "instrument the generated code to support LLVM source-based code coverage reports \
......@@ -2139,7 +2152,7 @@ options! {
21392152 #[rustc_lint_opt_deny_field_access("documented to do nothing")]
21402153 no_stack_check: bool = (false, parse_no_value, [UNTRACKED],
21412154 "this option is deprecated and does nothing",
2142 is_deprecated_and_do_nothing: true),
2155 removed: Warn),
21432156 no_vectorize_loops: bool = (false, parse_no_value, [TRACKED],
21442157 "disable loop vectorization optimization passes"),
21452158 no_vectorize_slp: bool = (false, parse_no_value, [TRACKED],
......@@ -2173,8 +2186,11 @@ options! {
21732186 "set rpath values in libs/exes (default: no)"),
21742187 save_temps: bool = (false, parse_bool, [UNTRACKED],
21752188 "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),
21782194 #[rustc_lint_opt_deny_field_access("use `Session::split_debuginfo` instead of this field")]
21792195 split_debuginfo: Option<SplitDebuginfo> = (None, parse_split_debuginfo, [TRACKED],
21802196 "how to handle split-debuginfo, a platform-specific option"),
......@@ -2240,7 +2256,7 @@ options! {
22402256 (default: no)"),
22412257 box_noalias: bool = (true, parse_bool, [TRACKED],
22422258 "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],
22442260 "set options for branch target identification and pointer authentication on AArch64"),
22452261 build_sdylib_interface: bool = (false, parse_bool, [UNTRACKED],
22462262 "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) {
13601360 }
13611361 }
13621362 }
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 }
13731363}
13741364
13751365/// Holds data on the current incremental compilation session, if there is one.
compiler/rustc_span/src/symbol.rs+2
......@@ -797,6 +797,7 @@ symbols! {
797797 diagnostic,
798798 diagnostic_namespace,
799799 diagnostic_on_const,
800 diagnostic_on_move,
800801 dialect,
801802 direct,
802803 discriminant_kind,
......@@ -1407,6 +1408,7 @@ symbols! {
14071408 omit_gdb_pretty_printer_section,
14081409 on,
14091410 on_const,
1411 on_move,
14101412 on_unimplemented,
14111413 opaque,
14121414 opaque_generic_const_args,
compiler/rustc_type_ir/Cargo.toml+1-1
......@@ -7,7 +7,7 @@ edition = "2024"
77# tidy-alphabetical-start
88arrayvec = { version = "0.7", default-features = false }
99bitflags = "2.4.1"
10derive-where = "1.2.7"
10derive-where = "1.6.1"
1111ena = "0.14.4"
1212indexmap = "2.0.0"
1313rustc-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};
2626/// for more details.
2727///
2828/// `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)]
3430#[derive(GenericTypeVisitable)]
3531#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
3632pub struct Binder<I: Interner, T> {
......@@ -365,12 +361,7 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
365361/// `instantiate`.
366362///
367363/// 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)]
374365#[derive(GenericTypeVisitable)]
375366#[cfg_attr(
376367 feature = "nightly",
......@@ -964,12 +955,7 @@ pub enum BoundVarIndexKind {
964955/// The "placeholder index" fully defines a placeholder region, type, or const. Placeholders are
965956/// identified by both a universe, as well as a name residing within that universe. Distinct bound
966957/// 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)]
973959#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
974960#[cfg_attr(
975961 feature = "nightly",
library/core/src/lib.rs+1-2
......@@ -107,8 +107,6 @@
107107#![feature(core_intrinsics)]
108108#![feature(coverage_attribute)]
109109#![feature(disjoint_bitor)]
110#![feature(internal_impls_macro)]
111#![feature(link_cfg)]
112110#![feature(offset_of_enum)]
113111#![feature(panic_internals)]
114112#![feature(pattern_type_macro)]
......@@ -144,6 +142,7 @@
144142#![feature(intra_doc_pointers)]
145143#![feature(intrinsics)]
146144#![feature(lang_items)]
145#![feature(link_cfg)]
147146#![feature(link_llvm_intrinsics)]
148147#![feature(macro_metavar_expr)]
149148#![feature(macro_metavar_expr_concat)]
library/core/src/marker.rs-3
......@@ -52,9 +52,6 @@ use crate::pin::UnsafePinned;
5252/// u32,
5353/// }
5454/// ```
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)]
5855macro marker_impls {
5956 ( $(#[$($meta:tt)*])* $Trait:ident for $({$($bounds:tt)*})? $T:ty $(, $($rest:tt)*)? ) => {
6057 $(#[$($meta)*])* impl< $($($bounds)*)? > $Trait for $T {}
library/std/src/lib.rs+8-8
......@@ -275,9 +275,7 @@
275275#![feature(cfg_sanitizer_cfi)]
276276#![feature(cfg_target_thread_local)]
277277#![feature(cfi_encoding)]
278#![feature(const_default)]
279278#![feature(const_trait_impl)]
280#![feature(core_float_math)]
281279#![feature(decl_macro)]
282280#![feature(deprecated_suggestion)]
283281#![feature(doc_cfg)]
......@@ -287,16 +285,11 @@
287285#![feature(f16)]
288286#![feature(f128)]
289287#![feature(ffi_const)]
290#![feature(formatting_options)]
291#![feature(funnel_shifts)]
292288#![feature(intra_doc_pointers)]
293#![feature(iter_advance_by)]
294#![feature(iter_next_chunk)]
295289#![feature(lang_items)]
296290#![feature(link_cfg)]
297291#![feature(linkage)]
298292#![feature(macro_metavar_expr_concat)]
299#![feature(maybe_uninit_fill)]
300293#![feature(min_specialization)]
301294#![feature(must_not_suspend)]
302295#![feature(needs_panic_runtime)]
......@@ -314,7 +307,6 @@
314307#![feature(try_blocks)]
315308#![feature(try_trait_v2)]
316309#![feature(type_alias_impl_trait)]
317#![feature(uint_carryless_mul)]
318310// tidy-alphabetical-end
319311//
320312// Library features (core):
......@@ -325,6 +317,8 @@
325317#![feature(char_internals)]
326318#![feature(clone_to_uninit)]
327319#![feature(const_convert)]
320#![feature(const_default)]
321#![feature(core_float_math)]
328322#![feature(core_intrinsics)]
329323#![feature(core_io_borrowed_buf)]
330324#![feature(cstr_display)]
......@@ -340,13 +334,18 @@
340334#![feature(float_minimum_maximum)]
341335#![feature(fmt_internals)]
342336#![feature(fn_ptr_trait)]
337#![feature(formatting_options)]
338#![feature(funnel_shifts)]
343339#![feature(generic_atomic)]
344340#![feature(hasher_prefixfree_extras)]
345341#![feature(hashmap_internals)]
346342#![feature(hint_must_use)]
347343#![feature(int_from_ascii)]
348344#![feature(ip)]
345#![feature(iter_advance_by)]
346#![feature(iter_next_chunk)]
349347#![feature(maybe_uninit_array_assume_init)]
348#![feature(maybe_uninit_fill)]
350349#![feature(panic_can_unwind)]
351350#![feature(panic_internals)]
352351#![feature(pin_coerce_unsized_trait)]
......@@ -364,6 +363,7 @@
364363#![feature(sync_unsafe_cell)]
365364#![feature(temporary_niche_types)]
366365#![feature(ub_checks)]
366#![feature(uint_carryless_mul)]
367367#![feature(used_with_arg)]
368368// tidy-alphabetical-end
369369//
src/bootstrap/src/utils/exec.rs+11
......@@ -7,6 +7,7 @@
77//! relevant to command execution in the bootstrap process. This includes settings such as
88//! dry-run mode, verbosity level, and failure behavior.
99
10use std::backtrace::{Backtrace, BacktraceStatus};
1011use std::collections::HashMap;
1112use std::ffi::{OsStr, OsString};
1213use std::fmt::{Debug, Formatter};
......@@ -930,6 +931,16 @@ Executed at: {executed_at}"#,
930931 if stderr.captures() {
931932 writeln!(error_message, "\n--- STDERR vvv\n{}", output.stderr().trim()).unwrap();
932933 }
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 }
933944
934945 match command.failure_behavior {
935946 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) -
7979 | clean::ProvidedAssocConstItem(..)
8080 | clean::ImplAssocConstItem(..)
8181 | clean::RequiredAssocTypeItem(..)
82 // check for trait impl
83 | clean::ImplItem(box clean::Impl { trait_: Some(_), .. })
82 | clean::ImplItem(_)
8483 )
8584 {
8685 return false;
src/tools/tidy/src/issues.txt-1
......@@ -1475,7 +1475,6 @@ ui/lint/issue-97094.rs
14751475ui/lint/issue-99387.rs
14761476ui/lint/let_underscore/issue-119696-err-on-fn.rs
14771477ui/lint/let_underscore/issue-119697-extra-let.rs
1478ui/lint/must_not_suspend/issue-89562.rs
14791478ui/lint/unused/issue-103320-must-use-ops.rs
14801479ui/lint/unused/issue-104397.rs
14811480ui/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
22//@ assembly-output: emit-asm
33//@ needs-asm-support
44//@ only-aarch64
tests/pretty/float-trailing-dot.rs created+8
......@@ -0,0 +1,8 @@
1//@ pp-exact
2
3fn 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]
3extern crate std;
4#[prelude_import]
5use ::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
14macro_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]
22macro_rules! inner { ($x:ident where $ ($rest : tt)*) => {}; }
23
24fn 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
9macro_rules! outer {
10 ($d:tt $($params:tt)*) => {
11 #[macro_export]
12 macro_rules! inner {
13 ($($params)* where $d($rest:tt)*) => {};
14 }
15 };
16}
17outer!($ $x:ident);
18
19fn 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.
7use std::io::{self};
8use std::fmt::{self, Debug};
9
10fn main() {}
tests/run-make/pointer-auth-link-with-c-lto-clang/rmake.rs+1
......@@ -32,6 +32,7 @@ fn main() {
3232 .opt_level("2")
3333 .linker(&env_var("CLANG"))
3434 .link_arg("-fuse-ld=lld")
35 .arg("-Cunsafe-allow-abi-mismatch=branch-protection")
3536 .arg("-Zbranch-protection=bti,gcs,pac-ret,leaf")
3637 .input("test.rs")
3738 .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
1515
1616fn main() {
1717 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();
1923 run("test");
2024 cc().arg("-v")
2125 .arg("-c")
......@@ -25,7 +29,11 @@ fn main() {
2529 .run();
2630 let obj_file = if is_windows_msvc() { "test.obj" } else { "test" };
2731 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();
2937 run("test");
3038
3139 // FIXME: +pc was only recently added to LLVM
......@@ -37,6 +45,10 @@ fn main() {
3745 // .run();
3846 // let obj_file = if is_windows_msvc() { "test.obj" } else { "test" };
3947 // 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();
4153 // run("test");
4254}
tests/rustdoc-ui/lints/lint-missing-doc-code-example.rs+5-1
......@@ -78,7 +78,11 @@ impl Clone for Struct {
7878 }
7979}
8080
81
81impl 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}
8286
8387/// doc
8488///
tests/rustdoc-ui/lints/lint-missing-doc-code-example.stderr+19-1
......@@ -1,3 +1,15 @@
1error: missing documentation for an associated function
2 --> $DIR/lint-missing-doc-code-example.rs:82:5
3 |
4LL | pub fn bar() {}
5 | ^^^^^^^^^^^^
6 |
7note: the lint level is defined here
8 --> $DIR/lint-missing-doc-code-example.rs:2:9
9 |
10LL | #![deny(missing_docs)]
11 | ^^^^^^^^^^^^
12
113error: missing code example in this documentation
214 --> $DIR/lint-missing-doc-code-example.rs:38:3
315 |
......@@ -28,5 +40,11 @@ error: missing code example in this documentation
2840LL | /// Doc
2941 | ^^^^^^^
3042
31error: aborting due to 4 previous errors
43error: missing code example in this documentation
44 --> $DIR/lint-missing-doc-code-example.rs:82:5
45 |
46LL | pub fn bar() {}
47 | ^^^^^^^^^^^^^^^
48
49error: aborting due to 6 previous errors
3250
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
6use std::future::Future;
7
8trait Foo<'a> {
9 type Future: Future<Output = u8> + 'a;
10
11 fn start(self, f: &'a u8) -> Self::Future;
12}
13
14impl<'a, Fn, Fut> Foo<'a> for Fn
15where
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
24fn foo<F>(f: F) where F: for<'a> Foo<'a> {
25 let bar = 5;
26 f.start(&bar);
27}
28
29fn 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)]
8pub 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
3extern crate other;
4
5use other::Foo;
6
7fn takes_foo(_: Foo) {}
8
9fn 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 @@
1error[E0382]: Foo
2 --> $DIR/error_is_shown_in_downstream_crates.rs:12:15
3 |
4LL | let foo = Foo;
5 | --- Bar
6LL | takes_foo(foo);
7 | --- value moved here
8LL | let bar = foo;
9 | ^^^ value used here after move
10 |
11note: 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 |
14LL | fn takes_foo(_: Foo) {}
15 | --------- ^^^ this parameter takes ownership of the value
16 | |
17 | in this function
18
19error: aborting due to 1 previous error
20
21For 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)]
8struct Foo;
9
10fn takes_foo(_: Foo) {}
11
12fn 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 @@
1error[E0382]: Foo
2 --> $DIR/on_move_simple.rs:15:15
3 |
4LL | let foo = Foo;
5 | --- Bar
6LL | takes_foo(foo);
7 | --- value moved here
8LL | let bar = foo;
9 | ^^^ value used here after move
10 |
11note: 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 |
14LL | fn takes_foo(_: Foo) {}
15 | --------- ^^^ this parameter takes ownership of the value
16 | |
17 | in this function
18note: if `Foo` implemented `Clone`, you could clone the value
19 --> $DIR/on_move_simple.rs:8:1
20 |
21LL | struct Foo;
22 | ^^^^^^^^^^ consider implementing `Clone` for this type
23...
24LL | takes_foo(foo);
25 | --- you could clone this value
26
27error: aborting due to 1 previous error
28
29For 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)]
8struct Foo;
9
10#[diagnostic::on_move(
11 message="Foo for {X}",
12 label="Bar for {X}",
13)]
14struct MyType<X> {
15 _x: X,
16}
17
18fn takes_foo(_: Foo) {}
19
20fn takes_mytype<X>(_: MyType<X>) {}
21
22fn 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 @@
1error[E0382]: Foo for Foo
2 --> $DIR/on_move_with_format.rs:25:15
3 |
4LL | let foo = Foo;
5 | --- Bar for Foo
6LL | takes_foo(foo);
7 | --- value moved here
8LL | let bar = foo;
9 | ^^^ value used here after move
10 |
11note: 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 |
14LL | fn takes_foo(_: Foo) {}
15 | --------- ^^^ this parameter takes ownership of the value
16 | |
17 | in this function
18note: if `Foo` implemented `Clone`, you could clone the value
19 --> $DIR/on_move_with_format.rs:8:1
20 |
21LL | struct Foo;
22 | ^^^^^^^^^^ consider implementing `Clone` for this type
23...
24LL | takes_foo(foo);
25 | --- you could clone this value
26
27error[E0382]: Foo for i32
28 --> $DIR/on_move_with_format.rs:30:15
29 |
30LL | let mytype = MyType { _x: 0 };
31 | ------ Bar for i32
32LL | takes_mytype(mytype);
33 | ------ value moved here
34LL | let baz = mytype;
35 | ^^^^^^ value used here after move
36 |
37note: 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 |
40LL | fn takes_mytype<X>(_: MyType<X>) {}
41 | ------------ ^^^^^^^^^ this parameter takes ownership of the value
42 | |
43 | in this function
44note: if `MyType<i32>` implemented `Clone`, you could clone the value
45 --> $DIR/on_move_with_format.rs:14:1
46 |
47LL | struct MyType<X> {
48 | ^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
49...
50LL | takes_mytype(mytype);
51 | ------ you could clone this value
52
53error: aborting due to 2 previous errors
54
55For 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)]
13struct Foo;
14
15fn takes_foo(_: Foo) {}
16
17fn 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 @@
1warning: `message` is ignored due to previous definition of `message`
2 --> $DIR/report_warning_on_duplicated_options.rs:8:5
3 |
4LL | message = "first message",
5 | ------------------------- `message` is first declared here
6...
7LL | 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
12warning: `label` is ignored due to previous definition of `label`
13 --> $DIR/report_warning_on_duplicated_options.rs:10:5
14 |
15LL | label = "first label",
16 | --------------------- `label` is first declared here
17...
18LL | label = "second label",
19 | ^^^^^^^^^^^^^^^^^^^^^^ `label` is later redundantly declared here
20
21error[E0382]: first message
22 --> $DIR/report_warning_on_duplicated_options.rs:20:15
23 |
24LL | let foo = Foo;
25 | --- first label
26LL | takes_foo(foo);
27 | --- value moved here
28LL | let bar = foo;
29 | ^^^ value used here after move
30 |
31note: 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 |
34LL | fn takes_foo(_: Foo) {}
35 | --------- ^^^ this parameter takes ownership of the value
36 | |
37 | in this function
38note: if `Foo` implemented `Clone`, you could clone the value
39 --> $DIR/report_warning_on_duplicated_options.rs:13:1
40 |
41LL | struct Foo;
42 | ^^^^^^^^^^ consider implementing `Clone` for this type
43...
44LL | takes_foo(foo);
45 | --- you could clone this value
46
47error: aborting due to 1 previous error; 2 warnings emitted
48
49For 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)]
9struct Foo;
10
11fn takes_foo(_: Foo) {}
12
13fn 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 @@
1warning: unknown parameter `Baz`
2 --> $DIR/report_warning_on_invalid_formats.rs:4:21
3 |
4LL | 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
10error[E0382]: Foo {Baz}
11 --> $DIR/report_warning_on_invalid_formats.rs:16:15
12 |
13LL | let foo = Foo;
14 | --- Bar
15LL | takes_foo(foo);
16 | --- value moved here
17LL | let bar = foo;
18 | ^^^ value used here after move
19 |
20note: 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 |
23LL | fn takes_foo(_: Foo) {}
24 | --------- ^^^ this parameter takes ownership of the value
25 | |
26 | in this function
27note: if `Foo` implemented `Clone`, you could clone the value
28 --> $DIR/report_warning_on_invalid_formats.rs:9:1
29 |
30LL | struct Foo;
31 | ^^^^^^^^^^ consider implementing `Clone` for this type
32...
33LL | takes_foo(foo);
34 | --- you could clone this value
35
36error: aborting due to 1 previous error; 1 warning emitted
37
38For 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]
5struct Foo;
6
7fn takes_foo(_: Foo) {}
8
9fn 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 @@
1warning: missing options for `on_move` attribute
2 --> $DIR/report_warning_on_invalid_meta_item_syntax.rs:3:1
3 |
4LL | #[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
10error[E0382]: use of moved value: `foo`
11 --> $DIR/report_warning_on_invalid_meta_item_syntax.rs:12:15
12 |
13LL | let foo = Foo;
14 | --- move occurs because `foo` has type `Foo`, which does not implement the `Copy` trait
15LL | takes_foo(foo);
16 | --- value moved here
17LL | let bar = foo;
18 | ^^^ value used here after move
19 |
20note: 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 |
23LL | fn takes_foo(_: Foo) {}
24 | --------- ^^^ this parameter takes ownership of the value
25 | |
26 | in this function
27note: if `Foo` implemented `Clone`, you could clone the value
28 --> $DIR/report_warning_on_invalid_meta_item_syntax.rs:5:1
29 |
30LL | struct Foo;
31 | ^^^^^^^^^^ consider implementing `Clone` for this type
32...
33LL | takes_foo(foo);
34 | --- you could clone this value
35
36error: aborting due to 1 previous error; 1 warning emitted
37
38For 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)]
9struct Foo;
10
11fn takes_foo(_: Foo) {}
12
13fn 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 @@
1warning: expected a literal or missing delimiter
2 --> $DIR/report_warning_on_malformed_options_without_delimiters.rs:3:22
3 |
4LL | #[diagnostic::on_move(
5 | ______________________^
6LL | |
7LL | |
8LL | | message = "Foo"
9LL | | label = "Bar",
10LL | | )]
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
16error[E0382]: use of moved value: `foo`
17 --> $DIR/report_warning_on_malformed_options_without_delimiters.rs:16:15
18 |
19LL | let foo = Foo;
20 | --- move occurs because `foo` has type `Foo`, which does not implement the `Copy` trait
21LL | takes_foo(foo);
22 | --- value moved here
23LL | let bar = foo;
24 | ^^^ value used here after move
25 |
26note: 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 |
29LL | fn takes_foo(_: Foo) {}
30 | --------- ^^^ this parameter takes ownership of the value
31 | |
32 | in this function
33note: if `Foo` implemented `Clone`, you could clone the value
34 --> $DIR/report_warning_on_malformed_options_without_delimiters.rs:9:1
35 |
36LL | struct Foo;
37 | ^^^^^^^^^^ consider implementing `Clone` for this type
38...
39LL | takes_foo(foo);
40 | --- you could clone this value
41
42error: aborting due to 1 previous error; 1 warning emitted
43
44For 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)]
9struct Foo;
10
11fn takes_foo(_: Foo) {}
12
13fn 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 @@
1warning: expected a literal or missing delimiter
2 --> $DIR/report_warning_on_malformed_options_without_literals.rs:3:22
3 |
4LL | #[diagnostic::on_move(
5 | ______________________^
6LL | |
7LL | |
8LL | | message = Foo,
9LL | | label = "Bar",
10LL | | )]
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
16error[E0382]: use of moved value: `foo`
17 --> $DIR/report_warning_on_malformed_options_without_literals.rs:16:15
18 |
19LL | let foo = Foo;
20 | --- move occurs because `foo` has type `Foo`, which does not implement the `Copy` trait
21LL | takes_foo(foo);
22 | --- value moved here
23LL | let bar = foo;
24 | ^^^ value used here after move
25 |
26note: 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 |
29LL | fn takes_foo(_: Foo) {}
30 | --------- ^^^ this parameter takes ownership of the value
31 | |
32 | in this function
33note: if `Foo` implemented `Clone`, you could clone the value
34 --> $DIR/report_warning_on_malformed_options_without_literals.rs:9:1
35 |
36LL | struct Foo;
37 | ^^^^^^^^^^ consider implementing `Clone` for this type
38...
39LL | takes_foo(foo);
40 | --- you could clone this value
41
42error: aborting due to 1 previous error; 1 warning emitted
43
44For 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]
5struct Foo;
6
7fn takes_foo(_: Foo) {}
8
9fn 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 @@
1warning: missing options for `on_move` attribute
2 --> $DIR/report_warning_on_missing_options.rs:3:1
3 |
4LL | #[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
10error[E0382]: use of moved value: `foo`
11 --> $DIR/report_warning_on_missing_options.rs:12:15
12 |
13LL | let foo = Foo;
14 | --- move occurs because `foo` has type `Foo`, which does not implement the `Copy` trait
15LL | takes_foo(foo);
16 | --- value moved here
17LL | let bar = foo;
18 | ^^^ value used here after move
19 |
20note: 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 |
23LL | fn takes_foo(_: Foo) {}
24 | --------- ^^^ this parameter takes ownership of the value
25 | |
26 | in this function
27note: if `Foo` implemented `Clone`, you could clone the value
28 --> $DIR/report_warning_on_missing_options.rs:5:1
29 |
30LL | struct Foo;
31 | ^^^^^^^^^^ consider implementing `Clone` for this type
32...
33LL | takes_foo(foo);
34 | --- you could clone this value
35
36error: aborting due to 1 previous error; 1 warning emitted
37
38For 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)]
7struct 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)]
14trait MyTrait {}
15
16fn takes_foo(_: Foo) {}
17
18fn 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 @@
1warning: `#[diagnostic::on_move]` can only be applied to enums, structs or unions
2 --> $DIR/report_warning_on_non_adt.rs:9:1
3 |
4LL | / #[diagnostic::on_move(
5LL | |
6LL | | message = "Foo",
7LL | | label = "Bar",
8LL | | )]
9 | |__^
10 |
11 = note: `#[warn(misplaced_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default
12
13error[E0382]: Foo
14 --> $DIR/report_warning_on_non_adt.rs:21:15
15 |
16LL | let foo = Foo;
17 | --- Bar
18LL | takes_foo(foo);
19 | --- value moved here
20LL | let bar = foo;
21 | ^^^ value used here after move
22 |
23note: 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 |
26LL | fn takes_foo(_: Foo) {}
27 | --------- ^^^ this parameter takes ownership of the value
28 | |
29 | in this function
30note: if `Foo` implemented `Clone`, you could clone the value
31 --> $DIR/report_warning_on_non_adt.rs:7:1
32 |
33LL | struct Foo;
34 | ^^^^^^^^^^ consider implementing `Clone` for this type
35...
36LL | takes_foo(foo);
37 | --- you could clone this value
38
39error: aborting due to 1 previous error; 1 warning emitted
40
41For 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)]
10struct Foo;
11
12fn takes_foo(_: Foo) {}
13
14fn 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 @@
1warning: unknown or malformed `on_move` attribute
2 --> $DIR/report_warning_on_unknown_options.rs:6:5
3 |
4LL | 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
10error[E0382]: Foo
11 --> $DIR/report_warning_on_unknown_options.rs:17:15
12 |
13LL | let foo = Foo;
14 | --- Bar
15LL | takes_foo(foo);
16 | --- value moved here
17LL | let bar = foo;
18 | ^^^ value used here after move
19 |
20note: 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 |
23LL | fn takes_foo(_: Foo) {}
24 | --------- ^^^ this parameter takes ownership of the value
25 | |
26 | in this function
27note: if `Foo` implemented `Clone`, you could clone the value
28 --> $DIR/report_warning_on_unknown_options.rs:10:1
29 |
30LL | struct Foo;
31 | ^^^^^^^^^^ consider implementing `Clone` for this type
32...
33LL | takes_foo(foo);
34 | --- you could clone this value
35
36error: aborting due to 1 previous error; 1 warning emitted
37
38For 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)]
9struct Foo;
10
11fn takes_foo(_: Foo) {}
12
13fn 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 @@
1error[E0382]: use of moved value: `foo`
2 --> $DIR/feature-gate-diagnostic-on-move.rs:16:15
3 |
4LL | let foo = Foo;
5 | --- move occurs because `foo` has type `Foo`, which does not implement the `Copy` trait
6LL | takes_foo(foo);
7 | --- value moved here
8LL | let bar = foo;
9 | ^^^ value used here after move
10 |
11note: 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 |
14LL | fn takes_foo(_: Foo) {}
15 | --------- ^^^ this parameter takes ownership of the value
16 | |
17 | in this function
18note: if `Foo` implemented `Clone`, you could clone the value
19 --> $DIR/feature-gate-diagnostic-on-move.rs:9:1
20 |
21LL | struct Foo;
22 | ^^^^^^^^^^ consider implementing `Clone` for this type
23...
24LL | takes_foo(foo);
25 | --- you could clone this value
26
27error: aborting due to 1 previous error
28
29For 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
4pub 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
47pub impl(in crate::a) trait T13 {} //~ ERROR trait implementation can only be restricted to ancestor modules
48
49pub impl(in crate::a::E) trait T14 {} //~ ERROR expected module, found enum `crate::a::E` [E0577]
50
51pub impl(crate) trait T15 {}
52pub impl(self) trait T16 {}
53
54pub impl(super) trait T17 {} //~ ERROR too many leading `super` keywords [E0433]
55
56// Check if we can resolve paths referring to modules declared later.
57pub impl(in crate::j) trait L4 {} //~ ERROR trait implementation can only be restricted to ancestor modules
58
59pub impl(in crate::I) trait L5 {} //~ ERROR expected module, found enum `crate::I` [E0577]
60
61pub enum I {}
62pub mod j {}
63
64// Check if we can resolve `use`d paths.
65mod m1 {
66 pub impl(in crate::m2) trait U1 {} // OK
67}
68
69use m1 as m2;
70
71mod 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
85fn main() {}
tests/ui/impl-restriction/restriction_resolution_errors.stderr created+140
......@@ -0,0 +1,140 @@
1error: trait implementation can only be restricted to ancestor modules
2 --> $DIR/restriction_resolution_errors.rs:14:21
3 |
4LL | pub impl(in ::std) trait T2 {}
5 | ^^^^^
6
7error: trait implementation can only be restricted to ancestor modules
8 --> $DIR/restriction_resolution_errors.rs:16:21
9 |
10LL | pub impl(in self::c) trait T3 {}
11 | ^^^^^^^
12
13error: trait implementation can only be restricted to ancestor modules
14 --> $DIR/restriction_resolution_errors.rs:18:21
15 |
16LL | pub impl(in super::d) trait T4 {}
17 | ^^^^^^^^
18
19error[E0433]: too many leading `super` keywords
20 --> $DIR/restriction_resolution_errors.rs:24:35
21 |
22LL | pub impl(in super::super::super) trait T7 {}
23 | ^^^^^ there are too many leading `super` keywords
24
25error: trait implementation can only be restricted to ancestor modules
26 --> $DIR/restriction_resolution_errors.rs:34:21
27 |
28LL | pub impl(in self::f) trait L1 {}
29 | ^^^^^^^
30
31error: trait implementation can only be restricted to ancestor modules
32 --> $DIR/restriction_resolution_errors.rs:38:21
33 |
34LL | pub impl(in super::h) trait L3 {}
35 | ^^^^^^^^
36
37error: trait implementation can only be restricted to ancestor modules
38 --> $DIR/restriction_resolution_errors.rs:47:13
39 |
40LL | pub impl(in crate::a) trait T13 {}
41 | ^^^^^^^^
42
43error[E0433]: too many leading `super` keywords
44 --> $DIR/restriction_resolution_errors.rs:54:10
45 |
46LL | pub impl(super) trait T17 {}
47 | ^^^^^ there are too many leading `super` keywords
48
49error: trait implementation can only be restricted to ancestor modules
50 --> $DIR/restriction_resolution_errors.rs:57:13
51 |
52LL | pub impl(in crate::j) trait L4 {}
53 | ^^^^^^^^
54
55error: trait implementation can only be restricted to ancestor modules
56 --> $DIR/restriction_resolution_errors.rs:73:21
57 |
58LL | pub impl(in crate::m2) trait U2 {}
59 | ^^^^^^^^^
60
61error: trait implementation can only be restricted to ancestor modules
62 --> $DIR/restriction_resolution_errors.rs:75:21
63 |
64LL | pub impl(in m6::m5) trait U4 {}
65 | ^^^^^^
66
67error[E0433]: cannot find module or crate `a` in this scope
68 --> $DIR/restriction_resolution_errors.rs:12:21
69 |
70LL | pub impl(in a::b) trait T1 {}
71 | ^ use of unresolved module or unlinked crate `a`
72 |
73help: there is a crate or module with a similar name
74 |
75LL - pub impl(in a::b) trait T1 {}
76LL + pub impl(in c::b) trait T1 {}
77 |
78help: consider importing this module
79 |
80LL + use a;
81 |
82
83error[E0433]: cannot find module `c` in the crate root
84 --> $DIR/restriction_resolution_errors.rs:20:28
85 |
86LL | pub impl(in crate::c) trait T5 {}
87 | ^ not found in the crate root
88
89error[E0577]: expected module, found enum `super::E`
90 --> $DIR/restriction_resolution_errors.rs:22:21
91 |
92LL | pub impl(in super::E) trait T6 {}
93 | ^^^^^^^^ not a module
94
95error[E0577]: expected module, found enum `super::G`
96 --> $DIR/restriction_resolution_errors.rs:36:21
97 |
98LL | pub impl(in super::G) trait L2 {}
99 | ^^^^^^^^ not a module
100
101error[E0577]: expected module, found enum `crate::a::E`
102 --> $DIR/restriction_resolution_errors.rs:49:13
103 |
104LL | pub mod b {
105 | --------- similarly named module `b` defined here
106...
107LL | pub impl(in crate::a::E) trait T14 {}
108 | ^^^^^^^^^^^
109 |
110help: a module with a similar name exists
111 |
112LL - pub impl(in crate::a::E) trait T14 {}
113LL + pub impl(in crate::a::b) trait T14 {}
114 |
115
116error[E0577]: expected module, found enum `crate::I`
117 --> $DIR/restriction_resolution_errors.rs:59:13
118 |
119LL | pub mod a {
120 | --------- similarly named module `a` defined here
121...
122LL | pub impl(in crate::I) trait L5 {}
123 | ^^^^^^^^
124 |
125help: a module with a similar name exists
126 |
127LL - pub impl(in crate::I) trait L5 {}
128LL + pub impl(in crate::a) trait L5 {}
129 |
130
131error[E0577]: expected module, found enum `m7`
132 --> $DIR/restriction_resolution_errors.rs:76:21
133 |
134LL | pub impl(in m7) trait U5 {}
135 | ^^ not a module
136
137error: aborting due to 18 previous errors
138
139Some errors have detailed explanations: E0433, E0577.
140For 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
4use std::sync::Mutex;
5
6// Copied from the issue. Allow-by-default for now, so run-pass
7pub 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
17async fn bar() {}
18
19fn 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
9use std::sync::Mutex;
10
11pub 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
21async fn bar() {}
22
23fn main() {}