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:
bors 2024-06-28 07:25:28 +00:00
commit 99f77a2eda
80 changed files with 980 additions and 308 deletions

View File

@ -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",

View File

@ -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),

View File

@ -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);

View File

@ -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));

View File

@ -227,7 +227,7 @@ impl<'hir> LoweringContext<'_, '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 @@ impl<'hir> LoweringContext<'_, 'hir> {
*capture_clause,
e.id,
None,
*decl_span,
e.span,
desugaring_kind,
hir::CoroutineSource::Block,
@ -616,6 +617,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
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 @@ impl<'hir> LoweringContext<'_, 'hir> {
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 @@ impl<'hir> LoweringContext<'_, 'hir> {
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,

View File

@ -211,6 +211,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// 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 @@ impl<'hir> LoweringContext<'_, '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 @@ impl<'hir> LoweringContext<'_, '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 @@ impl<'hir> LoweringContext<'_, 'hir> {
/// `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 @@ impl<'hir> LoweringContext<'_, 'hir> {
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 @@ impl<'hir> LoweringContext<'_, 'hir> {
&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 @@ impl<'hir> LoweringContext<'_, 'hir> {
};
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 @@ impl<'hir> LoweringContext<'_, 'hir> {
CaptureBy::Ref,
closure_id,
None,
span,
fn_decl_span,
body_span,
desugaring_kind,
coroutine_source,
mkbody,

View File

@ -540,7 +540,7 @@ impl<'a> State<'a> {
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

View File

@ -298,7 +298,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
// 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(_, _)

View File

@ -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

View File

@ -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),
))
})
}
_ => {}
}
}

View File

@ -585,6 +585,13 @@ pub const BUILTIN_ATTRIBUTES: &[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:
// ==========================================================================

View File

@ -563,6 +563,8 @@ declare_features! (
(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.

View File

@ -8,8 +8,8 @@ use rustc_session::config::{
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 @@ fn test_unstable_options_tracking_hash() {
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);

View File

@ -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 @@ impl CodegenFnAttrs {
no_sanitize: SanitizerSet::empty(),
instruction_set: None,
alignment: None,
patchable_function_entry: None,
}
}

View File

@ -3432,8 +3432,9 @@ impl<'a> Parser<'a> {
}
}
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 @@ impl MutVisitor for CondChecker<'_> {
| ExprKind::Match(_, _, _)
| ExprKind::Closure(_)
| ExprKind::Block(_, _)
| ExprKind::Gen(_, _, _)
| ExprKind::Gen(_, _, _, _)
| ExprKind::TryBlock(_)
| ExprKind::Underscore
| ExprKind::Path(_, _)

View File

@ -334,7 +334,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
None => closure_def,
}
}
ExprKind::Gen(_, _, _) => {
ExprKind::Gen(_, _, _, _) => {
self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span)
}
ExprKind::ConstBlock(ref constant) => {

View File

@ -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 @@ pub(crate) mod dep_tracking {
OomStrategy,
LanguageIdentifier,
NextSolverConfig,
PatchableFunctionEntry,
Polonius,
InliningThreshold,
FunctionReturn,
@ -3250,6 +3252,35 @@ impl DumpMonoStatsFormat {
}
}
/// `-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)]

View File

@ -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 @@ mod parse {
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 @@ options! {
"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

View File

@ -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" }

View File

@ -228,6 +228,46 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
}
}
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])

View File

@ -768,6 +768,7 @@ symbols! {
enable,
encode,
end,
entry_nops,
enumerate_method,
env,
env_CFG_RELEASE: env!("CFG_RELEASE"),
@ -1383,6 +1384,7 @@ symbols! {
passes,
pat,
pat_param,
patchable_function_entry,
path,
pattern_complexity,
pattern_parentheses,
@ -1421,6 +1423,7 @@ symbols! {
prefetch_read_instruction,
prefetch_write_data,
prefetch_write_instruction,
prefix_nops,
preg,
prelude,
prelude_import,

View File

@ -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;

View File

@ -50,6 +50,21 @@ pub trait CrateDef {
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 @@ pub trait CrateDefType: CrateDef {
}
}
#[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 $(;)?

View File

@ -206,15 +206,16 @@ impl BorrowMut<str> for String {
#[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);
}
}

View File

@ -459,6 +459,12 @@ impl<'a> Arguments<'a> {
}
}
// 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 {

View File

@ -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,23 +97,17 @@ 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 {
// INVARIANT: this creates an `ArgumentType<'b>` from a `&'b T` and
// a `fn(&T, ...)`, so the invariant is maintained.
ty: ArgumentType::Placeholder {
formatter: mem::transmute(f),
value: mem::transmute(x),
value: NonNull::from(x).cast(),
// SAFETY: function pointers always have the same layout.
formatter: unsafe { mem::transmute(f) },
_lifetime: PhantomData,
},
}
}
}
#[inline(always)]
pub fn new_display<'b, T: Display>(x: &'b T) -> Argument<'_> {
@ -162,7 +163,14 @@ impl<'a> Argument<'a> {
#[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 @@ impl UnsafeArg {
Self { _private: () }
}
}
extern "C" {
type Opaque;
}

View File

@ -888,12 +888,11 @@ impl Step for Rustc {
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 @@ macro_rules! tool_doc {
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 @@ macro_rules! tool_doc {
/// 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 @@ macro_rules! tool_doc {
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 @@ macro_rules! tool_doc {
}
}
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 @@ tool_doc!(
"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 @@ tool_doc!(
);
tool_doc!(
RunMakeSupport,
"run_make_support",
"src/tools/run-make-support",
rustc_tool = false,
is_library = true,

View File

@ -2983,6 +2983,9 @@ impl Step for Bootstrap {
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"])

View File

@ -656,6 +656,8 @@ impl Step for Cargo {
}
fn run(self, builder: &Builder<'_>) -> PathBuf {
builder.build.update_submodule(Path::new("src/tools/cargo"));
builder.ensure(ToolBuild {
compiler: self.compiler,
target: self.target,

View File

@ -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 @@ impl Step for Vendor {
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",

View File

@ -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")
}

View File

@ -469,8 +469,7 @@ impl 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));
}

View File

@ -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.

View File

@ -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(_, _, _))

View File

@ -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),

View File

@ -372,7 +372,7 @@ pub(crate) fn format_expr(
))
}
}
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 {

View File

@ -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{{.*}} }

View File

@ -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{{.*}} }

View File

@ -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{{.*}} }

View File

@ -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)

View File

@ -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)

View 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(())
}

View File

@ -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 = ()> = &block;
| ^^^^^^ 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 = ()> = &block;
| ^^^^^^ 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

View File

@ -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

View File

@ -26,16 +26,14 @@ 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
| | 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

View File

@ -2,19 +2,18 @@ error[E0277]: the type `&mut Context<'_>` may not be safely transferred across a
--> $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}`
| ^ ----- 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

View File

@ -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

View File

@ -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
|

View File

@ -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
|

View File

@ -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
@ -62,12 +62,7 @@ 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 | | };
| |_____^
| ^^^^^
note: required by a bound in `require_send`
--> $DIR/issue-68112.rs:11:25
|

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -2,11 +2,9 @@ error[E0373]: async block may outlive the current function, but it borrows `room
--> $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`
| ^^^^^ 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

View File

@ -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

View File

@ -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

View File

@ -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}`

View File

@ -5,12 +5,10 @@ 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 {
| ^^^^^ 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
|

View File

@ -2,66 +2,56 @@ 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
| ------------------- 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
| --------------- 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
| --------------------------- 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

View File

@ -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
|

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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() {}

View File

@ -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`.

View File

@ -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
|

View File

@ -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
|

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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; }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|

View File

@ -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) };

View File

@ -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() {}

View File

@ -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

View File

@ -0,0 +1,2 @@
//@ compile-flags: -Z patchable-function-entry=1,2
fn main() {}

View File

@ -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

View File

@ -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 {} } => {}

View File

@ -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 {

View File

@ -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 {});

View File

@ -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