Auto merge of #128278 - tgross35:rollup-zv7q0h5, r=tgross35

Rollup of 8 pull requests

Successful merges:

 - #125897 (from_ref, from_mut: clarify documentation)
 - #128207 (improve error message when `global_asm!` uses `asm!` options)
 - #128241 (Remove logic to suggest clone of function output)
 - #128259 ([illumos/solaris] set MSG_NOSIGNAL while writing to sockets)
 - #128262 (Delete `SimplifyArmIdentity` and `SimplifyBranchSame` tests)
 - #128266 (update `rust.channel` default value documentation)
 - #128267 (Add rustdoc GUI test to check title with and without search)
 - #128271 (Disable jump threading of float equality)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-07-27 18:29:13 +00:00
commit fbccf50533
39 changed files with 501 additions and 587 deletions

View File

@ -2266,6 +2266,11 @@ bitflags::bitflags! {
}
impl InlineAsmOptions {
pub const COUNT: usize = Self::all().bits().count_ones() as usize;
pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW).union(Self::NORETURN);
pub fn human_readable_names(&self) -> Vec<&'static str> {
let mut options = vec![];

View File

@ -1306,37 +1306,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
// result of `foo(...)` won't help.
break 'outer;
}
// We're suggesting `.clone()` on an borrowed value. See if the expression we have
// is an argument to a function or method call, and try to suggest cloning the
// *result* of the call, instead of the argument. This is closest to what people
// would actually be looking for in most cases, with maybe the exception of things
// like `fn(T) -> T`, but even then it is reasonable.
let typeck_results = self.infcx.tcx.typeck(self.mir_def_id());
let mut prev = expr;
while let hir::Node::Expr(parent) = self.infcx.tcx.parent_hir_node(prev.hir_id) {
if let hir::ExprKind::Call(..) | hir::ExprKind::MethodCall(..) = parent.kind
&& let Some(call_ty) = typeck_results.node_type_opt(parent.hir_id)
&& let call_ty = call_ty.peel_refs()
&& (!call_ty
.walk()
.any(|t| matches!(t.unpack(), ty::GenericArgKind::Lifetime(_)))
|| if let ty::Alias(ty::Projection, _) = call_ty.kind() {
// FIXME: this isn't quite right with lifetimes on assoc types,
// but ignore for now. We will only suggest cloning if
// `<Ty as Trait>::Assoc: Clone`, which should keep false positives
// down to a managable ammount.
true
} else {
false
})
&& self.implements_clone(call_ty)
&& self.suggest_cloning_inner(err, call_ty, parent)
{
return;
}
prev = parent;
}
}
}
let ty = ty.peel_refs();

View File

@ -199,6 +199,10 @@ builtin_macros_format_use_positional = consider using a positional formatting ar
builtin_macros_global_asm_clobber_abi = `clobber_abi` cannot be used with `global_asm!`
builtin_macros_global_asm_unsupported_option = the `{$symbol}` option cannot be used with `global_asm!`
.label = the `{$symbol}` option is not meaningful for global-scoped inline assembly
.suggestion = remove this option
builtin_macros_invalid_crate_attribute = invalid crate attribute
builtin_macros_multiple_default_attrs = multiple `#[default]` attributes

View File

@ -310,6 +310,16 @@ fn err_duplicate_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
p.dcx().emit_err(errors::AsmOptAlreadyprovided { span, symbol, full_span });
}
/// Report an invalid option error.
///
/// This function must be called immediately after the option token is parsed.
/// Otherwise, the suggestion will be incorrect.
fn err_unsupported_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
// Tool-only output
let full_span = if p.token.kind == token::Comma { span.to(p.token.span) } else { span };
p.dcx().emit_err(errors::GlobalAsmUnsupportedOption { span, symbol, full_span });
}
/// Try to set the provided option in the provided `AsmArgs`.
/// If it is already set, report a duplicate option error.
///
@ -318,13 +328,16 @@ fn err_duplicate_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
fn try_set_option<'a>(
p: &Parser<'a>,
args: &mut AsmArgs,
is_global_asm: bool,
symbol: Symbol,
option: ast::InlineAsmOptions,
) {
if !args.options.contains(option) {
args.options |= option;
} else {
if is_global_asm && !ast::InlineAsmOptions::GLOBAL_OPTIONS.contains(option) {
err_unsupported_option(p, symbol, p.prev_token.span);
} else if args.options.contains(option) {
err_duplicate_option(p, symbol, p.prev_token.span);
} else {
args.options |= option;
}
}
@ -338,25 +351,33 @@ fn parse_options<'a>(
p.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
while !p.eat(&token::CloseDelim(Delimiter::Parenthesis)) {
if !is_global_asm && p.eat_keyword(sym::pure) {
try_set_option(p, args, sym::pure, ast::InlineAsmOptions::PURE);
} else if !is_global_asm && p.eat_keyword(sym::nomem) {
try_set_option(p, args, sym::nomem, ast::InlineAsmOptions::NOMEM);
} else if !is_global_asm && p.eat_keyword(sym::readonly) {
try_set_option(p, args, sym::readonly, ast::InlineAsmOptions::READONLY);
} else if !is_global_asm && p.eat_keyword(sym::preserves_flags) {
try_set_option(p, args, sym::preserves_flags, ast::InlineAsmOptions::PRESERVES_FLAGS);
} else if !is_global_asm && p.eat_keyword(sym::noreturn) {
try_set_option(p, args, sym::noreturn, ast::InlineAsmOptions::NORETURN);
} else if !is_global_asm && p.eat_keyword(sym::nostack) {
try_set_option(p, args, sym::nostack, ast::InlineAsmOptions::NOSTACK);
} else if !is_global_asm && p.eat_keyword(sym::may_unwind) {
try_set_option(p, args, kw::Raw, ast::InlineAsmOptions::MAY_UNWIND);
} else if p.eat_keyword(sym::att_syntax) {
try_set_option(p, args, sym::att_syntax, ast::InlineAsmOptions::ATT_SYNTAX);
} else if p.eat_keyword(kw::Raw) {
try_set_option(p, args, kw::Raw, ast::InlineAsmOptions::RAW);
} else {
const OPTIONS: [(Symbol, ast::InlineAsmOptions); ast::InlineAsmOptions::COUNT] = [
(sym::pure, ast::InlineAsmOptions::PURE),
(sym::nomem, ast::InlineAsmOptions::NOMEM),
(sym::readonly, ast::InlineAsmOptions::READONLY),
(sym::preserves_flags, ast::InlineAsmOptions::PRESERVES_FLAGS),
(sym::noreturn, ast::InlineAsmOptions::NORETURN),
(sym::nostack, ast::InlineAsmOptions::NOSTACK),
(sym::may_unwind, ast::InlineAsmOptions::MAY_UNWIND),
(sym::att_syntax, ast::InlineAsmOptions::ATT_SYNTAX),
(kw::Raw, ast::InlineAsmOptions::RAW),
];
'blk: {
for (symbol, option) in OPTIONS {
let kw_matched =
if !is_global_asm || ast::InlineAsmOptions::GLOBAL_OPTIONS.contains(option) {
p.eat_keyword(symbol)
} else {
p.eat_keyword_noexpect(symbol)
};
if kw_matched {
try_set_option(p, args, is_global_asm, symbol, option);
break 'blk;
}
}
return p.unexpected();
}

View File

@ -845,6 +845,17 @@ pub(crate) struct AsmOptAlreadyprovided {
pub(crate) full_span: Span,
}
#[derive(Diagnostic)]
#[diag(builtin_macros_global_asm_unsupported_option)]
pub(crate) struct GlobalAsmUnsupportedOption {
#[primary_span]
#[label]
pub(crate) span: Span,
pub(crate) symbol: Symbol,
#[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
pub(crate) full_span: Span,
}
#[derive(Diagnostic)]
#[diag(builtin_macros_test_runner_invalid)]
pub(crate) struct TestRunnerInvalid {

View File

@ -509,6 +509,13 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
BinOp::Ne => ScalarInt::FALSE,
_ => return None,
};
if value.const_.ty().is_floating_point() {
// Floating point equality does not follow bit-patterns.
// -0.0 and NaN both have special rules for equality,
// and therefore we cannot use integer comparisons for them.
// Avoid handling them, though this could be extended in the future.
return None;
}
let value = value.const_.normalize(self.tcx, self.param_env).try_to_scalar_int()?;
let conds = conditions.map(self.arena, |c| Condition {
value,

View File

@ -599,7 +599,7 @@ impl<'a> Parser<'a> {
/// If the next token is the given keyword, eats it and returns `true`.
/// Otherwise, returns `false`. An expectation is also added for diagnostics purposes.
// Public for rustfmt usage.
// Public for rustc_builtin_macros and rustfmt usage.
#[inline]
pub fn eat_keyword(&mut self, kw: Symbol) -> bool {
if self.check_keyword(kw) {
@ -631,8 +631,11 @@ impl<'a> Parser<'a> {
false
}
/// If the next token is the given keyword, eats it and returns `true`.
/// Otherwise, returns `false`. No expectation is added.
// Public for rustc_builtin_macros usage.
#[inline]
fn eat_keyword_noexpect(&mut self, kw: Symbol) -> bool {
pub fn eat_keyword_noexpect(&mut self, kw: Symbol) -> bool {
if self.token.is_keyword(kw) {
self.bump();
true

View File

@ -244,10 +244,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
self.tcx.dcx().emit_err(NakedFunctionsOperands { unsupported_operands });
}
let supported_options =
InlineAsmOptions::RAW | InlineAsmOptions::NORETURN | InlineAsmOptions::ATT_SYNTAX;
let unsupported_options = asm.options.difference(supported_options);
let unsupported_options = asm.options.difference(InlineAsmOptions::NAKED_OPTIONS);
if !unsupported_options.is_empty() {
self.tcx.dcx().emit_err(NakedFunctionsAsmOptions {
span,

View File

@ -578,7 +578,10 @@
# The "channel" for the Rust build to produce. The stable/beta channels only
# allow using stable features, whereas the nightly and dev channels allow using
# nightly features
#channel = "dev"
#
# If using tarball sources, default value for `channel` is taken from the `src/ci/channel` file;
# otherwise, it's "dev".
#channel = if "is a tarball source" { content of `src/ci/channel` file } else { "dev" }
# A descriptive string to be appended to `rustc --version` output, which is
# also used in places like debuginfo `DW_AT_producer`. This may be useful for

View File

@ -1277,7 +1277,7 @@ impl<T, A: Allocator> Vec<T, A> {
/// valid for zero sized reads if the vector didn't allocate.
///
/// The caller must ensure that the vector outlives the pointer this
/// function returns, or else it will end up pointing to garbage.
/// function returns, or else it will end up dangling.
/// Modifying the vector may cause its buffer to be reallocated,
/// which would also make any pointers to it invalid.
///
@ -1337,7 +1337,7 @@ impl<T, A: Allocator> Vec<T, A> {
/// raw pointer valid for zero sized reads if the vector didn't allocate.
///
/// The caller must ensure that the vector outlives the pointer this
/// function returns, or else it will end up pointing to garbage.
/// function returns, or else it will end up dangling.
/// Modifying the vector may cause its buffer to be reallocated,
/// which would also make any pointers to it invalid.
///

View File

@ -777,8 +777,51 @@ where
/// Convert a reference to a raw pointer.
///
/// This is equivalent to `r as *const T`, but is a bit safer since it will never silently change
/// type or mutability, in particular if the code is refactored.
/// For `r: &T`, `from_ref(r)` is equivalent to `r as *const T` (except for the caveat noted below),
/// but is a bit safer since it will never silently change type or mutability, in particular if the
/// code is refactored.
///
/// The caller must ensure that the pointee outlives the pointer this function returns, or else it
/// will end up dangling.
///
/// The caller must also ensure that the memory the pointer (non-transitively) points to is never
/// written to (except inside an `UnsafeCell`) using this pointer or any pointer derived from it. If
/// you need to mutate the pointee, use [`from_mut`]`. Specifically, to turn a mutable reference `m:
/// &mut T` into `*const T`, prefer `from_mut(m).cast_const()` to obtain a pointer that can later be
/// used for mutation.
///
/// ## Interaction with lifetime extension
///
/// Note that this has subtle interactions with the rules for lifetime extension of temporaries in
/// tail expressions. This code is valid, albeit in a non-obvious way:
/// ```rust
/// # type T = i32;
/// # fn foo() -> T { 42 }
/// // The temporary holding the return value of `foo` has its lifetime extended,
/// // because the surrounding expression involves no function call.
/// let p = &foo() as *const T;
/// unsafe { p.read() };
/// ```
/// Naively replacing the cast with `from_ref` is not valid:
/// ```rust,no_run
/// # use std::ptr;
/// # type T = i32;
/// # fn foo() -> T { 42 }
/// // The temporary holding the return value of `foo` does *not* have its lifetime extended,
/// // because the surrounding expression involves no function call.
/// let p = ptr::from_ref(&foo());
/// unsafe { p.read() }; // UB! Reading from a dangling pointer ⚠️
/// ```
/// The recommended way to write this code is to avoid relying on lifetime extension
/// when raw pointers are involved:
/// ```rust
/// # use std::ptr;
/// # type T = i32;
/// # fn foo() -> T { 42 }
/// let x = foo();
/// let p = ptr::from_ref(&x);
/// unsafe { p.read() };
/// ```
#[inline(always)]
#[must_use]
#[stable(feature = "ptr_from_ref", since = "1.76.0")]
@ -791,8 +834,45 @@ pub const fn from_ref<T: ?Sized>(r: &T) -> *const T {
/// Convert a mutable reference to a raw pointer.
///
/// This is equivalent to `r as *mut T`, but is a bit safer since it will never silently change
/// type or mutability, in particular if the code is refactored.
/// For `r: &mut T`, `from_mut(r)` is equivalent to `r as *mut T` (except for the caveat noted
/// below), but is a bit safer since it will never silently change type or mutability, in particular
/// if the code is refactored.
///
/// The caller must ensure that the pointee outlives the pointer this function returns, or else it
/// will end up dangling.
///
/// ## Interaction with lifetime extension
///
/// Note that this has subtle interactions with the rules for lifetime extension of temporaries in
/// tail expressions. This code is valid, albeit in a non-obvious way:
/// ```rust
/// # type T = i32;
/// # fn foo() -> T { 42 }
/// // The temporary holding the return value of `foo` has its lifetime extended,
/// // because the surrounding expression involves no function call.
/// let p = &mut foo() as *mut T;
/// unsafe { p.write(T::default()) };
/// ```
/// Naively replacing the cast with `from_mut` is not valid:
/// ```rust,no_run
/// # use std::ptr;
/// # type T = i32;
/// # fn foo() -> T { 42 }
/// // The temporary holding the return value of `foo` does *not* have its lifetime extended,
/// // because the surrounding expression involves no function call.
/// let p = ptr::from_mut(&mut foo());
/// unsafe { p.write(T::default()) }; // UB! Writing to a dangling pointer ⚠️
/// ```
/// The recommended way to write this code is to avoid relying on lifetime extension
/// when raw pointers are involved:
/// ```rust
/// # use std::ptr;
/// # type T = i32;
/// # fn foo() -> T { 42 }
/// let mut x = foo();
/// let p = ptr::from_mut(&mut x);
/// unsafe { p.write(T::default()) };
/// ```
#[inline(always)]
#[must_use]
#[stable(feature = "ptr_from_ref", since = "1.76.0")]

View File

@ -726,7 +726,7 @@ impl<T> [T] {
/// Returns a raw pointer to the slice's buffer.
///
/// The caller must ensure that the slice outlives the pointer this
/// function returns, or else it will end up pointing to garbage.
/// function returns, or else it will end up dangling.
///
/// The caller must also ensure that the memory the pointer (non-transitively) points to
/// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer
@ -761,7 +761,7 @@ impl<T> [T] {
/// Returns an unsafe mutable pointer to the slice's buffer.
///
/// The caller must ensure that the slice outlives the pointer this
/// function returns, or else it will end up pointing to garbage.
/// function returns, or else it will end up dangling.
///
/// Modifying the container referenced by this slice may cause its buffer
/// to be reallocated, which would also make any pointers to it invalid.

View File

@ -20,6 +20,8 @@ use crate::{fmt, io};
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "solaris",
target_os = "illumos",
target_os = "haiku",
target_os = "nto",
))]
@ -31,6 +33,8 @@ use libc::MSG_NOSIGNAL;
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "solaris",
target_os = "illumos",
target_os = "haiku",
target_os = "nto",
)))]

View File

@ -42,6 +42,7 @@ cfg_if::cfg_if! {
target_os = "hurd",
target_os = "dragonfly", target_os = "freebsd",
target_os = "openbsd", target_os = "netbsd",
target_os = "solaris", target_os = "illumos",
target_os = "haiku", target_os = "nto"))] {
use libc::MSG_NOSIGNAL;
} else {

View File

@ -215,4 +215,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
severity: ChangeSeverity::Info,
summary: "Removed android-ndk r25b support in favor of android-ndk r26d.",
},
ChangeInfo {
change_id: 125181,
severity: ChangeSeverity::Warning,
summary: "For tarball sources, default value for `rust.channel` will be taken from `src/ci/channel` file.",
},
];

View File

@ -1,34 +0,0 @@
//@ compile-flags: -C no-prepopulate-passes -O -Z mir-opt-level=3 -Zunsound-mir-opts
// Ensure that `x?` has no overhead on `Result<T, E>` due to identity `match`es in lowering.
// This requires inlining to trigger the MIR optimizations in `SimplifyArmIdentity`.
#![crate_type = "lib"]
type R = Result<u64, i32>;
// This was written to the `?` from `try_trait`, but `try_trait_v2` uses a different structure,
// so the relevant desugar is copied inline in order to keep the test testing the same thing.
// FIXME(#85133): while this might be useful for `r#try!`, it would be nice to have a MIR
// optimization that picks up the `?` desugaring, as `SimplifyArmIdentity` does not.
#[no_mangle]
pub fn try_identity(x: R) -> R {
// CHECK: start:
// FIXME(JakobDegen): Broken by deaggregation change CHECK-NOT\: br {{.*}}
// CHECK ret void
let y = match into_result(x) {
Err(e) => return from_error(From::from(e)),
Ok(v) => v,
};
Ok(y)
}
#[inline]
fn into_result<T, E>(r: Result<T, E>) -> Result<T, E> {
r
}
#[inline]
fn from_error<T, E>(e: E) -> Result<T, E> {
Err(e)
}

View File

@ -0,0 +1,59 @@
- // MIR for `floats` before JumpThreading
+ // MIR for `floats` after JumpThreading
fn floats() -> u32 {
let mut _0: u32;
let _1: f64;
let mut _2: bool;
let mut _3: bool;
let mut _4: f64;
scope 1 {
debug x => _1;
}
bb0: {
StorageLive(_1);
StorageLive(_2);
_2 = const true;
- switchInt(move _2) -> [0: bb2, otherwise: bb1];
+ goto -> bb1;
}
bb1: {
_1 = const -0f64;
goto -> bb3;
}
bb2: {
_1 = const 1f64;
goto -> bb3;
}
bb3: {
StorageDead(_2);
StorageLive(_3);
StorageLive(_4);
_4 = _1;
_3 = Eq(move _4, const 0f64);
switchInt(move _3) -> [0: bb5, otherwise: bb4];
}
bb4: {
StorageDead(_4);
_0 = const 0_u32;
goto -> bb6;
}
bb5: {
StorageDead(_4);
_0 = const 1_u32;
goto -> bb6;
}
bb6: {
StorageDead(_3);
StorageDead(_1);
return;
}
}

View File

@ -0,0 +1,59 @@
- // MIR for `floats` before JumpThreading
+ // MIR for `floats` after JumpThreading
fn floats() -> u32 {
let mut _0: u32;
let _1: f64;
let mut _2: bool;
let mut _3: bool;
let mut _4: f64;
scope 1 {
debug x => _1;
}
bb0: {
StorageLive(_1);
StorageLive(_2);
_2 = const true;
- switchInt(move _2) -> [0: bb2, otherwise: bb1];
+ goto -> bb1;
}
bb1: {
_1 = const -0f64;
goto -> bb3;
}
bb2: {
_1 = const 1f64;
goto -> bb3;
}
bb3: {
StorageDead(_2);
StorageLive(_3);
StorageLive(_4);
_4 = _1;
_3 = Eq(move _4, const 0f64);
switchInt(move _3) -> [0: bb5, otherwise: bb4];
}
bb4: {
StorageDead(_4);
_0 = const 0_u32;
goto -> bb6;
}
bb5: {
StorageDead(_4);
_0 = const 1_u32;
goto -> bb6;
}
bb6: {
StorageDead(_3);
StorageDead(_1);
return;
}
}

View File

@ -521,6 +521,16 @@ fn aggregate_copy() -> u32 {
if c == 2 { b.0 } else { 13 }
}
fn floats() -> u32 {
// CHECK-LABEL: fn floats(
// CHECK: switchInt(
// Test for issue #128243, where float equality was assumed to be bitwise.
// When adding float support, it must be ensured that this continues working properly.
let x = if true { -0.0 } else { 1.0 };
if x == 0.0 { 0 } else { 1 }
}
fn main() {
// CHECK-LABEL: fn main(
too_complex(Ok(0));
@ -535,6 +545,7 @@ fn main() {
disappearing_bb(7);
aggregate(7);
assume(7, false);
floats();
}
// EMIT_MIR jump_threading.too_complex.JumpThreading.diff
@ -550,3 +561,4 @@ fn main() {
// EMIT_MIR jump_threading.aggregate.JumpThreading.diff
// EMIT_MIR jump_threading.assume.JumpThreading.diff
// EMIT_MIR jump_threading.aggregate_copy.JumpThreading.diff
// EMIT_MIR jump_threading.floats.JumpThreading.diff

View File

@ -1,89 +0,0 @@
- // MIR for `id_try` before SimplifyArmIdentity
+ // MIR for `id_try` after SimplifyArmIdentity
fn id_try(_1: Result<u8, i32>) -> Result<u8, i32> {
debug r => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:11: +0:12
let mut _0: std::result::Result<u8, i32>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:34: +0:49
let _2: u8; // in scope 0 at $DIR/simplify-arm.rs:+1:9: +1:10
let mut _3: std::result::Result<u8, i32>; // in scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
let mut _4: std::result::Result<u8, i32>; // in scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
let mut _5: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:15
let _6: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14
let mut _7: !; // in scope 0 at $DIR/simplify-arm.rs:+2:19: +2:51
let mut _8: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:37: +2:50
let mut _9: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:48: +2:49
let _10: u8; // in scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13
let mut _11: u8; // in scope 0 at $DIR/simplify-arm.rs:+5:8: +5:9
scope 1 {
debug x => _2; // in scope 1 at $DIR/simplify-arm.rs:+1:9: +1:10
}
scope 2 {
debug e => _6; // in scope 2 at $DIR/simplify-arm.rs:+2:13: +2:14
scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify-arm.rs:37:37: 37:50
debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
}
scope 6 (inlined from_error::<u8, i32>) { // at $DIR/simplify-arm.rs:37:26: 37:51
debug e => _8; // in scope 6 at $DIR/simplify-arm.rs:27:21: 27:22
}
}
scope 3 {
debug v => _10; // in scope 3 at $DIR/simplify-arm.rs:+3:12: +3:13
}
scope 4 (inlined into_result::<u8, i32>) { // at $DIR/simplify-arm.rs:36:19: 36:33
debug r => _4; // in scope 4 at $DIR/simplify-arm.rs:23:22: 23:23
}
bb0: {
StorageLive(_2); // scope 0 at $DIR/simplify-arm.rs:+1:9: +1:10
StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
StorageLive(_4); // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
_4 = _1; // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
_3 = move _4; // scope 4 at $DIR/simplify-arm.rs:24:5: 24:6
StorageDead(_4); // scope 0 at $DIR/simplify-arm.rs:+1:32: +1:33
_5 = discriminant(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:13: +1:33
}
bb1: {
StorageLive(_10); // scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13
_10 = ((_3 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13
_2 = _10; // scope 3 at $DIR/simplify-arm.rs:+3:18: +3:19
StorageDead(_10); // scope 0 at $DIR/simplify-arm.rs:+3:18: +3:19
StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7
StorageLive(_11); // scope 1 at $DIR/simplify-arm.rs:+5:8: +5:9
_11 = _2; // scope 1 at $DIR/simplify-arm.rs:+5:8: +5:9
Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10
((_0 as Ok).0: u8) = move _11; // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10
discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10
StorageDead(_11); // scope 1 at $DIR/simplify-arm.rs:+5:9: +5:10
StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:+6:1: +6:2
goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2
}
bb2: {
unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
}
bb3: {
StorageLive(_6); // scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14
_6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14
StorageLive(_8); // scope 2 at $DIR/simplify-arm.rs:+2:37: +2:50
StorageLive(_9); // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49
_9 = _6; // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49
_8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
StorageDead(_9); // scope 2 at $DIR/simplify-arm.rs:+2:49: +2:50
((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify-arm.rs:28:9: 28:10
Deinit(_0); // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11
discriminant(_0) = 1; // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11
StorageDead(_8); // scope 2 at $DIR/simplify-arm.rs:+2:50: +2:51
StorageDead(_6); // scope 0 at $DIR/simplify-arm.rs:+2:50: +2:51
StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7
StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:+6:1: +6:2
goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2
}
bb4: {
return; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2
}
}

View File

@ -1,89 +0,0 @@
- // MIR for `id_try` before SimplifyBranchSame
+ // MIR for `id_try` after SimplifyBranchSame
fn id_try(_1: Result<u8, i32>) -> Result<u8, i32> {
debug r => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:11: +0:12
let mut _0: std::result::Result<u8, i32>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:34: +0:49
let _2: u8; // in scope 0 at $DIR/simplify-arm.rs:+1:9: +1:10
let mut _3: std::result::Result<u8, i32>; // in scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
let mut _4: std::result::Result<u8, i32>; // in scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
let mut _5: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:15
let _6: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14
let mut _7: !; // in scope 0 at $DIR/simplify-arm.rs:+2:19: +2:51
let mut _8: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:37: +2:50
let mut _9: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:48: +2:49
let _10: u8; // in scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13
let mut _11: u8; // in scope 0 at $DIR/simplify-arm.rs:+5:8: +5:9
scope 1 {
debug x => _2; // in scope 1 at $DIR/simplify-arm.rs:+1:9: +1:10
}
scope 2 {
debug e => _6; // in scope 2 at $DIR/simplify-arm.rs:+2:13: +2:14
scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify-arm.rs:37:37: 37:50
debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
}
scope 6 (inlined from_error::<u8, i32>) { // at $DIR/simplify-arm.rs:37:26: 37:51
debug e => _8; // in scope 6 at $DIR/simplify-arm.rs:27:21: 27:22
}
}
scope 3 {
debug v => _10; // in scope 3 at $DIR/simplify-arm.rs:+3:12: +3:13
}
scope 4 (inlined into_result::<u8, i32>) { // at $DIR/simplify-arm.rs:36:19: 36:33
debug r => _4; // in scope 4 at $DIR/simplify-arm.rs:23:22: 23:23
}
bb0: {
StorageLive(_2); // scope 0 at $DIR/simplify-arm.rs:+1:9: +1:10
StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
StorageLive(_4); // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
_4 = _1; // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
_3 = move _4; // scope 4 at $DIR/simplify-arm.rs:24:5: 24:6
StorageDead(_4); // scope 0 at $DIR/simplify-arm.rs:+1:32: +1:33
_5 = discriminant(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:13: +1:33
}
bb1: {
StorageLive(_10); // scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13
_10 = ((_3 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13
_2 = _10; // scope 3 at $DIR/simplify-arm.rs:+3:18: +3:19
StorageDead(_10); // scope 0 at $DIR/simplify-arm.rs:+3:18: +3:19
StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7
StorageLive(_11); // scope 1 at $DIR/simplify-arm.rs:+5:8: +5:9
_11 = _2; // scope 1 at $DIR/simplify-arm.rs:+5:8: +5:9
Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10
((_0 as Ok).0: u8) = move _11; // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10
discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10
StorageDead(_11); // scope 1 at $DIR/simplify-arm.rs:+5:9: +5:10
StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:+6:1: +6:2
goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2
}
bb2: {
unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
}
bb3: {
StorageLive(_6); // scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14
_6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14
StorageLive(_8); // scope 2 at $DIR/simplify-arm.rs:+2:37: +2:50
StorageLive(_9); // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49
_9 = _6; // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49
_8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
StorageDead(_9); // scope 2 at $DIR/simplify-arm.rs:+2:49: +2:50
((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify-arm.rs:28:9: 28:10
Deinit(_0); // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11
discriminant(_0) = 1; // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11
StorageDead(_8); // scope 2 at $DIR/simplify-arm.rs:+2:50: +2:51
StorageDead(_6); // scope 0 at $DIR/simplify-arm.rs:+2:50: +2:51
StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7
StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:+6:1: +6:2
goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2
}
bb4: {
return; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2
}
}

View File

@ -1,50 +0,0 @@
// skip-filecheck
//@ compile-flags: -Z mir-opt-level=3 -Zunsound-mir-opts
// EMIT_MIR simplify_arm.id.SimplifyArmIdentity.diff
// EMIT_MIR simplify_arm.id.SimplifyBranchSame.diff
// EMIT_MIR simplify_arm.id_result.SimplifyArmIdentity.diff
// EMIT_MIR simplify_arm.id_result.SimplifyBranchSame.diff
// EMIT_MIR simplify_arm.id_try.SimplifyArmIdentity.diff
// EMIT_MIR simplify_arm.id_try.SimplifyBranchSame.diff
//@ ignore-test This pass is broken since deaggregation changed
fn id(o: Option<u8>) -> Option<u8> {
match o {
Some(v) => Some(v),
None => None,
}
}
fn id_result(r: Result<u8, i32>) -> Result<u8, i32> {
match r {
Ok(x) => Ok(x),
Err(y) => Err(y),
}
}
fn into_result<T, E>(r: Result<T, E>) -> Result<T, E> {
r
}
fn from_error<T, E>(e: E) -> Result<T, E> {
Err(e)
}
// This was written to the `?` from `try_trait`, but `try_trait_v2` uses a different structure,
// so the relevant desugar is copied inline in order to keep the test testing the same thing.
// FIXME(#85133): while this might be useful for `r#try!`, it would be nice to have a MIR
// optimization that picks up the `?` desugaring, as `SimplifyArmIdentity` does not.
fn id_try(r: Result<u8, i32>) -> Result<u8, i32> {
let x = match into_result(r) {
Err(e) => return from_error(From::from(e)),
Ok(v) => v,
};
Ok(x)
}
fn main() {
id(None);
id_result(Ok(4));
id_try(Ok(4));
}

View File

@ -1,26 +0,0 @@
// skip-filecheck
// Checks that `SimplifyArmIdentity` is not applied if enums have incompatible layouts.
// Regression test for issue #66856.
//
//@ compile-flags: -Zmir-opt-level=3
// EMIT_MIR_FOR_EACH_BIT_WIDTH
//@ ignore-test This pass is broken since deaggregation changed
enum Src {
Foo(u8),
Bar,
}
enum Dst {
Foo(u8),
}
// EMIT_MIR simplify_arm_identity.main.SimplifyArmIdentity.diff
fn main() {
let e: Src = Src::Foo(0);
let _: Dst = match e {
Src::Foo(x) => Dst::Foo(x),
Src::Bar => Dst::Foo(0),
};
}

View File

@ -1,44 +0,0 @@
// skip-filecheck
//@ compile-flags: -Zmir-opt-level=1 -Zunsound-mir-opts
//@ ignore-test
// FIXME: the pass is unsound and causes ICEs in the MIR validator
// EMIT_MIR simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff
use std::ptr::NonNull;
pub struct LinkedList {
head: Option<NonNull<Node>>,
tail: Option<NonNull<Node>>,
}
pub struct Node {
next: Option<NonNull<Node>>,
}
impl LinkedList {
pub fn new() -> Self {
Self { head: None, tail: None }
}
pub fn append(&mut self, other: &mut Self) {
match self.tail {
None => {}
Some(mut tail) => {
// `as_mut` is okay here because we have exclusive access to the entirety
// of both lists.
if let Some(other_head) = other.head.take() {
unsafe {
tail.as_mut().next = Some(other_head);
}
}
}
}
}
}
fn main() {
let mut one = LinkedList::new();
let mut two = LinkedList::new();
one.append(&mut two);
}

View File

@ -1,104 +0,0 @@
- // MIR for `<impl at $DIR/simplify_try_if_let.rs:15:1: 34:2>::append` before SimplifyArmIdentity
+ // MIR for `<impl at $DIR/simplify_try_if_let.rs:15:1: 34:2>::append` after SimplifyArmIdentity
fn <impl at $DIR/simplify_try_if_let.rs:15:1: 34:2>::append(_1: &mut LinkedList, _2: &mut LinkedList) -> () {
debug self => _1; // in scope 0 at $DIR/simplify_try_if_let.rs:20:19: 20:28
debug other => _2; // in scope 0 at $DIR/simplify_try_if_let.rs:20:30: 20:35
let mut _0: (); // return place in scope 0 at $DIR/simplify_try_if_let.rs:20:48: 20:48
let mut _3: isize; // in scope 0 at $DIR/simplify_try_if_let.rs:22:13: 22:17
let mut _4: std::ptr::NonNull<Node>; // in scope 0 at $DIR/simplify_try_if_let.rs:23:18: 23:26
let mut _5: std::option::Option<std::ptr::NonNull<Node>>; // in scope 0 at $DIR/simplify_try_if_let.rs:26:43: 26:60
let mut _6: &mut std::option::Option<std::ptr::NonNull<Node>>; // in scope 0 at $DIR/simplify_try_if_let.rs:26:43: 26:53
let mut _7: isize; // in scope 0 at $DIR/simplify_try_if_let.rs:26:24: 26:40
let mut _9: std::option::Option<std::ptr::NonNull<Node>>; // in scope 0 at $DIR/simplify_try_if_let.rs:28:46: 28:62
let mut _10: std::ptr::NonNull<Node>; // in scope 0 at $DIR/simplify_try_if_let.rs:28:51: 28:61
let mut _11: &mut Node; // in scope 0 at $DIR/simplify_try_if_let.rs:28:25: 28:38
let mut _12: &mut std::ptr::NonNull<Node>; // in scope 0 at $DIR/simplify_try_if_let.rs:28:25: 28:29
scope 1 {
debug tail => _4; // in scope 1 at $DIR/simplify_try_if_let.rs:23:18: 23:26
let _8: std::ptr::NonNull<Node>; // in scope 1 at $DIR/simplify_try_if_let.rs:26:29: 26:39
scope 2 {
- debug other_head => _8; // in scope 2 at $DIR/simplify_try_if_let.rs:26:29: 26:39
+ debug other_head => ((_9 as Some).0: std::ptr::NonNull<Node>); // in scope 2 at $DIR/simplify_try_if_let.rs:26:29: 26:39
scope 3 {
}
}
}
bb0: {
_3 = discriminant(((*_1).1: std::option::Option<std::ptr::NonNull<Node>>)); // scope 0 at $DIR/simplify_try_if_let.rs:22:13: 22:17
switchInt(move _3) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_try_if_let.rs:22:13: 22:17
}
bb1: {
StorageLive(_4); // scope 0 at $DIR/simplify_try_if_let.rs:23:18: 23:26
_4 = ((((*_1).1: std::option::Option<std::ptr::NonNull<Node>>) as Some).0: std::ptr::NonNull<Node>); // scope 0 at $DIR/simplify_try_if_let.rs:23:18: 23:26
StorageLive(_5); // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:60
StorageLive(_6); // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:53
_6 = &mut ((*_2).0: std::option::Option<std::ptr::NonNull<Node>>); // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:53
_5 = Option::<NonNull<Node>>::take(move _6) -> bb4; // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:60
// mir::Constant
// + span: $DIR/simplify_try_if_let.rs:26:54: 26:58
// + literal: Const { ty: for<'r> fn(&'r mut std::option::Option<std::ptr::NonNull<Node>>) -> std::option::Option<std::ptr::NonNull<Node>> {std::option::Option::<std::ptr::NonNull<Node>>::take}, val: Value(Scalar(<ZST>)) }
}
bb2: {
unreachable; // scope 0 at $DIR/simplify_try_if_let.rs:21:15: 21:24
}
bb3: {
_0 = const (); // scope 0 at $DIR/simplify_try_if_let.rs:22:21: 22:24
goto -> bb9; // scope 0 at $DIR/simplify_try_if_let.rs:21:9: 32:10
}
bb4: {
StorageDead(_6); // scope 1 at $DIR/simplify_try_if_let.rs:26:59: 26:60
_7 = discriminant(_5); // scope 1 at $DIR/simplify_try_if_let.rs:26:24: 26:40
switchInt(move _7) -> [1_isize: bb6, otherwise: bb5]; // scope 1 at $DIR/simplify_try_if_let.rs:26:24: 26:40
}
bb5: {
_0 = const (); // scope 1 at $DIR/simplify_try_if_let.rs:26:17: 30:18
goto -> bb8; // scope 1 at $DIR/simplify_try_if_let.rs:26:17: 30:18
}
bb6: {
StorageLive(_8); // scope 1 at $DIR/simplify_try_if_let.rs:26:29: 26:39
_8 = ((_5 as Some).0: std::ptr::NonNull<Node>); // scope 1 at $DIR/simplify_try_if_let.rs:26:29: 26:39
StorageLive(_9); // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62
- StorageLive(_10); // scope 3 at $DIR/simplify_try_if_let.rs:28:51: 28:61
- _10 = _8; // scope 3 at $DIR/simplify_try_if_let.rs:28:51: 28:61
- ((_9 as Some).0: std::ptr::NonNull<Node>) = move _10; // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62
- discriminant(_9) = 1; // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62
- StorageDead(_10); // scope 3 at $DIR/simplify_try_if_let.rs:28:61: 28:62
+ _9 = move _5; // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62
StorageLive(_11); // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:38
StorageLive(_12); // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:29
_12 = &mut _4; // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:29
_11 = NonNull::<Node>::as_mut(move _12) -> bb7; // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:38
// mir::Constant
// + span: $DIR/simplify_try_if_let.rs:28:30: 28:36
// + literal: Const { ty: for<'r> unsafe fn(&'r mut std::ptr::NonNull<Node>) -> &'r mut Node {std::ptr::NonNull::<Node>::as_mut}, val: Value(Scalar(<ZST>)) }
}
bb7: {
StorageDead(_12); // scope 3 at $DIR/simplify_try_if_let.rs:28:37: 28:38
((*_11).0: std::option::Option<std::ptr::NonNull<Node>>) = move _9; // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:62
StorageDead(_9); // scope 3 at $DIR/simplify_try_if_let.rs:28:61: 28:62
StorageDead(_11); // scope 3 at $DIR/simplify_try_if_let.rs:28:62: 28:63
_0 = const (); // scope 3 at $DIR/simplify_try_if_let.rs:27:21: 29:22
StorageDead(_8); // scope 1 at $DIR/simplify_try_if_let.rs:30:17: 30:18
goto -> bb8; // scope 1 at $DIR/simplify_try_if_let.rs:26:17: 30:18
}
bb8: {
StorageDead(_5); // scope 1 at $DIR/simplify_try_if_let.rs:31:13: 31:14
StorageDead(_4); // scope 0 at $DIR/simplify_try_if_let.rs:31:13: 31:14
goto -> bb9; // scope 0 at $DIR/simplify_try_if_let.rs:21:9: 32:10
}
bb9: {
return; // scope 0 at $DIR/simplify_try_if_let.rs:33:6: 33:6
}
}

View File

@ -0,0 +1,24 @@
// Checks that the search changes the title
include: "utils.goml"
go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
store-value: (title, "test_docs - Rust")
assert-document-property: {"title": |title|}
write-into: (".search-input", "test")
// To be SURE that the search will be run.
press-key: 'Enter'
wait-for: "#crate-search"
assert-document-property: {"title": '"test" Search - Rust'}
set-property: (".search-input", {"value": "another one"})
// To be SURE that the search will be run.
press-key: 'Enter'
wait-for: "#crate-search"
assert-document-property: {"title": '"another one" Search - Rust'}
press-key: "Escape"
assert-document-property: {"title": |title|}

View File

@ -26,14 +26,14 @@ fn main() {
}
global_asm!("", options(nomem));
//~^ ERROR expected one of
//~^ ERROR the `nomem` option cannot be used with `global_asm!`
global_asm!("", options(readonly));
//~^ ERROR expected one of
//~^ ERROR the `readonly` option cannot be used with `global_asm!`
global_asm!("", options(noreturn));
//~^ ERROR expected one of
//~^ ERROR the `noreturn` option cannot be used with `global_asm!`
global_asm!("", options(pure));
//~^ ERROR expected one of
//~^ ERROR the `pure` option cannot be used with `global_asm!`
global_asm!("", options(nostack));
//~^ ERROR expected one of
//~^ ERROR the `nostack` option cannot be used with `global_asm!`
global_asm!("", options(preserves_flags));
//~^ ERROR expected one of
//~^ ERROR the `preserves_flags` option cannot be used with `global_asm!`

View File

@ -36,41 +36,41 @@ LL | asm!("{}", out(reg) foo, clobber_abi("C"));
| |
| generic outputs
error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
error: the `nomem` option cannot be used with `global_asm!`
--> $DIR/bad-options.rs:28:25
|
LL | global_asm!("", options(nomem));
| ^^^^^ expected one of `)`, `att_syntax`, or `raw`
| ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly
error: expected one of `)`, `att_syntax`, or `raw`, found `readonly`
error: the `readonly` option cannot be used with `global_asm!`
--> $DIR/bad-options.rs:30:25
|
LL | global_asm!("", options(readonly));
| ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
| ^^^^^^^^ the `readonly` option is not meaningful for global-scoped inline assembly
error: expected one of `)`, `att_syntax`, or `raw`, found `noreturn`
error: the `noreturn` option cannot be used with `global_asm!`
--> $DIR/bad-options.rs:32:25
|
LL | global_asm!("", options(noreturn));
| ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
| ^^^^^^^^ the `noreturn` option is not meaningful for global-scoped inline assembly
error: expected one of `)`, `att_syntax`, or `raw`, found `pure`
error: the `pure` option cannot be used with `global_asm!`
--> $DIR/bad-options.rs:34:25
|
LL | global_asm!("", options(pure));
| ^^^^ expected one of `)`, `att_syntax`, or `raw`
| ^^^^ the `pure` option is not meaningful for global-scoped inline assembly
error: expected one of `)`, `att_syntax`, or `raw`, found `nostack`
error: the `nostack` option cannot be used with `global_asm!`
--> $DIR/bad-options.rs:36:25
|
LL | global_asm!("", options(nostack));
| ^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
| ^^^^^^^ the `nostack` option is not meaningful for global-scoped inline assembly
error: expected one of `)`, `att_syntax`, or `raw`, found `preserves_flags`
error: the `preserves_flags` option cannot be used with `global_asm!`
--> $DIR/bad-options.rs:38:25
|
LL | global_asm!("", options(preserves_flags));
| ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
| ^^^^^^^^^^^^^^^ the `preserves_flags` option is not meaningful for global-scoped inline assembly
error: invalid ABI for `clobber_abi`
--> $DIR/bad-options.rs:20:18

View File

@ -98,8 +98,10 @@ global_asm!("", options(FOO));
//~^ ERROR expected one of
global_asm!("", options(nomem FOO));
//~^ ERROR expected one of
//~| ERROR the `nomem` option cannot be used with `global_asm!`
global_asm!("", options(nomem, FOO));
//~^ ERROR expected one of
//~| ERROR the `nomem` option cannot be used with `global_asm!`
global_asm!("{}", options(), const FOO);
global_asm!("", clobber_abi(FOO));
//~^ ERROR expected string literal

View File

@ -218,56 +218,68 @@ error: expected one of `)`, `att_syntax`, or `raw`, found `FOO`
LL | global_asm!("", options(FOO));
| ^^^ expected one of `)`, `att_syntax`, or `raw`
error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
error: the `nomem` option cannot be used with `global_asm!`
--> $DIR/parse-error.rs:99:25
|
LL | global_asm!("", options(nomem FOO));
| ^^^^^ expected one of `)`, `att_syntax`, or `raw`
| ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly
error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
--> $DIR/parse-error.rs:101:25
error: expected one of `)` or `,`, found `FOO`
--> $DIR/parse-error.rs:99:31
|
LL | global_asm!("", options(nomem FOO));
| ^^^ expected one of `)` or `,`
error: the `nomem` option cannot be used with `global_asm!`
--> $DIR/parse-error.rs:102:25
|
LL | global_asm!("", options(nomem, FOO));
| ^^^^^ expected one of `)`, `att_syntax`, or `raw`
| ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly
error: expected one of `)`, `att_syntax`, or `raw`, found `FOO`
--> $DIR/parse-error.rs:102:32
|
LL | global_asm!("", options(nomem, FOO));
| ^^^ expected one of `)`, `att_syntax`, or `raw`
error: expected string literal
--> $DIR/parse-error.rs:104:29
--> $DIR/parse-error.rs:106:29
|
LL | global_asm!("", clobber_abi(FOO));
| ^^^ not a string literal
error: expected one of `)` or `,`, found `FOO`
--> $DIR/parse-error.rs:106:33
--> $DIR/parse-error.rs:108:33
|
LL | global_asm!("", clobber_abi("C" FOO));
| ^^^ expected one of `)` or `,`
error: expected string literal
--> $DIR/parse-error.rs:108:34
--> $DIR/parse-error.rs:110:34
|
LL | global_asm!("", clobber_abi("C", FOO));
| ^^^ not a string literal
error: `clobber_abi` cannot be used with `global_asm!`
--> $DIR/parse-error.rs:110:19
--> $DIR/parse-error.rs:112:19
|
LL | global_asm!("{}", clobber_abi("C"), const FOO);
| ^^^^^^^^^^^^^^^^
error: `clobber_abi` cannot be used with `global_asm!`
--> $DIR/parse-error.rs:112:28
--> $DIR/parse-error.rs:114:28
|
LL | global_asm!("", options(), clobber_abi("C"));
| ^^^^^^^^^^^^^^^^
error: `clobber_abi` cannot be used with `global_asm!`
--> $DIR/parse-error.rs:114:30
--> $DIR/parse-error.rs:116:30
|
LL | global_asm!("{}", options(), clobber_abi("C"), const FOO);
| ^^^^^^^^^^^^^^^^
error: duplicate argument named `a`
--> $DIR/parse-error.rs:116:35
--> $DIR/parse-error.rs:118:35
|
LL | global_asm!("{a}", a = const FOO, a = const BAR);
| ------------- ^^^^^^^^^^^^^ duplicate argument
@ -275,7 +287,7 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR);
| previously here
error: argument never used
--> $DIR/parse-error.rs:116:35
--> $DIR/parse-error.rs:118:35
|
LL | global_asm!("{a}", a = const FOO, a = const BAR);
| ^^^^^^^^^^^^^ argument never used
@ -283,19 +295,19 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR);
= help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"`
error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `""`
--> $DIR/parse-error.rs:119:28
--> $DIR/parse-error.rs:121:28
|
LL | global_asm!("", options(), "");
| ^^ expected one of `clobber_abi`, `const`, `options`, or `sym`
error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `"{}"`
--> $DIR/parse-error.rs:121:30
--> $DIR/parse-error.rs:123:30
|
LL | global_asm!("{}", const FOO, "{}", const FOO);
| ^^^^ expected one of `clobber_abi`, `const`, `options`, or `sym`
error: asm template must be a string literal
--> $DIR/parse-error.rs:123:13
--> $DIR/parse-error.rs:125:13
|
LL | global_asm!(format!("{{{}}}", 0), const FOO);
| ^^^^^^^^^^^^^^^^^^^^
@ -303,7 +315,7 @@ LL | global_asm!(format!("{{{}}}", 0), const FOO);
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
error: asm template must be a string literal
--> $DIR/parse-error.rs:125:20
--> $DIR/parse-error.rs:127:20
|
LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
| ^^^^^^^^^^^^^^^^^^^^
@ -398,6 +410,6 @@ help: consider using `const` instead of `let`
LL | const bar: /* Type */ = 0;
| ~~~~~ ++++++++++++
error: aborting due to 57 previous errors
error: aborting due to 59 previous errors
For more information about this error, try `rustc --explain E0435`.

View File

@ -111,11 +111,15 @@ global_asm!("{}", const);
global_asm!("{}", const(reg) FOO);
//~^ ERROR expected one of
global_asm!("", options(FOO));
//~^ ERROR expected one of
//~^ ERROR expected one of `)`, `att_syntax`, or `raw`, found `FOO`
global_asm!("", options(FOO,));
//~^ ERROR expected one of `)`, `att_syntax`, or `raw`, found `FOO`
global_asm!("", options(nomem FOO));
//~^ ERROR expected one of
//~^ ERROR the `nomem` option cannot be used with `global_asm!`
//~| ERROR expected one of `)` or `,`, found `FOO`
global_asm!("", options(nomem, FOO));
//~^ ERROR expected one of
//~^ ERROR the `nomem` option cannot be used with `global_asm!`
//~| ERROR expected one of `)`, `att_syntax`, or `raw`, found `FOO`
global_asm!("{}", options(), const FOO);
global_asm!("", clobber_abi(FOO));
//~^ ERROR expected string literal

View File

@ -264,62 +264,80 @@ error: expected one of `)`, `att_syntax`, or `raw`, found `FOO`
LL | global_asm!("", options(FOO));
| ^^^ expected one of `)`, `att_syntax`, or `raw`
error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
error: expected one of `)`, `att_syntax`, or `raw`, found `FOO`
--> $DIR/parse-error.rs:115:25
|
LL | global_asm!("", options(nomem FOO));
| ^^^^^ expected one of `)`, `att_syntax`, or `raw`
LL | global_asm!("", options(FOO,));
| ^^^ expected one of `)`, `att_syntax`, or `raw`
error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
error: the `nomem` option cannot be used with `global_asm!`
--> $DIR/parse-error.rs:117:25
|
LL | global_asm!("", options(nomem FOO));
| ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly
error: expected one of `)` or `,`, found `FOO`
--> $DIR/parse-error.rs:117:31
|
LL | global_asm!("", options(nomem FOO));
| ^^^ expected one of `)` or `,`
error: the `nomem` option cannot be used with `global_asm!`
--> $DIR/parse-error.rs:120:25
|
LL | global_asm!("", options(nomem, FOO));
| ^^^^^ expected one of `)`, `att_syntax`, or `raw`
| ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly
error: expected one of `)`, `att_syntax`, or `raw`, found `FOO`
--> $DIR/parse-error.rs:120:32
|
LL | global_asm!("", options(nomem, FOO));
| ^^^ expected one of `)`, `att_syntax`, or `raw`
error: expected string literal
--> $DIR/parse-error.rs:120:29
--> $DIR/parse-error.rs:124:29
|
LL | global_asm!("", clobber_abi(FOO));
| ^^^ not a string literal
error: expected one of `)` or `,`, found `FOO`
--> $DIR/parse-error.rs:122:33
--> $DIR/parse-error.rs:126:33
|
LL | global_asm!("", clobber_abi("C" FOO));
| ^^^ expected one of `)` or `,`
error: expected string literal
--> $DIR/parse-error.rs:124:34
--> $DIR/parse-error.rs:128:34
|
LL | global_asm!("", clobber_abi("C", FOO));
| ^^^ not a string literal
error: `clobber_abi` cannot be used with `global_asm!`
--> $DIR/parse-error.rs:126:19
--> $DIR/parse-error.rs:130:19
|
LL | global_asm!("{}", clobber_abi("C"), const FOO);
| ^^^^^^^^^^^^^^^^
error: `clobber_abi` cannot be used with `global_asm!`
--> $DIR/parse-error.rs:128:28
--> $DIR/parse-error.rs:132:28
|
LL | global_asm!("", options(), clobber_abi("C"));
| ^^^^^^^^^^^^^^^^
error: `clobber_abi` cannot be used with `global_asm!`
--> $DIR/parse-error.rs:130:30
--> $DIR/parse-error.rs:134:30
|
LL | global_asm!("{}", options(), clobber_abi("C"), const FOO);
| ^^^^^^^^^^^^^^^^
error: `clobber_abi` cannot be used with `global_asm!`
--> $DIR/parse-error.rs:132:17
--> $DIR/parse-error.rs:136:17
|
LL | global_asm!("", clobber_abi("C"), clobber_abi("C"));
| ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
error: duplicate argument named `a`
--> $DIR/parse-error.rs:134:35
--> $DIR/parse-error.rs:138:35
|
LL | global_asm!("{a}", a = const FOO, a = const BAR);
| ------------- ^^^^^^^^^^^^^ duplicate argument
@ -327,7 +345,7 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR);
| previously here
error: argument never used
--> $DIR/parse-error.rs:134:35
--> $DIR/parse-error.rs:138:35
|
LL | global_asm!("{a}", a = const FOO, a = const BAR);
| ^^^^^^^^^^^^^ argument never used
@ -335,19 +353,19 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR);
= help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"`
error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `""`
--> $DIR/parse-error.rs:137:28
--> $DIR/parse-error.rs:141:28
|
LL | global_asm!("", options(), "");
| ^^ expected one of `clobber_abi`, `const`, `options`, or `sym`
error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `"{}"`
--> $DIR/parse-error.rs:139:30
--> $DIR/parse-error.rs:143:30
|
LL | global_asm!("{}", const FOO, "{}", const FOO);
| ^^^^ expected one of `clobber_abi`, `const`, `options`, or `sym`
error: asm template must be a string literal
--> $DIR/parse-error.rs:141:13
--> $DIR/parse-error.rs:145:13
|
LL | global_asm!(format!("{{{}}}", 0), const FOO);
| ^^^^^^^^^^^^^^^^^^^^
@ -355,7 +373,7 @@ LL | global_asm!(format!("{{{}}}", 0), const FOO);
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
error: asm template must be a string literal
--> $DIR/parse-error.rs:143:20
--> $DIR/parse-error.rs:147:20
|
LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
| ^^^^^^^^^^^^^^^^^^^^
@ -363,7 +381,7 @@ LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
error: expected operand, options, or additional template string
--> $DIR/parse-error.rs:145:19
--> $DIR/parse-error.rs:149:19
|
LL | global_asm!("{}", label {});
| ^^^^^^^^ expected operand, options, or additional template string
@ -423,6 +441,6 @@ help: consider using `const` instead of `let`
LL | const bar: /* Type */ = 0;
| ~~~~~ ++++++++++++
error: aborting due to 64 previous errors
error: aborting due to 67 previous errors
For more information about this error, try `rustc --explain E0435`.

View File

@ -0,0 +1,11 @@
//@ needs-asm-support
//@ run-rustfix
use std::arch::global_asm;
fn main() {}
global_asm!("", options( raw));
//~^ ERROR the `nomem` option cannot be used with `global_asm!`
//~| ERROR the `readonly` option cannot be used with `global_asm!`
//~| ERROR the `noreturn` option cannot be used with `global_asm!`

View File

@ -0,0 +1,11 @@
//@ needs-asm-support
//@ run-rustfix
use std::arch::global_asm;
fn main() {}
global_asm!("", options(nomem, readonly, noreturn, raw));
//~^ ERROR the `nomem` option cannot be used with `global_asm!`
//~| ERROR the `readonly` option cannot be used with `global_asm!`
//~| ERROR the `noreturn` option cannot be used with `global_asm!`

View File

@ -0,0 +1,20 @@
error: the `nomem` option cannot be used with `global_asm!`
--> $DIR/unsupported-option.rs:8:25
|
LL | global_asm!("", options(nomem, readonly, noreturn, raw));
| ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly
error: the `readonly` option cannot be used with `global_asm!`
--> $DIR/unsupported-option.rs:8:32
|
LL | global_asm!("", options(nomem, readonly, noreturn, raw));
| ^^^^^^^^ the `readonly` option is not meaningful for global-scoped inline assembly
error: the `noreturn` option cannot be used with `global_asm!`
--> $DIR/unsupported-option.rs:8:42
|
LL | global_asm!("", options(nomem, readonly, noreturn, raw));
| ^^^^^^^^ the `noreturn` option is not meaningful for global-scoped inline assembly
error: aborting due to 3 previous errors

View File

@ -33,14 +33,14 @@ fn main() {
}
global_asm!("", options(nomem));
//~^ ERROR expected one of
//~^ ERROR the `nomem` option cannot be used with `global_asm!`
global_asm!("", options(readonly));
//~^ ERROR expected one of
//~^ ERROR the `readonly` option cannot be used with `global_asm!`
global_asm!("", options(noreturn));
//~^ ERROR expected one of
//~^ ERROR the `noreturn` option cannot be used with `global_asm!`
global_asm!("", options(pure));
//~^ ERROR expected one of
//~^ ERROR the `pure` option cannot be used with `global_asm!`
global_asm!("", options(nostack));
//~^ ERROR expected one of
//~^ ERROR the `nostack` option cannot be used with `global_asm!`
global_asm!("", options(preserves_flags));
//~^ ERROR expected one of
//~^ ERROR the `preserves_flags` option cannot be used with `global_asm!`

View File

@ -51,41 +51,41 @@ LL | asm!("{}", out(reg) foo, clobber_abi("C"), clobber_abi("C"));
| | clobber_abi
| generic outputs
error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
error: the `nomem` option cannot be used with `global_asm!`
--> $DIR/bad-options.rs:35:25
|
LL | global_asm!("", options(nomem));
| ^^^^^ expected one of `)`, `att_syntax`, or `raw`
| ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly
error: expected one of `)`, `att_syntax`, or `raw`, found `readonly`
error: the `readonly` option cannot be used with `global_asm!`
--> $DIR/bad-options.rs:37:25
|
LL | global_asm!("", options(readonly));
| ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
| ^^^^^^^^ the `readonly` option is not meaningful for global-scoped inline assembly
error: expected one of `)`, `att_syntax`, or `raw`, found `noreturn`
error: the `noreturn` option cannot be used with `global_asm!`
--> $DIR/bad-options.rs:39:25
|
LL | global_asm!("", options(noreturn));
| ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
| ^^^^^^^^ the `noreturn` option is not meaningful for global-scoped inline assembly
error: expected one of `)`, `att_syntax`, or `raw`, found `pure`
error: the `pure` option cannot be used with `global_asm!`
--> $DIR/bad-options.rs:41:25
|
LL | global_asm!("", options(pure));
| ^^^^ expected one of `)`, `att_syntax`, or `raw`
| ^^^^ the `pure` option is not meaningful for global-scoped inline assembly
error: expected one of `)`, `att_syntax`, or `raw`, found `nostack`
error: the `nostack` option cannot be used with `global_asm!`
--> $DIR/bad-options.rs:43:25
|
LL | global_asm!("", options(nostack));
| ^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
| ^^^^^^^ the `nostack` option is not meaningful for global-scoped inline assembly
error: expected one of `)`, `att_syntax`, or `raw`, found `preserves_flags`
error: the `preserves_flags` option cannot be used with `global_asm!`
--> $DIR/bad-options.rs:45:25
|
LL | global_asm!("", options(preserves_flags));
| ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
| ^^^^^^^^^^^^^^^ the `preserves_flags` option is not meaningful for global-scoped inline assembly
error: invalid ABI for `clobber_abi`
--> $DIR/bad-options.rs:24:18

View File

@ -11,10 +11,14 @@ LL | drop(x);
LL | return f(y);
| - borrow later used here
|
help: consider cloning the value if the performance cost is acceptable
help: if `T` implemented `Clone`, you could clone the value
--> $DIR/associated-types-outlives.rs:17:21
|
LL | 's: loop { y = denormalise(&x).clone(); break }
| ++++++++
LL | pub fn free_and_use<T: for<'a> Foo<'a>,
| ^ consider constraining this type parameter with `Clone`
...
LL | 's: loop { y = denormalise(&x); break }
| -- you could clone this value
error: aborting due to 1 previous error

View File

@ -73,10 +73,14 @@ LL | drop(a);
LL | drop(x);
| - borrow later used here
|
help: consider cloning the value if the performance cost is acceptable
note: if `AffineU32` implemented `Clone`, you could clone the value
--> $DIR/variance-issue-20533.rs:26:1
|
LL | let x = bat(&a).clone();
| ++++++++
LL | struct AffineU32(u32);
| ^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let x = bat(&a);
| -- you could clone this value
error[E0505]: cannot move out of `a` because it is borrowed
--> $DIR/variance-issue-20533.rs:59:14