| author | bors <bors@rust-lang.org> 2024-06-28 07:25:28 UTC |
| committer | bors <bors@rust-lang.org> 2024-06-28 07:25:28 UTC |
| log | 99f77a2eda555b50b518f74823ab636a20efb87f |
| tree | 8dd11cc66cae04d768306ccb8e6c7e625e25104d |
| parent | 42add88d2275b95c98e512ab680436ede691e853 |
| parent | 89a0cfe72afe047c699df3810e1ce5e4d9cb98b4 |
Rollup of 6 pull requests
Successful merges:
- #124741 (patchable-function-entry: Add unstable compiler flag and attribute)
- #126470 (make cargo submodule optional)
- #126956 (core: avoid `extern type`s in formatting infrastructure)
- #126970 (Simplify `str::clone_into`)
- #127022 (Support fetching `Attribute` of items.)
- #127058 (Tighten `fn_decl_span` for async blocks)
r? `@ghost`
`@rustbot` modify labels: rollup80 files changed, 980 insertions(+), 308 deletions(-)
Cargo.lock+2| ... | ... | @@ -4675,6 +4675,8 @@ name = "rustc_smir" |
| 4675 | 4675 | version = "0.0.0" |
| 4676 | 4676 | dependencies = [ |
| 4677 | 4677 | "rustc_abi", |
| 4678 | "rustc_ast", | |
| 4679 | "rustc_ast_pretty", | |
| 4678 | 4680 | "rustc_data_structures", |
| 4679 | 4681 | "rustc_hir", |
| 4680 | 4682 | "rustc_middle", |
compiler/rustc_ast/src/ast.rs+4-1| ... | ... | @@ -1454,7 +1454,10 @@ pub enum ExprKind { |
| 1454 | 1454 | Block(P<Block>, Option<Label>), |
| 1455 | 1455 | /// An `async` block (`async move { ... }`), |
| 1456 | 1456 | /// or a `gen` block (`gen move { ... }`) |
| 1457 | Gen(CaptureBy, P<Block>, GenBlockKind), | |
| 1457 | /// | |
| 1458 | /// The span is the "decl", which is the header before the body `{ }` | |
| 1459 | /// including the `asyng`/`gen` keywords and possibly `move`. | |
| 1460 | Gen(CaptureBy, P<Block>, GenBlockKind, Span), | |
| 1458 | 1461 | /// An await expression (`my_future.await`). Span is of await keyword. |
| 1459 | 1462 | Await(P<Expr>, Span), |
| 1460 | 1463 |
compiler/rustc_ast/src/mut_visit.rs+2-1| ... | ... | @@ -1528,8 +1528,9 @@ pub fn noop_visit_expr<T: MutVisitor>( |
| 1528 | 1528 | visit_opt(label, |label| vis.visit_label(label)); |
| 1529 | 1529 | vis.visit_block(blk); |
| 1530 | 1530 | } |
| 1531 | ExprKind::Gen(_capture_by, body, _kind) => { | |
| 1531 | ExprKind::Gen(_capture_by, body, _kind, decl_span) => { | |
| 1532 | 1532 | vis.visit_block(body); |
| 1533 | vis.visit_span(decl_span); | |
| 1533 | 1534 | } |
| 1534 | 1535 | ExprKind::Await(expr, await_kw_span) => { |
| 1535 | 1536 | vis.visit_expr(expr); |
compiler/rustc_ast/src/visit.rs+1-1| ... | ... | @@ -1122,7 +1122,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V |
| 1122 | 1122 | visit_opt!(visitor, visit_label, opt_label); |
| 1123 | 1123 | try_visit!(visitor.visit_block(block)); |
| 1124 | 1124 | } |
| 1125 | ExprKind::Gen(_capt, body, _kind) => try_visit!(visitor.visit_block(body)), | |
| 1125 | ExprKind::Gen(_capt, body, _kind, _decl_span) => try_visit!(visitor.visit_block(body)), | |
| 1126 | 1126 | ExprKind::Await(expr, _span) => try_visit!(visitor.visit_expr(expr)), |
| 1127 | 1127 | ExprKind::Assign(lhs, rhs, _span) => { |
| 1128 | 1128 | try_visit!(visitor.visit_expr(lhs)); |
compiler/rustc_ast_lowering/src/expr.rs+5-2| ... | ... | @@ -227,7 +227,7 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 227 | 227 | *fn_arg_span, |
| 228 | 228 | ), |
| 229 | 229 | }, |
| 230 | ExprKind::Gen(capture_clause, block, genblock_kind) => { | |
| 230 | ExprKind::Gen(capture_clause, block, genblock_kind, decl_span) => { | |
| 231 | 231 | let desugaring_kind = match genblock_kind { |
| 232 | 232 | GenBlockKind::Async => hir::CoroutineDesugaring::Async, |
| 233 | 233 | GenBlockKind::Gen => hir::CoroutineDesugaring::Gen, |
| ... | ... | @@ -237,6 +237,7 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 237 | 237 | *capture_clause, |
| 238 | 238 | e.id, |
| 239 | 239 | None, |
| 240 | *decl_span, | |
| 240 | 241 | e.span, |
| 241 | 242 | desugaring_kind, |
| 242 | 243 | hir::CoroutineSource::Block, |
| ... | ... | @@ -616,6 +617,7 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 616 | 617 | capture_clause: CaptureBy, |
| 617 | 618 | closure_node_id: NodeId, |
| 618 | 619 | return_ty: Option<hir::FnRetTy<'hir>>, |
| 620 | fn_decl_span: Span, | |
| 619 | 621 | span: Span, |
| 620 | 622 | desugaring_kind: hir::CoroutineDesugaring, |
| 621 | 623 | coroutine_source: hir::CoroutineSource, |
| ... | ... | @@ -692,7 +694,7 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 692 | 694 | bound_generic_params: &[], |
| 693 | 695 | fn_decl, |
| 694 | 696 | body, |
| 695 | fn_decl_span: self.lower_span(span), | |
| 697 | fn_decl_span: self.lower_span(fn_decl_span), | |
| 696 | 698 | fn_arg_span: None, |
| 697 | 699 | kind: hir::ClosureKind::Coroutine(coroutine_kind), |
| 698 | 700 | constness: hir::Constness::NotConst, |
| ... | ... | @@ -1083,6 +1085,7 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 1083 | 1085 | let (parameters, expr) = this.lower_coroutine_body_with_moved_arguments( |
| 1084 | 1086 | &inner_decl, |
| 1085 | 1087 | |this| this.with_new_scopes(fn_decl_span, |this| this.lower_expr_mut(body)), |
| 1088 | fn_decl_span, | |
| 1086 | 1089 | body.span, |
| 1087 | 1090 | coroutine_kind, |
| 1088 | 1091 | hir::CoroutineSource::Closure, |
compiler/rustc_ast_lowering/src/item.rs+8-8| ... | ... | @@ -211,6 +211,7 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 211 | 211 | // declaration (decl), not the return types. |
| 212 | 212 | let coroutine_kind = header.coroutine_kind; |
| 213 | 213 | let body_id = this.lower_maybe_coroutine_body( |
| 214 | *fn_sig_span, | |
| 214 | 215 | span, |
| 215 | 216 | hir_id, |
| 216 | 217 | decl, |
| ... | ... | @@ -799,6 +800,7 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 799 | 800 | } |
| 800 | 801 | AssocItemKind::Fn(box Fn { sig, generics, body: Some(body), .. }) => { |
| 801 | 802 | let body_id = self.lower_maybe_coroutine_body( |
| 803 | sig.span, | |
| 802 | 804 | i.span, |
| 803 | 805 | hir_id, |
| 804 | 806 | &sig.decl, |
| ... | ... | @@ -915,6 +917,7 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 915 | 917 | ), |
| 916 | 918 | AssocItemKind::Fn(box Fn { sig, generics, body, .. }) => { |
| 917 | 919 | let body_id = self.lower_maybe_coroutine_body( |
| 920 | sig.span, | |
| 918 | 921 | i.span, |
| 919 | 922 | hir_id, |
| 920 | 923 | &sig.decl, |
| ... | ... | @@ -1111,6 +1114,7 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 1111 | 1114 | /// `gen {}` block as appropriate. |
| 1112 | 1115 | fn lower_maybe_coroutine_body( |
| 1113 | 1116 | &mut self, |
| 1117 | fn_decl_span: Span, | |
| 1114 | 1118 | span: Span, |
| 1115 | 1119 | fn_id: hir::HirId, |
| 1116 | 1120 | decl: &FnDecl, |
| ... | ... | @@ -1124,6 +1128,7 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 1124 | 1128 | let (parameters, expr) = this.lower_coroutine_body_with_moved_arguments( |
| 1125 | 1129 | decl, |
| 1126 | 1130 | |this| this.lower_block_expr(body), |
| 1131 | fn_decl_span, | |
| 1127 | 1132 | body.span, |
| 1128 | 1133 | coroutine_kind, |
| 1129 | 1134 | hir::CoroutineSource::Fn, |
| ... | ... | @@ -1145,6 +1150,7 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 1145 | 1150 | &mut self, |
| 1146 | 1151 | decl: &FnDecl, |
| 1147 | 1152 | lower_body: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::Expr<'hir>, |
| 1153 | fn_decl_span: Span, | |
| 1148 | 1154 | body_span: Span, |
| 1149 | 1155 | coroutine_kind: CoroutineKind, |
| 1150 | 1156 | coroutine_source: hir::CoroutineSource, |
| ... | ... | @@ -1315,13 +1321,6 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 1315 | 1321 | }; |
| 1316 | 1322 | let closure_id = coroutine_kind.closure_id(); |
| 1317 | 1323 | |
| 1318 | let span = if let FnRetTy::Default(span) = decl.output | |
| 1319 | && matches!(coroutine_source, rustc_hir::CoroutineSource::Closure) | |
| 1320 | { | |
| 1321 | body_span.with_lo(span.lo()) | |
| 1322 | } else { | |
| 1323 | body_span | |
| 1324 | }; | |
| 1325 | 1324 | let coroutine_expr = self.make_desugared_coroutine_expr( |
| 1326 | 1325 | // The default capture mode here is by-ref. Later on during upvar analysis, |
| 1327 | 1326 | // we will force the captured arguments to by-move, but for async closures, |
| ... | ... | @@ -1330,7 +1329,8 @@ impl<'hir> LoweringContext<'_, 'hir> { |
| 1330 | 1329 | CaptureBy::Ref, |
| 1331 | 1330 | closure_id, |
| 1332 | 1331 | None, |
| 1333 | span, | |
| 1332 | fn_decl_span, | |
| 1333 | body_span, | |
| 1334 | 1334 | desugaring_kind, |
| 1335 | 1335 | coroutine_source, |
| 1336 | 1336 | mkbody, |
compiler/rustc_ast_pretty/src/pprust/state/expr.rs+1-1| ... | ... | @@ -540,7 +540,7 @@ impl<'a> State<'a> { |
| 540 | 540 | self.ibox(0); |
| 541 | 541 | self.print_block_with_attrs(blk, attrs); |
| 542 | 542 | } |
| 543 | ast::ExprKind::Gen(capture_clause, blk, kind) => { | |
| 543 | ast::ExprKind::Gen(capture_clause, blk, kind, _decl_span) => { | |
| 544 | 544 | self.word_nbsp(kind.modifier()); |
| 545 | 545 | self.print_capture_clause(*capture_clause); |
| 546 | 546 | // cbox/ibox in analogy to the `ExprKind::Block` arm above |
compiler/rustc_builtin_macros/src/assert/context.rs+1-1| ... | ... | @@ -298,7 +298,7 @@ impl<'cx, 'a> Context<'cx, 'a> { |
| 298 | 298 | // sync with the `rfc-2011-nicer-assert-messages/all-expr-kinds.rs` test. |
| 299 | 299 | ExprKind::Assign(_, _, _) |
| 300 | 300 | | ExprKind::AssignOp(_, _, _) |
| 301 | | ExprKind::Gen(_, _, _) | |
| 301 | | ExprKind::Gen(_, _, _, _) | |
| 302 | 302 | | ExprKind::Await(_, _) |
| 303 | 303 | | ExprKind::Block(_, _) |
| 304 | 304 | | ExprKind::Break(_, _) |
compiler/rustc_codegen_llvm/src/attributes.rs+30-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | |
| 3 | 3 | use rustc_codegen_ssa::traits::*; |
| 4 | 4 | use rustc_hir::def_id::DefId; |
| 5 | use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; | |
| 5 | use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFunctionEntry}; | |
| 6 | 6 | use rustc_middle::ty::{self, TyCtxt}; |
| 7 | 7 | use rustc_session::config::{FunctionReturn, OptLevel}; |
| 8 | 8 | use rustc_span::symbol::sym; |
| ... | ... | @@ -53,6 +53,34 @@ fn inline_attr<'ll>(cx: &CodegenCx<'ll, '_>, inline: InlineAttr) -> Option<&'ll |
| 53 | 53 | } |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | #[inline] | |
| 57 | fn patchable_function_entry_attrs<'ll>( | |
| 58 | cx: &CodegenCx<'ll, '_>, | |
| 59 | attr: Option<PatchableFunctionEntry>, | |
| 60 | ) -> SmallVec<[&'ll Attribute; 2]> { | |
| 61 | let mut attrs = SmallVec::new(); | |
| 62 | let patchable_spec = attr.unwrap_or_else(|| { | |
| 63 | PatchableFunctionEntry::from_config(cx.tcx.sess.opts.unstable_opts.patchable_function_entry) | |
| 64 | }); | |
| 65 | let entry = patchable_spec.entry(); | |
| 66 | let prefix = patchable_spec.prefix(); | |
| 67 | if entry > 0 { | |
| 68 | attrs.push(llvm::CreateAttrStringValue( | |
| 69 | cx.llcx, | |
| 70 | "patchable-function-entry", | |
| 71 | &format!("{}", entry), | |
| 72 | )); | |
| 73 | } | |
| 74 | if prefix > 0 { | |
| 75 | attrs.push(llvm::CreateAttrStringValue( | |
| 76 | cx.llcx, | |
| 77 | "patchable-function-prefix", | |
| 78 | &format!("{}", prefix), | |
| 79 | )); | |
| 80 | } | |
| 81 | attrs | |
| 82 | } | |
| 83 | ||
| 56 | 84 | /// Get LLVM sanitize attributes. |
| 57 | 85 | #[inline] |
| 58 | 86 | pub fn sanitize_attrs<'ll>( |
| ... | ... | @@ -421,6 +449,7 @@ pub fn from_fn_attrs<'ll, 'tcx>( |
| 421 | 449 | llvm::set_alignment(llfn, align); |
| 422 | 450 | } |
| 423 | 451 | to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize)); |
| 452 | to_add.extend(patchable_function_entry_attrs(cx, codegen_fn_attrs.patchable_function_entry)); | |
| 424 | 453 | |
| 425 | 454 | // Always annotate functions with the target-cpu they are compiled for. |
| 426 | 455 | // Without this, ThinLTO won't inline Rust functions into Clang generated |
compiler/rustc_codegen_ssa/src/codegen_attrs.rs+78-2| ... | ... | @@ -1,11 +1,13 @@ |
| 1 | 1 | use rustc_ast::{ast, attr, MetaItemKind, NestedMetaItem}; |
| 2 | 2 | use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr}; |
| 3 | use rustc_errors::{codes::*, struct_span_code_err}; | |
| 3 | use rustc_errors::{codes::*, struct_span_code_err, DiagMessage, SubdiagMessage}; | |
| 4 | 4 | use rustc_hir as hir; |
| 5 | 5 | use rustc_hir::def::DefKind; |
| 6 | 6 | use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; |
| 7 | 7 | use rustc_hir::{lang_items, weak_lang_items::WEAK_LANG_ITEMS, LangItem}; |
| 8 | use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; | |
| 8 | use rustc_middle::middle::codegen_fn_attrs::{ | |
| 9 | CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, | |
| 10 | }; | |
| 9 | 11 | use rustc_middle::mir::mono::Linkage; |
| 10 | 12 | use rustc_middle::query::Providers; |
| 11 | 13 | use rustc_middle::ty::{self as ty, TyCtxt}; |
| ... | ... | @@ -447,6 +449,80 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { |
| 447 | 449 | None |
| 448 | 450 | }; |
| 449 | 451 | } |
| 452 | sym::patchable_function_entry => { | |
| 453 | codegen_fn_attrs.patchable_function_entry = attr.meta_item_list().and_then(|l| { | |
| 454 | let mut prefix = None; | |
| 455 | let mut entry = None; | |
| 456 | for item in l { | |
| 457 | let Some(meta_item) = item.meta_item() else { | |
| 458 | tcx.dcx().span_err(item.span(), "expected name value pair"); | |
| 459 | continue; | |
| 460 | }; | |
| 461 | ||
| 462 | let Some(name_value_lit) = meta_item.name_value_literal() else { | |
| 463 | tcx.dcx().span_err(item.span(), "expected name value pair"); | |
| 464 | continue; | |
| 465 | }; | |
| 466 | ||
| 467 | fn emit_error_with_label( | |
| 468 | tcx: TyCtxt<'_>, | |
| 469 | span: Span, | |
| 470 | error: impl Into<DiagMessage>, | |
| 471 | label: impl Into<SubdiagMessage>, | |
| 472 | ) { | |
| 473 | let mut err: rustc_errors::Diag<'_, _> = | |
| 474 | tcx.dcx().struct_span_err(span, error); | |
| 475 | err.span_label(span, label); | |
| 476 | err.emit(); | |
| 477 | } | |
| 478 | ||
| 479 | let attrib_to_write = match meta_item.name_or_empty() { | |
| 480 | sym::prefix_nops => &mut prefix, | |
| 481 | sym::entry_nops => &mut entry, | |
| 482 | _ => { | |
| 483 | emit_error_with_label( | |
| 484 | tcx, | |
| 485 | item.span(), | |
| 486 | "unexpected parameter name", | |
| 487 | format!("expected {} or {}", sym::prefix_nops, sym::entry_nops), | |
| 488 | ); | |
| 489 | continue; | |
| 490 | } | |
| 491 | }; | |
| 492 | ||
| 493 | let rustc_ast::LitKind::Int(val, _) = name_value_lit.kind else { | |
| 494 | emit_error_with_label( | |
| 495 | tcx, | |
| 496 | name_value_lit.span, | |
| 497 | "invalid literal value", | |
| 498 | "value must be an integer between `0` and `255`", | |
| 499 | ); | |
| 500 | continue; | |
| 501 | }; | |
| 502 | ||
| 503 | let Ok(val) = val.get().try_into() else { | |
| 504 | emit_error_with_label( | |
| 505 | tcx, | |
| 506 | name_value_lit.span, | |
| 507 | "integer value out of range", | |
| 508 | "value must be between `0` and `255`", | |
| 509 | ); | |
| 510 | continue; | |
| 511 | }; | |
| 512 | ||
| 513 | *attrib_to_write = Some(val); | |
| 514 | } | |
| 515 | ||
| 516 | if let (None, None) = (prefix, entry) { | |
| 517 | tcx.dcx().span_err(attr.span, "must specify at least one parameter"); | |
| 518 | } | |
| 519 | ||
| 520 | Some(PatchableFunctionEntry::from_prefix_and_entry( | |
| 521 | prefix.unwrap_or(0), | |
| 522 | entry.unwrap_or(0), | |
| 523 | )) | |
| 524 | }) | |
| 525 | } | |
| 450 | 526 | _ => {} |
| 451 | 527 | } |
| 452 | 528 | } |
compiler/rustc_feature/src/builtin_attrs.rs+7| ... | ... | @@ -585,6 +585,13 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ |
| 585 | 585 | EncodeCrossCrate::No, derive_smart_pointer, experimental!(pointee) |
| 586 | 586 | ), |
| 587 | 587 | |
| 588 | // RFC 3543 | |
| 589 | // `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` | |
| 590 | gated!( | |
| 591 | patchable_function_entry, Normal, template!(List: "prefix_nops = m, entry_nops = n"), ErrorPreceding, | |
| 592 | EncodeCrossCrate::Yes, experimental!(patchable_function_entry) | |
| 593 | ), | |
| 594 | ||
| 588 | 595 | // ========================================================================== |
| 589 | 596 | // Internal attributes: Stability, deprecation, and unsafe: |
| 590 | 597 | // ========================================================================== |
compiler/rustc_feature/src/unstable.rs+2| ... | ... | @@ -563,6 +563,8 @@ declare_features! ( |
| 563 | 563 | (unstable, offset_of_slice, "CURRENT_RUSTC_VERSION", Some(126151)), |
| 564 | 564 | /// Allows using `#[optimize(X)]`. |
| 565 | 565 | (unstable, optimize_attribute, "1.34.0", Some(54882)), |
| 566 | /// Allows specifying nop padding on functions for dynamic patching. | |
| 567 | (unstable, patchable_function_entry, "CURRENT_RUSTC_VERSION", Some(123115)), | |
| 566 | 568 | /// Allows postfix match `expr.match { ... }` |
| 567 | 569 | (unstable, postfix_match, "1.79.0", Some(121618)), |
| 568 | 570 | /// Allows `use<'a, 'b, A, B>` in `impl Trait + use<...>` for precise capture of generic args. |
compiler/rustc_interface/src/tests.rs+7-2| ... | ... | @@ -8,8 +8,8 @@ use rustc_session::config::{ |
| 8 | 8 | ErrorOutputType, ExternEntry, ExternLocation, Externs, FunctionReturn, InliningThreshold, |
| 9 | 9 | Input, InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, |
| 10 | 10 | LtoCli, NextSolverConfig, OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, |
| 11 | PacRet, Passes, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, | |
| 12 | SymbolManglingVersion, WasiExecModel, | |
| 11 | PacRet, Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, | |
| 12 | SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, | |
| 13 | 13 | }; |
| 14 | 14 | use rustc_session::lint::Level; |
| 15 | 15 | use rustc_session::search_paths::SearchPath; |
| ... | ... | @@ -813,6 +813,11 @@ fn test_unstable_options_tracking_hash() { |
| 813 | 813 | tracked!(packed_bundled_libs, true); |
| 814 | 814 | tracked!(panic_abort_tests, true); |
| 815 | 815 | tracked!(panic_in_drop, PanicStrategy::Abort); |
| 816 | tracked!( | |
| 817 | patchable_function_entry, | |
| 818 | PatchableFunctionEntry::from_total_and_prefix_nops(10, 5) | |
| 819 | .expect("total must be greater than or equal to prefix") | |
| 820 | ); | |
| 816 | 821 | tracked!(plt, Some(true)); |
| 817 | 822 | tracked!(polonius, Polonius::Legacy); |
| 818 | 823 | tracked!(precise_enum_drop_elaboration, false); |
compiler/rustc_middle/src/middle/codegen_fn_attrs.rs+27| ... | ... | @@ -45,6 +45,32 @@ pub struct CodegenFnAttrs { |
| 45 | 45 | /// The `#[repr(align(...))]` attribute. Indicates the value of which the function should be |
| 46 | 46 | /// aligned to. |
| 47 | 47 | pub alignment: Option<Align>, |
| 48 | /// The `#[patchable_function_entry(...)]` attribute. Indicates how many nops should be around | |
| 49 | /// the function entry. | |
| 50 | pub patchable_function_entry: Option<PatchableFunctionEntry>, | |
| 51 | } | |
| 52 | ||
| 53 | #[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)] | |
| 54 | pub struct PatchableFunctionEntry { | |
| 55 | /// Nops to prepend to the function | |
| 56 | prefix: u8, | |
| 57 | /// Nops after entry, but before body | |
| 58 | entry: u8, | |
| 59 | } | |
| 60 | ||
| 61 | impl PatchableFunctionEntry { | |
| 62 | pub fn from_config(config: rustc_session::config::PatchableFunctionEntry) -> Self { | |
| 63 | Self { prefix: config.prefix(), entry: config.entry() } | |
| 64 | } | |
| 65 | pub fn from_prefix_and_entry(prefix: u8, entry: u8) -> Self { | |
| 66 | Self { prefix, entry } | |
| 67 | } | |
| 68 | pub fn prefix(&self) -> u8 { | |
| 69 | self.prefix | |
| 70 | } | |
| 71 | pub fn entry(&self) -> u8 { | |
| 72 | self.entry | |
| 73 | } | |
| 48 | 74 | } |
| 49 | 75 | |
| 50 | 76 | #[derive(Clone, Copy, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)] |
| ... | ... | @@ -121,6 +147,7 @@ impl CodegenFnAttrs { |
| 121 | 147 | no_sanitize: SanitizerSet::empty(), |
| 122 | 148 | instruction_set: None, |
| 123 | 149 | alignment: None, |
| 150 | patchable_function_entry: None, | |
| 124 | 151 | } |
| 125 | 152 | } |
| 126 | 153 |
compiler/rustc_parse/src/parser/expr.rs+3-2| ... | ... | @@ -3432,8 +3432,9 @@ impl<'a> Parser<'a> { |
| 3432 | 3432 | } |
| 3433 | 3433 | } |
| 3434 | 3434 | let capture_clause = self.parse_capture_clause()?; |
| 3435 | let decl_span = lo.to(self.prev_token.span); | |
| 3435 | 3436 | let (attrs, body) = self.parse_inner_attrs_and_block()?; |
| 3436 | let kind = ExprKind::Gen(capture_clause, body, kind); | |
| 3437 | let kind = ExprKind::Gen(capture_clause, body, kind, decl_span); | |
| 3437 | 3438 | Ok(self.mk_expr_with_attrs(lo.to(self.prev_token.span), kind, attrs)) |
| 3438 | 3439 | } |
| 3439 | 3440 | |
| ... | ... | @@ -4022,7 +4023,7 @@ impl MutVisitor for CondChecker<'_> { |
| 4022 | 4023 | | ExprKind::Match(_, _, _) |
| 4023 | 4024 | | ExprKind::Closure(_) |
| 4024 | 4025 | | ExprKind::Block(_, _) |
| 4025 | | ExprKind::Gen(_, _, _) | |
| 4026 | | ExprKind::Gen(_, _, _, _) | |
| 4026 | 4027 | | ExprKind::TryBlock(_) |
| 4027 | 4028 | | ExprKind::Underscore |
| 4028 | 4029 | | ExprKind::Path(_, _) |
compiler/rustc_resolve/src/def_collector.rs+1-1| ... | ... | @@ -334,7 +334,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { |
| 334 | 334 | None => closure_def, |
| 335 | 335 | } |
| 336 | 336 | } |
| 337 | ExprKind::Gen(_, _, _) => { | |
| 337 | ExprKind::Gen(_, _, _, _) => { | |
| 338 | 338 | self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span) |
| 339 | 339 | } |
| 340 | 340 | ExprKind::ConstBlock(ref constant) => { |
compiler/rustc_session/src/config.rs+33-2| ... | ... | @@ -2965,8 +2965,9 @@ pub(crate) mod dep_tracking { |
| 2965 | 2965 | CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FunctionReturn, |
| 2966 | 2966 | InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail, |
| 2967 | 2967 | LtoCli, NextSolverConfig, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes, |
| 2968 | Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm, | |
| 2969 | SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, | |
| 2968 | PatchableFunctionEntry, Polonius, RemapPathScopeComponents, ResolveDocLinks, | |
| 2969 | SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, | |
| 2970 | WasiExecModel, | |
| 2970 | 2971 | }; |
| 2971 | 2972 | use crate::lint; |
| 2972 | 2973 | use crate::utils::NativeLib; |
| ... | ... | @@ -3073,6 +3074,7 @@ pub(crate) mod dep_tracking { |
| 3073 | 3074 | OomStrategy, |
| 3074 | 3075 | LanguageIdentifier, |
| 3075 | 3076 | NextSolverConfig, |
| 3077 | PatchableFunctionEntry, | |
| 3076 | 3078 | Polonius, |
| 3077 | 3079 | InliningThreshold, |
| 3078 | 3080 | FunctionReturn, |
| ... | ... | @@ -3250,6 +3252,35 @@ impl DumpMonoStatsFormat { |
| 3250 | 3252 | } |
| 3251 | 3253 | } |
| 3252 | 3254 | |
| 3255 | /// `-Z patchable-function-entry` representation - how many nops to put before and after function | |
| 3256 | /// entry. | |
| 3257 | #[derive(Clone, Copy, PartialEq, Hash, Debug, Default)] | |
| 3258 | pub struct PatchableFunctionEntry { | |
| 3259 | /// Nops before the entry | |
| 3260 | prefix: u8, | |
| 3261 | /// Nops after the entry | |
| 3262 | entry: u8, | |
| 3263 | } | |
| 3264 | ||
| 3265 | impl PatchableFunctionEntry { | |
| 3266 | pub fn from_total_and_prefix_nops( | |
| 3267 | total_nops: u8, | |
| 3268 | prefix_nops: u8, | |
| 3269 | ) -> Option<PatchableFunctionEntry> { | |
| 3270 | if total_nops < prefix_nops { | |
| 3271 | None | |
| 3272 | } else { | |
| 3273 | Some(Self { prefix: prefix_nops, entry: total_nops - prefix_nops }) | |
| 3274 | } | |
| 3275 | } | |
| 3276 | pub fn prefix(&self) -> u8 { | |
| 3277 | self.prefix | |
| 3278 | } | |
| 3279 | pub fn entry(&self) -> u8 { | |
| 3280 | self.entry | |
| 3281 | } | |
| 3282 | } | |
| 3283 | ||
| 3253 | 3284 | /// `-Zpolonius` values, enabling the borrow checker polonius analysis, and which version: legacy, |
| 3254 | 3285 | /// or future prototype. |
| 3255 | 3286 | #[derive(Clone, Copy, PartialEq, Hash, Debug, Default)] |
compiler/rustc_session/src/options.rs+29| ... | ... | @@ -379,6 +379,7 @@ mod desc { |
| 379 | 379 | pub const parse_passes: &str = "a space-separated list of passes, or `all`"; |
| 380 | 380 | pub const parse_panic_strategy: &str = "either `unwind` or `abort`"; |
| 381 | 381 | pub const parse_on_broken_pipe: &str = "either `kill`, `error`, or `inherit`"; |
| 382 | pub const parse_patchable_function_entry: &str = "either two comma separated integers (total_nops,prefix_nops), with prefix_nops <= total_nops, or one integer (total_nops)"; | |
| 382 | 383 | pub const parse_opt_panic_strategy: &str = parse_panic_strategy; |
| 383 | 384 | pub const parse_oom_strategy: &str = "either `panic` or `abort`"; |
| 384 | 385 | pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`"; |
| ... | ... | @@ -734,6 +735,32 @@ mod parse { |
| 734 | 735 | true |
| 735 | 736 | } |
| 736 | 737 | |
| 738 | pub(crate) fn parse_patchable_function_entry( | |
| 739 | slot: &mut PatchableFunctionEntry, | |
| 740 | v: Option<&str>, | |
| 741 | ) -> bool { | |
| 742 | let mut total_nops = 0; | |
| 743 | let mut prefix_nops = 0; | |
| 744 | ||
| 745 | if !parse_number(&mut total_nops, v) { | |
| 746 | let parts = v.and_then(|v| v.split_once(',')).unzip(); | |
| 747 | if !parse_number(&mut total_nops, parts.0) { | |
| 748 | return false; | |
| 749 | } | |
| 750 | if !parse_number(&mut prefix_nops, parts.1) { | |
| 751 | return false; | |
| 752 | } | |
| 753 | } | |
| 754 | ||
| 755 | if let Some(pfe) = | |
| 756 | PatchableFunctionEntry::from_total_and_prefix_nops(total_nops, prefix_nops) | |
| 757 | { | |
| 758 | *slot = pfe; | |
| 759 | return true; | |
| 760 | } | |
| 761 | false | |
| 762 | } | |
| 763 | ||
| 737 | 764 | pub(crate) fn parse_oom_strategy(slot: &mut OomStrategy, v: Option<&str>) -> bool { |
| 738 | 765 | match v { |
| 739 | 766 | Some("panic") => *slot = OomStrategy::Panic, |
| ... | ... | @@ -1859,6 +1886,8 @@ options! { |
| 1859 | 1886 | "panic strategy for panics in drops"), |
| 1860 | 1887 | parse_only: bool = (false, parse_bool, [UNTRACKED], |
| 1861 | 1888 | "parse only; do not compile, assemble, or link (default: no)"), |
| 1889 | patchable_function_entry: PatchableFunctionEntry = (PatchableFunctionEntry::default(), parse_patchable_function_entry, [TRACKED], | |
| 1890 | "nop padding at function entry"), | |
| 1862 | 1891 | plt: Option<bool> = (None, parse_opt_bool, [TRACKED], |
| 1863 | 1892 | "whether to use the PLT when calling into shared libraries; |
| 1864 | 1893 | only has effect for PIC code on systems with ELF binaries |
compiler/rustc_smir/Cargo.toml+2| ... | ... | @@ -6,6 +6,8 @@ edition = "2021" |
| 6 | 6 | [dependencies] |
| 7 | 7 | # tidy-alphabetical-start |
| 8 | 8 | rustc_abi = { path = "../rustc_abi" } |
| 9 | rustc_ast = { path = "../rustc_ast" } | |
| 10 | rustc_ast_pretty = { path = "../rustc_ast_pretty" } | |
| 9 | 11 | rustc_data_structures = { path = "../rustc_data_structures" } |
| 10 | 12 | rustc_hir = { path = "../rustc_hir" } |
| 11 | 13 | rustc_middle = { path = "../rustc_middle" } |
compiler/rustc_smir/src/rustc_smir/context.rs+40| ... | ... | @@ -228,6 +228,46 @@ impl<'tcx> Context for TablesWrapper<'tcx> { |
| 228 | 228 | } |
| 229 | 229 | } |
| 230 | 230 | |
| 231 | fn get_attrs_by_path( | |
| 232 | &self, | |
| 233 | def_id: stable_mir::DefId, | |
| 234 | attr: &[stable_mir::Symbol], | |
| 235 | ) -> Vec<stable_mir::crate_def::Attribute> { | |
| 236 | let mut tables = self.0.borrow_mut(); | |
| 237 | let tcx = tables.tcx; | |
| 238 | let did = tables[def_id]; | |
| 239 | let attr_name: Vec<_> = | |
| 240 | attr.iter().map(|seg| rustc_span::symbol::Symbol::intern(&seg)).collect(); | |
| 241 | tcx.get_attrs_by_path(did, &attr_name) | |
| 242 | .map(|attribute| { | |
| 243 | let attr_str = rustc_ast_pretty::pprust::attribute_to_string(attribute); | |
| 244 | let span = attribute.span; | |
| 245 | stable_mir::crate_def::Attribute::new(attr_str, span.stable(&mut *tables)) | |
| 246 | }) | |
| 247 | .collect() | |
| 248 | } | |
| 249 | ||
| 250 | fn get_all_attrs(&self, def_id: stable_mir::DefId) -> Vec<stable_mir::crate_def::Attribute> { | |
| 251 | let mut tables = self.0.borrow_mut(); | |
| 252 | let tcx = tables.tcx; | |
| 253 | let did = tables[def_id]; | |
| 254 | let filter_fn = move |a: &&rustc_ast::ast::Attribute| { | |
| 255 | matches!(a.kind, rustc_ast::ast::AttrKind::Normal(_)) | |
| 256 | }; | |
| 257 | let attrs_iter = if let Some(did) = did.as_local() { | |
| 258 | tcx.hir().attrs(tcx.local_def_id_to_hir_id(did)).iter().filter(filter_fn) | |
| 259 | } else { | |
| 260 | tcx.item_attrs(did).iter().filter(filter_fn) | |
| 261 | }; | |
| 262 | attrs_iter | |
| 263 | .map(|attribute| { | |
| 264 | let attr_str = rustc_ast_pretty::pprust::attribute_to_string(attribute); | |
| 265 | let span = attribute.span; | |
| 266 | stable_mir::crate_def::Attribute::new(attr_str, span.stable(&mut *tables)) | |
| 267 | }) | |
| 268 | .collect() | |
| 269 | } | |
| 270 | ||
| 231 | 271 | fn span_to_string(&self, span: stable_mir::ty::Span) -> String { |
| 232 | 272 | let tables = self.0.borrow(); |
| 233 | 273 | tables.tcx.sess.source_map().span_to_diagnostic_string(tables[span]) |
compiler/rustc_span/src/symbol.rs+3| ... | ... | @@ -768,6 +768,7 @@ symbols! { |
| 768 | 768 | enable, |
| 769 | 769 | encode, |
| 770 | 770 | end, |
| 771 | entry_nops, | |
| 771 | 772 | enumerate_method, |
| 772 | 773 | env, |
| 773 | 774 | env_CFG_RELEASE: env!("CFG_RELEASE"), |
| ... | ... | @@ -1383,6 +1384,7 @@ symbols! { |
| 1383 | 1384 | passes, |
| 1384 | 1385 | pat, |
| 1385 | 1386 | pat_param, |
| 1387 | patchable_function_entry, | |
| 1386 | 1388 | path, |
| 1387 | 1389 | pattern_complexity, |
| 1388 | 1390 | pattern_parentheses, |
| ... | ... | @@ -1421,6 +1423,7 @@ symbols! { |
| 1421 | 1423 | prefetch_read_instruction, |
| 1422 | 1424 | prefetch_write_data, |
| 1423 | 1425 | prefetch_write_instruction, |
| 1426 | prefix_nops, | |
| 1424 | 1427 | preg, |
| 1425 | 1428 | prelude, |
| 1426 | 1429 | prelude_import, |
compiler/stable_mir/src/compiler_interface.rs+10| ... | ... | @@ -6,6 +6,7 @@ |
| 6 | 6 | use std::cell::Cell; |
| 7 | 7 | |
| 8 | 8 | use crate::abi::{FnAbi, Layout, LayoutShape}; |
| 9 | use crate::crate_def::Attribute; | |
| 9 | 10 | use crate::mir::alloc::{AllocId, GlobalAlloc}; |
| 10 | 11 | use crate::mir::mono::{Instance, InstanceDef, StaticDef}; |
| 11 | 12 | use crate::mir::{BinOp, Body, Place, UnOp}; |
| ... | ... | @@ -55,6 +56,15 @@ pub trait Context { |
| 55 | 56 | /// Returns the name of given `DefId` |
| 56 | 57 | fn def_name(&self, def_id: DefId, trimmed: bool) -> Symbol; |
| 57 | 58 | |
| 59 | /// Return attributes with the given attribute name. | |
| 60 | /// | |
| 61 | /// Single segmented name like `#[inline]` is specified as `&["inline".to_string()]`. | |
| 62 | /// Multi-segmented name like `#[rustfmt::skip]` is specified as `&["rustfmt".to_string(), "skip".to_string()]`. | |
| 63 | fn get_attrs_by_path(&self, def_id: DefId, attr: &[Symbol]) -> Vec<Attribute>; | |
| 64 | ||
| 65 | /// Get all attributes of a definition. | |
| 66 | fn get_all_attrs(&self, def_id: DefId) -> Vec<Attribute>; | |
| 67 | ||
| 58 | 68 | /// Returns printable, human readable form of `Span` |
| 59 | 69 | fn span_to_string(&self, span: Span) -> String; |
| 60 | 70 |
compiler/stable_mir/src/crate_def.rs+37| ... | ... | @@ -50,6 +50,21 @@ pub trait CrateDef { |
| 50 | 50 | let def_id = self.def_id(); |
| 51 | 51 | with(|cx| cx.span_of_an_item(def_id)) |
| 52 | 52 | } |
| 53 | ||
| 54 | /// Return attributes with the given attribute name. | |
| 55 | /// | |
| 56 | /// Single segmented name like `#[inline]` is specified as `&["inline".to_string()]`. | |
| 57 | /// Multi-segmented name like `#[rustfmt::skip]` is specified as `&["rustfmt".to_string(), "skip".to_string()]`. | |
| 58 | fn attrs_by_path(&self, attr: &[Symbol]) -> Vec<Attribute> { | |
| 59 | let def_id = self.def_id(); | |
| 60 | with(|cx| cx.get_attrs_by_path(def_id, attr)) | |
| 61 | } | |
| 62 | ||
| 63 | /// Return all attributes of this definition. | |
| 64 | fn all_attrs(&self) -> Vec<Attribute> { | |
| 65 | let def_id = self.def_id(); | |
| 66 | with(|cx| cx.get_all_attrs(def_id)) | |
| 67 | } | |
| 53 | 68 | } |
| 54 | 69 | |
| 55 | 70 | /// A trait that can be used to retrieve a definition's type. |
| ... | ... | @@ -69,6 +84,28 @@ pub trait CrateDefType: CrateDef { |
| 69 | 84 | } |
| 70 | 85 | } |
| 71 | 86 | |
| 87 | #[derive(Clone, Debug, PartialEq, Eq)] | |
| 88 | pub struct Attribute { | |
| 89 | value: String, | |
| 90 | span: Span, | |
| 91 | } | |
| 92 | ||
| 93 | impl Attribute { | |
| 94 | pub fn new(value: String, span: Span) -> Attribute { | |
| 95 | Attribute { value, span } | |
| 96 | } | |
| 97 | ||
| 98 | /// Get the span of this attribute. | |
| 99 | pub fn span(&self) -> Span { | |
| 100 | self.span | |
| 101 | } | |
| 102 | ||
| 103 | /// Get the string representation of this attribute. | |
| 104 | pub fn as_str(&self) -> &str { | |
| 105 | &self.value | |
| 106 | } | |
| 107 | } | |
| 108 | ||
| 72 | 109 | macro_rules! crate_def { |
| 73 | 110 | ( $(#[$attr:meta])* |
| 74 | 111 | $vis:vis $name:ident $(;)? |
library/alloc/src/str.rs+4-3| ... | ... | @@ -206,15 +206,16 @@ impl BorrowMut<str> for String { |
| 206 | 206 | #[stable(feature = "rust1", since = "1.0.0")] |
| 207 | 207 | impl ToOwned for str { |
| 208 | 208 | type Owned = String; |
| 209 | ||
| 209 | 210 | #[inline] |
| 210 | 211 | fn to_owned(&self) -> String { |
| 211 | 212 | unsafe { String::from_utf8_unchecked(self.as_bytes().to_owned()) } |
| 212 | 213 | } |
| 213 | 214 | |
| 215 | #[inline] | |
| 214 | 216 | fn clone_into(&self, target: &mut String) { |
| 215 | let mut b = mem::take(target).into_bytes(); | |
| 216 | self.as_bytes().clone_into(&mut b); | |
| 217 | *target = unsafe { String::from_utf8_unchecked(b) } | |
| 217 | target.clear(); | |
| 218 | target.push_str(self); | |
| 218 | 219 | } |
| 219 | 220 | } |
| 220 | 221 |
library/core/src/fmt/mod.rs+6| ... | ... | @@ -459,6 +459,12 @@ impl<'a> Arguments<'a> { |
| 459 | 459 | } |
| 460 | 460 | } |
| 461 | 461 | |
| 462 | // Manually implementing these results in better error messages. | |
| 463 | #[stable(feature = "rust1", since = "1.0.0")] | |
| 464 | impl !Send for Arguments<'_> {} | |
| 465 | #[stable(feature = "rust1", since = "1.0.0")] | |
| 466 | impl !Sync for Arguments<'_> {} | |
| 467 | ||
| 462 | 468 | #[stable(feature = "rust1", since = "1.0.0")] |
| 463 | 469 | impl Debug for Arguments<'_> { |
| 464 | 470 | fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { |
library/core/src/fmt/rt.rs+25-21| ... | ... | @@ -5,6 +5,7 @@ |
| 5 | 5 | |
| 6 | 6 | use super::*; |
| 7 | 7 | use crate::hint::unreachable_unchecked; |
| 8 | use crate::ptr::NonNull; | |
| 8 | 9 | |
| 9 | 10 | #[lang = "format_placeholder"] |
| 10 | 11 | #[derive(Copy, Clone)] |
| ... | ... | @@ -66,7 +67,13 @@ pub(super) enum Flag { |
| 66 | 67 | |
| 67 | 68 | #[derive(Copy, Clone)] |
| 68 | 69 | enum ArgumentType<'a> { |
| 69 | Placeholder { value: &'a Opaque, formatter: fn(&Opaque, &mut Formatter<'_>) -> Result }, | |
| 70 | Placeholder { | |
| 71 | // INVARIANT: `formatter` has type `fn(&T, _) -> _` for some `T`, and `value` | |
| 72 | // was derived from a `&'a T`. | |
| 73 | value: NonNull<()>, | |
| 74 | formatter: unsafe fn(NonNull<()>, &mut Formatter<'_>) -> Result, | |
| 75 | _lifetime: PhantomData<&'a ()>, | |
| 76 | }, | |
| 70 | 77 | Count(usize), |
| 71 | 78 | } |
| 72 | 79 | |
| ... | ... | @@ -90,21 +97,15 @@ pub struct Argument<'a> { |
| 90 | 97 | impl<'a> Argument<'a> { |
| 91 | 98 | #[inline(always)] |
| 92 | 99 | fn new<'b, T>(x: &'b T, f: fn(&T, &mut Formatter<'_>) -> Result) -> Argument<'b> { |
| 93 | // SAFETY: `mem::transmute(x)` is safe because | |
| 94 | // 1. `&'b T` keeps the lifetime it originated with `'b` | |
| 95 | // (so as to not have an unbounded lifetime) | |
| 96 | // 2. `&'b T` and `&'b Opaque` have the same memory layout | |
| 97 | // (when `T` is `Sized`, as it is here) | |
| 98 | // `mem::transmute(f)` is safe since `fn(&T, &mut Formatter<'_>) -> Result` | |
| 99 | // and `fn(&Opaque, &mut Formatter<'_>) -> Result` have the same ABI | |
| 100 | // (as long as `T` is `Sized`) | |
| 101 | unsafe { | |
| 102 | Argument { | |
| 103 | ty: ArgumentType::Placeholder { | |
| 104 | formatter: mem::transmute(f), | |
| 105 | value: mem::transmute(x), | |
| 106 | }, | |
| 107 | } | |
| 100 | Argument { | |
| 101 | // INVARIANT: this creates an `ArgumentType<'b>` from a `&'b T` and | |
| 102 | // a `fn(&T, ...)`, so the invariant is maintained. | |
| 103 | ty: ArgumentType::Placeholder { | |
| 104 | value: NonNull::from(x).cast(), | |
| 105 | // SAFETY: function pointers always have the same layout. | |
| 106 | formatter: unsafe { mem::transmute(f) }, | |
| 107 | _lifetime: PhantomData, | |
| 108 | }, | |
| 108 | 109 | } |
| 109 | 110 | } |
| 110 | 111 | |
| ... | ... | @@ -162,7 +163,14 @@ impl<'a> Argument<'a> { |
| 162 | 163 | #[inline(always)] |
| 163 | 164 | pub(super) unsafe fn fmt(&self, f: &mut Formatter<'_>) -> Result { |
| 164 | 165 | match self.ty { |
| 165 | ArgumentType::Placeholder { formatter, value } => formatter(value, f), | |
| 166 | // SAFETY: | |
| 167 | // Because of the invariant that if `formatter` had the type | |
| 168 | // `fn(&T, _) -> _` then `value` has type `&'b T` where `'b` is | |
| 169 | // the lifetime of the `ArgumentType`, and because references | |
| 170 | // and `NonNull` are ABI-compatible, this is completely equivalent | |
| 171 | // to calling the original function passed to `new` with the | |
| 172 | // original reference, which is sound. | |
| 173 | ArgumentType::Placeholder { formatter, value, .. } => unsafe { formatter(value, f) }, | |
| 166 | 174 | // SAFETY: the caller promised this. |
| 167 | 175 | ArgumentType::Count(_) => unsafe { unreachable_unchecked() }, |
| 168 | 176 | } |
| ... | ... | @@ -208,7 +216,3 @@ impl UnsafeArg { |
| 208 | 216 | Self { _private: () } |
| 209 | 217 | } |
| 210 | 218 | } |
| 211 | ||
| 212 | extern "C" { | |
| 213 | type Opaque; | |
| 214 | } |
src/bootstrap/src/core/build_steps/doc.rs+18-24| ... | ... | @@ -888,12 +888,11 @@ impl Step for Rustc { |
| 888 | 888 | macro_rules! tool_doc { |
| 889 | 889 | ( |
| 890 | 890 | $tool: ident, |
| 891 | $should_run: literal, | |
| 892 | 891 | $path: literal, |
| 893 | 892 | $(rustc_tool = $rustc_tool:literal, )? |
| 894 | $(in_tree = $in_tree:literal ,)? | |
| 895 | 893 | $(is_library = $is_library:expr,)? |
| 896 | 894 | $(crates = $crates:expr)? |
| 895 | $(, submodule $(= $submodule:literal)? )? | |
| 897 | 896 | ) => { |
| 898 | 897 | #[derive(Debug, Clone, Hash, PartialEq, Eq)] |
| 899 | 898 | pub struct $tool { |
| ... | ... | @@ -907,7 +906,7 @@ macro_rules! tool_doc { |
| 907 | 906 | |
| 908 | 907 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { |
| 909 | 908 | let builder = run.builder; |
| 910 | run.crate_or_deps($should_run).default_condition(builder.config.compiler_docs) | |
| 909 | run.path($path).default_condition(builder.config.compiler_docs) | |
| 911 | 910 | } |
| 912 | 911 | |
| 913 | 912 | fn make_run(run: RunConfig<'_>) { |
| ... | ... | @@ -921,6 +920,15 @@ macro_rules! tool_doc { |
| 921 | 920 | /// we do not merge it with the other documentation from std, test and |
| 922 | 921 | /// proc_macros. This is largely just a wrapper around `cargo doc`. |
| 923 | 922 | fn run(self, builder: &Builder<'_>) { |
| 923 | let source_type = SourceType::InTree; | |
| 924 | $( | |
| 925 | let _ = source_type; // silence the "unused variable" warning | |
| 926 | let source_type = SourceType::Submodule; | |
| 927 | ||
| 928 | let path = Path::new(submodule_helper!( $path, submodule $( = $submodule )? )); | |
| 929 | builder.update_submodule(&path); | |
| 930 | )? | |
| 931 | ||
| 924 | 932 | let stage = builder.top_stage; |
| 925 | 933 | let target = self.target; |
| 926 | 934 | |
| ... | ... | @@ -941,12 +949,6 @@ macro_rules! tool_doc { |
| 941 | 949 | builder.ensure(compile::Rustc::new(compiler, target)); |
| 942 | 950 | } |
| 943 | 951 | |
| 944 | let source_type = if true $(&& $in_tree)? { | |
| 945 | SourceType::InTree | |
| 946 | } else { | |
| 947 | SourceType::Submodule | |
| 948 | }; | |
| 949 | ||
| 950 | 952 | // Build cargo command. |
| 951 | 953 | let mut cargo = prepare_tool_cargo( |
| 952 | 954 | builder, |
| ... | ... | @@ -1008,21 +1010,14 @@ macro_rules! tool_doc { |
| 1008 | 1010 | } |
| 1009 | 1011 | } |
| 1010 | 1012 | |
| 1011 | tool_doc!(Rustdoc, "rustdoc-tool", "src/tools/rustdoc", crates = ["rustdoc", "rustdoc-json-types"]); | |
| 1012 | tool_doc!( | |
| 1013 | Rustfmt, | |
| 1014 | "rustfmt-nightly", | |
| 1015 | "src/tools/rustfmt", | |
| 1016 | crates = ["rustfmt-nightly", "rustfmt-config_proc_macro"] | |
| 1017 | ); | |
| 1018 | tool_doc!(Clippy, "clippy", "src/tools/clippy", crates = ["clippy_config", "clippy_utils"]); | |
| 1019 | tool_doc!(Miri, "miri", "src/tools/miri", crates = ["miri"]); | |
| 1013 | tool_doc!(Rustdoc, "src/tools/rustdoc", crates = ["rustdoc", "rustdoc-json-types"]); | |
| 1014 | tool_doc!(Rustfmt, "src/tools/rustfmt", crates = ["rustfmt-nightly", "rustfmt-config_proc_macro"]); | |
| 1015 | tool_doc!(Clippy, "src/tools/clippy", crates = ["clippy_config", "clippy_utils"]); | |
| 1016 | tool_doc!(Miri, "src/tools/miri", crates = ["miri"]); | |
| 1020 | 1017 | tool_doc!( |
| 1021 | 1018 | Cargo, |
| 1022 | "cargo", | |
| 1023 | 1019 | "src/tools/cargo", |
| 1024 | 1020 | rustc_tool = false, |
| 1025 | in_tree = false, | |
| 1026 | 1021 | crates = [ |
| 1027 | 1022 | "cargo", |
| 1028 | 1023 | "cargo-credential", |
| ... | ... | @@ -1034,12 +1029,12 @@ tool_doc!( |
| 1034 | 1029 | "crates-io", |
| 1035 | 1030 | "mdman", |
| 1036 | 1031 | "rustfix", |
| 1037 | ] | |
| 1032 | ], | |
| 1033 | submodule = "src/tools/cargo" | |
| 1038 | 1034 | ); |
| 1039 | tool_doc!(Tidy, "tidy", "src/tools/tidy", rustc_tool = false, crates = ["tidy"]); | |
| 1035 | tool_doc!(Tidy, "src/tools/tidy", rustc_tool = false, crates = ["tidy"]); | |
| 1040 | 1036 | tool_doc!( |
| 1041 | 1037 | Bootstrap, |
| 1042 | "bootstrap", | |
| 1043 | 1038 | "src/bootstrap", |
| 1044 | 1039 | rustc_tool = false, |
| 1045 | 1040 | is_library = true, |
| ... | ... | @@ -1047,7 +1042,6 @@ tool_doc!( |
| 1047 | 1042 | ); |
| 1048 | 1043 | tool_doc!( |
| 1049 | 1044 | RunMakeSupport, |
| 1050 | "run_make_support", | |
| 1051 | 1045 | "src/tools/run-make-support", |
| 1052 | 1046 | rustc_tool = false, |
| 1053 | 1047 | is_library = true, |
src/bootstrap/src/core/build_steps/test.rs+3| ... | ... | @@ -2983,6 +2983,9 @@ impl Step for Bootstrap { |
| 2983 | 2983 | let compiler = builder.compiler(0, host); |
| 2984 | 2984 | let _guard = builder.msg(Kind::Test, 0, "bootstrap", host, host); |
| 2985 | 2985 | |
| 2986 | // Some tests require cargo submodule to be present. | |
| 2987 | builder.build.update_submodule(Path::new("src/tools/cargo")); | |
| 2988 | ||
| 2986 | 2989 | let mut check_bootstrap = Command::new(builder.python()); |
| 2987 | 2990 | check_bootstrap |
| 2988 | 2991 | .args(["-m", "unittest", "bootstrap_test.py"]) |
src/bootstrap/src/core/build_steps/tool.rs+2| ... | ... | @@ -656,6 +656,8 @@ impl Step for Cargo { |
| 656 | 656 | } |
| 657 | 657 | |
| 658 | 658 | fn run(self, builder: &Builder<'_>) -> PathBuf { |
| 659 | builder.build.update_submodule(Path::new("src/tools/cargo")); | |
| 660 | ||
| 659 | 661 | builder.ensure(ToolBuild { |
| 660 | 662 | compiler: self.compiler, |
| 661 | 663 | target: self.target, |
src/bootstrap/src/core/build_steps/vendor.rs+4-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; |
| 2 | use std::path::PathBuf; | |
| 2 | use std::path::{Path, PathBuf}; | |
| 3 | 3 | use std::process::Command; |
| 4 | 4 | |
| 5 | 5 | #[derive(Debug, Clone, Hash, PartialEq, Eq)] |
| ... | ... | @@ -34,6 +34,9 @@ impl Step for Vendor { |
| 34 | 34 | cmd.arg("--versioned-dirs"); |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | // cargo submodule must be present for `x vendor` to work. | |
| 38 | builder.build.update_submodule(Path::new("src/tools/cargo")); | |
| 39 | ||
| 37 | 40 | // Sync these paths by default. |
| 38 | 41 | for p in [ |
| 39 | 42 | "src/tools/cargo/Cargo.toml", |
src/bootstrap/src/core/metadata.rs+4-12| ... | ... | @@ -67,9 +67,9 @@ pub fn build(build: &mut Build) { |
| 67 | 67 | |
| 68 | 68 | /// Invokes `cargo metadata` to get package metadata of each workspace member. |
| 69 | 69 | /// |
| 70 | /// Note that `src/tools/cargo` is no longer a workspace member but we still | |
| 71 | /// treat it as one here, by invoking an additional `cargo metadata` command. | |
| 72 | fn workspace_members(build: &Build) -> impl Iterator<Item = Package> { | |
| 70 | /// This is used to resolve specific crate paths in `fn should_run` to compile | |
| 71 | /// particular crate (e.g., `x build sysroot` to build library/sysroot). | |
| 72 | fn workspace_members(build: &Build) -> Vec<Package> { | |
| 73 | 73 | let collect_metadata = |manifest_path| { |
| 74 | 74 | let mut cargo = Command::new(&build.initial_cargo); |
| 75 | 75 | cargo |
| ... | ... | @@ -88,13 +88,5 @@ fn workspace_members(build: &Build) -> impl Iterator<Item = Package> { |
| 88 | 88 | }; |
| 89 | 89 | |
| 90 | 90 | // Collects `metadata.packages` from all workspaces. |
| 91 | let packages = collect_metadata("Cargo.toml"); | |
| 92 | let cargo_packages = collect_metadata("src/tools/cargo/Cargo.toml"); | |
| 93 | let ra_packages = collect_metadata("src/tools/rust-analyzer/Cargo.toml"); | |
| 94 | let bootstrap_packages = collect_metadata("src/bootstrap/Cargo.toml"); | |
| 95 | ||
| 96 | // We only care about the root package from `src/tool/cargo` workspace. | |
| 97 | let cargo_package = cargo_packages.into_iter().find(|pkg| pkg.name == "cargo").into_iter(); | |
| 98 | ||
| 99 | packages.into_iter().chain(cargo_package).chain(ra_packages).chain(bootstrap_packages) | |
| 91 | collect_metadata("Cargo.toml") | |
| 100 | 92 | } |
src/bootstrap/src/lib.rs+1-2| ... | ... | @@ -469,8 +469,7 @@ impl Build { |
| 469 | 469 | |
| 470 | 470 | // Make sure we update these before gathering metadata so we don't get an error about missing |
| 471 | 471 | // Cargo.toml files. |
| 472 | let rust_submodules = | |
| 473 | ["src/tools/cargo", "src/doc/book", "library/backtrace", "library/stdarch"]; | |
| 472 | let rust_submodules = ["src/doc/book", "library/backtrace", "library/stdarch"]; | |
| 474 | 473 | for s in rust_submodules { |
| 475 | 474 | build.update_submodule(Path::new(s)); |
| 476 | 475 | } |
src/doc/unstable-book/src/compiler-flags/patchable-function-entry.md created+24| ... | ... | @@ -0,0 +1,24 @@ |
| 1 | # `patchable-function-entry` | |
| 2 | ||
| 3 | -------------------- | |
| 4 | ||
| 5 | The `-Z patchable-function-entry=total_nops,prefix_nops` or `-Z patchable-function-entry=total_nops` | |
| 6 | compiler flag enables nop padding of function entries with 'total_nops' nops, with | |
| 7 | an offset for the entry of the function at 'prefix_nops' nops. In the second form, | |
| 8 | 'prefix_nops' defaults to 0. | |
| 9 | ||
| 10 | As an illustrative example, `-Z patchable-function-entry=3,2` would produce: | |
| 11 | ||
| 12 | ```text | |
| 13 | nop | |
| 14 | nop | |
| 15 | function_label: | |
| 16 | nop | |
| 17 | //Actual function code begins here | |
| 18 | ``` | |
| 19 | ||
| 20 | This flag is used for hotpatching, especially in the Linux kernel. The flag | |
| 21 | arguments are modeled after the `-fpatchable-function-entry` flag as defined | |
| 22 | for both [Clang](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fpatchable-function-entry) | |
| 23 | and [gcc](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#index-fpatchable-function-entry) | |
| 24 | and is intended to provide the same effect. |
src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs+1-1| ... | ... | @@ -549,7 +549,7 @@ fn ident_difference_expr_with_base_location( |
| 549 | 549 | | (Assign(_, _, _), Assign(_, _, _)) |
| 550 | 550 | | (TryBlock(_), TryBlock(_)) |
| 551 | 551 | | (Await(_, _), Await(_, _)) |
| 552 | | (Gen(_, _, _), Gen(_, _, _)) | |
| 552 | | (Gen(_, _, _, _), Gen(_, _, _, _)) | |
| 553 | 553 | | (Block(_, _), Block(_, _)) |
| 554 | 554 | | (Closure(_), Closure(_)) |
| 555 | 555 | | (Match(_, _, _), Match(_, _, _)) |
src/tools/clippy/clippy_utils/src/ast_utils.rs+1-1| ... | ... | @@ -226,7 +226,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool { |
| 226 | 226 | && eq_fn_decl(lf, rf) |
| 227 | 227 | && eq_expr(le, re) |
| 228 | 228 | }, |
| 229 | (Gen(lc, lb, lk), Gen(rc, rb, rk)) => lc == rc && eq_block(lb, rb) && lk == rk, | |
| 229 | (Gen(lc, lb, lk, _), Gen(rc, rb, rk, _)) => lc == rc && eq_block(lb, rb) && lk == rk, | |
| 230 | 230 | (Range(lf, lt, ll), Range(rf, rt, rl)) => ll == rl && eq_expr_opt(lf, rf) && eq_expr_opt(lt, rt), |
| 231 | 231 | (AddrOf(lbk, lm, le), AddrOf(rbk, rm, re)) => lbk == rbk && lm == rm && eq_expr(le, re), |
| 232 | 232 | (Path(lq, lp), Path(rq, rp)) => both(lq, rq, eq_qself) && eq_path(lp, rp), |
src/tools/rustfmt/src/expr.rs+1-1| ... | ... | @@ -372,7 +372,7 @@ pub(crate) fn format_expr( |
| 372 | 372 | )) |
| 373 | 373 | } |
| 374 | 374 | } |
| 375 | ast::ExprKind::Gen(capture_by, ref block, ref kind) => { | |
| 375 | ast::ExprKind::Gen(capture_by, ref block, ref kind, _) => { | |
| 376 | 376 | let mover = if matches!(capture_by, ast::CaptureBy::Value { .. }) { |
| 377 | 377 | "move " |
| 378 | 378 | } else { |
tests/codegen/patchable-function-entry/patchable-function-entry-both-flags.rs created+64| ... | ... | @@ -0,0 +1,64 @@ |
| 1 | //@ compile-flags: -Z patchable-function-entry=15,10 | |
| 2 | ||
| 3 | #![feature(patchable_function_entry)] | |
| 4 | #![crate_type = "lib"] | |
| 5 | ||
| 6 | // This should have the default, as set by the compile flags | |
| 7 | #[no_mangle] | |
| 8 | pub fn fun0() {} | |
| 9 | ||
| 10 | // The attribute should override the compile flags | |
| 11 | #[no_mangle] | |
| 12 | #[patchable_function_entry(prefix_nops = 1, entry_nops = 2)] | |
| 13 | pub fn fun1() {} | |
| 14 | ||
| 15 | // If we override an attribute to 0 or unset, the attribute should go away | |
| 16 | #[no_mangle] | |
| 17 | #[patchable_function_entry(entry_nops = 0)] | |
| 18 | pub fn fun2() {} | |
| 19 | ||
| 20 | // The attribute should override the compile flags | |
| 21 | #[no_mangle] | |
| 22 | #[patchable_function_entry(prefix_nops = 20, entry_nops = 1)] | |
| 23 | pub fn fun3() {} | |
| 24 | ||
| 25 | // The attribute should override the compile flags | |
| 26 | #[no_mangle] | |
| 27 | #[patchable_function_entry(prefix_nops = 2, entry_nops = 19)] | |
| 28 | pub fn fun4() {} | |
| 29 | ||
| 30 | // The attribute should override patchable-function-entry to 3 and | |
| 31 | // patchable-function-prefix to the default of 0, clearing it entirely | |
| 32 | #[no_mangle] | |
| 33 | #[patchable_function_entry(entry_nops = 3)] | |
| 34 | pub fn fun5() {} | |
| 35 | ||
| 36 | // The attribute should override patchable-function-prefix to 4 | |
| 37 | // and patchable-function-entry to the default of 0, clearing it entirely | |
| 38 | #[no_mangle] | |
| 39 | #[patchable_function_entry(prefix_nops = 4)] | |
| 40 | pub fn fun6() {} | |
| 41 | ||
| 42 | // CHECK: @fun0() unnamed_addr #0 | |
| 43 | // CHECK: @fun1() unnamed_addr #1 | |
| 44 | // CHECK: @fun2() unnamed_addr #2 | |
| 45 | // CHECK: @fun3() unnamed_addr #3 | |
| 46 | // CHECK: @fun4() unnamed_addr #4 | |
| 47 | // CHECK: @fun5() unnamed_addr #5 | |
| 48 | // CHECK: @fun6() unnamed_addr #6 | |
| 49 | ||
| 50 | // CHECK: attributes #0 = { {{.*}}"patchable-function-entry"="5"{{.*}}"patchable-function-prefix"="10" {{.*}} } | |
| 51 | // CHECK: attributes #1 = { {{.*}}"patchable-function-entry"="2"{{.*}}"patchable-function-prefix"="1" {{.*}} } | |
| 52 | ||
| 53 | // CHECK-NOT: attributes #2 = { {{.*}}patchable-function-entry{{.*}} } | |
| 54 | // CHECK-NOT: attributes #2 = { {{.*}}patchable-function-prefix{{.*}} } | |
| 55 | // CHECK: attributes #2 = { {{.*}} } | |
| 56 | ||
| 57 | // CHECK: attributes #3 = { {{.*}}"patchable-function-entry"="1"{{.*}}"patchable-function-prefix"="20" {{.*}} } | |
| 58 | // CHECK: attributes #4 = { {{.*}}"patchable-function-entry"="19"{{.*}}"patchable-function-prefix"="2" {{.*}} } | |
| 59 | ||
| 60 | // CHECK: attributes #5 = { {{.*}}"patchable-function-entry"="3"{{.*}} } | |
| 61 | // CHECK-NOT: attributes #5 = { {{.*}}patchable-function-prefix{{.*}} } | |
| 62 | ||
| 63 | // CHECK: attributes #6 = { {{.*}}"patchable-function-prefix"="4"{{.*}} } | |
| 64 | // CHECK-NOT: attributes #6 = { {{.*}}patchable-function-entry{{.*}} } |
tests/codegen/patchable-function-entry/patchable-function-entry-no-flag.rs created+39| ... | ... | @@ -0,0 +1,39 @@ |
| 1 | #![feature(patchable_function_entry)] | |
| 2 | #![crate_type = "lib"] | |
| 3 | ||
| 4 | // No patchable function entry should be set | |
| 5 | #[no_mangle] | |
| 6 | pub fn fun0() {} | |
| 7 | ||
| 8 | // The attribute should work even without compiler flags | |
| 9 | #[no_mangle] | |
| 10 | #[patchable_function_entry(prefix_nops = 1, entry_nops = 2)] | |
| 11 | pub fn fun1() {} | |
| 12 | ||
| 13 | // The attribute should work even without compiler flags | |
| 14 | // and only set patchable-function-entry to 3. | |
| 15 | #[no_mangle] | |
| 16 | #[patchable_function_entry(entry_nops = 3)] | |
| 17 | pub fn fun2() {} | |
| 18 | ||
| 19 | // The attribute should work even without compiler flags | |
| 20 | // and only set patchable-function-prefix to 4. | |
| 21 | #[no_mangle] | |
| 22 | #[patchable_function_entry(prefix_nops = 4)] | |
| 23 | pub fn fun3() {} | |
| 24 | ||
| 25 | // CHECK: @fun0() unnamed_addr #0 | |
| 26 | // CHECK: @fun1() unnamed_addr #1 | |
| 27 | // CHECK: @fun2() unnamed_addr #2 | |
| 28 | // CHECK: @fun3() unnamed_addr #3 | |
| 29 | ||
| 30 | // CHECK-NOT: attributes #0 = { {{.*}}patchable-function-entry{{.*}} } | |
| 31 | // CHECK-NOT: attributes #0 = { {{.*}}patchable-function-prefix{{.*}} } | |
| 32 | ||
| 33 | // CHECK: attributes #1 = { {{.*}}"patchable-function-entry"="2"{{.*}}"patchable-function-prefix"="1" {{.*}} } | |
| 34 | ||
| 35 | // CHECK: attributes #2 = { {{.*}}"patchable-function-entry"="3"{{.*}} } | |
| 36 | // CHECK-NOT: attributes #2 = { {{.*}}patchable-function-prefix{{.*}} } | |
| 37 | ||
| 38 | // CHECK: attributes #3 = { {{.*}}"patchable-function-prefix"="4"{{.*}} } | |
| 39 | // CHECK-NOT: attributes #3 = { {{.*}}patchable-function-entry{{.*}} } |
tests/codegen/patchable-function-entry/patchable-function-entry-one-flag.rs created+66| ... | ... | @@ -0,0 +1,66 @@ |
| 1 | //@ compile-flags: -Z patchable-function-entry=15 | |
| 2 | ||
| 3 | #![feature(patchable_function_entry)] | |
| 4 | #![crate_type = "lib"] | |
| 5 | ||
| 6 | // This should have the default, as set by the compile flags | |
| 7 | #[no_mangle] | |
| 8 | pub fn fun0() {} | |
| 9 | ||
| 10 | // The attribute should override the compile flags | |
| 11 | #[no_mangle] | |
| 12 | #[patchable_function_entry(prefix_nops = 1, entry_nops = 2)] | |
| 13 | pub fn fun1() {} | |
| 14 | ||
| 15 | // If we override an attribute to 0 or unset, the attribute should go away | |
| 16 | #[no_mangle] | |
| 17 | #[patchable_function_entry(entry_nops = 0)] | |
| 18 | pub fn fun2() {} | |
| 19 | ||
| 20 | // The attribute should override the compile flags | |
| 21 | #[no_mangle] | |
| 22 | #[patchable_function_entry(prefix_nops = 20, entry_nops = 1)] | |
| 23 | pub fn fun3() {} | |
| 24 | ||
| 25 | // The attribute should override the compile flags | |
| 26 | #[no_mangle] | |
| 27 | #[patchable_function_entry(prefix_nops = 2, entry_nops = 19)] | |
| 28 | pub fn fun4() {} | |
| 29 | ||
| 30 | // The attribute should override patchable-function-entry to 3 | |
| 31 | // and patchable-function-prefix to the default of 0, clearing it entirely | |
| 32 | #[no_mangle] | |
| 33 | #[patchable_function_entry(entry_nops = 3)] | |
| 34 | pub fn fun5() {} | |
| 35 | ||
| 36 | // The attribute should override patchable-function-prefix to 4 | |
| 37 | // and patchable-function-entry to the default of 0, clearing it entirely | |
| 38 | #[no_mangle] | |
| 39 | #[patchable_function_entry(prefix_nops = 4)] | |
| 40 | pub fn fun6() {} | |
| 41 | ||
| 42 | // CHECK: @fun0() unnamed_addr #0 | |
| 43 | // CHECK: @fun1() unnamed_addr #1 | |
| 44 | // CHECK: @fun2() unnamed_addr #2 | |
| 45 | // CHECK: @fun3() unnamed_addr #3 | |
| 46 | // CHECK: @fun4() unnamed_addr #4 | |
| 47 | // CHECK: @fun5() unnamed_addr #5 | |
| 48 | // CHECK: @fun6() unnamed_addr #6 | |
| 49 | ||
| 50 | // CHECK: attributes #0 = { {{.*}}"patchable-function-entry"="15" {{.*}} } | |
| 51 | // CHECK-NOT: attributes #0 = { {{.*}}patchable-function-prefix{{.*}} } | |
| 52 | ||
| 53 | // CHECK: attributes #1 = { {{.*}}"patchable-function-entry"="2"{{.*}}"patchable-function-prefix"="1" {{.*}} } | |
| 54 | ||
| 55 | // CHECK-NOT: attributes #2 = { {{.*}}patchable-function-entry{{.*}} } | |
| 56 | // CHECK-NOT: attributes #2 = { {{.*}}patchable-function-prefix{{.*}} } | |
| 57 | // CHECK: attributes #2 = { {{.*}} } | |
| 58 | ||
| 59 | // CHECK: attributes #3 = { {{.*}}"patchable-function-entry"="1"{{.*}}"patchable-function-prefix"="20" {{.*}} } | |
| 60 | // CHECK: attributes #4 = { {{.*}}"patchable-function-entry"="19"{{.*}}"patchable-function-prefix"="2" {{.*}} } | |
| 61 | ||
| 62 | // CHECK: attributes #5 = { {{.*}}"patchable-function-entry"="3"{{.*}} } | |
| 63 | // CHECK-NOT: attributes #5 = { {{.*}}patchable-function-prefix{{.*}} } | |
| 64 | ||
| 65 | // CHECK: attributes #6 = { {{.*}}"patchable-function-prefix"="4"{{.*}} } | |
| 66 | // CHECK-NOT: attributes #6 = { {{.*}}patchable-function-entry{{.*}} } |
tests/coverage/issue-83601.cov-map+3-3| ... | ... | @@ -1,12 +1,12 @@ |
| 1 | 1 | Function name: issue_83601::main |
| 2 | Raw bytes (21): 0x[01, 01, 01, 05, 00, 03, 01, 06, 01, 02, 1c, 05, 03, 09, 01, 1c, 02, 02, 05, 03, 02] | |
| 2 | Raw bytes (21): 0x[01, 01, 01, 05, 09, 03, 01, 06, 01, 02, 1c, 05, 03, 09, 01, 1c, 02, 02, 05, 03, 02] | |
| 3 | 3 | Number of files: 1 |
| 4 | 4 | - file 0 => global file 1 |
| 5 | 5 | Number of expressions: 1 |
| 6 | - expression 0 operands: lhs = Counter(1), rhs = Zero | |
| 6 | - expression 0 operands: lhs = Counter(1), rhs = Counter(2) | |
| 7 | 7 | Number of file 0 mappings: 3 |
| 8 | 8 | - Code(Counter(0)) at (prev + 6, 1) to (start + 2, 28) |
| 9 | 9 | - Code(Counter(1)) at (prev + 3, 9) to (start + 1, 28) |
| 10 | 10 | - Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 3, 2) |
| 11 | = (c1 - Zero) | |
| 11 | = (c1 - c2) | |
| 12 | 12 |
tests/coverage/issue-84561.cov-map+7-7| ... | ... | @@ -54,15 +54,15 @@ Number of file 0 mappings: 1 |
| 54 | 54 | - Code(Counter(0)) at (prev + 167, 9) to (start + 2, 10) |
| 55 | 55 | |
| 56 | 56 | Function name: issue_84561::test3 |
| 57 | Raw bytes (375): 0x[01, 01, 31, 05, 00, 0d, 00, 15, 00, 12, 00, 15, 00, 21, 00, 1e, 00, 21, 00, 31, 00, 3d, 00, 2e, 45, 3d, 00, 42, 49, 45, 00, 3f, 51, 42, 49, 45, 00, 7a, 55, 51, 00, 7a, 55, 51, 00, 77, 5d, 7a, 55, 51, 00, 77, 61, 7a, 55, 51, 00, 72, 65, 77, 61, 7a, 55, 51, 00, 75, be, 01, c2, 01, 79, 69, 6d, 69, 6d, 69, 6d, c2, 01, 00, 69, 6d, c2, 01, 79, 69, 6d, bb, 01, 7d, 75, be, 01, c2, 01, 79, 69, 6d, b6, 01, 00, bb, 01, 7d, 75, be, 01, c2, 01, 79, 69, 6d, 33, 01, 08, 01, 03, 1c, 05, 04, 09, 01, 1c, 02, 02, 05, 04, 1f, 0d, 05, 05, 00, 1f, 06, 01, 05, 00, 1f, 15, 01, 09, 01, 1c, 12, 02, 05, 00, 1f, 0e, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 21, 01, 05, 03, 0f, 00, 03, 20, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 1e, 01, 05, 00, 0f, 00, 05, 09, 03, 10, 00, 05, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 1a, 04, 09, 05, 06, 31, 06, 05, 03, 06, 22, 04, 05, 03, 06, 3d, 04, 09, 04, 06, 2e, 05, 08, 00, 0f, 45, 01, 09, 03, 0a, 2a, 05, 09, 03, 0a, 3f, 05, 08, 00, 0f, 51, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 3a, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 77, 03, 05, 00, 0f, 77, 01, 0c, 00, 13, 5d, 01, 0d, 00, 13, 56, 02, 0d, 00, 13, 72, 04, 05, 02, 13, 65, 03, 0d, 00, 13, 6e, 02, 0d, 00, 13, bb, 01, 03, 05, 00, 0f, 69, 01, 0c, 00, 13, 6d, 01, 0d, 03, 0e, 75, 04, 0d, 00, 13, c2, 01, 02, 0d, 00, 17, c2, 01, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 92, 01, 02, 15, 00, 1b, be, 01, 04, 0d, 00, 13, 7d, 03, 09, 00, 19, b6, 01, 02, 05, 00, 0f, b2, 01, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02] | |
| 57 | Raw bytes (375): 0x[01, 01, 31, 05, 09, 0d, 00, 15, 19, 12, 00, 15, 19, 21, 00, 1e, 00, 21, 00, 31, 00, 3d, 00, 2e, 45, 3d, 00, 42, 49, 45, 00, 3f, 51, 42, 49, 45, 00, 7a, 55, 51, 00, 7a, 55, 51, 00, 77, 5d, 7a, 55, 51, 00, 77, 61, 7a, 55, 51, 00, 72, 65, 77, 61, 7a, 55, 51, 00, 75, be, 01, c2, 01, 79, 69, 6d, 69, 6d, 69, 6d, c2, 01, 00, 69, 6d, c2, 01, 79, 69, 6d, bb, 01, 7d, 75, be, 01, c2, 01, 79, 69, 6d, b6, 01, 00, bb, 01, 7d, 75, be, 01, c2, 01, 79, 69, 6d, 33, 01, 08, 01, 03, 1c, 05, 04, 09, 01, 1c, 02, 02, 05, 04, 1f, 0d, 05, 05, 00, 1f, 06, 01, 05, 00, 1f, 15, 01, 09, 01, 1c, 12, 02, 05, 00, 1f, 0e, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 21, 01, 05, 03, 0f, 00, 03, 20, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 1e, 01, 05, 00, 0f, 00, 05, 09, 03, 10, 00, 05, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 1a, 04, 09, 05, 06, 31, 06, 05, 03, 06, 22, 04, 05, 03, 06, 3d, 04, 09, 04, 06, 2e, 05, 08, 00, 0f, 45, 01, 09, 03, 0a, 2a, 05, 09, 03, 0a, 3f, 05, 08, 00, 0f, 51, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 3a, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 77, 03, 05, 00, 0f, 77, 01, 0c, 00, 13, 5d, 01, 0d, 00, 13, 56, 02, 0d, 00, 13, 72, 04, 05, 02, 13, 65, 03, 0d, 00, 13, 6e, 02, 0d, 00, 13, bb, 01, 03, 05, 00, 0f, 69, 01, 0c, 00, 13, 6d, 01, 0d, 03, 0e, 75, 04, 0d, 00, 13, c2, 01, 02, 0d, 00, 17, c2, 01, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 92, 01, 02, 15, 00, 1b, be, 01, 04, 0d, 00, 13, 7d, 03, 09, 00, 19, b6, 01, 02, 05, 00, 0f, b2, 01, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02] | |
| 58 | 58 | Number of files: 1 |
| 59 | 59 | - file 0 => global file 1 |
| 60 | 60 | Number of expressions: 49 |
| 61 | - expression 0 operands: lhs = Counter(1), rhs = Zero | |
| 61 | - expression 0 operands: lhs = Counter(1), rhs = Counter(2) | |
| 62 | 62 | - expression 1 operands: lhs = Counter(3), rhs = Zero |
| 63 | - expression 2 operands: lhs = Counter(5), rhs = Zero | |
| 63 | - expression 2 operands: lhs = Counter(5), rhs = Counter(6) | |
| 64 | 64 | - expression 3 operands: lhs = Expression(4, Sub), rhs = Zero |
| 65 | - expression 4 operands: lhs = Counter(5), rhs = Zero | |
| 65 | - expression 4 operands: lhs = Counter(5), rhs = Counter(6) | |
| 66 | 66 | - expression 5 operands: lhs = Counter(8), rhs = Zero |
| 67 | 67 | - expression 6 operands: lhs = Expression(7, Sub), rhs = Zero |
| 68 | 68 | - expression 7 operands: lhs = Counter(8), rhs = Zero |
| ... | ... | @@ -111,15 +111,15 @@ Number of file 0 mappings: 51 |
| 111 | 111 | - Code(Counter(0)) at (prev + 8, 1) to (start + 3, 28) |
| 112 | 112 | - Code(Counter(1)) at (prev + 4, 9) to (start + 1, 28) |
| 113 | 113 | - Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 4, 31) |
| 114 | = (c1 - Zero) | |
| 114 | = (c1 - c2) | |
| 115 | 115 | - Code(Counter(3)) at (prev + 5, 5) to (start + 0, 31) |
| 116 | 116 | - Code(Expression(1, Sub)) at (prev + 1, 5) to (start + 0, 31) |
| 117 | 117 | = (c3 - Zero) |
| 118 | 118 | - Code(Counter(5)) at (prev + 1, 9) to (start + 1, 28) |
| 119 | 119 | - Code(Expression(4, Sub)) at (prev + 2, 5) to (start + 0, 31) |
| 120 | = (c5 - Zero) | |
| 120 | = (c5 - c6) | |
| 121 | 121 | - Code(Expression(3, Sub)) at (prev + 1, 5) to (start + 0, 15) |
| 122 | = ((c5 - Zero) - Zero) | |
| 122 | = ((c5 - c6) - Zero) | |
| 123 | 123 | - Code(Zero) at (prev + 0, 32) to (start + 0, 48) |
| 124 | 124 | - Code(Counter(8)) at (prev + 1, 5) to (start + 3, 15) |
| 125 | 125 | - Code(Zero) at (prev + 3, 32) to (start + 0, 48) |
tests/ui-fulldeps/stable-mir/check_attribute.rs created+155| ... | ... | @@ -0,0 +1,155 @@ |
| 1 | //@ run-pass | |
| 2 | //! Test information regarding type layout. | |
| 3 | ||
| 4 | //@ ignore-stage1 | |
| 5 | //@ ignore-cross-compile | |
| 6 | //@ ignore-remote | |
| 7 | //@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837 | |
| 8 | ||
| 9 | #![feature(rustc_private)] | |
| 10 | #![feature(control_flow_enum)] | |
| 11 | ||
| 12 | extern crate rustc_hir; | |
| 13 | #[macro_use] | |
| 14 | extern crate rustc_smir; | |
| 15 | extern crate rustc_driver; | |
| 16 | extern crate rustc_interface; | |
| 17 | extern crate stable_mir; | |
| 18 | ||
| 19 | use rustc_smir::rustc_internal; | |
| 20 | use stable_mir::{CrateDef, CrateItems}; | |
| 21 | use std::io::Write; | |
| 22 | use std::ops::ControlFlow; | |
| 23 | ||
| 24 | const CRATE_NAME: &str = "input"; | |
| 25 | ||
| 26 | /// This function uses the Stable MIR APIs to get information about the test crate. | |
| 27 | fn test_stable_mir() -> ControlFlow<()> { | |
| 28 | // Find items in the local crate. | |
| 29 | let items = stable_mir::all_local_items(); | |
| 30 | ||
| 31 | test_builtins(&items); | |
| 32 | test_derive(&items); | |
| 33 | test_tool(&items); | |
| 34 | test_all_attrs(&items); | |
| 35 | ||
| 36 | ControlFlow::Continue(()) | |
| 37 | } | |
| 38 | ||
| 39 | // Test built-in attributes. | |
| 40 | fn test_builtins(items: &CrateItems) { | |
| 41 | let target_fn = *get_item(&items, "builtins_fn").unwrap(); | |
| 42 | let allow_attrs = target_fn.attrs_by_path(&["allow".to_string()]); | |
| 43 | assert_eq!(allow_attrs[0].as_str(), "#![allow(unused_variables)]"); | |
| 44 | ||
| 45 | let inline_attrs = target_fn.attrs_by_path(&["inline".to_string()]); | |
| 46 | assert_eq!(inline_attrs[0].as_str(), "#[inline]"); | |
| 47 | ||
| 48 | let deprecated_attrs = target_fn.attrs_by_path(&["deprecated".to_string()]); | |
| 49 | assert_eq!(deprecated_attrs[0].as_str(), "#[deprecated(since = \"5.2.0\")]"); | |
| 50 | } | |
| 51 | ||
| 52 | // Test derive attribute. | |
| 53 | fn test_derive(items: &CrateItems) { | |
| 54 | let target_struct = *get_item(&items, "Foo").unwrap(); | |
| 55 | let attrs = target_struct.attrs_by_path(&["derive".to_string()]); | |
| 56 | // No `derive` attribute since it's expanded before MIR. | |
| 57 | assert_eq!(attrs.len(), 0); | |
| 58 | ||
| 59 | // Check derived trait method's attributes. | |
| 60 | let derived_fmt = *get_item(&items, "<Foo as std::fmt::Debug>::fmt").unwrap(); | |
| 61 | // The Rust reference lies about this attribute. It doesn't show up in `clone` or `fmt` impl. | |
| 62 | let _fmt_attrs = derived_fmt.attrs_by_path(&["automatically_derived".to_string()]); | |
| 63 | } | |
| 64 | ||
| 65 | // Test tool attributes. | |
| 66 | fn test_tool(items: &CrateItems) { | |
| 67 | let rustfmt_fn = *get_item(&items, "do_not_format").unwrap(); | |
| 68 | let rustfmt_attrs = rustfmt_fn.attrs_by_path(&["rustfmt".to_string(), "skip".to_string()]); | |
| 69 | assert_eq!(rustfmt_attrs[0].as_str(), "#[rustfmt::skip]"); | |
| 70 | ||
| 71 | let clippy_fn = *get_item(&items, "complex_fn").unwrap(); | |
| 72 | let clippy_attrs = clippy_fn.attrs_by_path(&["clippy".to_string(), | |
| 73 | "cyclomatic_complexity".to_string()]); | |
| 74 | assert_eq!(clippy_attrs[0].as_str(), "#[clippy::cyclomatic_complexity = \"100\"]"); | |
| 75 | } | |
| 76 | ||
| 77 | fn test_all_attrs(items: &CrateItems) { | |
| 78 | let target_fn = *get_item(&items, "many_attrs").unwrap(); | |
| 79 | let all_attrs = target_fn.all_attrs(); | |
| 80 | assert_eq!(all_attrs[0].as_str(), "#[inline]"); | |
| 81 | assert_eq!(all_attrs[1].as_str(), "#[allow(unused_variables)]"); | |
| 82 | assert_eq!(all_attrs[2].as_str(), "#[allow(dead_code)]"); | |
| 83 | assert_eq!(all_attrs[3].as_str(), "#[allow(unused_imports)]"); | |
| 84 | assert_eq!(all_attrs[4].as_str(), "#![allow(clippy::filter_map)]"); | |
| 85 | } | |
| 86 | ||
| 87 | ||
| 88 | fn get_item<'a>( | |
| 89 | items: &'a CrateItems, | |
| 90 | name: &str, | |
| 91 | ) -> Option<&'a stable_mir::CrateItem> { | |
| 92 | items.iter().find(|crate_item| crate_item.name() == name) | |
| 93 | } | |
| 94 | ||
| 95 | /// This test will generate and analyze a dummy crate using the stable mir. | |
| 96 | /// For that, it will first write the dummy crate into a file. | |
| 97 | /// Then it will create a `StableMir` using custom arguments and then | |
| 98 | /// it will run the compiler. | |
| 99 | fn main() { | |
| 100 | let path = "attribute_input.rs"; | |
| 101 | generate_input(&path).unwrap(); | |
| 102 | let args = vec![ | |
| 103 | "rustc".to_string(), | |
| 104 | "--crate-type=lib".to_string(), | |
| 105 | "--crate-name".to_string(), | |
| 106 | CRATE_NAME.to_string(), | |
| 107 | path.to_string(), | |
| 108 | ]; | |
| 109 | run!(args, test_stable_mir).unwrap(); | |
| 110 | } | |
| 111 | ||
| 112 | fn generate_input(path: &str) -> std::io::Result<()> { | |
| 113 | let mut file = std::fs::File::create(path)?; | |
| 114 | write!( | |
| 115 | file, | |
| 116 | r#" | |
| 117 | // General metadata applied to the enclosing module or crate. | |
| 118 | #![crate_type = "lib"] | |
| 119 | ||
| 120 | // Mixed inner and outer attributes. | |
| 121 | #[inline] | |
| 122 | #[deprecated(since = "5.2.0")] | |
| 123 | fn builtins_fn() {{ | |
| 124 | #![allow(unused_variables)] | |
| 125 | ||
| 126 | let x = (); | |
| 127 | let y = (); | |
| 128 | let z = (); | |
| 129 | }} | |
| 130 | ||
| 131 | // A derive attribute to automatically implement a trait. | |
| 132 | #[derive(Debug, Clone, Copy)] | |
| 133 | struct Foo(u32); | |
| 134 | ||
| 135 | // A rustfmt tool attribute. | |
| 136 | #[rustfmt::skip] | |
| 137 | fn do_not_format() {{}} | |
| 138 | ||
| 139 | // A clippy tool attribute. | |
| 140 | #[clippy::cyclomatic_complexity = "100"] | |
| 141 | pub fn complex_fn() {{}} | |
| 142 | ||
| 143 | // A function with many attributes. | |
| 144 | #[inline] | |
| 145 | #[allow(unused_variables)] | |
| 146 | #[allow(dead_code)] | |
| 147 | #[allow(unused_imports)] | |
| 148 | fn many_attrs() {{ | |
| 149 | #![allow(clippy::filter_map)] | |
| 150 | todo!() | |
| 151 | }} | |
| 152 | "# | |
| 153 | )?; | |
| 154 | Ok(()) | |
| 155 | } |
tests/ui/async-await/async-block-control-flow-static-semantics.stderr+12-14| ... | ... | @@ -1,20 +1,18 @@ |
| 1 | 1 | error[E0267]: `break` inside `async` block |
| 2 | 2 | --> $DIR/async-block-control-flow-static-semantics.rs:32:9 |
| 3 | 3 | | |
| 4 | LL | / async { | |
| 5 | LL | | break 0u8; | |
| 6 | | | ^^^^^^^^^ cannot `break` inside `async` block | |
| 7 | LL | | }; | |
| 8 | | |_____- enclosing `async` block | |
| 4 | LL | async { | |
| 5 | | ----- enclosing `async` block | |
| 6 | LL | break 0u8; | |
| 7 | | ^^^^^^^^^ cannot `break` inside `async` block | |
| 9 | 8 | |
| 10 | 9 | error[E0267]: `break` inside `async` block |
| 11 | 10 | --> $DIR/async-block-control-flow-static-semantics.rs:39:13 |
| 12 | 11 | | |
| 13 | LL | / async { | |
| 14 | LL | | break 0u8; | |
| 15 | | | ^^^^^^^^^ cannot `break` inside `async` block | |
| 16 | LL | | }; | |
| 17 | | |_________- enclosing `async` block | |
| 12 | LL | async { | |
| 13 | | ----- enclosing `async` block | |
| 14 | LL | break 0u8; | |
| 15 | | ^^^^^^^^^ cannot `break` inside `async` block | |
| 18 | 16 | |
| 19 | 17 | error[E0308]: mismatched types |
| 20 | 18 | --> $DIR/async-block-control-flow-static-semantics.rs:21:58 |
| ... | ... | @@ -29,13 +27,13 @@ LL | | |
| 29 | 27 | LL | | } |
| 30 | 28 | | |_^ expected `u8`, found `()` |
| 31 | 29 | |
| 32 | error[E0271]: expected `{async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 25:6}` to be a future that resolves to `()`, but it resolves to `u8` | |
| 30 | error[E0271]: expected `{async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 23:22}` to be a future that resolves to `()`, but it resolves to `u8` | |
| 33 | 31 | --> $DIR/async-block-control-flow-static-semantics.rs:26:39 |
| 34 | 32 | | |
| 35 | 33 | LL | let _: &dyn Future<Output = ()> = &block; |
| 36 | 34 | | ^^^^^^ expected `()`, found `u8` |
| 37 | 35 | | |
| 38 | = note: required for the cast from `&{async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 25:6}` to `&dyn Future<Output = ()>` | |
| 36 | = note: required for the cast from `&{async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 23:22}` to `&dyn Future<Output = ()>` | |
| 39 | 37 | |
| 40 | 38 | error[E0308]: mismatched types |
| 41 | 39 | --> $DIR/async-block-control-flow-static-semantics.rs:12:43 |
| ... | ... | @@ -45,13 +43,13 @@ LL | fn return_targets_async_block_not_fn() -> u8 { |
| 45 | 43 | | | |
| 46 | 44 | | implicitly returns `()` as its body has no tail or `return` expression |
| 47 | 45 | |
| 48 | error[E0271]: expected `{async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 16:6}` to be a future that resolves to `()`, but it resolves to `u8` | |
| 46 | error[E0271]: expected `{async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 14:22}` to be a future that resolves to `()`, but it resolves to `u8` | |
| 49 | 47 | --> $DIR/async-block-control-flow-static-semantics.rs:17:39 |
| 50 | 48 | | |
| 51 | 49 | LL | let _: &dyn Future<Output = ()> = &block; |
| 52 | 50 | | ^^^^^^ expected `()`, found `u8` |
| 53 | 51 | | |
| 54 | = note: required for the cast from `&{async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 16:6}` to `&dyn Future<Output = ()>` | |
| 52 | = note: required for the cast from `&{async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 14:22}` to `&dyn Future<Output = ()>` | |
| 55 | 53 | |
| 56 | 54 | error[E0308]: mismatched types |
| 57 | 55 | --> $DIR/async-block-control-flow-static-semantics.rs:49:44 |
tests/ui/async-await/async-borrowck-escaping-block-error.stderr+4-6| ... | ... | @@ -2,9 +2,8 @@ error[E0373]: async block may outlive the current function, but it borrows `x`, |
| 2 | 2 | --> $DIR/async-borrowck-escaping-block-error.rs:6:14 |
| 3 | 3 | | |
| 4 | 4 | LL | Box::new(async { x } ) |
| 5 | | ^^^^^^^^-^^ | |
| 6 | | | | | |
| 7 | | | `x` is borrowed here | |
| 5 | | ^^^^^ - `x` is borrowed here | |
| 6 | | | | |
| 8 | 7 | | may outlive borrowed value `x` |
| 9 | 8 | | |
| 10 | 9 | note: async block is returned here |
| ... | ... | @@ -21,9 +20,8 @@ error[E0373]: async block may outlive the current function, but it borrows `x`, |
| 21 | 20 | --> $DIR/async-borrowck-escaping-block-error.rs:11:5 |
| 22 | 21 | | |
| 23 | 22 | LL | async { *x } |
| 24 | | ^^^^^^^^--^^ | |
| 25 | | | | | |
| 26 | | | `x` is borrowed here | |
| 23 | | ^^^^^ -- `x` is borrowed here | |
| 24 | | | | |
| 27 | 25 | | may outlive borrowed value `x` |
| 28 | 26 | | |
| 29 | 27 | note: async block is returned here |
tests/ui/async-await/async-closures/wrong-fn-kind.stderr+11-13| ... | ... | @@ -22,20 +22,18 @@ LL | fn needs_async_fn(_: impl async Fn()) {} |
| 22 | 22 | error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure |
| 23 | 23 | --> $DIR/wrong-fn-kind.rs:9:20 |
| 24 | 24 | | |
| 25 | LL | fn needs_async_fn(_: impl async Fn()) {} | |
| 26 | | --------------- change this to accept `FnMut` instead of `Fn` | |
| 25 | LL | fn needs_async_fn(_: impl async Fn()) {} | |
| 26 | | --------------- change this to accept `FnMut` instead of `Fn` | |
| 27 | 27 | ... |
| 28 | LL | needs_async_fn(async || { | |
| 29 | | -------------- ^------- | |
| 30 | | | | | |
| 31 | | _____|______________in this closure | |
| 32 | | | | | |
| 33 | | | expects `Fn` instead of `FnMut` | |
| 34 | LL | | | |
| 35 | LL | | x += 1; | |
| 36 | | | - mutable borrow occurs due to use of `x` in closure | |
| 37 | LL | | }); | |
| 38 | | |_____^ cannot borrow as mutable | |
| 28 | LL | needs_async_fn(async || { | |
| 29 | | -------------- ^^^^^^^^ | |
| 30 | | | | | |
| 31 | | | cannot borrow as mutable | |
| 32 | | | in this closure | |
| 33 | | expects `Fn` instead of `FnMut` | |
| 34 | LL | | |
| 35 | LL | x += 1; | |
| 36 | | - mutable borrow occurs due to use of `x` in closure | |
| 39 | 37 | |
| 40 | 38 | error: aborting due to 2 previous errors |
| 41 | 39 |
tests/ui/async-await/async-is-unwindsafe.stderr+12-13| ... | ... | @@ -1,20 +1,19 @@ |
| 1 | 1 | error[E0277]: the type `&mut Context<'_>` may not be safely transferred across an unwind boundary |
| 2 | 2 | --> $DIR/async-is-unwindsafe.rs:12:5 |
| 3 | 3 | | |
| 4 | LL | is_unwindsafe(async { | |
| 5 | | ______^ - | |
| 6 | | | ___________________| | |
| 7 | LL | || | |
| 8 | LL | || use std::ptr::null; | |
| 9 | LL | || use std::task::{Context, RawWaker, RawWakerVTable, Waker}; | |
| 10 | ... || | |
| 11 | LL | || drop(cx_ref); | |
| 12 | LL | || }); | |
| 13 | | ||_____-^ `&mut Context<'_>` may not be safely transferred across an unwind boundary | |
| 14 | | |_____| | |
| 15 | | within this `{async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6}` | |
| 4 | LL | is_unwindsafe(async { | |
| 5 | | ^ ----- within this `{async block@$DIR/async-is-unwindsafe.rs:12:19: 12:24}` | |
| 6 | | _____| | |
| 7 | | | | |
| 8 | LL | | | |
| 9 | LL | | use std::ptr::null; | |
| 10 | LL | | use std::task::{Context, RawWaker, RawWakerVTable, Waker}; | |
| 11 | ... | | |
| 12 | LL | | drop(cx_ref); | |
| 13 | LL | | }); | |
| 14 | | |______^ `&mut Context<'_>` may not be safely transferred across an unwind boundary | |
| 16 | 15 | | |
| 17 | = help: within `{async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6}`, the trait `UnwindSafe` is not implemented for `&mut Context<'_>`, which is required by `{async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6}: UnwindSafe` | |
| 16 | = help: within `{async block@$DIR/async-is-unwindsafe.rs:12:19: 12:24}`, the trait `UnwindSafe` is not implemented for `&mut Context<'_>`, which is required by `{async block@$DIR/async-is-unwindsafe.rs:12:19: 12:24}: UnwindSafe` | |
| 18 | 17 | = note: `UnwindSafe` is implemented for `&Context<'_>`, but not for `&mut Context<'_>` |
| 19 | 18 | note: future does not implement `UnwindSafe` as this value is used across an await |
| 20 | 19 | --> $DIR/async-is-unwindsafe.rs:25:18 |
tests/ui/async-await/coroutine-desc.stderr+2-2| ... | ... | @@ -8,8 +8,8 @@ LL | fun(async {}, async {}); |
| 8 | 8 | | | expected all arguments to be this `async` block type because they need to match the type of this parameter |
| 9 | 9 | | arguments to this function are incorrect |
| 10 | 10 | | |
| 11 | = note: expected `async` block `{async block@$DIR/coroutine-desc.rs:10:9: 10:17}` | |
| 12 | found `async` block `{async block@$DIR/coroutine-desc.rs:10:19: 10:27}` | |
| 11 | = note: expected `async` block `{async block@$DIR/coroutine-desc.rs:10:9: 10:14}` | |
| 12 | found `async` block `{async block@$DIR/coroutine-desc.rs:10:19: 10:24}` | |
| 13 | 13 | = note: no two async blocks, even if identical, have the same type |
| 14 | 14 | = help: consider pinning your async block and casting it to a trait object |
| 15 | 15 | note: function defined here |
tests/ui/async-await/coroutine-not-future.stderr+2-2| ... | ... | @@ -26,11 +26,11 @@ note: required by a bound in `takes_coroutine` |
| 26 | 26 | LL | fn takes_coroutine<ResumeTy>(_g: impl Coroutine<ResumeTy, Yield = (), Return = ()>) {} |
| 27 | 27 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_coroutine` |
| 28 | 28 | |
| 29 | error[E0277]: the trait bound `{async block@$DIR/coroutine-not-future.rs:39:21: 39:29}: Coroutine<_>` is not satisfied | |
| 29 | error[E0277]: the trait bound `{async block@$DIR/coroutine-not-future.rs:39:21: 39:26}: Coroutine<_>` is not satisfied | |
| 30 | 30 | --> $DIR/coroutine-not-future.rs:39:21 |
| 31 | 31 | | |
| 32 | 32 | LL | takes_coroutine(async {}); |
| 33 | | --------------- ^^^^^^^^ the trait `Coroutine<_>` is not implemented for `{async block@$DIR/coroutine-not-future.rs:39:21: 39:29}` | |
| 33 | | --------------- ^^^^^^^^ the trait `Coroutine<_>` is not implemented for `{async block@$DIR/coroutine-not-future.rs:39:21: 39:26}` | |
| 34 | 34 | | | |
| 35 | 35 | | required by a bound introduced by this call |
| 36 | 36 | | |
tests/ui/async-await/issue-67252-unnamed-future.stderr+1-1| ... | ... | @@ -8,7 +8,7 @@ LL | | let _a = a; |
| 8 | 8 | LL | | }); |
| 9 | 9 | | |______^ future created by async block is not `Send` |
| 10 | 10 | | |
| 11 | = help: within `{async block@$DIR/issue-67252-unnamed-future.rs:18:11: 22:6}`, the trait `Send` is not implemented for `*mut ()`, which is required by `{async block@$DIR/issue-67252-unnamed-future.rs:18:11: 22:6}: Send` | |
| 11 | = help: within `{async block@$DIR/issue-67252-unnamed-future.rs:18:11: 18:16}`, the trait `Send` is not implemented for `*mut ()`, which is required by `{async block@$DIR/issue-67252-unnamed-future.rs:18:11: 18:16}: Send` | |
| 12 | 12 | note: future is not `Send` as this value is used across an await |
| 13 | 13 | --> $DIR/issue-67252-unnamed-future.rs:20:17 |
| 14 | 14 | | |
tests/ui/async-await/issue-68112.stderr+5-10| ... | ... | @@ -4,7 +4,7 @@ error: future cannot be sent between threads safely |
| 4 | 4 | LL | require_send(send_fut); |
| 5 | 5 | | ^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send` |
| 6 | 6 | | |
| 7 | = help: the trait `Sync` is not implemented for `RefCell<i32>`, which is required by `{async block@$DIR/issue-68112.rs:29:20: 33:6}: Send` | |
| 7 | = help: the trait `Sync` is not implemented for `RefCell<i32>`, which is required by `{async block@$DIR/issue-68112.rs:29:20: 29:25}: Send` | |
| 8 | 8 | = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead |
| 9 | 9 | note: future is not `Send` as it awaits another future which is not `Send` |
| 10 | 10 | --> $DIR/issue-68112.rs:31:17 |
| ... | ... | @@ -23,7 +23,7 @@ error: future cannot be sent between threads safely |
| 23 | 23 | LL | require_send(send_fut); |
| 24 | 24 | | ^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send` |
| 25 | 25 | | |
| 26 | = help: the trait `Sync` is not implemented for `RefCell<i32>`, which is required by `{async block@$DIR/issue-68112.rs:39:20: 42:6}: Send` | |
| 26 | = help: the trait `Sync` is not implemented for `RefCell<i32>`, which is required by `{async block@$DIR/issue-68112.rs:39:20: 39:25}: Send` | |
| 27 | 27 | = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead |
| 28 | 28 | note: future is not `Send` as it awaits another future which is not `Send` |
| 29 | 29 | --> $DIR/issue-68112.rs:40:17 |
| ... | ... | @@ -42,7 +42,7 @@ error[E0277]: `RefCell<i32>` cannot be shared between threads safely |
| 42 | 42 | LL | require_send(send_fut); |
| 43 | 43 | | ^^^^^^^^^^^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely |
| 44 | 44 | | |
| 45 | = help: the trait `Sync` is not implemented for `RefCell<i32>`, which is required by `{async block@$DIR/issue-68112.rs:57:20: 61:6}: Send` | |
| 45 | = help: the trait `Sync` is not implemented for `RefCell<i32>`, which is required by `{async block@$DIR/issue-68112.rs:57:20: 57:25}: Send` | |
| 46 | 46 | = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead |
| 47 | 47 | = note: required for `Arc<RefCell<i32>>` to implement `Send` |
| 48 | 48 | note: required because it's used within this `async` fn body |
| ... | ... | @@ -61,13 +61,8 @@ LL | fn make_non_send_future2() -> impl Future<Output = Arc<RefCell<i32>>> { |
| 61 | 61 | note: required because it's used within this `async` block |
| 62 | 62 | --> $DIR/issue-68112.rs:57:20 |
| 63 | 63 | | |
| 64 | LL | let send_fut = async { | |
| 65 | | ____________________^ | |
| 66 | LL | | let non_send_fut = make_non_send_future2(); | |
| 67 | LL | | let _ = non_send_fut.await; | |
| 68 | LL | | ready(0).await; | |
| 69 | LL | | }; | |
| 70 | | |_____^ | |
| 64 | LL | let send_fut = async { | |
| 65 | | ^^^^^ | |
| 71 | 66 | note: required by a bound in `require_send` |
| 72 | 67 | --> $DIR/issue-68112.rs:11:25 |
| 73 | 68 | | |
tests/ui/async-await/issue-70935-complex-spans.stderr+6-14| ... | ... | @@ -4,7 +4,7 @@ error[E0277]: `*mut ()` cannot be shared between threads safely |
| 4 | 4 | LL | fn foo(x: NotSync) -> impl Future + Send { |
| 5 | 5 | | ^^^^^^^^^^^^^^^^^^ `*mut ()` cannot be shared between threads safely |
| 6 | 6 | | |
| 7 | = help: within `NotSync`, the trait `Sync` is not implemented for `*mut ()`, which is required by `{async block@$DIR/issue-70935-complex-spans.rs:18:5: 22:6}: Send` | |
| 7 | = help: within `NotSync`, the trait `Sync` is not implemented for `*mut ()`, which is required by `{async block@$DIR/issue-70935-complex-spans.rs:18:5: 18:15}: Send` | |
| 8 | 8 | note: required because it appears within the type `PhantomData<*mut ()>` |
| 9 | 9 | --> $SRC_DIR/core/src/marker.rs:LL:COL |
| 10 | 10 | note: required because it appears within the type `NotSync` |
| ... | ... | @@ -28,12 +28,8 @@ LL | | } |
| 28 | 28 | note: required because it's used within this `async` block |
| 29 | 29 | --> $DIR/issue-70935-complex-spans.rs:18:5 |
| 30 | 30 | | |
| 31 | LL | / async move { | |
| 32 | LL | | baz(|| async { | |
| 33 | LL | | foo(x.clone()); | |
| 34 | LL | | }).await; | |
| 35 | LL | | } | |
| 36 | | |_____^ | |
| 31 | LL | async move { | |
| 32 | | ^^^^^^^^^^ | |
| 37 | 33 | |
| 38 | 34 | error[E0277]: `*mut ()` cannot be shared between threads safely |
| 39 | 35 | --> $DIR/issue-70935-complex-spans.rs:15:23 |
| ... | ... | @@ -41,7 +37,7 @@ error[E0277]: `*mut ()` cannot be shared between threads safely |
| 41 | 37 | LL | fn foo(x: NotSync) -> impl Future + Send { |
| 42 | 38 | | ^^^^^^^^^^^^^^^^^^ `*mut ()` cannot be shared between threads safely |
| 43 | 39 | | |
| 44 | = help: within `NotSync`, the trait `Sync` is not implemented for `*mut ()`, which is required by `{async block@$DIR/issue-70935-complex-spans.rs:18:5: 22:6}: Send` | |
| 40 | = help: within `NotSync`, the trait `Sync` is not implemented for `*mut ()`, which is required by `{async block@$DIR/issue-70935-complex-spans.rs:18:5: 18:15}: Send` | |
| 45 | 41 | note: required because it appears within the type `PhantomData<*mut ()>` |
| 46 | 42 | --> $SRC_DIR/core/src/marker.rs:LL:COL |
| 47 | 43 | note: required because it appears within the type `NotSync` |
| ... | ... | @@ -65,12 +61,8 @@ LL | | } |
| 65 | 61 | note: required because it's used within this `async` block |
| 66 | 62 | --> $DIR/issue-70935-complex-spans.rs:18:5 |
| 67 | 63 | | |
| 68 | LL | / async move { | |
| 69 | LL | | baz(|| async { | |
| 70 | LL | | foo(x.clone()); | |
| 71 | LL | | }).await; | |
| 72 | LL | | } | |
| 73 | | |_____^ | |
| 64 | LL | async move { | |
| 65 | | ^^^^^^^^^^ | |
| 74 | 66 | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` |
| 75 | 67 | |
| 76 | 68 | error: aborting due to 2 previous errors |
tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr+8-6| ... | ... | @@ -13,14 +13,15 @@ LL | y |
| 13 | 13 | error[E0506]: cannot assign to `*x` because it is borrowed |
| 14 | 14 | --> $DIR/issue-74072-lifetime-name-annotations.rs:18:9 |
| 15 | 15 | | |
| 16 | LL | (async move || { | |
| 17 | | - return type of async closure is &'1 i32 | |
| 18 | ... | |
| 16 | 19 | LL | let y = &*x; |
| 17 | 20 | | --- `*x` is borrowed here |
| 18 | 21 | LL | *x += 1; |
| 19 | 22 | | ^^^^^^^ `*x` is assigned to here but it was already borrowed |
| 20 | 23 | LL | y |
| 21 | 24 | | - returning this value requires that `*x` is borrowed for `'1` |
| 22 | LL | })() | |
| 23 | | - return type of async closure is &'1 i32 | |
| 24 | 25 | |
| 25 | 26 | error: lifetime may not live long enough |
| 26 | 27 | --> $DIR/issue-74072-lifetime-name-annotations.rs:14:20 |
| ... | ... | @@ -61,14 +62,15 @@ LL | } |
| 61 | 62 | error[E0506]: cannot assign to `*x` because it is borrowed |
| 62 | 63 | --> $DIR/issue-74072-lifetime-name-annotations.rs:28:9 |
| 63 | 64 | | |
| 65 | LL | (async move || -> &i32 { | |
| 66 | | - return type of async closure is &'1 i32 | |
| 67 | ... | |
| 64 | 68 | LL | let y = &*x; |
| 65 | 69 | | --- `*x` is borrowed here |
| 66 | 70 | LL | *x += 1; |
| 67 | 71 | | ^^^^^^^ `*x` is assigned to here but it was already borrowed |
| 68 | 72 | LL | y |
| 69 | 73 | | - returning this value requires that `*x` is borrowed for `'1` |
| 70 | LL | })() | |
| 71 | | - return type of async closure is &'1 i32 | |
| 72 | 74 | |
| 73 | 75 | error: lifetime may not live long enough |
| 74 | 76 | --> $DIR/issue-74072-lifetime-name-annotations.rs:24:28 |
| ... | ... | @@ -109,14 +111,14 @@ LL | } |
| 109 | 111 | error[E0506]: cannot assign to `*x` because it is borrowed |
| 110 | 112 | --> $DIR/issue-74072-lifetime-name-annotations.rs:36:9 |
| 111 | 113 | | |
| 114 | LL | async move { | |
| 115 | | - return type of async block is &'1 i32 | |
| 112 | 116 | LL | let y = &*x; |
| 113 | 117 | | --- `*x` is borrowed here |
| 114 | 118 | LL | *x += 1; |
| 115 | 119 | | ^^^^^^^ `*x` is assigned to here but it was already borrowed |
| 116 | 120 | LL | y |
| 117 | 121 | | - returning this value requires that `*x` is borrowed for `'1` |
| 118 | LL | } | |
| 119 | | - return type of async block is &'1 i32 | |
| 120 | 122 | |
| 121 | 123 | error: aborting due to 8 previous errors |
| 122 | 124 |
tests/ui/async-await/issue-86507.stderr+1-1| ... | ... | @@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless |
| 13 | 13 | | |
| 14 | 14 | LL | let x = x; |
| 15 | 15 | | ^ has type `&T` which is not `Send`, because `T` is not `Sync` |
| 16 | = note: required for the cast from `Pin<Box<{async block@$DIR/issue-86507.rs:18:17: 20:18}>>` to `Pin<Box<(dyn Future<Output = ()> + Send + 'async_trait)>>` | |
| 16 | = note: required for the cast from `Pin<Box<{async block@$DIR/issue-86507.rs:18:17: 18:27}>>` to `Pin<Box<(dyn Future<Output = ()> + Send + 'async_trait)>>` | |
| 17 | 17 | help: consider further restricting this bound |
| 18 | 18 | | |
| 19 | 19 | LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T) |
tests/ui/async-await/issues/issue-78938-async-block.stderr+4-6| ... | ... | @@ -1,12 +1,10 @@ |
| 1 | 1 | error[E0373]: async block may outlive the current function, but it borrows `room_ref`, which is owned by the current function |
| 2 | 2 | --> $DIR/issue-78938-async-block.rs:8:33 |
| 3 | 3 | | |
| 4 | LL | let gameloop_handle = spawn(async { | |
| 5 | | _________________________________^ | |
| 6 | LL | | game_loop(Arc::clone(&room_ref)) | |
| 7 | | | -------- `room_ref` is borrowed here | |
| 8 | LL | | }); | |
| 9 | | |_____^ may outlive borrowed value `room_ref` | |
| 4 | LL | let gameloop_handle = spawn(async { | |
| 5 | | ^^^^^ may outlive borrowed value `room_ref` | |
| 6 | LL | game_loop(Arc::clone(&room_ref)) | |
| 7 | | -------- `room_ref` is borrowed here | |
| 10 | 8 | | |
| 11 | 9 | = note: async blocks are not executed immediately and must either take a reference or ownership of outside variables they use |
| 12 | 10 | help: to force the async block to take ownership of `room_ref` (and any other referenced variables), use the `move` keyword |
tests/ui/async-await/track-caller/async-closure-gate.afn.stderr+2-2| ... | ... | @@ -72,7 +72,7 @@ LL | | } |
| 72 | 72 | | |_____^ expected `()`, found `async` block |
| 73 | 73 | | |
| 74 | 74 | = note: expected unit type `()` |
| 75 | found `async` block `{async block@$DIR/async-closure-gate.rs:27:5: 32:6}` | |
| 75 | found `async` block `{async block@$DIR/async-closure-gate.rs:27:5: 27:10}` | |
| 76 | 76 | |
| 77 | 77 | error[E0308]: mismatched types |
| 78 | 78 | --> $DIR/async-closure-gate.rs:44:5 |
| ... | ... | @@ -89,7 +89,7 @@ LL | | } |
| 89 | 89 | | |_____^ expected `()`, found `async` block |
| 90 | 90 | | |
| 91 | 91 | = note: expected unit type `()` |
| 92 | found `async` block `{async block@$DIR/async-closure-gate.rs:44:5: 51:6}` | |
| 92 | found `async` block `{async block@$DIR/async-closure-gate.rs:44:5: 44:10}` | |
| 93 | 93 | |
| 94 | 94 | error: aborting due to 8 previous errors |
| 95 | 95 |
tests/ui/async-await/track-caller/async-closure-gate.nofeat.stderr+2-2| ... | ... | @@ -72,7 +72,7 @@ LL | | } |
| 72 | 72 | | |_____^ expected `()`, found `async` block |
| 73 | 73 | | |
| 74 | 74 | = note: expected unit type `()` |
| 75 | found `async` block `{async block@$DIR/async-closure-gate.rs:27:5: 32:6}` | |
| 75 | found `async` block `{async block@$DIR/async-closure-gate.rs:27:5: 27:10}` | |
| 76 | 76 | |
| 77 | 77 | error[E0308]: mismatched types |
| 78 | 78 | --> $DIR/async-closure-gate.rs:44:5 |
| ... | ... | @@ -89,7 +89,7 @@ LL | | } |
| 89 | 89 | | |_____^ expected `()`, found `async` block |
| 90 | 90 | | |
| 91 | 91 | = note: expected unit type `()` |
| 92 | found `async` block `{async block@$DIR/async-closure-gate.rs:44:5: 51:6}` | |
| 92 | found `async` block `{async block@$DIR/async-closure-gate.rs:44:5: 44:10}` | |
| 93 | 93 | |
| 94 | 94 | error: aborting due to 8 previous errors |
| 95 | 95 |
tests/ui/async-await/try-on-option-in-async.stderr+5-7| ... | ... | @@ -1,13 +1,11 @@ |
| 1 | 1 | error[E0277]: the `?` operator can only be used in an async block that returns `Result` or `Option` (or another type that implements `FromResidual`) |
| 2 | 2 | --> $DIR/try-on-option-in-async.rs:8:10 |
| 3 | 3 | | |
| 4 | LL | / async { | |
| 5 | LL | | let x: Option<u32> = None; | |
| 6 | LL | | x?; | |
| 7 | | | ^ cannot use the `?` operator in an async block that returns `{integer}` | |
| 8 | LL | | 22 | |
| 9 | LL | | } | |
| 10 | | |_____- this function should return `Result` or `Option` to accept `?` | |
| 4 | LL | async { | |
| 5 | | ----- this function should return `Result` or `Option` to accept `?` | |
| 6 | LL | let x: Option<u32> = None; | |
| 7 | LL | x?; | |
| 8 | | ^ cannot use the `?` operator in an async block that returns `{integer}` | |
| 11 | 9 | | |
| 12 | 10 | = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `{integer}` |
| 13 | 11 |
tests/ui/borrowck/cloning-in-async-block-121547.stderr+8-10| ... | ... | @@ -1,16 +1,14 @@ |
| 1 | 1 | error[E0382]: use of moved value: `value` |
| 2 | 2 | --> $DIR/cloning-in-async-block-121547.rs:5:9 |
| 3 | 3 | | |
| 4 | LL | async fn clone_async_block(value: String) { | |
| 5 | | ----- move occurs because `value` has type `String`, which does not implement the `Copy` trait | |
| 6 | LL | for _ in 0..10 { | |
| 7 | | -------------- inside of this loop | |
| 8 | LL | / async { | |
| 9 | LL | | drop(value); | |
| 10 | | | ----- use occurs due to use in coroutine | |
| 11 | LL | | | |
| 12 | LL | | }.await | |
| 13 | | |_________^ value moved here, in previous iteration of loop | |
| 4 | LL | async fn clone_async_block(value: String) { | |
| 5 | | ----- move occurs because `value` has type `String`, which does not implement the `Copy` trait | |
| 6 | LL | for _ in 0..10 { | |
| 7 | | -------------- inside of this loop | |
| 8 | LL | async { | |
| 9 | | ^^^^^ value moved here, in previous iteration of loop | |
| 10 | LL | drop(value); | |
| 11 | | ----- use occurs due to use in coroutine | |
| 14 | 12 | | |
| 15 | 13 | help: consider cloning the value if the performance cost is acceptable |
| 16 | 14 | | |
tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr+20-30| ... | ... | @@ -1,67 +1,57 @@ |
| 1 | 1 | error[E0267]: `break` inside `async` function |
| 2 | 2 | --> $DIR/break-inside-coroutine-issue-124495.rs:8:5 |
| 3 | 3 | | |
| 4 | LL | async fn async_fn() { | |
| 5 | | _____________________- | |
| 6 | LL | | break; | |
| 7 | | | ^^^^^ cannot `break` inside `async` function | |
| 8 | LL | | } | |
| 9 | | |_- enclosing `async` function | |
| 4 | LL | async fn async_fn() { | |
| 5 | | ------------------- enclosing `async` function | |
| 6 | LL | break; | |
| 7 | | ^^^^^ cannot `break` inside `async` function | |
| 10 | 8 | |
| 11 | 9 | error[E0267]: `break` inside `gen` function |
| 12 | 10 | --> $DIR/break-inside-coroutine-issue-124495.rs:12:5 |
| 13 | 11 | | |
| 14 | LL | gen fn gen_fn() { | |
| 15 | | _________________- | |
| 16 | LL | | break; | |
| 17 | | | ^^^^^ cannot `break` inside `gen` function | |
| 18 | LL | | } | |
| 19 | | |_- enclosing `gen` function | |
| 12 | LL | gen fn gen_fn() { | |
| 13 | | --------------- enclosing `gen` function | |
| 14 | LL | break; | |
| 15 | | ^^^^^ cannot `break` inside `gen` function | |
| 20 | 16 | |
| 21 | 17 | error[E0267]: `break` inside `async gen` function |
| 22 | 18 | --> $DIR/break-inside-coroutine-issue-124495.rs:16:5 |
| 23 | 19 | | |
| 24 | LL | async gen fn async_gen_fn() { | |
| 25 | | _____________________________- | |
| 26 | LL | | break; | |
| 27 | | | ^^^^^ cannot `break` inside `async gen` function | |
| 28 | LL | | } | |
| 29 | | |_- enclosing `async gen` function | |
| 20 | LL | async gen fn async_gen_fn() { | |
| 21 | | --------------------------- enclosing `async gen` function | |
| 22 | LL | break; | |
| 23 | | ^^^^^ cannot `break` inside `async gen` function | |
| 30 | 24 | |
| 31 | 25 | error[E0267]: `break` inside `async` block |
| 32 | 26 | --> $DIR/break-inside-coroutine-issue-124495.rs:20:21 |
| 33 | 27 | | |
| 34 | 28 | LL | let _ = async { break; }; |
| 35 | | --------^^^^^--- | |
| 36 | | | | | |
| 37 | | | cannot `break` inside `async` block | |
| 29 | | ----- ^^^^^ cannot `break` inside `async` block | |
| 30 | | | | |
| 38 | 31 | | enclosing `async` block |
| 39 | 32 | |
| 40 | 33 | error[E0267]: `break` inside `async` closure |
| 41 | 34 | --> $DIR/break-inside-coroutine-issue-124495.rs:22:24 |
| 42 | 35 | | |
| 43 | 36 | LL | let _ = async || { break; }; |
| 44 | | -----------^^^^^--- | |
| 45 | | | | | |
| 46 | | | cannot `break` inside `async` closure | |
| 37 | | -------- ^^^^^ cannot `break` inside `async` closure | |
| 38 | | | | |
| 47 | 39 | | enclosing `async` closure |
| 48 | 40 | |
| 49 | 41 | error[E0267]: `break` inside `gen` block |
| 50 | 42 | --> $DIR/break-inside-coroutine-issue-124495.rs:24:19 |
| 51 | 43 | | |
| 52 | 44 | LL | let _ = gen { break; }; |
| 53 | | ------^^^^^--- | |
| 54 | | | | | |
| 55 | | | cannot `break` inside `gen` block | |
| 45 | | --- ^^^^^ cannot `break` inside `gen` block | |
| 46 | | | | |
| 56 | 47 | | enclosing `gen` block |
| 57 | 48 | |
| 58 | 49 | error[E0267]: `break` inside `async gen` block |
| 59 | 50 | --> $DIR/break-inside-coroutine-issue-124495.rs:26:25 |
| 60 | 51 | | |
| 61 | 52 | LL | let _ = async gen { break; }; |
| 62 | | ------------^^^^^--- | |
| 63 | | | | | |
| 64 | | | cannot `break` inside `async gen` block | |
| 53 | | --------- ^^^^^ cannot `break` inside `async gen` block | |
| 54 | | | | |
| 65 | 55 | | enclosing `async gen` block |
| 66 | 56 | |
| 67 | 57 | error: aborting due to 7 previous errors |
tests/ui/coroutine/clone-impl-async.stderr+12-12| ... | ... | @@ -1,8 +1,8 @@ |
| 1 | error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:12:27: 16:6}: Copy` is not satisfied | |
| 1 | error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:12:27: 12:32}: Copy` is not satisfied | |
| 2 | 2 | --> $DIR/clone-impl-async.rs:17:16 |
| 3 | 3 | | |
| 4 | 4 | LL | check_copy(&inner_non_clone); |
| 5 | | ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:12:27: 16:6}` | |
| 5 | | ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:12:27: 12:32}` | |
| 6 | 6 | | | |
| 7 | 7 | | required by a bound introduced by this call |
| 8 | 8 | | |
| ... | ... | @@ -12,11 +12,11 @@ note: required by a bound in `check_copy` |
| 12 | 12 | LL | fn check_copy<T: Copy>(_x: &T) {} |
| 13 | 13 | | ^^^^ required by this bound in `check_copy` |
| 14 | 14 | |
| 15 | error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:12:27: 16:6}: Clone` is not satisfied | |
| 15 | error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:12:27: 12:32}: Clone` is not satisfied | |
| 16 | 16 | --> $DIR/clone-impl-async.rs:19:17 |
| 17 | 17 | | |
| 18 | 18 | LL | check_clone(&inner_non_clone); |
| 19 | | ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:12:27: 16:6}` | |
| 19 | | ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:12:27: 12:32}` | |
| 20 | 20 | | | |
| 21 | 21 | | required by a bound introduced by this call |
| 22 | 22 | | |
| ... | ... | @@ -26,11 +26,11 @@ note: required by a bound in `check_clone` |
| 26 | 26 | LL | fn check_clone<T: Clone>(_x: &T) {} |
| 27 | 27 | | ^^^^^ required by this bound in `check_clone` |
| 28 | 28 | |
| 29 | error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:23:27: 25:6}: Copy` is not satisfied | |
| 29 | error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:23:27: 23:37}: Copy` is not satisfied | |
| 30 | 30 | --> $DIR/clone-impl-async.rs:26:16 |
| 31 | 31 | | |
| 32 | 32 | LL | check_copy(&outer_non_clone); |
| 33 | | ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:23:27: 25:6}` | |
| 33 | | ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:23:27: 23:37}` | |
| 34 | 34 | | | |
| 35 | 35 | | required by a bound introduced by this call |
| 36 | 36 | | |
| ... | ... | @@ -40,11 +40,11 @@ note: required by a bound in `check_copy` |
| 40 | 40 | LL | fn check_copy<T: Copy>(_x: &T) {} |
| 41 | 41 | | ^^^^ required by this bound in `check_copy` |
| 42 | 42 | |
| 43 | error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:23:27: 25:6}: Clone` is not satisfied | |
| 43 | error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:23:27: 23:37}: Clone` is not satisfied | |
| 44 | 44 | --> $DIR/clone-impl-async.rs:28:17 |
| 45 | 45 | | |
| 46 | 46 | LL | check_clone(&outer_non_clone); |
| 47 | | ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:23:27: 25:6}` | |
| 47 | | ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:23:27: 23:37}` | |
| 48 | 48 | | | |
| 49 | 49 | | required by a bound introduced by this call |
| 50 | 50 | | |
| ... | ... | @@ -54,11 +54,11 @@ note: required by a bound in `check_clone` |
| 54 | 54 | LL | fn check_clone<T: Clone>(_x: &T) {} |
| 55 | 55 | | ^^^^^ required by this bound in `check_clone` |
| 56 | 56 | |
| 57 | error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:31:28: 31:41}: Copy` is not satisfied | |
| 57 | error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:31:28: 31:38}: Copy` is not satisfied | |
| 58 | 58 | --> $DIR/clone-impl-async.rs:32:16 |
| 59 | 59 | | |
| 60 | 60 | LL | check_copy(&maybe_copy_clone); |
| 61 | | ---------- ^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:31:28: 31:41}` | |
| 61 | | ---------- ^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:31:28: 31:38}` | |
| 62 | 62 | | | |
| 63 | 63 | | required by a bound introduced by this call |
| 64 | 64 | | |
| ... | ... | @@ -68,11 +68,11 @@ note: required by a bound in `check_copy` |
| 68 | 68 | LL | fn check_copy<T: Copy>(_x: &T) {} |
| 69 | 69 | | ^^^^ required by this bound in `check_copy` |
| 70 | 70 | |
| 71 | error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:31:28: 31:41}: Clone` is not satisfied | |
| 71 | error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:31:28: 31:38}: Clone` is not satisfied | |
| 72 | 72 | --> $DIR/clone-impl-async.rs:34:17 |
| 73 | 73 | | |
| 74 | 74 | LL | check_clone(&maybe_copy_clone); |
| 75 | | ----------- ^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:31:28: 31:41}` | |
| 75 | | ----------- ^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:31:28: 31:38}` | |
| 76 | 76 | | | |
| 77 | 77 | | required by a bound introduced by this call |
| 78 | 78 | | |
tests/ui/coroutine/gen_block_is_coro.stderr+6-6| ... | ... | @@ -1,20 +1,20 @@ |
| 1 | error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:21}: Coroutine` is not satisfied | |
| 1 | error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}: Coroutine` is not satisfied | |
| 2 | 2 | --> $DIR/gen_block_is_coro.rs:6:13 |
| 3 | 3 | | |
| 4 | 4 | LL | fn foo() -> impl Coroutine<Yield = u32, Return = ()> { |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:21}` | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}` | |
| 6 | 6 | |
| 7 | error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:21}: Coroutine` is not satisfied | |
| 7 | error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:8}: Coroutine` is not satisfied | |
| 8 | 8 | --> $DIR/gen_block_is_coro.rs:10:13 |
| 9 | 9 | | |
| 10 | 10 | LL | fn bar() -> impl Coroutine<Yield = i64, Return = ()> { |
| 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:21}` | |
| 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:8}` | |
| 12 | 12 | |
| 13 | error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:21}: Coroutine` is not satisfied | |
| 13 | error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:8}: Coroutine` is not satisfied | |
| 14 | 14 | --> $DIR/gen_block_is_coro.rs:14:13 |
| 15 | 15 | | |
| 16 | 16 | LL | fn baz() -> impl Coroutine<Yield = i32, Return = ()> { |
| 17 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:21}` | |
| 17 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:8}` | |
| 18 | 18 | |
| 19 | 19 | error: aborting due to 3 previous errors |
| 20 | 20 |
tests/ui/coroutine/gen_block_is_no_future.stderr+3-3| ... | ... | @@ -1,10 +1,10 @@ |
| 1 | error[E0277]: `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:21}` is not a future | |
| 1 | error[E0277]: `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:8}` is not a future | |
| 2 | 2 | --> $DIR/gen_block_is_no_future.rs:4:13 |
| 3 | 3 | | |
| 4 | 4 | LL | fn foo() -> impl std::future::Future { |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^ `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:21}` is not a future | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^ `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:8}` is not a future | |
| 6 | 6 | | |
| 7 | = help: the trait `Future` is not implemented for `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:21}` | |
| 7 | = help: the trait `Future` is not implemented for `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:8}` | |
| 8 | 8 | |
| 9 | 9 | error: aborting due to 1 previous error |
| 10 | 10 |
tests/ui/coroutine/gen_block_move.stderr+5-8| ... | ... | @@ -1,14 +1,11 @@ |
| 1 | 1 | error[E0373]: gen block may outlive the current function, but it borrows `x`, which is owned by the current function |
| 2 | 2 | --> $DIR/gen_block_move.rs:7:5 |
| 3 | 3 | | |
| 4 | LL | / gen { | |
| 5 | LL | | yield 42; | |
| 6 | LL | | if x == "foo" { return } | |
| 7 | LL | | x.clear(); | |
| 8 | | | - `x` is borrowed here | |
| 9 | LL | | for x in 3..6 { yield x } | |
| 10 | LL | | } | |
| 11 | | |_____^ may outlive borrowed value `x` | |
| 4 | LL | gen { | |
| 5 | | ^^^ may outlive borrowed value `x` | |
| 6 | ... | |
| 7 | LL | x.clear(); | |
| 8 | | - `x` is borrowed here | |
| 12 | 9 | | |
| 13 | 10 | note: gen block is returned here |
| 14 | 11 | --> $DIR/gen_block_move.rs:7:5 |
tests/ui/feature-gates/feature-gate-patchable-function-entry.rs created+3| ... | ... | @@ -0,0 +1,3 @@ |
| 1 | #[patchable_function_entry(prefix_nops = 1, entry_nops = 1)] | |
| 2 | //~^ ERROR: the `#[patchable_function_entry]` attribute is an experimental feature | |
| 3 | fn main() {} |
tests/ui/feature-gates/feature-gate-patchable-function-entry.stderr created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | error[E0658]: the `#[patchable_function_entry]` attribute is an experimental feature | |
| 2 | --> $DIR/feature-gate-patchable-function-entry.rs:1:1 | |
| 3 | | | |
| 4 | LL | #[patchable_function_entry(prefix_nops = 1, entry_nops = 1)] | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | = note: see issue #123115 <https://github.com/rust-lang/rust/issues/123115> for more information | |
| 8 | = help: add `#![feature(patchable_function_entry)]` to the crate attributes to enable | |
| 9 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date | |
| 10 | ||
| 11 | error: aborting due to 1 previous error | |
| 12 | ||
| 13 | For more information about this error, try `rustc --explain E0658`. |
tests/ui/fmt/send-sync.stderr+6-24| ... | ... | @@ -1,45 +1,27 @@ |
| 1 | error[E0277]: `core::fmt::rt::Opaque` cannot be shared between threads safely | |
| 1 | error[E0277]: `Arguments<'_>` cannot be sent between threads safely | |
| 2 | 2 | --> $DIR/send-sync.rs:8:10 |
| 3 | 3 | | |
| 4 | 4 | LL | send(format_args!("{:?}", c)); |
| 5 | | ---- ^^^^^^^^^^^^^^^^^^^^^^^ `core::fmt::rt::Opaque` cannot be shared between threads safely | |
| 5 | | ---- ^^^^^^^^^^^^^^^^^^^^^^^ `Arguments<'_>` cannot be sent between threads safely | |
| 6 | 6 | | | |
| 7 | 7 | | required by a bound introduced by this call |
| 8 | 8 | | |
| 9 | = help: within `[core::fmt::rt::Argument<'_>]`, the trait `Sync` is not implemented for `core::fmt::rt::Opaque`, which is required by `Arguments<'_>: Send` | |
| 10 | = note: required because it appears within the type `&core::fmt::rt::Opaque` | |
| 11 | note: required because it appears within the type `core::fmt::rt::ArgumentType<'_>` | |
| 12 | --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL | |
| 13 | note: required because it appears within the type `core::fmt::rt::Argument<'_>` | |
| 14 | --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL | |
| 15 | = note: required because it appears within the type `[core::fmt::rt::Argument<'_>]` | |
| 16 | = note: required for `&[core::fmt::rt::Argument<'_>]` to implement `Send` | |
| 17 | note: required because it appears within the type `Arguments<'_>` | |
| 18 | --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL | |
| 9 | = help: the trait `Send` is not implemented for `Arguments<'_>` | |
| 19 | 10 | note: required by a bound in `send` |
| 20 | 11 | --> $DIR/send-sync.rs:1:12 |
| 21 | 12 | | |
| 22 | 13 | LL | fn send<T: Send>(_: T) {} |
| 23 | 14 | | ^^^^ required by this bound in `send` |
| 24 | 15 | |
| 25 | error[E0277]: `core::fmt::rt::Opaque` cannot be shared between threads safely | |
| 16 | error[E0277]: `Arguments<'_>` cannot be shared between threads safely | |
| 26 | 17 | --> $DIR/send-sync.rs:9:10 |
| 27 | 18 | | |
| 28 | 19 | LL | sync(format_args!("{:?}", c)); |
| 29 | | ---- ^^^^^^^^^^^^^^^^^^^^^^^ `core::fmt::rt::Opaque` cannot be shared between threads safely | |
| 20 | | ---- ^^^^^^^^^^^^^^^^^^^^^^^ `Arguments<'_>` cannot be shared between threads safely | |
| 30 | 21 | | | |
| 31 | 22 | | required by a bound introduced by this call |
| 32 | 23 | | |
| 33 | = help: within `Arguments<'_>`, the trait `Sync` is not implemented for `core::fmt::rt::Opaque`, which is required by `Arguments<'_>: Sync` | |
| 34 | = note: required because it appears within the type `&core::fmt::rt::Opaque` | |
| 35 | note: required because it appears within the type `core::fmt::rt::ArgumentType<'_>` | |
| 36 | --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL | |
| 37 | note: required because it appears within the type `core::fmt::rt::Argument<'_>` | |
| 38 | --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL | |
| 39 | = note: required because it appears within the type `[core::fmt::rt::Argument<'_>]` | |
| 40 | = note: required because it appears within the type `&[core::fmt::rt::Argument<'_>]` | |
| 41 | note: required because it appears within the type `Arguments<'_>` | |
| 42 | --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL | |
| 24 | = help: the trait `Sync` is not implemented for `Arguments<'_>` | |
| 43 | 25 | note: required by a bound in `sync` |
| 44 | 26 | --> $DIR/send-sync.rs:2:12 |
| 45 | 27 | | |
tests/ui/generic-associated-types/issue-90014-tait.stderr+1-1| ... | ... | @@ -10,7 +10,7 @@ LL | async { () } |
| 10 | 10 | | ^^^^^^^^^^^^ expected future, found `async` block |
| 11 | 11 | | |
| 12 | 12 | = note: expected opaque type `Foo<'_>::Fut<'a>` |
| 13 | found `async` block `{async block@$DIR/issue-90014-tait.rs:18:9: 18:21}` | |
| 13 | found `async` block `{async block@$DIR/issue-90014-tait.rs:18:9: 18:14}` | |
| 14 | 14 | note: this item must have the opaque type in its signature in order to be able to register hidden types |
| 15 | 15 | --> $DIR/issue-90014-tait.rs:17:8 |
| 16 | 16 | | |
tests/ui/impl-trait/issue-55872-3.stderr+2-2| ... | ... | @@ -1,8 +1,8 @@ |
| 1 | error[E0277]: the trait bound `{async block@$DIR/issue-55872-3.rs:15:9: 15:17}: Copy` is not satisfied | |
| 1 | error[E0277]: the trait bound `{async block@$DIR/issue-55872-3.rs:15:9: 15:14}: Copy` is not satisfied | |
| 2 | 2 | --> $DIR/issue-55872-3.rs:13:20 |
| 3 | 3 | | |
| 4 | 4 | LL | fn foo<T>() -> Self::E { |
| 5 | | ^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/issue-55872-3.rs:15:9: 15:17}` | |
| 5 | | ^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/issue-55872-3.rs:15:9: 15:14}` | |
| 6 | 6 | |
| 7 | 7 | error: aborting due to 1 previous error |
| 8 | 8 |
tests/ui/impl-trait/issues/issue-78722-2.stderr+2-2| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | error[E0271]: expected `{async block@$DIR/issue-78722-2.rs:13:13: 13:21}` to be a future that resolves to `u8`, but it resolves to `()` | |
| 1 | error[E0271]: expected `{async block@$DIR/issue-78722-2.rs:13:13: 13:18}` to be a future that resolves to `u8`, but it resolves to `()` | |
| 2 | 2 | --> $DIR/issue-78722-2.rs:11:30 |
| 3 | 3 | | |
| 4 | 4 | LL | fn concrete_use() -> F { |
| ... | ... | @@ -16,7 +16,7 @@ LL | let f: F = async { 1 }; |
| 16 | 16 | | expected due to this |
| 17 | 17 | | |
| 18 | 18 | = note: expected opaque type `F` |
| 19 | found `async` block `{async block@$DIR/issue-78722-2.rs:16:20: 16:31}` | |
| 19 | found `async` block `{async block@$DIR/issue-78722-2.rs:16:20: 16:25}` | |
| 20 | 20 | |
| 21 | 21 | error: aborting due to 2 previous errors |
| 22 | 22 |
tests/ui/impl-trait/issues/issue-78722.stderr+1-1| ... | ... | @@ -8,7 +8,7 @@ LL | let f: F = async { 1 }; |
| 8 | 8 | = help: add `#![feature(const_async_blocks)]` to the crate attributes to enable |
| 9 | 9 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 10 | 10 | |
| 11 | error[E0271]: expected `{async block@$DIR/issue-78722.rs:10:13: 10:21}` to be a future that resolves to `u8`, but it resolves to `()` | |
| 11 | error[E0271]: expected `{async block@$DIR/issue-78722.rs:10:13: 10:18}` to be a future that resolves to `u8`, but it resolves to `()` | |
| 12 | 12 | --> $DIR/issue-78722.rs:8:30 |
| 13 | 13 | | |
| 14 | 14 | LL | fn concrete_use() -> F { |
tests/ui/impl-trait/nested-return-type4.stderr+1-1| ... | ... | @@ -4,7 +4,7 @@ error[E0700]: hidden type for `impl Future<Output = impl Sized>` captures lifeti |
| 4 | 4 | LL | fn test<'s: 's>(s: &'s str) -> impl std::future::Future<Output = impl Sized> { |
| 5 | 5 | | -- --------------------------------------------- opaque type defined here |
| 6 | 6 | | | |
| 7 | | hidden type `{async block@$DIR/nested-return-type4.rs:4:5: 4:31}` captures the lifetime `'s` as defined here | |
| 7 | | hidden type `{async block@$DIR/nested-return-type4.rs:4:5: 4:15}` captures the lifetime `'s` as defined here | |
| 8 | 8 | LL | async move { let _s = s; } |
| 9 | 9 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 10 | 10 | | |
tests/ui/mismatched_types/mismatch-sugg-for-shorthand-field.stderr+2-2| ... | ... | @@ -52,13 +52,13 @@ error[E0308]: mismatched types |
| 52 | 52 | --> $DIR/mismatch-sugg-for-shorthand-field.rs:57:20 |
| 53 | 53 | | |
| 54 | 54 | LL | let a = async { 42 }; |
| 55 | | ------------ the found `async` block | |
| 55 | | ----- the found `async` block | |
| 56 | 56 | ... |
| 57 | 57 | LL | let s = Demo { a }; |
| 58 | 58 | | ^ expected `Pin<Box<...>>`, found `async` block |
| 59 | 59 | | |
| 60 | 60 | = note: expected struct `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>` |
| 61 | found `async` block `{async block@$DIR/mismatch-sugg-for-shorthand-field.rs:53:13: 53:25}` | |
| 61 | found `async` block `{async block@$DIR/mismatch-sugg-for-shorthand-field.rs:53:13: 53:18}` | |
| 62 | 62 | help: you need to pin and box this expression |
| 63 | 63 | | |
| 64 | 64 | LL | let s = Demo { a: Box::pin(a) }; |
tests/ui/patchable-function-entry/patchable-function-entry-attribute.rs created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | #![feature(patchable_function_entry)] | |
| 2 | fn main() {} | |
| 3 | ||
| 4 | #[patchable_function_entry(prefix_nops = 256, entry_nops = 0)]//~error: integer value out of range | |
| 5 | pub fn too_high_pnops() {} | |
| 6 | ||
| 7 | #[patchable_function_entry(prefix_nops = "stringvalue", entry_nops = 0)]//~error: invalid literal value | |
| 8 | pub fn non_int_nop() {} | |
| 9 | ||
| 10 | #[patchable_function_entry]//~error: malformed `patchable_function_entry` attribute input | |
| 11 | pub fn malformed_attribute() {} | |
| 12 | ||
| 13 | #[patchable_function_entry(prefix_nops = 10, something = 0)]//~error: unexpected parameter name | |
| 14 | pub fn unexpected_parameter_name() {} | |
| 15 | ||
| 16 | #[patchable_function_entry()]//~error: must specify at least one parameter | |
| 17 | pub fn no_parameters_given() {} |
tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr created+32| ... | ... | @@ -0,0 +1,32 @@ |
| 1 | error: malformed `patchable_function_entry` attribute input | |
| 2 | --> $DIR/patchable-function-entry-attribute.rs:10:1 | |
| 3 | | | |
| 4 | LL | #[patchable_function_entry] | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` | |
| 6 | ||
| 7 | error: integer value out of range | |
| 8 | --> $DIR/patchable-function-entry-attribute.rs:4:42 | |
| 9 | | | |
| 10 | LL | #[patchable_function_entry(prefix_nops = 256, entry_nops = 0)] | |
| 11 | | ^^^ value must be between `0` and `255` | |
| 12 | ||
| 13 | error: invalid literal value | |
| 14 | --> $DIR/patchable-function-entry-attribute.rs:7:42 | |
| 15 | | | |
| 16 | LL | #[patchable_function_entry(prefix_nops = "stringvalue", entry_nops = 0)] | |
| 17 | | ^^^^^^^^^^^^^ value must be an integer between `0` and `255` | |
| 18 | ||
| 19 | error: unexpected parameter name | |
| 20 | --> $DIR/patchable-function-entry-attribute.rs:13:46 | |
| 21 | | | |
| 22 | LL | #[patchable_function_entry(prefix_nops = 10, something = 0)] | |
| 23 | | ^^^^^^^^^^^^^ expected prefix_nops or entry_nops | |
| 24 | ||
| 25 | error: must specify at least one parameter | |
| 26 | --> $DIR/patchable-function-entry-attribute.rs:16:1 | |
| 27 | | | |
| 28 | LL | #[patchable_function_entry()] | |
| 29 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 30 | ||
| 31 | error: aborting due to 5 previous errors | |
| 32 |
tests/ui/patchable-function-entry/patchable-function-entry-flags.rs created+2| ... | ... | @@ -0,0 +1,2 @@ |
| 1 | //@ compile-flags: -Z patchable-function-entry=1,2 | |
| 2 | fn main() {} |
tests/ui/patchable-function-entry/patchable-function-entry-flags.stderr created+2| ... | ... | @@ -0,0 +1,2 @@ |
| 1 | error: incorrect value `1,2` for unstable option `patchable-function-entry` - either two comma separated integers (total_nops,prefix_nops), with prefix_nops <= total_nops, or one integer (total_nops) was expected | |
| 2 |
tests/ui/pattern/non-structural-match-types.stderr+1-1| ... | ... | @@ -4,7 +4,7 @@ error: `{closure@$DIR/non-structural-match-types.rs:9:17: 9:19}` cannot be used |
| 4 | 4 | LL | const { || {} } => {} |
| 5 | 5 | | ^^^^^^^^^^^^^^^ |
| 6 | 6 | |
| 7 | error: `{async block@$DIR/non-structural-match-types.rs:12:17: 12:25}` cannot be used in patterns | |
| 7 | error: `{async block@$DIR/non-structural-match-types.rs:12:17: 12:22}` cannot be used in patterns | |
| 8 | 8 | --> $DIR/non-structural-match-types.rs:12:9 |
| 9 | 9 | | |
| 10 | 10 | LL | const { async {} } => {} |
tests/ui/suggestions/expected-boxed-future-isnt-pinned.stderr+1-1| ... | ... | @@ -79,7 +79,7 @@ LL | | } |
| 79 | 79 | | |_____^ expected `Pin<Box<...>>`, found `async` block |
| 80 | 80 | | |
| 81 | 81 | = note: expected struct `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>` |
| 82 | found `async` block `{async block@$DIR/expected-boxed-future-isnt-pinned.rs:28:5: 30:6}` | |
| 82 | found `async` block `{async block@$DIR/expected-boxed-future-isnt-pinned.rs:28:5: 28:10}` | |
| 83 | 83 | help: you need to pin and box this expression |
| 84 | 84 | | |
| 85 | 85 | LL ~ Box::pin(async { |
tests/ui/traits/next-solver/async.fail.stderr+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | error[E0271]: type mismatch resolving `<{async block@$DIR/async.rs:12:17: 12:25} as Future>::Output == i32` | |
| 1 | error[E0271]: type mismatch resolving `<{async block@$DIR/async.rs:12:17: 12:22} as Future>::Output == i32` | |
| 2 | 2 | --> $DIR/async.rs:12:17 |
| 3 | 3 | | |
| 4 | 4 | LL | needs_async(async {}); |
tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.stderr+1-3| ... | ... | @@ -2,9 +2,7 @@ error[E0733]: recursion in an async block requires boxing |
| 2 | 2 | --> $DIR/indirect-recursion-issue-112047.rs:22:9 |
| 3 | 3 | | |
| 4 | 4 | LL | async move { recur(self).await; } |
| 5 | | ^^^^^^^^^^^^^-----------------^^^ | |
| 6 | | | | |
| 7 | | recursive call here | |
| 5 | | ^^^^^^^^^^ ----------------- recursive call here | |
| 8 | 6 | | |
| 9 | 7 | note: which leads to this async fn |
| 10 | 8 | --> $DIR/indirect-recursion-issue-112047.rs:14:1 |