mirror of
https://github.com/rust-lang/rust
synced 2024-09-30 05:40:24 +00:00
Auto merge of #127076 - matthiaskrgr:rollup-l01gm36, r=matthiaskrgr
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: rollup
This commit is contained in:
commit
99f77a2eda
|
@ -4675,6 +4675,8 @@ name = "rustc_smir"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rustc_abi",
|
||||
"rustc_ast",
|
||||
"rustc_ast_pretty",
|
||||
"rustc_data_structures",
|
||||
"rustc_hir",
|
||||
"rustc_middle",
|
||||
|
|
|
@ -1454,7 +1454,10 @@ pub enum ExprKind {
|
|||
Block(P<Block>, Option<Label>),
|
||||
/// An `async` block (`async move { ... }`),
|
||||
/// or a `gen` block (`gen move { ... }`)
|
||||
Gen(CaptureBy, P<Block>, GenBlockKind),
|
||||
///
|
||||
/// The span is the "decl", which is the header before the body `{ }`
|
||||
/// including the `asyng`/`gen` keywords and possibly `move`.
|
||||
Gen(CaptureBy, P<Block>, GenBlockKind, Span),
|
||||
/// An await expression (`my_future.await`). Span is of await keyword.
|
||||
Await(P<Expr>, Span),
|
||||
|
||||
|
|
|
@ -1528,8 +1528,9 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
|||
visit_opt(label, |label| vis.visit_label(label));
|
||||
vis.visit_block(blk);
|
||||
}
|
||||
ExprKind::Gen(_capture_by, body, _kind) => {
|
||||
ExprKind::Gen(_capture_by, body, _kind, decl_span) => {
|
||||
vis.visit_block(body);
|
||||
vis.visit_span(decl_span);
|
||||
}
|
||||
ExprKind::Await(expr, await_kw_span) => {
|
||||
vis.visit_expr(expr);
|
||||
|
|
|
@ -1122,7 +1122,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
|
|||
visit_opt!(visitor, visit_label, opt_label);
|
||||
try_visit!(visitor.visit_block(block));
|
||||
}
|
||||
ExprKind::Gen(_capt, body, _kind) => try_visit!(visitor.visit_block(body)),
|
||||
ExprKind::Gen(_capt, body, _kind, _decl_span) => try_visit!(visitor.visit_block(body)),
|
||||
ExprKind::Await(expr, _span) => try_visit!(visitor.visit_expr(expr)),
|
||||
ExprKind::Assign(lhs, rhs, _span) => {
|
||||
try_visit!(visitor.visit_expr(lhs));
|
||||
|
|
|
@ -227,7 +227,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
|
|||
*fn_arg_span,
|
||||
),
|
||||
},
|
||||
ExprKind::Gen(capture_clause, block, genblock_kind) => {
|
||||
ExprKind::Gen(capture_clause, block, genblock_kind, decl_span) => {
|
||||
let desugaring_kind = match genblock_kind {
|
||||
GenBlockKind::Async => hir::CoroutineDesugaring::Async,
|
||||
GenBlockKind::Gen => hir::CoroutineDesugaring::Gen,
|
||||
|
@ -237,6 +237,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
|
|||
*capture_clause,
|
||||
e.id,
|
||||
None,
|
||||
*decl_span,
|
||||
e.span,
|
||||
desugaring_kind,
|
||||
hir::CoroutineSource::Block,
|
||||
|
@ -616,6 +617,7 @@ pub(super) fn make_desugared_coroutine_expr(
|
|||
capture_clause: CaptureBy,
|
||||
closure_node_id: NodeId,
|
||||
return_ty: Option<hir::FnRetTy<'hir>>,
|
||||
fn_decl_span: Span,
|
||||
span: Span,
|
||||
desugaring_kind: hir::CoroutineDesugaring,
|
||||
coroutine_source: hir::CoroutineSource,
|
||||
|
@ -692,7 +694,7 @@ pub(super) fn make_desugared_coroutine_expr(
|
|||
bound_generic_params: &[],
|
||||
fn_decl,
|
||||
body,
|
||||
fn_decl_span: self.lower_span(span),
|
||||
fn_decl_span: self.lower_span(fn_decl_span),
|
||||
fn_arg_span: None,
|
||||
kind: hir::ClosureKind::Coroutine(coroutine_kind),
|
||||
constness: hir::Constness::NotConst,
|
||||
|
@ -1083,6 +1085,7 @@ fn lower_expr_coroutine_closure(
|
|||
let (parameters, expr) = this.lower_coroutine_body_with_moved_arguments(
|
||||
&inner_decl,
|
||||
|this| this.with_new_scopes(fn_decl_span, |this| this.lower_expr_mut(body)),
|
||||
fn_decl_span,
|
||||
body.span,
|
||||
coroutine_kind,
|
||||
hir::CoroutineSource::Closure,
|
||||
|
|
|
@ -211,6 +211,7 @@ fn lower_item_kind(
|
|||
// declaration (decl), not the return types.
|
||||
let coroutine_kind = header.coroutine_kind;
|
||||
let body_id = this.lower_maybe_coroutine_body(
|
||||
*fn_sig_span,
|
||||
span,
|
||||
hir_id,
|
||||
decl,
|
||||
|
@ -799,6 +800,7 @@ fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
|
|||
}
|
||||
AssocItemKind::Fn(box Fn { sig, generics, body: Some(body), .. }) => {
|
||||
let body_id = self.lower_maybe_coroutine_body(
|
||||
sig.span,
|
||||
i.span,
|
||||
hir_id,
|
||||
&sig.decl,
|
||||
|
@ -915,6 +917,7 @@ fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
|
|||
),
|
||||
AssocItemKind::Fn(box Fn { sig, generics, body, .. }) => {
|
||||
let body_id = self.lower_maybe_coroutine_body(
|
||||
sig.span,
|
||||
i.span,
|
||||
hir_id,
|
||||
&sig.decl,
|
||||
|
@ -1111,6 +1114,7 @@ pub(super) fn lower_const_body(&mut self, span: Span, expr: Option<&Expr>) -> hi
|
|||
/// `gen {}` block as appropriate.
|
||||
fn lower_maybe_coroutine_body(
|
||||
&mut self,
|
||||
fn_decl_span: Span,
|
||||
span: Span,
|
||||
fn_id: hir::HirId,
|
||||
decl: &FnDecl,
|
||||
|
@ -1124,6 +1128,7 @@ fn lower_maybe_coroutine_body(
|
|||
let (parameters, expr) = this.lower_coroutine_body_with_moved_arguments(
|
||||
decl,
|
||||
|this| this.lower_block_expr(body),
|
||||
fn_decl_span,
|
||||
body.span,
|
||||
coroutine_kind,
|
||||
hir::CoroutineSource::Fn,
|
||||
|
@ -1145,6 +1150,7 @@ pub fn lower_coroutine_body_with_moved_arguments(
|
|||
&mut self,
|
||||
decl: &FnDecl,
|
||||
lower_body: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::Expr<'hir>,
|
||||
fn_decl_span: Span,
|
||||
body_span: Span,
|
||||
coroutine_kind: CoroutineKind,
|
||||
coroutine_source: hir::CoroutineSource,
|
||||
|
@ -1315,13 +1321,6 @@ pub fn lower_coroutine_body_with_moved_arguments(
|
|||
};
|
||||
let closure_id = coroutine_kind.closure_id();
|
||||
|
||||
let span = if let FnRetTy::Default(span) = decl.output
|
||||
&& matches!(coroutine_source, rustc_hir::CoroutineSource::Closure)
|
||||
{
|
||||
body_span.with_lo(span.lo())
|
||||
} else {
|
||||
body_span
|
||||
};
|
||||
let coroutine_expr = self.make_desugared_coroutine_expr(
|
||||
// The default capture mode here is by-ref. Later on during upvar analysis,
|
||||
// we will force the captured arguments to by-move, but for async closures,
|
||||
|
@ -1330,7 +1329,8 @@ pub fn lower_coroutine_body_with_moved_arguments(
|
|||
CaptureBy::Ref,
|
||||
closure_id,
|
||||
None,
|
||||
span,
|
||||
fn_decl_span,
|
||||
body_span,
|
||||
desugaring_kind,
|
||||
coroutine_source,
|
||||
mkbody,
|
||||
|
|
|
@ -540,7 +540,7 @@ pub(super) fn print_expr_outer_attr_style(
|
|||
self.ibox(0);
|
||||
self.print_block_with_attrs(blk, attrs);
|
||||
}
|
||||
ast::ExprKind::Gen(capture_clause, blk, kind) => {
|
||||
ast::ExprKind::Gen(capture_clause, blk, kind, _decl_span) => {
|
||||
self.word_nbsp(kind.modifier());
|
||||
self.print_capture_clause(*capture_clause);
|
||||
// cbox/ibox in analogy to the `ExprKind::Block` arm above
|
||||
|
|
|
@ -298,7 +298,7 @@ fn manage_cond_expr(&mut self, expr: &mut P<Expr>) {
|
|||
// sync with the `rfc-2011-nicer-assert-messages/all-expr-kinds.rs` test.
|
||||
ExprKind::Assign(_, _, _)
|
||||
| ExprKind::AssignOp(_, _, _)
|
||||
| ExprKind::Gen(_, _, _)
|
||||
| ExprKind::Gen(_, _, _, _)
|
||||
| ExprKind::Await(_, _)
|
||||
| ExprKind::Block(_, _)
|
||||
| ExprKind::Break(_, _)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFunctionEntry};
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_session::config::{FunctionReturn, OptLevel};
|
||||
use rustc_span::symbol::sym;
|
||||
|
@ -53,6 +53,34 @@ fn inline_attr<'ll>(cx: &CodegenCx<'ll, '_>, inline: InlineAttr) -> Option<&'ll
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn patchable_function_entry_attrs<'ll>(
|
||||
cx: &CodegenCx<'ll, '_>,
|
||||
attr: Option<PatchableFunctionEntry>,
|
||||
) -> SmallVec<[&'ll Attribute; 2]> {
|
||||
let mut attrs = SmallVec::new();
|
||||
let patchable_spec = attr.unwrap_or_else(|| {
|
||||
PatchableFunctionEntry::from_config(cx.tcx.sess.opts.unstable_opts.patchable_function_entry)
|
||||
});
|
||||
let entry = patchable_spec.entry();
|
||||
let prefix = patchable_spec.prefix();
|
||||
if entry > 0 {
|
||||
attrs.push(llvm::CreateAttrStringValue(
|
||||
cx.llcx,
|
||||
"patchable-function-entry",
|
||||
&format!("{}", entry),
|
||||
));
|
||||
}
|
||||
if prefix > 0 {
|
||||
attrs.push(llvm::CreateAttrStringValue(
|
||||
cx.llcx,
|
||||
"patchable-function-prefix",
|
||||
&format!("{}", prefix),
|
||||
));
|
||||
}
|
||||
attrs
|
||||
}
|
||||
|
||||
/// Get LLVM sanitize attributes.
|
||||
#[inline]
|
||||
pub fn sanitize_attrs<'ll>(
|
||||
|
@ -421,6 +449,7 @@ pub fn from_fn_attrs<'ll, 'tcx>(
|
|||
llvm::set_alignment(llfn, align);
|
||||
}
|
||||
to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize));
|
||||
to_add.extend(patchable_function_entry_attrs(cx, codegen_fn_attrs.patchable_function_entry));
|
||||
|
||||
// Always annotate functions with the target-cpu they are compiled for.
|
||||
// Without this, ThinLTO won't inline Rust functions into Clang generated
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
use rustc_ast::{ast, attr, MetaItemKind, NestedMetaItem};
|
||||
use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr};
|
||||
use rustc_errors::{codes::*, struct_span_code_err};
|
||||
use rustc_errors::{codes::*, struct_span_code_err, DiagMessage, SubdiagMessage};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
|
||||
use rustc_hir::{lang_items, weak_lang_items::WEAK_LANG_ITEMS, LangItem};
|
||||
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
|
||||
use rustc_middle::middle::codegen_fn_attrs::{
|
||||
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry,
|
||||
};
|
||||
use rustc_middle::mir::mono::Linkage;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::{self as ty, TyCtxt};
|
||||
|
@ -447,6 +449,80 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
None
|
||||
};
|
||||
}
|
||||
sym::patchable_function_entry => {
|
||||
codegen_fn_attrs.patchable_function_entry = attr.meta_item_list().and_then(|l| {
|
||||
let mut prefix = None;
|
||||
let mut entry = None;
|
||||
for item in l {
|
||||
let Some(meta_item) = item.meta_item() else {
|
||||
tcx.dcx().span_err(item.span(), "expected name value pair");
|
||||
continue;
|
||||
};
|
||||
|
||||
let Some(name_value_lit) = meta_item.name_value_literal() else {
|
||||
tcx.dcx().span_err(item.span(), "expected name value pair");
|
||||
continue;
|
||||
};
|
||||
|
||||
fn emit_error_with_label(
|
||||
tcx: TyCtxt<'_>,
|
||||
span: Span,
|
||||
error: impl Into<DiagMessage>,
|
||||
label: impl Into<SubdiagMessage>,
|
||||
) {
|
||||
let mut err: rustc_errors::Diag<'_, _> =
|
||||
tcx.dcx().struct_span_err(span, error);
|
||||
err.span_label(span, label);
|
||||
err.emit();
|
||||
}
|
||||
|
||||
let attrib_to_write = match meta_item.name_or_empty() {
|
||||
sym::prefix_nops => &mut prefix,
|
||||
sym::entry_nops => &mut entry,
|
||||
_ => {
|
||||
emit_error_with_label(
|
||||
tcx,
|
||||
item.span(),
|
||||
"unexpected parameter name",
|
||||
format!("expected {} or {}", sym::prefix_nops, sym::entry_nops),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let rustc_ast::LitKind::Int(val, _) = name_value_lit.kind else {
|
||||
emit_error_with_label(
|
||||
tcx,
|
||||
name_value_lit.span,
|
||||
"invalid literal value",
|
||||
"value must be an integer between `0` and `255`",
|
||||
);
|
||||
continue;
|
||||
};
|
||||
|
||||
let Ok(val) = val.get().try_into() else {
|
||||
emit_error_with_label(
|
||||
tcx,
|
||||
name_value_lit.span,
|
||||
"integer value out of range",
|
||||
"value must be between `0` and `255`",
|
||||
);
|
||||
continue;
|
||||
};
|
||||
|
||||
*attrib_to_write = Some(val);
|
||||
}
|
||||
|
||||
if let (None, None) = (prefix, entry) {
|
||||
tcx.dcx().span_err(attr.span, "must specify at least one parameter");
|
||||
}
|
||||
|
||||
Some(PatchableFunctionEntry::from_prefix_and_entry(
|
||||
prefix.unwrap_or(0),
|
||||
entry.unwrap_or(0),
|
||||
))
|
||||
})
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -585,6 +585,13 @@ pub struct BuiltinAttribute {
|
|||
EncodeCrossCrate::No, derive_smart_pointer, experimental!(pointee)
|
||||
),
|
||||
|
||||
// RFC 3543
|
||||
// `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]`
|
||||
gated!(
|
||||
patchable_function_entry, Normal, template!(List: "prefix_nops = m, entry_nops = n"), ErrorPreceding,
|
||||
EncodeCrossCrate::Yes, experimental!(patchable_function_entry)
|
||||
),
|
||||
|
||||
// ==========================================================================
|
||||
// Internal attributes: Stability, deprecation, and unsafe:
|
||||
// ==========================================================================
|
||||
|
|
|
@ -563,6 +563,8 @@ pub fn internal(&self, feature: Symbol) -> bool {
|
|||
(unstable, offset_of_slice, "CURRENT_RUSTC_VERSION", Some(126151)),
|
||||
/// Allows using `#[optimize(X)]`.
|
||||
(unstable, optimize_attribute, "1.34.0", Some(54882)),
|
||||
/// Allows specifying nop padding on functions for dynamic patching.
|
||||
(unstable, patchable_function_entry, "CURRENT_RUSTC_VERSION", Some(123115)),
|
||||
/// Allows postfix match `expr.match { ... }`
|
||||
(unstable, postfix_match, "1.79.0", Some(121618)),
|
||||
/// Allows `use<'a, 'b, A, B>` in `impl Trait + use<...>` for precise capture of generic args.
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
ErrorOutputType, ExternEntry, ExternLocation, Externs, FunctionReturn, InliningThreshold,
|
||||
Input, InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail,
|
||||
LtoCli, NextSolverConfig, OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey,
|
||||
PacRet, Passes, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath,
|
||||
SymbolManglingVersion, WasiExecModel,
|
||||
PacRet, Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip,
|
||||
SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
|
||||
};
|
||||
use rustc_session::lint::Level;
|
||||
use rustc_session::search_paths::SearchPath;
|
||||
|
@ -813,6 +813,11 @@ macro_rules! tracked {
|
|||
tracked!(packed_bundled_libs, true);
|
||||
tracked!(panic_abort_tests, true);
|
||||
tracked!(panic_in_drop, PanicStrategy::Abort);
|
||||
tracked!(
|
||||
patchable_function_entry,
|
||||
PatchableFunctionEntry::from_total_and_prefix_nops(10, 5)
|
||||
.expect("total must be greater than or equal to prefix")
|
||||
);
|
||||
tracked!(plt, Some(true));
|
||||
tracked!(polonius, Polonius::Legacy);
|
||||
tracked!(precise_enum_drop_elaboration, false);
|
||||
|
|
|
@ -45,6 +45,32 @@ pub struct CodegenFnAttrs {
|
|||
/// The `#[repr(align(...))]` attribute. Indicates the value of which the function should be
|
||||
/// aligned to.
|
||||
pub alignment: Option<Align>,
|
||||
/// The `#[patchable_function_entry(...)]` attribute. Indicates how many nops should be around
|
||||
/// the function entry.
|
||||
pub patchable_function_entry: Option<PatchableFunctionEntry>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
||||
pub struct PatchableFunctionEntry {
|
||||
/// Nops to prepend to the function
|
||||
prefix: u8,
|
||||
/// Nops after entry, but before body
|
||||
entry: u8,
|
||||
}
|
||||
|
||||
impl PatchableFunctionEntry {
|
||||
pub fn from_config(config: rustc_session::config::PatchableFunctionEntry) -> Self {
|
||||
Self { prefix: config.prefix(), entry: config.entry() }
|
||||
}
|
||||
pub fn from_prefix_and_entry(prefix: u8, entry: u8) -> Self {
|
||||
Self { prefix, entry }
|
||||
}
|
||||
pub fn prefix(&self) -> u8 {
|
||||
self.prefix
|
||||
}
|
||||
pub fn entry(&self) -> u8 {
|
||||
self.entry
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
|
||||
|
@ -121,6 +147,7 @@ pub const fn new() -> CodegenFnAttrs {
|
|||
no_sanitize: SanitizerSet::empty(),
|
||||
instruction_set: None,
|
||||
alignment: None,
|
||||
patchable_function_entry: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3432,8 +3432,9 @@ fn parse_gen_block(&mut self) -> PResult<'a, P<Expr>> {
|
|||
}
|
||||
}
|
||||
let capture_clause = self.parse_capture_clause()?;
|
||||
let decl_span = lo.to(self.prev_token.span);
|
||||
let (attrs, body) = self.parse_inner_attrs_and_block()?;
|
||||
let kind = ExprKind::Gen(capture_clause, body, kind);
|
||||
let kind = ExprKind::Gen(capture_clause, body, kind, decl_span);
|
||||
Ok(self.mk_expr_with_attrs(lo.to(self.prev_token.span), kind, attrs))
|
||||
}
|
||||
|
||||
|
@ -4022,7 +4023,7 @@ fn visit_expr(&mut self, e: &mut P<Expr>) {
|
|||
| ExprKind::Match(_, _, _)
|
||||
| ExprKind::Closure(_)
|
||||
| ExprKind::Block(_, _)
|
||||
| ExprKind::Gen(_, _, _)
|
||||
| ExprKind::Gen(_, _, _, _)
|
||||
| ExprKind::TryBlock(_)
|
||||
| ExprKind::Underscore
|
||||
| ExprKind::Path(_, _)
|
||||
|
|
|
@ -334,7 +334,7 @@ fn visit_expr(&mut self, expr: &'a Expr) {
|
|||
None => closure_def,
|
||||
}
|
||||
}
|
||||
ExprKind::Gen(_, _, _) => {
|
||||
ExprKind::Gen(_, _, _, _) => {
|
||||
self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span)
|
||||
}
|
||||
ExprKind::ConstBlock(ref constant) => {
|
||||
|
|
|
@ -2965,8 +2965,9 @@ pub(crate) mod dep_tracking {
|
|||
CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FunctionReturn,
|
||||
InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail,
|
||||
LtoCli, NextSolverConfig, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes,
|
||||
Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm,
|
||||
SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
|
||||
PatchableFunctionEntry, Polonius, RemapPathScopeComponents, ResolveDocLinks,
|
||||
SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion,
|
||||
WasiExecModel,
|
||||
};
|
||||
use crate::lint;
|
||||
use crate::utils::NativeLib;
|
||||
|
@ -3073,6 +3074,7 @@ fn hash(
|
|||
OomStrategy,
|
||||
LanguageIdentifier,
|
||||
NextSolverConfig,
|
||||
PatchableFunctionEntry,
|
||||
Polonius,
|
||||
InliningThreshold,
|
||||
FunctionReturn,
|
||||
|
@ -3250,6 +3252,35 @@ pub fn extension(self) -> &'static str {
|
|||
}
|
||||
}
|
||||
|
||||
/// `-Z patchable-function-entry` representation - how many nops to put before and after function
|
||||
/// entry.
|
||||
#[derive(Clone, Copy, PartialEq, Hash, Debug, Default)]
|
||||
pub struct PatchableFunctionEntry {
|
||||
/// Nops before the entry
|
||||
prefix: u8,
|
||||
/// Nops after the entry
|
||||
entry: u8,
|
||||
}
|
||||
|
||||
impl PatchableFunctionEntry {
|
||||
pub fn from_total_and_prefix_nops(
|
||||
total_nops: u8,
|
||||
prefix_nops: u8,
|
||||
) -> Option<PatchableFunctionEntry> {
|
||||
if total_nops < prefix_nops {
|
||||
None
|
||||
} else {
|
||||
Some(Self { prefix: prefix_nops, entry: total_nops - prefix_nops })
|
||||
}
|
||||
}
|
||||
pub fn prefix(&self) -> u8 {
|
||||
self.prefix
|
||||
}
|
||||
pub fn entry(&self) -> u8 {
|
||||
self.entry
|
||||
}
|
||||
}
|
||||
|
||||
/// `-Zpolonius` values, enabling the borrow checker polonius analysis, and which version: legacy,
|
||||
/// or future prototype.
|
||||
#[derive(Clone, Copy, PartialEq, Hash, Debug, Default)]
|
||||
|
|
|
@ -379,6 +379,7 @@ mod desc {
|
|||
pub const parse_passes: &str = "a space-separated list of passes, or `all`";
|
||||
pub const parse_panic_strategy: &str = "either `unwind` or `abort`";
|
||||
pub const parse_on_broken_pipe: &str = "either `kill`, `error`, or `inherit`";
|
||||
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)";
|
||||
pub const parse_opt_panic_strategy: &str = parse_panic_strategy;
|
||||
pub const parse_oom_strategy: &str = "either `panic` or `abort`";
|
||||
pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
|
||||
|
@ -734,6 +735,32 @@ pub(crate) fn parse_on_broken_pipe(slot: &mut OnBrokenPipe, v: Option<&str>) ->
|
|||
true
|
||||
}
|
||||
|
||||
pub(crate) fn parse_patchable_function_entry(
|
||||
slot: &mut PatchableFunctionEntry,
|
||||
v: Option<&str>,
|
||||
) -> bool {
|
||||
let mut total_nops = 0;
|
||||
let mut prefix_nops = 0;
|
||||
|
||||
if !parse_number(&mut total_nops, v) {
|
||||
let parts = v.and_then(|v| v.split_once(',')).unzip();
|
||||
if !parse_number(&mut total_nops, parts.0) {
|
||||
return false;
|
||||
}
|
||||
if !parse_number(&mut prefix_nops, parts.1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(pfe) =
|
||||
PatchableFunctionEntry::from_total_and_prefix_nops(total_nops, prefix_nops)
|
||||
{
|
||||
*slot = pfe;
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub(crate) fn parse_oom_strategy(slot: &mut OomStrategy, v: Option<&str>) -> bool {
|
||||
match v {
|
||||
Some("panic") => *slot = OomStrategy::Panic,
|
||||
|
@ -1859,6 +1886,8 @@ pub(crate) fn parse_wasm_c_abi(slot: &mut WasmCAbi, v: Option<&str>) -> bool {
|
|||
"panic strategy for panics in drops"),
|
||||
parse_only: bool = (false, parse_bool, [UNTRACKED],
|
||||
"parse only; do not compile, assemble, or link (default: no)"),
|
||||
patchable_function_entry: PatchableFunctionEntry = (PatchableFunctionEntry::default(), parse_patchable_function_entry, [TRACKED],
|
||||
"nop padding at function entry"),
|
||||
plt: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
||||
"whether to use the PLT when calling into shared libraries;
|
||||
only has effect for PIC code on systems with ELF binaries
|
||||
|
|
|
@ -6,6 +6,8 @@ edition = "2021"
|
|||
[dependencies]
|
||||
# tidy-alphabetical-start
|
||||
rustc_abi = { path = "../rustc_abi" }
|
||||
rustc_ast = { path = "../rustc_ast" }
|
||||
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_hir = { path = "../rustc_hir" }
|
||||
rustc_middle = { path = "../rustc_middle" }
|
||||
|
|
|
@ -228,6 +228,46 @@ fn def_name(&self, def_id: stable_mir::DefId, trimmed: bool) -> Symbol {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_attrs_by_path(
|
||||
&self,
|
||||
def_id: stable_mir::DefId,
|
||||
attr: &[stable_mir::Symbol],
|
||||
) -> Vec<stable_mir::crate_def::Attribute> {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let tcx = tables.tcx;
|
||||
let did = tables[def_id];
|
||||
let attr_name: Vec<_> =
|
||||
attr.iter().map(|seg| rustc_span::symbol::Symbol::intern(&seg)).collect();
|
||||
tcx.get_attrs_by_path(did, &attr_name)
|
||||
.map(|attribute| {
|
||||
let attr_str = rustc_ast_pretty::pprust::attribute_to_string(attribute);
|
||||
let span = attribute.span;
|
||||
stable_mir::crate_def::Attribute::new(attr_str, span.stable(&mut *tables))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn get_all_attrs(&self, def_id: stable_mir::DefId) -> Vec<stable_mir::crate_def::Attribute> {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let tcx = tables.tcx;
|
||||
let did = tables[def_id];
|
||||
let filter_fn = move |a: &&rustc_ast::ast::Attribute| {
|
||||
matches!(a.kind, rustc_ast::ast::AttrKind::Normal(_))
|
||||
};
|
||||
let attrs_iter = if let Some(did) = did.as_local() {
|
||||
tcx.hir().attrs(tcx.local_def_id_to_hir_id(did)).iter().filter(filter_fn)
|
||||
} else {
|
||||
tcx.item_attrs(did).iter().filter(filter_fn)
|
||||
};
|
||||
attrs_iter
|
||||
.map(|attribute| {
|
||||
let attr_str = rustc_ast_pretty::pprust::attribute_to_string(attribute);
|
||||
let span = attribute.span;
|
||||
stable_mir::crate_def::Attribute::new(attr_str, span.stable(&mut *tables))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn span_to_string(&self, span: stable_mir::ty::Span) -> String {
|
||||
let tables = self.0.borrow();
|
||||
tables.tcx.sess.source_map().span_to_diagnostic_string(tables[span])
|
||||
|
|
|
@ -768,6 +768,7 @@
|
|||
enable,
|
||||
encode,
|
||||
end,
|
||||
entry_nops,
|
||||
enumerate_method,
|
||||
env,
|
||||
env_CFG_RELEASE: env!("CFG_RELEASE"),
|
||||
|
@ -1383,6 +1384,7 @@
|
|||
passes,
|
||||
pat,
|
||||
pat_param,
|
||||
patchable_function_entry,
|
||||
path,
|
||||
pattern_complexity,
|
||||
pattern_parentheses,
|
||||
|
@ -1421,6 +1423,7 @@
|
|||
prefetch_read_instruction,
|
||||
prefetch_write_data,
|
||||
prefetch_write_instruction,
|
||||
prefix_nops,
|
||||
preg,
|
||||
prelude,
|
||||
prelude_import,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
use std::cell::Cell;
|
||||
|
||||
use crate::abi::{FnAbi, Layout, LayoutShape};
|
||||
use crate::crate_def::Attribute;
|
||||
use crate::mir::alloc::{AllocId, GlobalAlloc};
|
||||
use crate::mir::mono::{Instance, InstanceDef, StaticDef};
|
||||
use crate::mir::{BinOp, Body, Place, UnOp};
|
||||
|
@ -55,6 +56,15 @@ pub trait Context {
|
|||
/// Returns the name of given `DefId`
|
||||
fn def_name(&self, def_id: DefId, trimmed: bool) -> Symbol;
|
||||
|
||||
/// Return attributes with the given attribute name.
|
||||
///
|
||||
/// Single segmented name like `#[inline]` is specified as `&["inline".to_string()]`.
|
||||
/// Multi-segmented name like `#[rustfmt::skip]` is specified as `&["rustfmt".to_string(), "skip".to_string()]`.
|
||||
fn get_attrs_by_path(&self, def_id: DefId, attr: &[Symbol]) -> Vec<Attribute>;
|
||||
|
||||
/// Get all attributes of a definition.
|
||||
fn get_all_attrs(&self, def_id: DefId) -> Vec<Attribute>;
|
||||
|
||||
/// Returns printable, human readable form of `Span`
|
||||
fn span_to_string(&self, span: Span) -> String;
|
||||
|
||||
|
|
|
@ -50,6 +50,21 @@ fn span(&self) -> Span {
|
|||
let def_id = self.def_id();
|
||||
with(|cx| cx.span_of_an_item(def_id))
|
||||
}
|
||||
|
||||
/// Return attributes with the given attribute name.
|
||||
///
|
||||
/// Single segmented name like `#[inline]` is specified as `&["inline".to_string()]`.
|
||||
/// Multi-segmented name like `#[rustfmt::skip]` is specified as `&["rustfmt".to_string(), "skip".to_string()]`.
|
||||
fn attrs_by_path(&self, attr: &[Symbol]) -> Vec<Attribute> {
|
||||
let def_id = self.def_id();
|
||||
with(|cx| cx.get_attrs_by_path(def_id, attr))
|
||||
}
|
||||
|
||||
/// Return all attributes of this definition.
|
||||
fn all_attrs(&self) -> Vec<Attribute> {
|
||||
let def_id = self.def_id();
|
||||
with(|cx| cx.get_all_attrs(def_id))
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait that can be used to retrieve a definition's type.
|
||||
|
@ -69,6 +84,28 @@ fn ty_with_args(&self, args: &GenericArgs) -> Ty {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Attribute {
|
||||
value: String,
|
||||
span: Span,
|
||||
}
|
||||
|
||||
impl Attribute {
|
||||
pub fn new(value: String, span: Span) -> Attribute {
|
||||
Attribute { value, span }
|
||||
}
|
||||
|
||||
/// Get the span of this attribute.
|
||||
pub fn span(&self) -> Span {
|
||||
self.span
|
||||
}
|
||||
|
||||
/// Get the string representation of this attribute.
|
||||
pub fn as_str(&self) -> &str {
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! crate_def {
|
||||
( $(#[$attr:meta])*
|
||||
$vis:vis $name:ident $(;)?
|
||||
|
|
|
@ -206,15 +206,16 @@ fn borrow_mut(&mut self) -> &mut str {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl ToOwned for str {
|
||||
type Owned = String;
|
||||
|
||||
#[inline]
|
||||
fn to_owned(&self) -> String {
|
||||
unsafe { String::from_utf8_unchecked(self.as_bytes().to_owned()) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn clone_into(&self, target: &mut String) {
|
||||
let mut b = mem::take(target).into_bytes();
|
||||
self.as_bytes().clone_into(&mut b);
|
||||
*target = unsafe { String::from_utf8_unchecked(b) }
|
||||
target.clear();
|
||||
target.push_str(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -459,6 +459,12 @@ fn as_statically_known_str(&self) -> Option<&'static str> {
|
|||
}
|
||||
}
|
||||
|
||||
// Manually implementing these results in better error messages.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl !Send for Arguments<'_> {}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl !Sync for Arguments<'_> {}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Debug for Arguments<'_> {
|
||||
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
use super::*;
|
||||
use crate::hint::unreachable_unchecked;
|
||||
use crate::ptr::NonNull;
|
||||
|
||||
#[lang = "format_placeholder"]
|
||||
#[derive(Copy, Clone)]
|
||||
|
@ -66,7 +67,13 @@ pub(super) enum Flag {
|
|||
|
||||
#[derive(Copy, Clone)]
|
||||
enum ArgumentType<'a> {
|
||||
Placeholder { value: &'a Opaque, formatter: fn(&Opaque, &mut Formatter<'_>) -> Result },
|
||||
Placeholder {
|
||||
// INVARIANT: `formatter` has type `fn(&T, _) -> _` for some `T`, and `value`
|
||||
// was derived from a `&'a T`.
|
||||
value: NonNull<()>,
|
||||
formatter: unsafe fn(NonNull<()>, &mut Formatter<'_>) -> Result,
|
||||
_lifetime: PhantomData<&'a ()>,
|
||||
},
|
||||
Count(usize),
|
||||
}
|
||||
|
||||
|
@ -90,21 +97,15 @@ pub struct Argument<'a> {
|
|||
impl<'a> Argument<'a> {
|
||||
#[inline(always)]
|
||||
fn new<'b, T>(x: &'b T, f: fn(&T, &mut Formatter<'_>) -> Result) -> Argument<'b> {
|
||||
// SAFETY: `mem::transmute(x)` is safe because
|
||||
// 1. `&'b T` keeps the lifetime it originated with `'b`
|
||||
// (so as to not have an unbounded lifetime)
|
||||
// 2. `&'b T` and `&'b Opaque` have the same memory layout
|
||||
// (when `T` is `Sized`, as it is here)
|
||||
// `mem::transmute(f)` is safe since `fn(&T, &mut Formatter<'_>) -> Result`
|
||||
// and `fn(&Opaque, &mut Formatter<'_>) -> Result` have the same ABI
|
||||
// (as long as `T` is `Sized`)
|
||||
unsafe {
|
||||
Argument {
|
||||
ty: ArgumentType::Placeholder {
|
||||
formatter: mem::transmute(f),
|
||||
value: mem::transmute(x),
|
||||
},
|
||||
}
|
||||
Argument {
|
||||
// INVARIANT: this creates an `ArgumentType<'b>` from a `&'b T` and
|
||||
// a `fn(&T, ...)`, so the invariant is maintained.
|
||||
ty: ArgumentType::Placeholder {
|
||||
value: NonNull::from(x).cast(),
|
||||
// SAFETY: function pointers always have the same layout.
|
||||
formatter: unsafe { mem::transmute(f) },
|
||||
_lifetime: PhantomData,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,7 +163,14 @@ pub fn from_usize(x: &usize) -> Argument<'_> {
|
|||
#[inline(always)]
|
||||
pub(super) unsafe fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
||||
match self.ty {
|
||||
ArgumentType::Placeholder { formatter, value } => formatter(value, f),
|
||||
// SAFETY:
|
||||
// Because of the invariant that if `formatter` had the type
|
||||
// `fn(&T, _) -> _` then `value` has type `&'b T` where `'b` is
|
||||
// the lifetime of the `ArgumentType`, and because references
|
||||
// and `NonNull` are ABI-compatible, this is completely equivalent
|
||||
// to calling the original function passed to `new` with the
|
||||
// original reference, which is sound.
|
||||
ArgumentType::Placeholder { formatter, value, .. } => unsafe { formatter(value, f) },
|
||||
// SAFETY: the caller promised this.
|
||||
ArgumentType::Count(_) => unsafe { unreachable_unchecked() },
|
||||
}
|
||||
|
@ -208,7 +216,3 @@ pub unsafe fn new() -> Self {
|
|||
Self { _private: () }
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
type Opaque;
|
||||
}
|
||||
|
|
|
@ -888,12 +888,11 @@ fn run(self, builder: &Builder<'_>) {
|
|||
macro_rules! tool_doc {
|
||||
(
|
||||
$tool: ident,
|
||||
$should_run: literal,
|
||||
$path: literal,
|
||||
$(rustc_tool = $rustc_tool:literal, )?
|
||||
$(in_tree = $in_tree:literal ,)?
|
||||
$(is_library = $is_library:expr,)?
|
||||
$(crates = $crates:expr)?
|
||||
$(, submodule $(= $submodule:literal)? )?
|
||||
) => {
|
||||
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct $tool {
|
||||
|
@ -907,7 +906,7 @@ impl Step for $tool {
|
|||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
let builder = run.builder;
|
||||
run.crate_or_deps($should_run).default_condition(builder.config.compiler_docs)
|
||||
run.path($path).default_condition(builder.config.compiler_docs)
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
|
@ -921,6 +920,15 @@ fn make_run(run: RunConfig<'_>) {
|
|||
/// we do not merge it with the other documentation from std, test and
|
||||
/// proc_macros. This is largely just a wrapper around `cargo doc`.
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
let source_type = SourceType::InTree;
|
||||
$(
|
||||
let _ = source_type; // silence the "unused variable" warning
|
||||
let source_type = SourceType::Submodule;
|
||||
|
||||
let path = Path::new(submodule_helper!( $path, submodule $( = $submodule )? ));
|
||||
builder.update_submodule(&path);
|
||||
)?
|
||||
|
||||
let stage = builder.top_stage;
|
||||
let target = self.target;
|
||||
|
||||
|
@ -941,12 +949,6 @@ fn run(self, builder: &Builder<'_>) {
|
|||
builder.ensure(compile::Rustc::new(compiler, target));
|
||||
}
|
||||
|
||||
let source_type = if true $(&& $in_tree)? {
|
||||
SourceType::InTree
|
||||
} else {
|
||||
SourceType::Submodule
|
||||
};
|
||||
|
||||
// Build cargo command.
|
||||
let mut cargo = prepare_tool_cargo(
|
||||
builder,
|
||||
|
@ -1008,21 +1010,14 @@ fn run(self, builder: &Builder<'_>) {
|
|||
}
|
||||
}
|
||||
|
||||
tool_doc!(Rustdoc, "rustdoc-tool", "src/tools/rustdoc", crates = ["rustdoc", "rustdoc-json-types"]);
|
||||
tool_doc!(
|
||||
Rustfmt,
|
||||
"rustfmt-nightly",
|
||||
"src/tools/rustfmt",
|
||||
crates = ["rustfmt-nightly", "rustfmt-config_proc_macro"]
|
||||
);
|
||||
tool_doc!(Clippy, "clippy", "src/tools/clippy", crates = ["clippy_config", "clippy_utils"]);
|
||||
tool_doc!(Miri, "miri", "src/tools/miri", crates = ["miri"]);
|
||||
tool_doc!(Rustdoc, "src/tools/rustdoc", crates = ["rustdoc", "rustdoc-json-types"]);
|
||||
tool_doc!(Rustfmt, "src/tools/rustfmt", crates = ["rustfmt-nightly", "rustfmt-config_proc_macro"]);
|
||||
tool_doc!(Clippy, "src/tools/clippy", crates = ["clippy_config", "clippy_utils"]);
|
||||
tool_doc!(Miri, "src/tools/miri", crates = ["miri"]);
|
||||
tool_doc!(
|
||||
Cargo,
|
||||
"cargo",
|
||||
"src/tools/cargo",
|
||||
rustc_tool = false,
|
||||
in_tree = false,
|
||||
crates = [
|
||||
"cargo",
|
||||
"cargo-credential",
|
||||
|
@ -1034,12 +1029,12 @@ fn run(self, builder: &Builder<'_>) {
|
|||
"crates-io",
|
||||
"mdman",
|
||||
"rustfix",
|
||||
]
|
||||
],
|
||||
submodule = "src/tools/cargo"
|
||||
);
|
||||
tool_doc!(Tidy, "tidy", "src/tools/tidy", rustc_tool = false, crates = ["tidy"]);
|
||||
tool_doc!(Tidy, "src/tools/tidy", rustc_tool = false, crates = ["tidy"]);
|
||||
tool_doc!(
|
||||
Bootstrap,
|
||||
"bootstrap",
|
||||
"src/bootstrap",
|
||||
rustc_tool = false,
|
||||
is_library = true,
|
||||
|
@ -1047,7 +1042,6 @@ fn run(self, builder: &Builder<'_>) {
|
|||
);
|
||||
tool_doc!(
|
||||
RunMakeSupport,
|
||||
"run_make_support",
|
||||
"src/tools/run-make-support",
|
||||
rustc_tool = false,
|
||||
is_library = true,
|
||||
|
|
|
@ -2983,6 +2983,9 @@ fn run(self, builder: &Builder<'_>) {
|
|||
let compiler = builder.compiler(0, host);
|
||||
let _guard = builder.msg(Kind::Test, 0, "bootstrap", host, host);
|
||||
|
||||
// Some tests require cargo submodule to be present.
|
||||
builder.build.update_submodule(Path::new("src/tools/cargo"));
|
||||
|
||||
let mut check_bootstrap = Command::new(builder.python());
|
||||
check_bootstrap
|
||||
.args(["-m", "unittest", "bootstrap_test.py"])
|
||||
|
|
|
@ -656,6 +656,8 @@ fn make_run(run: RunConfig<'_>) {
|
|||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
builder.build.update_submodule(Path::new("src/tools/cargo"));
|
||||
|
||||
builder.ensure(ToolBuild {
|
||||
compiler: self.compiler,
|
||||
target: self.target,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
||||
|
@ -34,6 +34,9 @@ fn run(self, builder: &Builder<'_>) -> Self::Output {
|
|||
cmd.arg("--versioned-dirs");
|
||||
}
|
||||
|
||||
// cargo submodule must be present for `x vendor` to work.
|
||||
builder.build.update_submodule(Path::new("src/tools/cargo"));
|
||||
|
||||
// Sync these paths by default.
|
||||
for p in [
|
||||
"src/tools/cargo/Cargo.toml",
|
||||
|
|
|
@ -67,9 +67,9 @@ pub fn build(build: &mut Build) {
|
|||
|
||||
/// Invokes `cargo metadata` to get package metadata of each workspace member.
|
||||
///
|
||||
/// Note that `src/tools/cargo` is no longer a workspace member but we still
|
||||
/// treat it as one here, by invoking an additional `cargo metadata` command.
|
||||
fn workspace_members(build: &Build) -> impl Iterator<Item = Package> {
|
||||
/// This is used to resolve specific crate paths in `fn should_run` to compile
|
||||
/// particular crate (e.g., `x build sysroot` to build library/sysroot).
|
||||
fn workspace_members(build: &Build) -> Vec<Package> {
|
||||
let collect_metadata = |manifest_path| {
|
||||
let mut cargo = Command::new(&build.initial_cargo);
|
||||
cargo
|
||||
|
@ -88,13 +88,5 @@ fn workspace_members(build: &Build) -> impl Iterator<Item = Package> {
|
|||
};
|
||||
|
||||
// Collects `metadata.packages` from all workspaces.
|
||||
let packages = collect_metadata("Cargo.toml");
|
||||
let cargo_packages = collect_metadata("src/tools/cargo/Cargo.toml");
|
||||
let ra_packages = collect_metadata("src/tools/rust-analyzer/Cargo.toml");
|
||||
let bootstrap_packages = collect_metadata("src/bootstrap/Cargo.toml");
|
||||
|
||||
// We only care about the root package from `src/tool/cargo` workspace.
|
||||
let cargo_package = cargo_packages.into_iter().find(|pkg| pkg.name == "cargo").into_iter();
|
||||
|
||||
packages.into_iter().chain(cargo_package).chain(ra_packages).chain(bootstrap_packages)
|
||||
collect_metadata("Cargo.toml")
|
||||
}
|
||||
|
|
|
@ -469,8 +469,7 @@ pub fn new(mut config: Config) -> Build {
|
|||
|
||||
// Make sure we update these before gathering metadata so we don't get an error about missing
|
||||
// Cargo.toml files.
|
||||
let rust_submodules =
|
||||
["src/tools/cargo", "src/doc/book", "library/backtrace", "library/stdarch"];
|
||||
let rust_submodules = ["src/doc/book", "library/backtrace", "library/stdarch"];
|
||||
for s in rust_submodules {
|
||||
build.update_submodule(Path::new(s));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
# `patchable-function-entry`
|
||||
|
||||
--------------------
|
||||
|
||||
The `-Z patchable-function-entry=total_nops,prefix_nops` or `-Z patchable-function-entry=total_nops`
|
||||
compiler flag enables nop padding of function entries with 'total_nops' nops, with
|
||||
an offset for the entry of the function at 'prefix_nops' nops. In the second form,
|
||||
'prefix_nops' defaults to 0.
|
||||
|
||||
As an illustrative example, `-Z patchable-function-entry=3,2` would produce:
|
||||
|
||||
```text
|
||||
nop
|
||||
nop
|
||||
function_label:
|
||||
nop
|
||||
//Actual function code begins here
|
||||
```
|
||||
|
||||
This flag is used for hotpatching, especially in the Linux kernel. The flag
|
||||
arguments are modeled after the `-fpatchable-function-entry` flag as defined
|
||||
for both [Clang](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fpatchable-function-entry)
|
||||
and [gcc](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#index-fpatchable-function-entry)
|
||||
and is intended to provide the same effect.
|
|
@ -549,7 +549,7 @@ fn ident_difference_expr_with_base_location(
|
|||
| (Assign(_, _, _), Assign(_, _, _))
|
||||
| (TryBlock(_), TryBlock(_))
|
||||
| (Await(_, _), Await(_, _))
|
||||
| (Gen(_, _, _), Gen(_, _, _))
|
||||
| (Gen(_, _, _, _), Gen(_, _, _, _))
|
||||
| (Block(_, _), Block(_, _))
|
||||
| (Closure(_), Closure(_))
|
||||
| (Match(_, _, _), Match(_, _, _))
|
||||
|
|
|
@ -226,7 +226,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
|
|||
&& eq_fn_decl(lf, rf)
|
||||
&& eq_expr(le, re)
|
||||
},
|
||||
(Gen(lc, lb, lk), Gen(rc, rb, rk)) => lc == rc && eq_block(lb, rb) && lk == rk,
|
||||
(Gen(lc, lb, lk, _), Gen(rc, rb, rk, _)) => lc == rc && eq_block(lb, rb) && lk == rk,
|
||||
(Range(lf, lt, ll), Range(rf, rt, rl)) => ll == rl && eq_expr_opt(lf, rf) && eq_expr_opt(lt, rt),
|
||||
(AddrOf(lbk, lm, le), AddrOf(rbk, rm, re)) => lbk == rbk && lm == rm && eq_expr(le, re),
|
||||
(Path(lq, lp), Path(rq, rp)) => both(lq, rq, eq_qself) && eq_path(lp, rp),
|
||||
|
|
|
@ -372,7 +372,7 @@ fn needs_space_after_range(rhs: &ast::Expr) -> bool {
|
|||
))
|
||||
}
|
||||
}
|
||||
ast::ExprKind::Gen(capture_by, ref block, ref kind) => {
|
||||
ast::ExprKind::Gen(capture_by, ref block, ref kind, _) => {
|
||||
let mover = if matches!(capture_by, ast::CaptureBy::Value { .. }) {
|
||||
"move "
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
//@ compile-flags: -Z patchable-function-entry=15,10
|
||||
|
||||
#![feature(patchable_function_entry)]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// This should have the default, as set by the compile flags
|
||||
#[no_mangle]
|
||||
pub fn fun0() {}
|
||||
|
||||
// The attribute should override the compile flags
|
||||
#[no_mangle]
|
||||
#[patchable_function_entry(prefix_nops = 1, entry_nops = 2)]
|
||||
pub fn fun1() {}
|
||||
|
||||
// If we override an attribute to 0 or unset, the attribute should go away
|
||||
#[no_mangle]
|
||||
#[patchable_function_entry(entry_nops = 0)]
|
||||
pub fn fun2() {}
|
||||
|
||||
// The attribute should override the compile flags
|
||||
#[no_mangle]
|
||||
#[patchable_function_entry(prefix_nops = 20, entry_nops = 1)]
|
||||
pub fn fun3() {}
|
||||
|
||||
// The attribute should override the compile flags
|
||||
#[no_mangle]
|
||||
#[patchable_function_entry(prefix_nops = 2, entry_nops = 19)]
|
||||
pub fn fun4() {}
|
||||
|
||||
// The attribute should override patchable-function-entry to 3 and
|
||||
// patchable-function-prefix to the default of 0, clearing it entirely
|
||||
#[no_mangle]
|
||||
#[patchable_function_entry(entry_nops = 3)]
|
||||
pub fn fun5() {}
|
||||
|
||||
// The attribute should override patchable-function-prefix to 4
|
||||
// and patchable-function-entry to the default of 0, clearing it entirely
|
||||
#[no_mangle]
|
||||
#[patchable_function_entry(prefix_nops = 4)]
|
||||
pub fn fun6() {}
|
||||
|
||||
// CHECK: @fun0() unnamed_addr #0
|
||||
// CHECK: @fun1() unnamed_addr #1
|
||||
// CHECK: @fun2() unnamed_addr #2
|
||||
// CHECK: @fun3() unnamed_addr #3
|
||||
// CHECK: @fun4() unnamed_addr #4
|
||||
// CHECK: @fun5() unnamed_addr #5
|
||||
// CHECK: @fun6() unnamed_addr #6
|
||||
|
||||
// CHECK: attributes #0 = { {{.*}}"patchable-function-entry"="5"{{.*}}"patchable-function-prefix"="10" {{.*}} }
|
||||
// CHECK: attributes #1 = { {{.*}}"patchable-function-entry"="2"{{.*}}"patchable-function-prefix"="1" {{.*}} }
|
||||
|
||||
// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-entry{{.*}} }
|
||||
// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-prefix{{.*}} }
|
||||
// CHECK: attributes #2 = { {{.*}} }
|
||||
|
||||
// CHECK: attributes #3 = { {{.*}}"patchable-function-entry"="1"{{.*}}"patchable-function-prefix"="20" {{.*}} }
|
||||
// CHECK: attributes #4 = { {{.*}}"patchable-function-entry"="19"{{.*}}"patchable-function-prefix"="2" {{.*}} }
|
||||
|
||||
// CHECK: attributes #5 = { {{.*}}"patchable-function-entry"="3"{{.*}} }
|
||||
// CHECK-NOT: attributes #5 = { {{.*}}patchable-function-prefix{{.*}} }
|
||||
|
||||
// CHECK: attributes #6 = { {{.*}}"patchable-function-prefix"="4"{{.*}} }
|
||||
// CHECK-NOT: attributes #6 = { {{.*}}patchable-function-entry{{.*}} }
|
|
@ -0,0 +1,39 @@
|
|||
#![feature(patchable_function_entry)]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// No patchable function entry should be set
|
||||
#[no_mangle]
|
||||
pub fn fun0() {}
|
||||
|
||||
// The attribute should work even without compiler flags
|
||||
#[no_mangle]
|
||||
#[patchable_function_entry(prefix_nops = 1, entry_nops = 2)]
|
||||
pub fn fun1() {}
|
||||
|
||||
// The attribute should work even without compiler flags
|
||||
// and only set patchable-function-entry to 3.
|
||||
#[no_mangle]
|
||||
#[patchable_function_entry(entry_nops = 3)]
|
||||
pub fn fun2() {}
|
||||
|
||||
// The attribute should work even without compiler flags
|
||||
// and only set patchable-function-prefix to 4.
|
||||
#[no_mangle]
|
||||
#[patchable_function_entry(prefix_nops = 4)]
|
||||
pub fn fun3() {}
|
||||
|
||||
// CHECK: @fun0() unnamed_addr #0
|
||||
// CHECK: @fun1() unnamed_addr #1
|
||||
// CHECK: @fun2() unnamed_addr #2
|
||||
// CHECK: @fun3() unnamed_addr #3
|
||||
|
||||
// CHECK-NOT: attributes #0 = { {{.*}}patchable-function-entry{{.*}} }
|
||||
// CHECK-NOT: attributes #0 = { {{.*}}patchable-function-prefix{{.*}} }
|
||||
|
||||
// CHECK: attributes #1 = { {{.*}}"patchable-function-entry"="2"{{.*}}"patchable-function-prefix"="1" {{.*}} }
|
||||
|
||||
// CHECK: attributes #2 = { {{.*}}"patchable-function-entry"="3"{{.*}} }
|
||||
// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-prefix{{.*}} }
|
||||
|
||||
// CHECK: attributes #3 = { {{.*}}"patchable-function-prefix"="4"{{.*}} }
|
||||
// CHECK-NOT: attributes #3 = { {{.*}}patchable-function-entry{{.*}} }
|
|
@ -0,0 +1,66 @@
|
|||
//@ compile-flags: -Z patchable-function-entry=15
|
||||
|
||||
#![feature(patchable_function_entry)]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// This should have the default, as set by the compile flags
|
||||
#[no_mangle]
|
||||
pub fn fun0() {}
|
||||
|
||||
// The attribute should override the compile flags
|
||||
#[no_mangle]
|
||||
#[patchable_function_entry(prefix_nops = 1, entry_nops = 2)]
|
||||
pub fn fun1() {}
|
||||
|
||||
// If we override an attribute to 0 or unset, the attribute should go away
|
||||
#[no_mangle]
|
||||
#[patchable_function_entry(entry_nops = 0)]
|
||||
pub fn fun2() {}
|
||||
|
||||
// The attribute should override the compile flags
|
||||
#[no_mangle]
|
||||
#[patchable_function_entry(prefix_nops = 20, entry_nops = 1)]
|
||||
pub fn fun3() {}
|
||||
|
||||
// The attribute should override the compile flags
|
||||
#[no_mangle]
|
||||
#[patchable_function_entry(prefix_nops = 2, entry_nops = 19)]
|
||||
pub fn fun4() {}
|
||||
|
||||
// The attribute should override patchable-function-entry to 3
|
||||
// and patchable-function-prefix to the default of 0, clearing it entirely
|
||||
#[no_mangle]
|
||||
#[patchable_function_entry(entry_nops = 3)]
|
||||
pub fn fun5() {}
|
||||
|
||||
// The attribute should override patchable-function-prefix to 4
|
||||
// and patchable-function-entry to the default of 0, clearing it entirely
|
||||
#[no_mangle]
|
||||
#[patchable_function_entry(prefix_nops = 4)]
|
||||
pub fn fun6() {}
|
||||
|
||||
// CHECK: @fun0() unnamed_addr #0
|
||||
// CHECK: @fun1() unnamed_addr #1
|
||||
// CHECK: @fun2() unnamed_addr #2
|
||||
// CHECK: @fun3() unnamed_addr #3
|
||||
// CHECK: @fun4() unnamed_addr #4
|
||||
// CHECK: @fun5() unnamed_addr #5
|
||||
// CHECK: @fun6() unnamed_addr #6
|
||||
|
||||
// CHECK: attributes #0 = { {{.*}}"patchable-function-entry"="15" {{.*}} }
|
||||
// CHECK-NOT: attributes #0 = { {{.*}}patchable-function-prefix{{.*}} }
|
||||
|
||||
// CHECK: attributes #1 = { {{.*}}"patchable-function-entry"="2"{{.*}}"patchable-function-prefix"="1" {{.*}} }
|
||||
|
||||
// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-entry{{.*}} }
|
||||
// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-prefix{{.*}} }
|
||||
// CHECK: attributes #2 = { {{.*}} }
|
||||
|
||||
// CHECK: attributes #3 = { {{.*}}"patchable-function-entry"="1"{{.*}}"patchable-function-prefix"="20" {{.*}} }
|
||||
// CHECK: attributes #4 = { {{.*}}"patchable-function-entry"="19"{{.*}}"patchable-function-prefix"="2" {{.*}} }
|
||||
|
||||
// CHECK: attributes #5 = { {{.*}}"patchable-function-entry"="3"{{.*}} }
|
||||
// CHECK-NOT: attributes #5 = { {{.*}}patchable-function-prefix{{.*}} }
|
||||
|
||||
// CHECK: attributes #6 = { {{.*}}"patchable-function-prefix"="4"{{.*}} }
|
||||
// CHECK-NOT: attributes #6 = { {{.*}}patchable-function-entry{{.*}} }
|
|
@ -1,12 +1,12 @@
|
|||
Function name: issue_83601::main
|
||||
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]
|
||||
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]
|
||||
Number of files: 1
|
||||
- file 0 => global file 1
|
||||
Number of expressions: 1
|
||||
- expression 0 operands: lhs = Counter(1), rhs = Zero
|
||||
- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
|
||||
Number of file 0 mappings: 3
|
||||
- Code(Counter(0)) at (prev + 6, 1) to (start + 2, 28)
|
||||
- Code(Counter(1)) at (prev + 3, 9) to (start + 1, 28)
|
||||
- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 3, 2)
|
||||
= (c1 - Zero)
|
||||
= (c1 - c2)
|
||||
|
||||
|
|
|
@ -54,15 +54,15 @@ Number of file 0 mappings: 1
|
|||
- Code(Counter(0)) at (prev + 167, 9) to (start + 2, 10)
|
||||
|
||||
Function name: issue_84561::test3
|
||||
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]
|
||||
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]
|
||||
Number of files: 1
|
||||
- file 0 => global file 1
|
||||
Number of expressions: 49
|
||||
- expression 0 operands: lhs = Counter(1), rhs = Zero
|
||||
- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
|
||||
- expression 1 operands: lhs = Counter(3), rhs = Zero
|
||||
- expression 2 operands: lhs = Counter(5), rhs = Zero
|
||||
- expression 2 operands: lhs = Counter(5), rhs = Counter(6)
|
||||
- expression 3 operands: lhs = Expression(4, Sub), rhs = Zero
|
||||
- expression 4 operands: lhs = Counter(5), rhs = Zero
|
||||
- expression 4 operands: lhs = Counter(5), rhs = Counter(6)
|
||||
- expression 5 operands: lhs = Counter(8), rhs = Zero
|
||||
- expression 6 operands: lhs = Expression(7, Sub), rhs = Zero
|
||||
- expression 7 operands: lhs = Counter(8), rhs = Zero
|
||||
|
@ -111,15 +111,15 @@ Number of file 0 mappings: 51
|
|||
- Code(Counter(0)) at (prev + 8, 1) to (start + 3, 28)
|
||||
- Code(Counter(1)) at (prev + 4, 9) to (start + 1, 28)
|
||||
- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 4, 31)
|
||||
= (c1 - Zero)
|
||||
= (c1 - c2)
|
||||
- Code(Counter(3)) at (prev + 5, 5) to (start + 0, 31)
|
||||
- Code(Expression(1, Sub)) at (prev + 1, 5) to (start + 0, 31)
|
||||
= (c3 - Zero)
|
||||
- Code(Counter(5)) at (prev + 1, 9) to (start + 1, 28)
|
||||
- Code(Expression(4, Sub)) at (prev + 2, 5) to (start + 0, 31)
|
||||
= (c5 - Zero)
|
||||
= (c5 - c6)
|
||||
- Code(Expression(3, Sub)) at (prev + 1, 5) to (start + 0, 15)
|
||||
= ((c5 - Zero) - Zero)
|
||||
= ((c5 - c6) - Zero)
|
||||
- Code(Zero) at (prev + 0, 32) to (start + 0, 48)
|
||||
- Code(Counter(8)) at (prev + 1, 5) to (start + 3, 15)
|
||||
- Code(Zero) at (prev + 3, 32) to (start + 0, 48)
|
||||
|
|
155
tests/ui-fulldeps/stable-mir/check_attribute.rs
Normal file
155
tests/ui-fulldeps/stable-mir/check_attribute.rs
Normal file
|
@ -0,0 +1,155 @@
|
|||
//@ run-pass
|
||||
//! Test information regarding type layout.
|
||||
|
||||
//@ ignore-stage1
|
||||
//@ ignore-cross-compile
|
||||
//@ ignore-remote
|
||||
//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(control_flow_enum)]
|
||||
|
||||
extern crate rustc_hir;
|
||||
#[macro_use]
|
||||
extern crate rustc_smir;
|
||||
extern crate rustc_driver;
|
||||
extern crate rustc_interface;
|
||||
extern crate stable_mir;
|
||||
|
||||
use rustc_smir::rustc_internal;
|
||||
use stable_mir::{CrateDef, CrateItems};
|
||||
use std::io::Write;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
const CRATE_NAME: &str = "input";
|
||||
|
||||
/// This function uses the Stable MIR APIs to get information about the test crate.
|
||||
fn test_stable_mir() -> ControlFlow<()> {
|
||||
// Find items in the local crate.
|
||||
let items = stable_mir::all_local_items();
|
||||
|
||||
test_builtins(&items);
|
||||
test_derive(&items);
|
||||
test_tool(&items);
|
||||
test_all_attrs(&items);
|
||||
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
|
||||
// Test built-in attributes.
|
||||
fn test_builtins(items: &CrateItems) {
|
||||
let target_fn = *get_item(&items, "builtins_fn").unwrap();
|
||||
let allow_attrs = target_fn.attrs_by_path(&["allow".to_string()]);
|
||||
assert_eq!(allow_attrs[0].as_str(), "#![allow(unused_variables)]");
|
||||
|
||||
let inline_attrs = target_fn.attrs_by_path(&["inline".to_string()]);
|
||||
assert_eq!(inline_attrs[0].as_str(), "#[inline]");
|
||||
|
||||
let deprecated_attrs = target_fn.attrs_by_path(&["deprecated".to_string()]);
|
||||
assert_eq!(deprecated_attrs[0].as_str(), "#[deprecated(since = \"5.2.0\")]");
|
||||
}
|
||||
|
||||
// Test derive attribute.
|
||||
fn test_derive(items: &CrateItems) {
|
||||
let target_struct = *get_item(&items, "Foo").unwrap();
|
||||
let attrs = target_struct.attrs_by_path(&["derive".to_string()]);
|
||||
// No `derive` attribute since it's expanded before MIR.
|
||||
assert_eq!(attrs.len(), 0);
|
||||
|
||||
// Check derived trait method's attributes.
|
||||
let derived_fmt = *get_item(&items, "<Foo as std::fmt::Debug>::fmt").unwrap();
|
||||
// The Rust reference lies about this attribute. It doesn't show up in `clone` or `fmt` impl.
|
||||
let _fmt_attrs = derived_fmt.attrs_by_path(&["automatically_derived".to_string()]);
|
||||
}
|
||||
|
||||
// Test tool attributes.
|
||||
fn test_tool(items: &CrateItems) {
|
||||
let rustfmt_fn = *get_item(&items, "do_not_format").unwrap();
|
||||
let rustfmt_attrs = rustfmt_fn.attrs_by_path(&["rustfmt".to_string(), "skip".to_string()]);
|
||||
assert_eq!(rustfmt_attrs[0].as_str(), "#[rustfmt::skip]");
|
||||
|
||||
let clippy_fn = *get_item(&items, "complex_fn").unwrap();
|
||||
let clippy_attrs = clippy_fn.attrs_by_path(&["clippy".to_string(),
|
||||
"cyclomatic_complexity".to_string()]);
|
||||
assert_eq!(clippy_attrs[0].as_str(), "#[clippy::cyclomatic_complexity = \"100\"]");
|
||||
}
|
||||
|
||||
fn test_all_attrs(items: &CrateItems) {
|
||||
let target_fn = *get_item(&items, "many_attrs").unwrap();
|
||||
let all_attrs = target_fn.all_attrs();
|
||||
assert_eq!(all_attrs[0].as_str(), "#[inline]");
|
||||
assert_eq!(all_attrs[1].as_str(), "#[allow(unused_variables)]");
|
||||
assert_eq!(all_attrs[2].as_str(), "#[allow(dead_code)]");
|
||||
assert_eq!(all_attrs[3].as_str(), "#[allow(unused_imports)]");
|
||||
assert_eq!(all_attrs[4].as_str(), "#![allow(clippy::filter_map)]");
|
||||
}
|
||||
|
||||
|
||||
fn get_item<'a>(
|
||||
items: &'a CrateItems,
|
||||
name: &str,
|
||||
) -> Option<&'a stable_mir::CrateItem> {
|
||||
items.iter().find(|crate_item| crate_item.name() == name)
|
||||
}
|
||||
|
||||
/// This test will generate and analyze a dummy crate using the stable mir.
|
||||
/// For that, it will first write the dummy crate into a file.
|
||||
/// Then it will create a `StableMir` using custom arguments and then
|
||||
/// it will run the compiler.
|
||||
fn main() {
|
||||
let path = "attribute_input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
"rustc".to_string(),
|
||||
"--crate-type=lib".to_string(),
|
||||
"--crate-name".to_string(),
|
||||
CRATE_NAME.to_string(),
|
||||
path.to_string(),
|
||||
];
|
||||
run!(args, test_stable_mir).unwrap();
|
||||
}
|
||||
|
||||
fn generate_input(path: &str) -> std::io::Result<()> {
|
||||
let mut file = std::fs::File::create(path)?;
|
||||
write!(
|
||||
file,
|
||||
r#"
|
||||
// General metadata applied to the enclosing module or crate.
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// Mixed inner and outer attributes.
|
||||
#[inline]
|
||||
#[deprecated(since = "5.2.0")]
|
||||
fn builtins_fn() {{
|
||||
#![allow(unused_variables)]
|
||||
|
||||
let x = ();
|
||||
let y = ();
|
||||
let z = ();
|
||||
}}
|
||||
|
||||
// A derive attribute to automatically implement a trait.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
struct Foo(u32);
|
||||
|
||||
// A rustfmt tool attribute.
|
||||
#[rustfmt::skip]
|
||||
fn do_not_format() {{}}
|
||||
|
||||
// A clippy tool attribute.
|
||||
#[clippy::cyclomatic_complexity = "100"]
|
||||
pub fn complex_fn() {{}}
|
||||
|
||||
// A function with many attributes.
|
||||
#[inline]
|
||||
#[allow(unused_variables)]
|
||||
#[allow(dead_code)]
|
||||
#[allow(unused_imports)]
|
||||
fn many_attrs() {{
|
||||
#![allow(clippy::filter_map)]
|
||||
todo!()
|
||||
}}
|
||||
"#
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
|
@ -1,20 +1,18 @@
|
|||
error[E0267]: `break` inside `async` block
|
||||
--> $DIR/async-block-control-flow-static-semantics.rs:32:9
|
||||
|
|
||||
LL | / async {
|
||||
LL | | break 0u8;
|
||||
| | ^^^^^^^^^ cannot `break` inside `async` block
|
||||
LL | | };
|
||||
| |_____- enclosing `async` block
|
||||
LL | async {
|
||||
| ----- enclosing `async` block
|
||||
LL | break 0u8;
|
||||
| ^^^^^^^^^ cannot `break` inside `async` block
|
||||
|
||||
error[E0267]: `break` inside `async` block
|
||||
--> $DIR/async-block-control-flow-static-semantics.rs:39:13
|
||||
|
|
||||
LL | / async {
|
||||
LL | | break 0u8;
|
||||
| | ^^^^^^^^^ cannot `break` inside `async` block
|
||||
LL | | };
|
||||
| |_________- enclosing `async` block
|
||||
LL | async {
|
||||
| ----- enclosing `async` block
|
||||
LL | break 0u8;
|
||||
| ^^^^^^^^^ cannot `break` inside `async` block
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/async-block-control-flow-static-semantics.rs:21:58
|
||||
|
@ -29,13 +27,13 @@ LL | |
|
|||
LL | | }
|
||||
| |_^ expected `u8`, found `()`
|
||||
|
||||
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`
|
||||
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`
|
||||
--> $DIR/async-block-control-flow-static-semantics.rs:26:39
|
||||
|
|
||||
LL | let _: &dyn Future<Output = ()> = █
|
||||
| ^^^^^^ expected `()`, found `u8`
|
||||
|
|
||||
= note: required for the cast from `&{async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 25:6}` to `&dyn Future<Output = ()>`
|
||||
= note: required for the cast from `&{async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 23:22}` to `&dyn Future<Output = ()>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/async-block-control-flow-static-semantics.rs:12:43
|
||||
|
@ -45,13 +43,13 @@ LL | fn return_targets_async_block_not_fn() -> u8 {
|
|||
| |
|
||||
| implicitly returns `()` as its body has no tail or `return` expression
|
||||
|
||||
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`
|
||||
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`
|
||||
--> $DIR/async-block-control-flow-static-semantics.rs:17:39
|
||||
|
|
||||
LL | let _: &dyn Future<Output = ()> = █
|
||||
| ^^^^^^ expected `()`, found `u8`
|
||||
|
|
||||
= note: required for the cast from `&{async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 16:6}` to `&dyn Future<Output = ()>`
|
||||
= note: required for the cast from `&{async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 14:22}` to `&dyn Future<Output = ()>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/async-block-control-flow-static-semantics.rs:49:44
|
||||
|
|
|
@ -2,9 +2,8 @@ error[E0373]: async block may outlive the current function, but it borrows `x`,
|
|||
--> $DIR/async-borrowck-escaping-block-error.rs:6:14
|
||||
|
|
||||
LL | Box::new(async { x } )
|
||||
| ^^^^^^^^-^^
|
||||
| | |
|
||||
| | `x` is borrowed here
|
||||
| ^^^^^ - `x` is borrowed here
|
||||
| |
|
||||
| may outlive borrowed value `x`
|
||||
|
|
||||
note: async block is returned here
|
||||
|
@ -21,9 +20,8 @@ error[E0373]: async block may outlive the current function, but it borrows `x`,
|
|||
--> $DIR/async-borrowck-escaping-block-error.rs:11:5
|
||||
|
|
||||
LL | async { *x }
|
||||
| ^^^^^^^^--^^
|
||||
| | |
|
||||
| | `x` is borrowed here
|
||||
| ^^^^^ -- `x` is borrowed here
|
||||
| |
|
||||
| may outlive borrowed value `x`
|
||||
|
|
||||
note: async block is returned here
|
||||
|
|
|
@ -22,20 +22,18 @@ LL | fn needs_async_fn(_: impl async Fn()) {}
|
|||
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
|
||||
--> $DIR/wrong-fn-kind.rs:9:20
|
||||
|
|
||||
LL | fn needs_async_fn(_: impl async Fn()) {}
|
||||
| --------------- change this to accept `FnMut` instead of `Fn`
|
||||
LL | fn needs_async_fn(_: impl async Fn()) {}
|
||||
| --------------- change this to accept `FnMut` instead of `Fn`
|
||||
...
|
||||
LL | needs_async_fn(async || {
|
||||
| -------------- ^-------
|
||||
| | |
|
||||
| _____|______________in this closure
|
||||
| | |
|
||||
| | expects `Fn` instead of `FnMut`
|
||||
LL | |
|
||||
LL | | x += 1;
|
||||
| | - mutable borrow occurs due to use of `x` in closure
|
||||
LL | | });
|
||||
| |_____^ cannot borrow as mutable
|
||||
LL | needs_async_fn(async || {
|
||||
| -------------- ^^^^^^^^
|
||||
| | |
|
||||
| | cannot borrow as mutable
|
||||
| | in this closure
|
||||
| expects `Fn` instead of `FnMut`
|
||||
LL |
|
||||
LL | x += 1;
|
||||
| - mutable borrow occurs due to use of `x` in closure
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
error[E0277]: the type `&mut Context<'_>` may not be safely transferred across an unwind boundary
|
||||
--> $DIR/async-is-unwindsafe.rs:12:5
|
||||
|
|
||||
LL | is_unwindsafe(async {
|
||||
| ______^ -
|
||||
| | ___________________|
|
||||
LL | ||
|
||||
LL | || use std::ptr::null;
|
||||
LL | || use std::task::{Context, RawWaker, RawWakerVTable, Waker};
|
||||
... ||
|
||||
LL | || drop(cx_ref);
|
||||
LL | || });
|
||||
| ||_____-^ `&mut Context<'_>` may not be safely transferred across an unwind boundary
|
||||
| |_____|
|
||||
| within this `{async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6}`
|
||||
LL | is_unwindsafe(async {
|
||||
| ^ ----- within this `{async block@$DIR/async-is-unwindsafe.rs:12:19: 12:24}`
|
||||
| _____|
|
||||
| |
|
||||
LL | |
|
||||
LL | | use std::ptr::null;
|
||||
LL | | use std::task::{Context, RawWaker, RawWakerVTable, Waker};
|
||||
... |
|
||||
LL | | drop(cx_ref);
|
||||
LL | | });
|
||||
| |______^ `&mut Context<'_>` may not be safely transferred across an unwind boundary
|
||||
|
|
||||
= 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`
|
||||
= 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`
|
||||
= note: `UnwindSafe` is implemented for `&Context<'_>`, but not for `&mut Context<'_>`
|
||||
note: future does not implement `UnwindSafe` as this value is used across an await
|
||||
--> $DIR/async-is-unwindsafe.rs:25:18
|
||||
|
|
|
@ -8,8 +8,8 @@ LL | fun(async {}, async {});
|
|||
| | expected all arguments to be this `async` block type because they need to match the type of this parameter
|
||||
| arguments to this function are incorrect
|
||||
|
|
||||
= note: expected `async` block `{async block@$DIR/coroutine-desc.rs:10:9: 10:17}`
|
||||
found `async` block `{async block@$DIR/coroutine-desc.rs:10:19: 10:27}`
|
||||
= note: expected `async` block `{async block@$DIR/coroutine-desc.rs:10:9: 10:14}`
|
||||
found `async` block `{async block@$DIR/coroutine-desc.rs:10:19: 10:24}`
|
||||
= note: no two async blocks, even if identical, have the same type
|
||||
= help: consider pinning your async block and casting it to a trait object
|
||||
note: function defined here
|
||||
|
|
|
@ -26,11 +26,11 @@ note: required by a bound in `takes_coroutine`
|
|||
LL | fn takes_coroutine<ResumeTy>(_g: impl Coroutine<ResumeTy, Yield = (), Return = ()>) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_coroutine`
|
||||
|
||||
error[E0277]: the trait bound `{async block@$DIR/coroutine-not-future.rs:39:21: 39:29}: Coroutine<_>` is not satisfied
|
||||
error[E0277]: the trait bound `{async block@$DIR/coroutine-not-future.rs:39:21: 39:26}: Coroutine<_>` is not satisfied
|
||||
--> $DIR/coroutine-not-future.rs:39:21
|
||||
|
|
||||
LL | takes_coroutine(async {});
|
||||
| --------------- ^^^^^^^^ the trait `Coroutine<_>` is not implemented for `{async block@$DIR/coroutine-not-future.rs:39:21: 39:29}`
|
||||
| --------------- ^^^^^^^^ the trait `Coroutine<_>` is not implemented for `{async block@$DIR/coroutine-not-future.rs:39:21: 39:26}`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
|
|
|
@ -8,7 +8,7 @@ LL | | let _a = a;
|
|||
LL | | });
|
||||
| |______^ future created by async block is not `Send`
|
||||
|
|
||||
= 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`
|
||||
= 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`
|
||||
note: future is not `Send` as this value is used across an await
|
||||
--> $DIR/issue-67252-unnamed-future.rs:20:17
|
||||
|
|
||||
|
|
|
@ -4,7 +4,7 @@ error: future cannot be sent between threads safely
|
|||
LL | require_send(send_fut);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
|
||||
|
|
||||
= 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`
|
||||
= 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`
|
||||
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
|
||||
note: future is not `Send` as it awaits another future which is not `Send`
|
||||
--> $DIR/issue-68112.rs:31:17
|
||||
|
@ -23,7 +23,7 @@ error: future cannot be sent between threads safely
|
|||
LL | require_send(send_fut);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
|
||||
|
|
||||
= 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`
|
||||
= 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`
|
||||
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
|
||||
note: future is not `Send` as it awaits another future which is not `Send`
|
||||
--> $DIR/issue-68112.rs:40:17
|
||||
|
@ -42,7 +42,7 @@ error[E0277]: `RefCell<i32>` cannot be shared between threads safely
|
|||
LL | require_send(send_fut);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
|
||||
|
|
||||
= 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`
|
||||
= 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`
|
||||
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
|
||||
= note: required for `Arc<RefCell<i32>>` to implement `Send`
|
||||
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>>> {
|
|||
note: required because it's used within this `async` block
|
||||
--> $DIR/issue-68112.rs:57:20
|
||||
|
|
||||
LL | let send_fut = async {
|
||||
| ____________________^
|
||||
LL | | let non_send_fut = make_non_send_future2();
|
||||
LL | | let _ = non_send_fut.await;
|
||||
LL | | ready(0).await;
|
||||
LL | | };
|
||||
| |_____^
|
||||
LL | let send_fut = async {
|
||||
| ^^^^^
|
||||
note: required by a bound in `require_send`
|
||||
--> $DIR/issue-68112.rs:11:25
|
||||
|
|
||||
|
|
|
@ -4,7 +4,7 @@ error[E0277]: `*mut ()` cannot be shared between threads safely
|
|||
LL | fn foo(x: NotSync) -> impl Future + Send {
|
||||
| ^^^^^^^^^^^^^^^^^^ `*mut ()` cannot be shared between threads safely
|
||||
|
|
||||
= 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`
|
||||
= 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`
|
||||
note: required because it appears within the type `PhantomData<*mut ()>`
|
||||
--> $SRC_DIR/core/src/marker.rs:LL:COL
|
||||
note: required because it appears within the type `NotSync`
|
||||
|
@ -28,12 +28,8 @@ LL | | }
|
|||
note: required because it's used within this `async` block
|
||||
--> $DIR/issue-70935-complex-spans.rs:18:5
|
||||
|
|
||||
LL | / async move {
|
||||
LL | | baz(|| async {
|
||||
LL | | foo(x.clone());
|
||||
LL | | }).await;
|
||||
LL | | }
|
||||
| |_____^
|
||||
LL | async move {
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0277]: `*mut ()` cannot be shared between threads safely
|
||||
--> $DIR/issue-70935-complex-spans.rs:15:23
|
||||
|
@ -41,7 +37,7 @@ error[E0277]: `*mut ()` cannot be shared between threads safely
|
|||
LL | fn foo(x: NotSync) -> impl Future + Send {
|
||||
| ^^^^^^^^^^^^^^^^^^ `*mut ()` cannot be shared between threads safely
|
||||
|
|
||||
= 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`
|
||||
= 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`
|
||||
note: required because it appears within the type `PhantomData<*mut ()>`
|
||||
--> $SRC_DIR/core/src/marker.rs:LL:COL
|
||||
note: required because it appears within the type `NotSync`
|
||||
|
@ -65,12 +61,8 @@ LL | | }
|
|||
note: required because it's used within this `async` block
|
||||
--> $DIR/issue-70935-complex-spans.rs:18:5
|
||||
|
|
||||
LL | / async move {
|
||||
LL | | baz(|| async {
|
||||
LL | | foo(x.clone());
|
||||
LL | | }).await;
|
||||
LL | | }
|
||||
| |_____^
|
||||
LL | async move {
|
||||
| ^^^^^^^^^^
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
|
|
@ -13,14 +13,15 @@ LL | y
|
|||
error[E0506]: cannot assign to `*x` because it is borrowed
|
||||
--> $DIR/issue-74072-lifetime-name-annotations.rs:18:9
|
||||
|
|
||||
LL | (async move || {
|
||||
| - return type of async closure is &'1 i32
|
||||
...
|
||||
LL | let y = &*x;
|
||||
| --- `*x` is borrowed here
|
||||
LL | *x += 1;
|
||||
| ^^^^^^^ `*x` is assigned to here but it was already borrowed
|
||||
LL | y
|
||||
| - returning this value requires that `*x` is borrowed for `'1`
|
||||
LL | })()
|
||||
| - return type of async closure is &'1 i32
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/issue-74072-lifetime-name-annotations.rs:14:20
|
||||
|
@ -61,14 +62,15 @@ LL | }
|
|||
error[E0506]: cannot assign to `*x` because it is borrowed
|
||||
--> $DIR/issue-74072-lifetime-name-annotations.rs:28:9
|
||||
|
|
||||
LL | (async move || -> &i32 {
|
||||
| - return type of async closure is &'1 i32
|
||||
...
|
||||
LL | let y = &*x;
|
||||
| --- `*x` is borrowed here
|
||||
LL | *x += 1;
|
||||
| ^^^^^^^ `*x` is assigned to here but it was already borrowed
|
||||
LL | y
|
||||
| - returning this value requires that `*x` is borrowed for `'1`
|
||||
LL | })()
|
||||
| - return type of async closure is &'1 i32
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/issue-74072-lifetime-name-annotations.rs:24:28
|
||||
|
@ -109,14 +111,14 @@ LL | }
|
|||
error[E0506]: cannot assign to `*x` because it is borrowed
|
||||
--> $DIR/issue-74072-lifetime-name-annotations.rs:36:9
|
||||
|
|
||||
LL | async move {
|
||||
| - return type of async block is &'1 i32
|
||||
LL | let y = &*x;
|
||||
| --- `*x` is borrowed here
|
||||
LL | *x += 1;
|
||||
| ^^^^^^^ `*x` is assigned to here but it was already borrowed
|
||||
LL | y
|
||||
| - returning this value requires that `*x` is borrowed for `'1`
|
||||
LL | }
|
||||
| - return type of async block is &'1 i32
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless
|
|||
|
|
||||
LL | let x = x;
|
||||
| ^ has type `&T` which is not `Send`, because `T` is not `Sync`
|
||||
= 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)>>`
|
||||
= 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)>>`
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T)
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
error[E0373]: async block may outlive the current function, but it borrows `room_ref`, which is owned by the current function
|
||||
--> $DIR/issue-78938-async-block.rs:8:33
|
||||
|
|
||||
LL | let gameloop_handle = spawn(async {
|
||||
| _________________________________^
|
||||
LL | | game_loop(Arc::clone(&room_ref))
|
||||
| | -------- `room_ref` is borrowed here
|
||||
LL | | });
|
||||
| |_____^ may outlive borrowed value `room_ref`
|
||||
LL | let gameloop_handle = spawn(async {
|
||||
| ^^^^^ may outlive borrowed value `room_ref`
|
||||
LL | game_loop(Arc::clone(&room_ref))
|
||||
| -------- `room_ref` is borrowed here
|
||||
|
|
||||
= note: async blocks are not executed immediately and must either take a reference or ownership of outside variables they use
|
||||
help: to force the async block to take ownership of `room_ref` (and any other referenced variables), use the `move` keyword
|
||||
|
|
|
@ -72,7 +72,7 @@ LL | | }
|
|||
| |_____^ expected `()`, found `async` block
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found `async` block `{async block@$DIR/async-closure-gate.rs:27:5: 32:6}`
|
||||
found `async` block `{async block@$DIR/async-closure-gate.rs:27:5: 27:10}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/async-closure-gate.rs:44:5
|
||||
|
@ -89,7 +89,7 @@ LL | | }
|
|||
| |_____^ expected `()`, found `async` block
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found `async` block `{async block@$DIR/async-closure-gate.rs:44:5: 51:6}`
|
||||
found `async` block `{async block@$DIR/async-closure-gate.rs:44:5: 44:10}`
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ LL | | }
|
|||
| |_____^ expected `()`, found `async` block
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found `async` block `{async block@$DIR/async-closure-gate.rs:27:5: 32:6}`
|
||||
found `async` block `{async block@$DIR/async-closure-gate.rs:27:5: 27:10}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/async-closure-gate.rs:44:5
|
||||
|
@ -89,7 +89,7 @@ LL | | }
|
|||
| |_____^ expected `()`, found `async` block
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found `async` block `{async block@$DIR/async-closure-gate.rs:44:5: 51:6}`
|
||||
found `async` block `{async block@$DIR/async-closure-gate.rs:44:5: 44:10}`
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
error[E0277]: the `?` operator can only be used in an async block that returns `Result` or `Option` (or another type that implements `FromResidual`)
|
||||
--> $DIR/try-on-option-in-async.rs:8:10
|
||||
|
|
||||
LL | / async {
|
||||
LL | | let x: Option<u32> = None;
|
||||
LL | | x?;
|
||||
| | ^ cannot use the `?` operator in an async block that returns `{integer}`
|
||||
LL | | 22
|
||||
LL | | }
|
||||
| |_____- this function should return `Result` or `Option` to accept `?`
|
||||
LL | async {
|
||||
| ----- this function should return `Result` or `Option` to accept `?`
|
||||
LL | let x: Option<u32> = None;
|
||||
LL | x?;
|
||||
| ^ cannot use the `?` operator in an async block that returns `{integer}`
|
||||
|
|
||||
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `{integer}`
|
||||
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
error[E0382]: use of moved value: `value`
|
||||
--> $DIR/cloning-in-async-block-121547.rs:5:9
|
||||
|
|
||||
LL | async fn clone_async_block(value: String) {
|
||||
| ----- move occurs because `value` has type `String`, which does not implement the `Copy` trait
|
||||
LL | for _ in 0..10 {
|
||||
| -------------- inside of this loop
|
||||
LL | / async {
|
||||
LL | | drop(value);
|
||||
| | ----- use occurs due to use in coroutine
|
||||
LL | |
|
||||
LL | | }.await
|
||||
| |_________^ value moved here, in previous iteration of loop
|
||||
LL | async fn clone_async_block(value: String) {
|
||||
| ----- move occurs because `value` has type `String`, which does not implement the `Copy` trait
|
||||
LL | for _ in 0..10 {
|
||||
| -------------- inside of this loop
|
||||
LL | async {
|
||||
| ^^^^^ value moved here, in previous iteration of loop
|
||||
LL | drop(value);
|
||||
| ----- use occurs due to use in coroutine
|
||||
|
|
||||
help: consider cloning the value if the performance cost is acceptable
|
||||
|
|
||||
|
|
|
@ -1,67 +1,57 @@
|
|||
error[E0267]: `break` inside `async` function
|
||||
--> $DIR/break-inside-coroutine-issue-124495.rs:8:5
|
||||
|
|
||||
LL | async fn async_fn() {
|
||||
| _____________________-
|
||||
LL | | break;
|
||||
| | ^^^^^ cannot `break` inside `async` function
|
||||
LL | | }
|
||||
| |_- enclosing `async` function
|
||||
LL | async fn async_fn() {
|
||||
| ------------------- enclosing `async` function
|
||||
LL | break;
|
||||
| ^^^^^ cannot `break` inside `async` function
|
||||
|
||||
error[E0267]: `break` inside `gen` function
|
||||
--> $DIR/break-inside-coroutine-issue-124495.rs:12:5
|
||||
|
|
||||
LL | gen fn gen_fn() {
|
||||
| _________________-
|
||||
LL | | break;
|
||||
| | ^^^^^ cannot `break` inside `gen` function
|
||||
LL | | }
|
||||
| |_- enclosing `gen` function
|
||||
LL | gen fn gen_fn() {
|
||||
| --------------- enclosing `gen` function
|
||||
LL | break;
|
||||
| ^^^^^ cannot `break` inside `gen` function
|
||||
|
||||
error[E0267]: `break` inside `async gen` function
|
||||
--> $DIR/break-inside-coroutine-issue-124495.rs:16:5
|
||||
|
|
||||
LL | async gen fn async_gen_fn() {
|
||||
| _____________________________-
|
||||
LL | | break;
|
||||
| | ^^^^^ cannot `break` inside `async gen` function
|
||||
LL | | }
|
||||
| |_- enclosing `async gen` function
|
||||
LL | async gen fn async_gen_fn() {
|
||||
| --------------------------- enclosing `async gen` function
|
||||
LL | break;
|
||||
| ^^^^^ cannot `break` inside `async gen` function
|
||||
|
||||
error[E0267]: `break` inside `async` block
|
||||
--> $DIR/break-inside-coroutine-issue-124495.rs:20:21
|
||||
|
|
||||
LL | let _ = async { break; };
|
||||
| --------^^^^^---
|
||||
| | |
|
||||
| | cannot `break` inside `async` block
|
||||
| ----- ^^^^^ cannot `break` inside `async` block
|
||||
| |
|
||||
| enclosing `async` block
|
||||
|
||||
error[E0267]: `break` inside `async` closure
|
||||
--> $DIR/break-inside-coroutine-issue-124495.rs:22:24
|
||||
|
|
||||
LL | let _ = async || { break; };
|
||||
| -----------^^^^^---
|
||||
| | |
|
||||
| | cannot `break` inside `async` closure
|
||||
| -------- ^^^^^ cannot `break` inside `async` closure
|
||||
| |
|
||||
| enclosing `async` closure
|
||||
|
||||
error[E0267]: `break` inside `gen` block
|
||||
--> $DIR/break-inside-coroutine-issue-124495.rs:24:19
|
||||
|
|
||||
LL | let _ = gen { break; };
|
||||
| ------^^^^^---
|
||||
| | |
|
||||
| | cannot `break` inside `gen` block
|
||||
| --- ^^^^^ cannot `break` inside `gen` block
|
||||
| |
|
||||
| enclosing `gen` block
|
||||
|
||||
error[E0267]: `break` inside `async gen` block
|
||||
--> $DIR/break-inside-coroutine-issue-124495.rs:26:25
|
||||
|
|
||||
LL | let _ = async gen { break; };
|
||||
| ------------^^^^^---
|
||||
| | |
|
||||
| | cannot `break` inside `async gen` block
|
||||
| --------- ^^^^^ cannot `break` inside `async gen` block
|
||||
| |
|
||||
| enclosing `async gen` block
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:12:27: 16:6}: Copy` is not satisfied
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:12:27: 12:32}: Copy` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:17:16
|
||||
|
|
||||
LL | check_copy(&inner_non_clone);
|
||||
| ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:12:27: 16:6}`
|
||||
| ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:12:27: 12:32}`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
|
@ -12,11 +12,11 @@ note: required by a bound in `check_copy`
|
|||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:12:27: 16:6}: Clone` is not satisfied
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:12:27: 12:32}: Clone` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:19:17
|
||||
|
|
||||
LL | check_clone(&inner_non_clone);
|
||||
| ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:12:27: 16:6}`
|
||||
| ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:12:27: 12:32}`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
|
@ -26,11 +26,11 @@ note: required by a bound in `check_clone`
|
|||
LL | fn check_clone<T: Clone>(_x: &T) {}
|
||||
| ^^^^^ required by this bound in `check_clone`
|
||||
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:23:27: 25:6}: Copy` is not satisfied
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:23:27: 23:37}: Copy` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:26:16
|
||||
|
|
||||
LL | check_copy(&outer_non_clone);
|
||||
| ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:23:27: 25:6}`
|
||||
| ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:23:27: 23:37}`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
|
@ -40,11 +40,11 @@ note: required by a bound in `check_copy`
|
|||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:23:27: 25:6}: Clone` is not satisfied
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:23:27: 23:37}: Clone` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:28:17
|
||||
|
|
||||
LL | check_clone(&outer_non_clone);
|
||||
| ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:23:27: 25:6}`
|
||||
| ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:23:27: 23:37}`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
|
@ -54,11 +54,11 @@ note: required by a bound in `check_clone`
|
|||
LL | fn check_clone<T: Clone>(_x: &T) {}
|
||||
| ^^^^^ required by this bound in `check_clone`
|
||||
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:31:28: 31:41}: Copy` is not satisfied
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:31:28: 31:38}: Copy` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:32:16
|
||||
|
|
||||
LL | check_copy(&maybe_copy_clone);
|
||||
| ---------- ^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:31:28: 31:41}`
|
||||
| ---------- ^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:31:28: 31:38}`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
|
@ -68,11 +68,11 @@ note: required by a bound in `check_copy`
|
|||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:31:28: 31:41}: Clone` is not satisfied
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:31:28: 31:38}: Clone` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:34:17
|
||||
|
|
||||
LL | check_clone(&maybe_copy_clone);
|
||||
| ----------- ^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:31:28: 31:41}`
|
||||
| ----------- ^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:31:28: 31:38}`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:21}: Coroutine` is not satisfied
|
||||
error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}: Coroutine` is not satisfied
|
||||
--> $DIR/gen_block_is_coro.rs:6:13
|
||||
|
|
||||
LL | fn foo() -> impl Coroutine<Yield = u32, Return = ()> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:21}`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}`
|
||||
|
||||
error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:21}: Coroutine` is not satisfied
|
||||
error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:8}: Coroutine` is not satisfied
|
||||
--> $DIR/gen_block_is_coro.rs:10:13
|
||||
|
|
||||
LL | fn bar() -> impl Coroutine<Yield = i64, Return = ()> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:21}`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:8}`
|
||||
|
||||
error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:21}: Coroutine` is not satisfied
|
||||
error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:8}: Coroutine` is not satisfied
|
||||
--> $DIR/gen_block_is_coro.rs:14:13
|
||||
|
|
||||
LL | fn baz() -> impl Coroutine<Yield = i32, Return = ()> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:21}`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:8}`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
error[E0277]: `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:21}` is not a future
|
||||
error[E0277]: `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:8}` is not a future
|
||||
--> $DIR/gen_block_is_no_future.rs:4:13
|
||||
|
|
||||
LL | fn foo() -> impl std::future::Future {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:21}` is not a future
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:8}` is not a future
|
||||
|
|
||||
= help: the trait `Future` is not implemented for `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:21}`
|
||||
= help: the trait `Future` is not implemented for `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:8}`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
error[E0373]: gen block may outlive the current function, but it borrows `x`, which is owned by the current function
|
||||
--> $DIR/gen_block_move.rs:7:5
|
||||
|
|
||||
LL | / gen {
|
||||
LL | | yield 42;
|
||||
LL | | if x == "foo" { return }
|
||||
LL | | x.clear();
|
||||
| | - `x` is borrowed here
|
||||
LL | | for x in 3..6 { yield x }
|
||||
LL | | }
|
||||
| |_____^ may outlive borrowed value `x`
|
||||
LL | gen {
|
||||
| ^^^ may outlive borrowed value `x`
|
||||
...
|
||||
LL | x.clear();
|
||||
| - `x` is borrowed here
|
||||
|
|
||||
note: gen block is returned here
|
||||
--> $DIR/gen_block_move.rs:7:5
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
#[patchable_function_entry(prefix_nops = 1, entry_nops = 1)]
|
||||
//~^ ERROR: the `#[patchable_function_entry]` attribute is an experimental feature
|
||||
fn main() {}
|
|
@ -0,0 +1,13 @@
|
|||
error[E0658]: the `#[patchable_function_entry]` attribute is an experimental feature
|
||||
--> $DIR/feature-gate-patchable-function-entry.rs:1:1
|
||||
|
|
||||
LL | #[patchable_function_entry(prefix_nops = 1, entry_nops = 1)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #123115 <https://github.com/rust-lang/rust/issues/123115> for more information
|
||||
= help: add `#![feature(patchable_function_entry)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -1,45 +1,27 @@
|
|||
error[E0277]: `core::fmt::rt::Opaque` cannot be shared between threads safely
|
||||
error[E0277]: `Arguments<'_>` cannot be sent between threads safely
|
||||
--> $DIR/send-sync.rs:8:10
|
||||
|
|
||||
LL | send(format_args!("{:?}", c));
|
||||
| ---- ^^^^^^^^^^^^^^^^^^^^^^^ `core::fmt::rt::Opaque` cannot be shared between threads safely
|
||||
| ---- ^^^^^^^^^^^^^^^^^^^^^^^ `Arguments<'_>` cannot be sent between threads safely
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: within `[core::fmt::rt::Argument<'_>]`, the trait `Sync` is not implemented for `core::fmt::rt::Opaque`, which is required by `Arguments<'_>: Send`
|
||||
= note: required because it appears within the type `&core::fmt::rt::Opaque`
|
||||
note: required because it appears within the type `core::fmt::rt::ArgumentType<'_>`
|
||||
--> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
|
||||
note: required because it appears within the type `core::fmt::rt::Argument<'_>`
|
||||
--> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
|
||||
= note: required because it appears within the type `[core::fmt::rt::Argument<'_>]`
|
||||
= note: required for `&[core::fmt::rt::Argument<'_>]` to implement `Send`
|
||||
note: required because it appears within the type `Arguments<'_>`
|
||||
--> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
|
||||
= help: the trait `Send` is not implemented for `Arguments<'_>`
|
||||
note: required by a bound in `send`
|
||||
--> $DIR/send-sync.rs:1:12
|
||||
|
|
||||
LL | fn send<T: Send>(_: T) {}
|
||||
| ^^^^ required by this bound in `send`
|
||||
|
||||
error[E0277]: `core::fmt::rt::Opaque` cannot be shared between threads safely
|
||||
error[E0277]: `Arguments<'_>` cannot be shared between threads safely
|
||||
--> $DIR/send-sync.rs:9:10
|
||||
|
|
||||
LL | sync(format_args!("{:?}", c));
|
||||
| ---- ^^^^^^^^^^^^^^^^^^^^^^^ `core::fmt::rt::Opaque` cannot be shared between threads safely
|
||||
| ---- ^^^^^^^^^^^^^^^^^^^^^^^ `Arguments<'_>` cannot be shared between threads safely
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: within `Arguments<'_>`, the trait `Sync` is not implemented for `core::fmt::rt::Opaque`, which is required by `Arguments<'_>: Sync`
|
||||
= note: required because it appears within the type `&core::fmt::rt::Opaque`
|
||||
note: required because it appears within the type `core::fmt::rt::ArgumentType<'_>`
|
||||
--> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
|
||||
note: required because it appears within the type `core::fmt::rt::Argument<'_>`
|
||||
--> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
|
||||
= note: required because it appears within the type `[core::fmt::rt::Argument<'_>]`
|
||||
= note: required because it appears within the type `&[core::fmt::rt::Argument<'_>]`
|
||||
note: required because it appears within the type `Arguments<'_>`
|
||||
--> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
|
||||
= help: the trait `Sync` is not implemented for `Arguments<'_>`
|
||||
note: required by a bound in `sync`
|
||||
--> $DIR/send-sync.rs:2:12
|
||||
|
|
||||
|
|
|
@ -10,7 +10,7 @@ LL | async { () }
|
|||
| ^^^^^^^^^^^^ expected future, found `async` block
|
||||
|
|
||||
= note: expected opaque type `Foo<'_>::Fut<'a>`
|
||||
found `async` block `{async block@$DIR/issue-90014-tait.rs:18:9: 18:21}`
|
||||
found `async` block `{async block@$DIR/issue-90014-tait.rs:18:9: 18:14}`
|
||||
note: this item must have the opaque type in its signature in order to be able to register hidden types
|
||||
--> $DIR/issue-90014-tait.rs:17:8
|
||||
|
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error[E0277]: the trait bound `{async block@$DIR/issue-55872-3.rs:15:9: 15:17}: Copy` is not satisfied
|
||||
error[E0277]: the trait bound `{async block@$DIR/issue-55872-3.rs:15:9: 15:14}: Copy` is not satisfied
|
||||
--> $DIR/issue-55872-3.rs:13:20
|
||||
|
|
||||
LL | fn foo<T>() -> Self::E {
|
||||
| ^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/issue-55872-3.rs:15:9: 15:17}`
|
||||
| ^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/issue-55872-3.rs:15:9: 15:14}`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
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 `()`
|
||||
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 `()`
|
||||
--> $DIR/issue-78722-2.rs:11:30
|
||||
|
|
||||
LL | fn concrete_use() -> F {
|
||||
|
@ -16,7 +16,7 @@ LL | let f: F = async { 1 };
|
|||
| expected due to this
|
||||
|
|
||||
= note: expected opaque type `F`
|
||||
found `async` block `{async block@$DIR/issue-78722-2.rs:16:20: 16:31}`
|
||||
found `async` block `{async block@$DIR/issue-78722-2.rs:16:20: 16:25}`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ LL | let f: F = async { 1 };
|
|||
= help: add `#![feature(const_async_blocks)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
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 `()`
|
||||
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 `()`
|
||||
--> $DIR/issue-78722.rs:8:30
|
||||
|
|
||||
LL | fn concrete_use() -> F {
|
||||
|
|
|
@ -4,7 +4,7 @@ error[E0700]: hidden type for `impl Future<Output = impl Sized>` captures lifeti
|
|||
LL | fn test<'s: 's>(s: &'s str) -> impl std::future::Future<Output = impl Sized> {
|
||||
| -- --------------------------------------------- opaque type defined here
|
||||
| |
|
||||
| hidden type `{async block@$DIR/nested-return-type4.rs:4:5: 4:31}` captures the lifetime `'s` as defined here
|
||||
| hidden type `{async block@$DIR/nested-return-type4.rs:4:5: 4:15}` captures the lifetime `'s` as defined here
|
||||
LL | async move { let _s = s; }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
|
|
|
@ -52,13 +52,13 @@ error[E0308]: mismatched types
|
|||
--> $DIR/mismatch-sugg-for-shorthand-field.rs:57:20
|
||||
|
|
||||
LL | let a = async { 42 };
|
||||
| ------------ the found `async` block
|
||||
| ----- the found `async` block
|
||||
...
|
||||
LL | let s = Demo { a };
|
||||
| ^ expected `Pin<Box<...>>`, found `async` block
|
||||
|
|
||||
= note: expected struct `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>`
|
||||
found `async` block `{async block@$DIR/mismatch-sugg-for-shorthand-field.rs:53:13: 53:25}`
|
||||
found `async` block `{async block@$DIR/mismatch-sugg-for-shorthand-field.rs:53:13: 53:18}`
|
||||
help: you need to pin and box this expression
|
||||
|
|
||||
LL | let s = Demo { a: Box::pin(a) };
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
#![feature(patchable_function_entry)]
|
||||
fn main() {}
|
||||
|
||||
#[patchable_function_entry(prefix_nops = 256, entry_nops = 0)]//~error: integer value out of range
|
||||
pub fn too_high_pnops() {}
|
||||
|
||||
#[patchable_function_entry(prefix_nops = "stringvalue", entry_nops = 0)]//~error: invalid literal value
|
||||
pub fn non_int_nop() {}
|
||||
|
||||
#[patchable_function_entry]//~error: malformed `patchable_function_entry` attribute input
|
||||
pub fn malformed_attribute() {}
|
||||
|
||||
#[patchable_function_entry(prefix_nops = 10, something = 0)]//~error: unexpected parameter name
|
||||
pub fn unexpected_parameter_name() {}
|
||||
|
||||
#[patchable_function_entry()]//~error: must specify at least one parameter
|
||||
pub fn no_parameters_given() {}
|
|
@ -0,0 +1,32 @@
|
|||
error: malformed `patchable_function_entry` attribute input
|
||||
--> $DIR/patchable-function-entry-attribute.rs:10:1
|
||||
|
|
||||
LL | #[patchable_function_entry]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]`
|
||||
|
||||
error: integer value out of range
|
||||
--> $DIR/patchable-function-entry-attribute.rs:4:42
|
||||
|
|
||||
LL | #[patchable_function_entry(prefix_nops = 256, entry_nops = 0)]
|
||||
| ^^^ value must be between `0` and `255`
|
||||
|
||||
error: invalid literal value
|
||||
--> $DIR/patchable-function-entry-attribute.rs:7:42
|
||||
|
|
||||
LL | #[patchable_function_entry(prefix_nops = "stringvalue", entry_nops = 0)]
|
||||
| ^^^^^^^^^^^^^ value must be an integer between `0` and `255`
|
||||
|
||||
error: unexpected parameter name
|
||||
--> $DIR/patchable-function-entry-attribute.rs:13:46
|
||||
|
|
||||
LL | #[patchable_function_entry(prefix_nops = 10, something = 0)]
|
||||
| ^^^^^^^^^^^^^ expected prefix_nops or entry_nops
|
||||
|
||||
error: must specify at least one parameter
|
||||
--> $DIR/patchable-function-entry-attribute.rs:16:1
|
||||
|
|
||||
LL | #[patchable_function_entry()]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
//@ compile-flags: -Z patchable-function-entry=1,2
|
||||
fn main() {}
|
|
@ -0,0 +1,2 @@
|
|||
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
|
||||
|
|
@ -4,7 +4,7 @@ error: `{closure@$DIR/non-structural-match-types.rs:9:17: 9:19}` cannot be used
|
|||
LL | const { || {} } => {}
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: `{async block@$DIR/non-structural-match-types.rs:12:17: 12:25}` cannot be used in patterns
|
||||
error: `{async block@$DIR/non-structural-match-types.rs:12:17: 12:22}` cannot be used in patterns
|
||||
--> $DIR/non-structural-match-types.rs:12:9
|
||||
|
|
||||
LL | const { async {} } => {}
|
||||
|
|
|
@ -79,7 +79,7 @@ LL | | }
|
|||
| |_____^ expected `Pin<Box<...>>`, found `async` block
|
||||
|
|
||||
= note: expected struct `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>`
|
||||
found `async` block `{async block@$DIR/expected-boxed-future-isnt-pinned.rs:28:5: 30:6}`
|
||||
found `async` block `{async block@$DIR/expected-boxed-future-isnt-pinned.rs:28:5: 28:10}`
|
||||
help: you need to pin and box this expression
|
||||
|
|
||||
LL ~ Box::pin(async {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0271]: type mismatch resolving `<{async block@$DIR/async.rs:12:17: 12:25} as Future>::Output == i32`
|
||||
error[E0271]: type mismatch resolving `<{async block@$DIR/async.rs:12:17: 12:22} as Future>::Output == i32`
|
||||
--> $DIR/async.rs:12:17
|
||||
|
|
||||
LL | needs_async(async {});
|
||||
|
|
|
@ -2,9 +2,7 @@ error[E0733]: recursion in an async block requires boxing
|
|||
--> $DIR/indirect-recursion-issue-112047.rs:22:9
|
||||
|
|
||||
LL | async move { recur(self).await; }
|
||||
| ^^^^^^^^^^^^^-----------------^^^
|
||||
| |
|
||||
| recursive call here
|
||||
| ^^^^^^^^^^ ----------------- recursive call here
|
||||
|
|
||||
note: which leads to this async fn
|
||||
--> $DIR/indirect-recursion-issue-112047.rs:14:1
|
||||
|
|
Loading…
Reference in a new issue