Auto merge of #130179 - workingjubilee:rollup-l78cv44, r=workingjubilee

Rollup of 11 pull requests

Successful merges:

 - #128316 (Stabilize most of `io_error_more`)
 - #129473 (use  `download-ci-llvm=true` in the default compiler config)
 - #129529 (Add test to build crates used by r-a on stable)
 - #129981 (Remove `serialized_bitcode` from `LtoModuleCodegen`.)
 - #130094 (Inform the solver if evaluation is concurrent)
 - #130132 ([illumos] enable SIGSEGV handler to detect stack overflows)
 - #130146 (bootstrap `naked_asm!` for `compiler-builtins`)
 - #130149 (Helper function for formatting with `LifetimeSuggestionPosition`)
 - #130152 (adapt a test for llvm 20)
 - #130162 (bump download-ci-llvm-stamp)
 - #130164 (move some const fn out of the const_ptr_as_ref feature)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-09-10 07:26:27 +00:00
commit 26b2b8d162
34 changed files with 265 additions and 100 deletions

View File

@ -812,6 +812,44 @@ pub(super) fn expand_asm<'cx>(
}) })
} }
pub(super) fn expand_naked_asm<'cx>(
ecx: &'cx mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
) -> MacroExpanderResult<'cx> {
ExpandResult::Ready(match parse_args(ecx, sp, tts, false) {
Ok(args) => {
let ExpandResult::Ready(mac) = expand_preparsed_asm(ecx, args) else {
return ExpandResult::Retry(());
};
let expr = match mac {
Ok(mut inline_asm) => {
// for future compatibility, we always set the NORETURN option.
//
// When we turn `asm!` into `naked_asm!` with this implementation, we can drop
// the `options(noreturn)`, which makes the upgrade smooth when `naked_asm!`
// starts disallowing the `noreturn` option in the future
inline_asm.options |= ast::InlineAsmOptions::NORETURN;
P(ast::Expr {
id: ast::DUMMY_NODE_ID,
kind: ast::ExprKind::InlineAsm(P(inline_asm)),
span: sp,
attrs: ast::AttrVec::new(),
tokens: None,
})
}
Err(guar) => DummyResult::raw_expr(sp, Some(guar)),
};
MacEager::expr(expr)
}
Err(err) => {
let guar = err.emit();
DummyResult::any(sp, guar)
}
})
}
pub(super) fn expand_global_asm<'cx>( pub(super) fn expand_global_asm<'cx>(
ecx: &'cx mut ExtCtxt<'_>, ecx: &'cx mut ExtCtxt<'_>,
sp: Span, sp: Span,

View File

@ -94,6 +94,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
line: source_util::expand_line, line: source_util::expand_line,
log_syntax: log_syntax::expand_log_syntax, log_syntax: log_syntax::expand_log_syntax,
module_path: source_util::expand_mod, module_path: source_util::expand_mod,
naked_asm: asm::expand_naked_asm,
option_env: env::expand_option_env, option_env: env::expand_option_env,
pattern_type: pattern_type::expand, pattern_type: pattern_type::expand,
std_panic: edition_panic::expand_panic, std_panic: edition_panic::expand_panic,

View File

@ -272,7 +272,6 @@ fn fat_lto(
}*/ }*/
} }
}; };
let mut serialized_bitcode = Vec::new();
{ {
info!("using {:?} as a base module", module.name); info!("using {:?} as a base module", module.name);
@ -317,7 +316,6 @@ fn fat_lto(
unimplemented!("from uncompressed file") unimplemented!("from uncompressed file")
} }
} }
serialized_bitcode.push(bc_decoded);
} }
save_temp_bitcode(cgcx, &module, "lto.input"); save_temp_bitcode(cgcx, &module, "lto.input");
@ -337,7 +335,7 @@ fn fat_lto(
// of now. // of now.
module.module_llvm.temp_dir = Some(tmp_path); module.module_llvm.temp_dir = Some(tmp_path);
Ok(LtoModuleCodegen::Fat { module, _serialized_bitcode: serialized_bitcode }) Ok(LtoModuleCodegen::Fat(module))
} }
pub struct ModuleBuffer(PathBuf); pub struct ModuleBuffer(PathBuf);

View File

@ -314,7 +314,6 @@ fn fat_lto(
} }
} }
}; };
let mut serialized_bitcode = Vec::new();
{ {
let (llcx, llmod) = { let (llcx, llmod) = {
let llvm = &module.module_llvm; let llvm = &module.module_llvm;
@ -342,9 +341,7 @@ fn fat_lto(
serialized_modules.sort_by(|module1, module2| module1.1.cmp(&module2.1)); serialized_modules.sort_by(|module1, module2| module1.1.cmp(&module2.1));
// For all serialized bitcode files we parse them and link them in as we did // For all serialized bitcode files we parse them and link them in as we did
// above, this is all mostly handled in C++. Like above, though, we don't // above, this is all mostly handled in C++.
// know much about the memory management here so we err on the side of being
// save and persist everything with the original module.
let mut linker = Linker::new(llmod); let mut linker = Linker::new(llmod);
for (bc_decoded, name) in serialized_modules { for (bc_decoded, name) in serialized_modules {
let _timer = cgcx let _timer = cgcx
@ -355,7 +352,6 @@ fn fat_lto(
info!("linking {:?}", name); info!("linking {:?}", name);
let data = bc_decoded.data(); let data = bc_decoded.data();
linker.add(data).map_err(|()| write::llvm_err(dcx, LlvmError::LoadBitcode { name }))?; linker.add(data).map_err(|()| write::llvm_err(dcx, LlvmError::LoadBitcode { name }))?;
serialized_bitcode.push(bc_decoded);
} }
drop(linker); drop(linker);
save_temp_bitcode(cgcx, &module, "lto.input"); save_temp_bitcode(cgcx, &module, "lto.input");
@ -372,7 +368,7 @@ fn fat_lto(
} }
} }
Ok(LtoModuleCodegen::Fat { module, _serialized_bitcode: serialized_bitcode }) Ok(LtoModuleCodegen::Fat(module))
} }
pub(crate) struct Linker<'a>(&'a mut llvm::Linker<'a>); pub(crate) struct Linker<'a>(&'a mut llvm::Linker<'a>);

View File

@ -41,18 +41,14 @@ pub struct ThinShared<B: WriteBackendMethods> {
} }
pub enum LtoModuleCodegen<B: WriteBackendMethods> { pub enum LtoModuleCodegen<B: WriteBackendMethods> {
Fat { Fat(ModuleCodegen<B::Module>),
module: ModuleCodegen<B::Module>,
_serialized_bitcode: Vec<SerializedModule<B::ModuleBuffer>>,
},
Thin(ThinModule<B>), Thin(ThinModule<B>),
} }
impl<B: WriteBackendMethods> LtoModuleCodegen<B> { impl<B: WriteBackendMethods> LtoModuleCodegen<B> {
pub fn name(&self) -> &str { pub fn name(&self) -> &str {
match *self { match *self {
LtoModuleCodegen::Fat { .. } => "everything", LtoModuleCodegen::Fat(_) => "everything",
LtoModuleCodegen::Thin(ref m) => m.name(), LtoModuleCodegen::Thin(ref m) => m.name(),
} }
} }
@ -68,7 +64,7 @@ impl<B: WriteBackendMethods> LtoModuleCodegen<B> {
cgcx: &CodegenContext<B>, cgcx: &CodegenContext<B>,
) -> Result<ModuleCodegen<B::Module>, FatalError> { ) -> Result<ModuleCodegen<B::Module>, FatalError> {
match self { match self {
LtoModuleCodegen::Fat { mut module, .. } => { LtoModuleCodegen::Fat(mut module) => {
B::optimize_fat(cgcx, &mut module)?; B::optimize_fat(cgcx, &mut module)?;
Ok(module) Ok(module)
} }
@ -81,7 +77,7 @@ impl<B: WriteBackendMethods> LtoModuleCodegen<B> {
pub fn cost(&self) -> u64 { pub fn cost(&self) -> u64 {
match *self { match *self {
// Only one module with fat LTO, so the cost doesn't matter. // Only one module with fat LTO, so the cost doesn't matter.
LtoModuleCodegen::Fat { .. } => 0, LtoModuleCodegen::Fat(_) => 0,
LtoModuleCodegen::Thin(ref m) => m.cost(), LtoModuleCodegen::Thin(ref m) => m.cost(),
} }
} }

View File

@ -168,6 +168,19 @@ impl Lifetime {
(LifetimeSuggestionPosition::Normal, self.ident.span) (LifetimeSuggestionPosition::Normal, self.ident.span)
} }
} }
pub fn suggestion(&self, new_lifetime: &str) -> (Span, String) {
debug_assert!(new_lifetime.starts_with('\''));
let (pos, span) = self.suggestion_position();
let code = match pos {
LifetimeSuggestionPosition::Normal => format!("{new_lifetime}"),
LifetimeSuggestionPosition::Ampersand => format!("{new_lifetime} "),
LifetimeSuggestionPosition::ElidedPath => format!("<{new_lifetime}>"),
LifetimeSuggestionPosition::ElidedPathArgument => format!("{new_lifetime}, "),
LifetimeSuggestionPosition::ObjectDefault => format!("+ {new_lifetime}"),
};
(span, code)
}
} }
/// A `Path` is essentially Rust's notion of a name; for instance, /// A `Path` is essentially Rust's notion of a name; for instance,

View File

@ -1191,23 +1191,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
(generics.span, "<'a>".to_owned()) (generics.span, "<'a>".to_owned())
}; };
let lifetime_sugg = match lifetime_ref.suggestion_position() { let lifetime_sugg = lifetime_ref.suggestion("'a");
(hir::LifetimeSuggestionPosition::Normal, span) => {
(span, "'a".to_owned())
}
(hir::LifetimeSuggestionPosition::Ampersand, span) => {
(span, "'a ".to_owned())
}
(hir::LifetimeSuggestionPosition::ElidedPath, span) => {
(span, "<'a>".to_owned())
}
(hir::LifetimeSuggestionPosition::ElidedPathArgument, span) => {
(span, "'a, ".to_owned())
}
(hir::LifetimeSuggestionPosition::ObjectDefault, span) => {
(span, "+ 'a".to_owned())
}
};
let suggestions = vec![lifetime_sugg, new_param_sugg]; let suggestions = vec![lifetime_sugg, new_param_sugg];
diag.span_label( diag.span_label(

View File

@ -181,6 +181,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
} }
} }
fn evaluation_is_concurrent(&self) -> bool {
self.sess.threads() > 1
}
fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T { fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T {
self.expand_abstract_consts(t) self.expand_abstract_consts(t)
} }

View File

@ -1255,6 +1255,7 @@ symbols! {
mut_preserve_binding_mode_2024, mut_preserve_binding_mode_2024,
mut_ref, mut_ref,
naked, naked,
naked_asm,
naked_functions, naked_functions,
name, name,
names, names,

View File

@ -852,18 +852,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
impl<'hir, 'tcx> hir::intravisit::Visitor<'hir> for LifetimeReplaceVisitor<'tcx, '_> { impl<'hir, 'tcx> hir::intravisit::Visitor<'hir> for LifetimeReplaceVisitor<'tcx, '_> {
fn visit_lifetime(&mut self, lt: &'hir hir::Lifetime) { fn visit_lifetime(&mut self, lt: &'hir hir::Lifetime) {
if lt.res == self.needle { if lt.res == self.needle {
let (pos, span) = lt.suggestion_position(); self.add_lt_suggs.push(lt.suggestion(self.new_lt));
let new_lt = &self.new_lt;
let sugg = match pos {
hir::LifetimeSuggestionPosition::Normal => format!("{new_lt}"),
hir::LifetimeSuggestionPosition::Ampersand => format!("{new_lt} "),
hir::LifetimeSuggestionPosition::ElidedPath => format!("<{new_lt}>"),
hir::LifetimeSuggestionPosition::ElidedPathArgument => {
format!("{new_lt}, ")
}
hir::LifetimeSuggestionPosition::ObjectDefault => format!("+ {new_lt}"),
};
self.add_lt_suggs.push((span, sugg));
} }
} }

View File

@ -237,7 +237,7 @@ pub fn supertrait_def_ids<I: Interner>(
cx: I, cx: I,
trait_def_id: I::DefId, trait_def_id: I::DefId,
) -> impl Iterator<Item = I::DefId> { ) -> impl Iterator<Item = I::DefId> {
let mut set: HashSet<I::DefId> = HashSet::default(); let mut set = HashSet::default();
let mut stack = vec![trait_def_id]; let mut stack = vec![trait_def_id];
set.insert(trait_def_id); set.insert(trait_def_id);

View File

@ -137,6 +137,8 @@ pub trait Interner:
f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R,
) -> R; ) -> R;
fn evaluation_is_concurrent(&self) -> bool;
fn expand_abstract_consts<T: TypeFoldable<Self>>(self, t: T) -> T; fn expand_abstract_consts<T: TypeFoldable<Self>>(self, t: T) -> T;
type GenericsOf: GenericsOf<Self>; type GenericsOf: GenericsOf<Self>;
@ -404,4 +406,7 @@ impl<I: Interner> search_graph::Cx for I {
) -> R { ) -> R {
I::with_global_cache(self, mode, f) I::with_global_cache(self, mode, f)
} }
fn evaluation_is_concurrent(&self) -> bool {
self.evaluation_is_concurrent()
}
} }

View File

@ -44,22 +44,28 @@ impl<X: Cx> GlobalCache<X> {
cx: X, cx: X,
input: X::Input, input: X::Input,
result: X::Result, origin_result: X::Result,
dep_node: X::DepNodeIndex, dep_node: X::DepNodeIndex,
additional_depth: usize, additional_depth: usize,
encountered_overflow: bool, encountered_overflow: bool,
nested_goals: NestedGoals<X>, nested_goals: NestedGoals<X>,
) { ) {
let result = cx.mk_tracked(result, dep_node); let result = cx.mk_tracked(origin_result, dep_node);
let entry = self.map.entry(input).or_default(); let entry = self.map.entry(input).or_default();
if encountered_overflow { if encountered_overflow {
let with_overflow = WithOverflow { nested_goals, result }; let with_overflow = WithOverflow { nested_goals, result };
let prev = entry.with_overflow.insert(additional_depth, with_overflow); let prev = entry.with_overflow.insert(additional_depth, with_overflow);
assert!(prev.is_none()); if let Some(prev) = &prev {
assert!(cx.evaluation_is_concurrent());
assert_eq!(cx.get_tracked(&prev.result), origin_result);
}
} else { } else {
let prev = entry.success.replace(Success { additional_depth, nested_goals, result }); let prev = entry.success.replace(Success { additional_depth, nested_goals, result });
assert!(prev.is_none()); if let Some(prev) = &prev {
assert!(cx.evaluation_is_concurrent());
assert_eq!(cx.get_tracked(&prev.result), origin_result);
}
} }
} }

View File

@ -53,6 +53,8 @@ pub trait Cx: Copy {
mode: SolverMode, mode: SolverMode,
f: impl FnOnce(&mut GlobalCache<Self>) -> R, f: impl FnOnce(&mut GlobalCache<Self>) -> R,
) -> R; ) -> R;
fn evaluation_is_concurrent(&self) -> bool;
} }
pub trait Delegate { pub trait Delegate {

View File

@ -42,6 +42,9 @@
# Unless you're developing for a target where Rust CI doesn't build a compiler # Unless you're developing for a target where Rust CI doesn't build a compiler
# toolchain or changing LLVM locally, you probably want to leave this enabled. # toolchain or changing LLVM locally, you probably want to leave this enabled.
# #
# Set this to `true` to download if CI llvm available otherwise it builds
# from `src/llvm-project`.
#
# Set this to `"if-unchanged"` to download only if the llvm-project has not # Set this to `"if-unchanged"` to download only if the llvm-project has not
# been modified. You can also use this if you are unsure whether you're on a # been modified. You can also use this if you are unsure whether you're on a
# tier 1 target. All tier 1 targets are currently supported. # tier 1 target. All tier 1 targets are currently supported.
@ -236,7 +239,7 @@
# Instead of downloading the src/stage0 version of cargo-clippy specified, # Instead of downloading the src/stage0 version of cargo-clippy specified,
# use this cargo-clippy binary instead as the stage0 snapshot cargo-clippy. # use this cargo-clippy binary instead as the stage0 snapshot cargo-clippy.
# #
# Note that this option should be used with the same toolchain as the `rustc` option above. # Note that this option should be used with the same toolchain as the `rustc` option above.
# Otherwise, clippy is likely to fail due to a toolchain conflict. # Otherwise, clippy is likely to fail due to a toolchain conflict.
#cargo-clippy = "/path/to/cargo-clippy" #cargo-clippy = "/path/to/cargo-clippy"

View File

@ -17,6 +17,20 @@ pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) {
/* compiler built-in */ /* compiler built-in */
} }
/// Inline assembly used in combination with `#[naked]` functions.
///
/// Refer to [Rust By Example] for a usage guide and the [reference] for
/// detailed information about the syntax and available options.
///
/// [Rust By Example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html
/// [reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html
#[unstable(feature = "naked_functions", issue = "90957")]
#[rustc_builtin_macro]
#[cfg(not(bootstrap))]
pub macro naked_asm("assembly template", $(operands,)* $(options($(option),*))?) {
/* compiler built-in */
}
/// Module-level inline assembly. /// Module-level inline assembly.
/// ///
/// Refer to [Rust By Example] for a usage guide and the [reference] for /// Refer to [Rust By Example] for a usage guide and the [reference] for

View File

@ -270,7 +270,7 @@ impl<T: ?Sized> *const T {
/// } /// }
/// ``` /// ```
#[stable(feature = "ptr_as_ref", since = "1.9.0")] #[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] #[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
#[inline] #[inline]
pub const unsafe fn as_ref<'a>(self) -> Option<&'a T> { pub const unsafe fn as_ref<'a>(self) -> Option<&'a T> {
// SAFETY: the caller must guarantee that `self` is valid // SAFETY: the caller must guarantee that `self` is valid
@ -302,7 +302,7 @@ impl<T: ?Sized> *const T {
/// ``` /// ```
// FIXME: mention it in the docs for `as_ref` and `as_uninit_ref` once stabilized. // FIXME: mention it in the docs for `as_ref` and `as_uninit_ref` once stabilized.
#[unstable(feature = "ptr_as_ref_unchecked", issue = "122034")] #[unstable(feature = "ptr_as_ref_unchecked", issue = "122034")]
#[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] #[rustc_const_unstable(feature = "ptr_as_ref_unchecked", issue = "122034")]
#[inline] #[inline]
#[must_use] #[must_use]
pub const unsafe fn as_ref_unchecked<'a>(self) -> &'a T { pub const unsafe fn as_ref_unchecked<'a>(self) -> &'a T {
@ -336,7 +336,7 @@ impl<T: ?Sized> *const T {
/// ``` /// ```
#[inline] #[inline]
#[unstable(feature = "ptr_as_uninit", issue = "75402")] #[unstable(feature = "ptr_as_uninit", issue = "75402")]
#[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
pub const unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit<T>> pub const unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit<T>>
where where
T: Sized, T: Sized,
@ -1664,7 +1664,7 @@ impl<T> *const [T] {
/// [allocated object]: crate::ptr#allocated-object /// [allocated object]: crate::ptr#allocated-object
#[inline] #[inline]
#[unstable(feature = "ptr_as_uninit", issue = "75402")] #[unstable(feature = "ptr_as_uninit", issue = "75402")]
#[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
pub const unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit<T>]> { pub const unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit<T>]> {
if self.is_null() { if self.is_null() {
None None

View File

@ -261,7 +261,7 @@ impl<T: ?Sized> *mut T {
/// } /// }
/// ``` /// ```
#[stable(feature = "ptr_as_ref", since = "1.9.0")] #[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] #[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
#[inline] #[inline]
pub const unsafe fn as_ref<'a>(self) -> Option<&'a T> { pub const unsafe fn as_ref<'a>(self) -> Option<&'a T> {
// SAFETY: the caller must guarantee that `self` is valid for a // SAFETY: the caller must guarantee that `self` is valid for a
@ -295,7 +295,7 @@ impl<T: ?Sized> *mut T {
/// ``` /// ```
// FIXME: mention it in the docs for `as_ref` and `as_uninit_ref` once stabilized. // FIXME: mention it in the docs for `as_ref` and `as_uninit_ref` once stabilized.
#[unstable(feature = "ptr_as_ref_unchecked", issue = "122034")] #[unstable(feature = "ptr_as_ref_unchecked", issue = "122034")]
#[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] #[rustc_const_unstable(feature = "ptr_as_ref_unchecked", issue = "122034")]
#[inline] #[inline]
#[must_use] #[must_use]
pub const unsafe fn as_ref_unchecked<'a>(self) -> &'a T { pub const unsafe fn as_ref_unchecked<'a>(self) -> &'a T {
@ -334,7 +334,7 @@ impl<T: ?Sized> *mut T {
/// ``` /// ```
#[inline] #[inline]
#[unstable(feature = "ptr_as_uninit", issue = "75402")] #[unstable(feature = "ptr_as_uninit", issue = "75402")]
#[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
pub const unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit<T>> pub const unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit<T>>
where where
T: Sized, T: Sized,
@ -580,7 +580,7 @@ impl<T: ?Sized> *mut T {
/// println!("{s:?}"); // It'll print: "[4, 2, 3]". /// println!("{s:?}"); // It'll print: "[4, 2, 3]".
/// ``` /// ```
#[stable(feature = "ptr_as_ref", since = "1.9.0")] #[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] #[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
#[inline] #[inline]
pub const unsafe fn as_mut<'a>(self) -> Option<&'a mut T> { pub const unsafe fn as_mut<'a>(self) -> Option<&'a mut T> {
// SAFETY: the caller must guarantee that `self` is be valid for // SAFETY: the caller must guarantee that `self` is be valid for
@ -616,7 +616,7 @@ impl<T: ?Sized> *mut T {
/// ``` /// ```
// FIXME: mention it in the docs for `as_mut` and `as_uninit_mut` once stabilized. // FIXME: mention it in the docs for `as_mut` and `as_uninit_mut` once stabilized.
#[unstable(feature = "ptr_as_ref_unchecked", issue = "122034")] #[unstable(feature = "ptr_as_ref_unchecked", issue = "122034")]
#[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] #[rustc_const_unstable(feature = "ptr_as_ref_unchecked", issue = "122034")]
#[inline] #[inline]
#[must_use] #[must_use]
pub const unsafe fn as_mut_unchecked<'a>(self) -> &'a mut T { pub const unsafe fn as_mut_unchecked<'a>(self) -> &'a mut T {
@ -639,7 +639,7 @@ impl<T: ?Sized> *mut T {
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion). /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
#[inline] #[inline]
#[unstable(feature = "ptr_as_uninit", issue = "75402")] #[unstable(feature = "ptr_as_uninit", issue = "75402")]
#[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
pub const unsafe fn as_uninit_mut<'a>(self) -> Option<&'a mut MaybeUninit<T>> pub const unsafe fn as_uninit_mut<'a>(self) -> Option<&'a mut MaybeUninit<T>>
where where
T: Sized, T: Sized,
@ -2016,7 +2016,7 @@ impl<T> *mut [T] {
/// [allocated object]: crate::ptr#allocated-object /// [allocated object]: crate::ptr#allocated-object
#[inline] #[inline]
#[unstable(feature = "ptr_as_uninit", issue = "75402")] #[unstable(feature = "ptr_as_uninit", issue = "75402")]
#[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
pub const unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit<T>]> { pub const unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit<T>]> {
if self.is_null() { if self.is_null() {
None None
@ -2068,7 +2068,7 @@ impl<T> *mut [T] {
/// [allocated object]: crate::ptr#allocated-object /// [allocated object]: crate::ptr#allocated-object
#[inline] #[inline]
#[unstable(feature = "ptr_as_uninit", issue = "75402")] #[unstable(feature = "ptr_as_uninit", issue = "75402")]
#[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
pub const unsafe fn as_uninit_slice_mut<'a>(self) -> Option<&'a mut [MaybeUninit<T>]> { pub const unsafe fn as_uninit_slice_mut<'a>(self) -> Option<&'a mut [MaybeUninit<T>]> {
if self.is_null() { if self.is_null() {
None None

View File

@ -133,7 +133,7 @@ impl<T: Sized> NonNull<T> {
#[inline] #[inline]
#[must_use] #[must_use]
#[unstable(feature = "ptr_as_uninit", issue = "75402")] #[unstable(feature = "ptr_as_uninit", issue = "75402")]
#[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
pub const unsafe fn as_uninit_ref<'a>(self) -> &'a MaybeUninit<T> { pub const unsafe fn as_uninit_ref<'a>(self) -> &'a MaybeUninit<T> {
// SAFETY: the caller must guarantee that `self` meets all the // SAFETY: the caller must guarantee that `self` meets all the
// requirements for a reference. // requirements for a reference.
@ -157,7 +157,7 @@ impl<T: Sized> NonNull<T> {
#[inline] #[inline]
#[must_use] #[must_use]
#[unstable(feature = "ptr_as_uninit", issue = "75402")] #[unstable(feature = "ptr_as_uninit", issue = "75402")]
#[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
pub const unsafe fn as_uninit_mut<'a>(self) -> &'a mut MaybeUninit<T> { pub const unsafe fn as_uninit_mut<'a>(self) -> &'a mut MaybeUninit<T> {
// SAFETY: the caller must guarantee that `self` meets all the // SAFETY: the caller must guarantee that `self` meets all the
// requirements for a reference. // requirements for a reference.
@ -1563,7 +1563,7 @@ impl<T> NonNull<[T]> {
#[inline] #[inline]
#[must_use] #[must_use]
#[unstable(feature = "ptr_as_uninit", issue = "75402")] #[unstable(feature = "ptr_as_uninit", issue = "75402")]
#[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
pub const unsafe fn as_uninit_slice<'a>(self) -> &'a [MaybeUninit<T>] { pub const unsafe fn as_uninit_slice<'a>(self) -> &'a [MaybeUninit<T>] {
// SAFETY: the caller must uphold the safety contract for `as_uninit_slice`. // SAFETY: the caller must uphold the safety contract for `as_uninit_slice`.
unsafe { slice::from_raw_parts(self.cast().as_ptr(), self.len()) } unsafe { slice::from_raw_parts(self.cast().as_ptr(), self.len()) }
@ -1628,7 +1628,7 @@ impl<T> NonNull<[T]> {
#[inline] #[inline]
#[must_use] #[must_use]
#[unstable(feature = "ptr_as_uninit", issue = "75402")] #[unstable(feature = "ptr_as_uninit", issue = "75402")]
#[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
pub const unsafe fn as_uninit_slice_mut<'a>(self) -> &'a mut [MaybeUninit<T>] { pub const unsafe fn as_uninit_slice_mut<'a>(self) -> &'a mut [MaybeUninit<T>] {
// SAFETY: the caller must uphold the safety contract for `as_uninit_slice_mut`. // SAFETY: the caller must uphold the safety contract for `as_uninit_slice_mut`.
unsafe { slice::from_raw_parts_mut(self.cast().as_ptr(), self.len()) } unsafe { slice::from_raw_parts_mut(self.cast().as_ptr(), self.len()) }

View File

@ -223,10 +223,10 @@ pub enum ErrorKind {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
ConnectionReset, ConnectionReset,
/// The remote host is not reachable. /// The remote host is not reachable.
#[unstable(feature = "io_error_more", issue = "86442")] #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
HostUnreachable, HostUnreachable,
/// The network containing the remote host is not reachable. /// The network containing the remote host is not reachable.
#[unstable(feature = "io_error_more", issue = "86442")] #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
NetworkUnreachable, NetworkUnreachable,
/// The connection was aborted (terminated) by the remote server. /// The connection was aborted (terminated) by the remote server.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -243,7 +243,7 @@ pub enum ErrorKind {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
AddrNotAvailable, AddrNotAvailable,
/// The system's networking is down. /// The system's networking is down.
#[unstable(feature = "io_error_more", issue = "86442")] #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
NetworkDown, NetworkDown,
/// The operation failed because a pipe was closed. /// The operation failed because a pipe was closed.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -259,18 +259,18 @@ pub enum ErrorKind {
/// ///
/// For example, a filesystem path was specified where one of the intermediate directory /// For example, a filesystem path was specified where one of the intermediate directory
/// components was, in fact, a plain file. /// components was, in fact, a plain file.
#[unstable(feature = "io_error_more", issue = "86442")] #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
NotADirectory, NotADirectory,
/// The filesystem object is, unexpectedly, a directory. /// The filesystem object is, unexpectedly, a directory.
/// ///
/// A directory was specified when a non-directory was expected. /// A directory was specified when a non-directory was expected.
#[unstable(feature = "io_error_more", issue = "86442")] #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
IsADirectory, IsADirectory,
/// A non-empty directory was specified where an empty directory was expected. /// A non-empty directory was specified where an empty directory was expected.
#[unstable(feature = "io_error_more", issue = "86442")] #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
DirectoryNotEmpty, DirectoryNotEmpty,
/// The filesystem or storage medium is read-only, but a write operation was attempted. /// The filesystem or storage medium is read-only, but a write operation was attempted.
#[unstable(feature = "io_error_more", issue = "86442")] #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
ReadOnlyFilesystem, ReadOnlyFilesystem,
/// Loop in the filesystem or IO subsystem; often, too many levels of symbolic links. /// Loop in the filesystem or IO subsystem; often, too many levels of symbolic links.
/// ///
@ -285,7 +285,7 @@ pub enum ErrorKind {
/// ///
/// With some network filesystems, notably NFS, an open file (or directory) can be invalidated /// With some network filesystems, notably NFS, an open file (or directory) can be invalidated
/// by problems with the network or server. /// by problems with the network or server.
#[unstable(feature = "io_error_more", issue = "86442")] #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
StaleNetworkFileHandle, StaleNetworkFileHandle,
/// A parameter was incorrect. /// A parameter was incorrect.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -319,13 +319,13 @@ pub enum ErrorKind {
/// The underlying storage (typically, a filesystem) is full. /// The underlying storage (typically, a filesystem) is full.
/// ///
/// This does not include out of quota errors. /// This does not include out of quota errors.
#[unstable(feature = "io_error_more", issue = "86442")] #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
StorageFull, StorageFull,
/// Seek on unseekable file. /// Seek on unseekable file.
/// ///
/// Seeking was attempted on an open file handle which is not suitable for seeking - for /// Seeking was attempted on an open file handle which is not suitable for seeking - for
/// example, on Unix, a named pipe opened with `File::open`. /// example, on Unix, a named pipe opened with `File::open`.
#[unstable(feature = "io_error_more", issue = "86442")] #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
NotSeekable, NotSeekable,
/// Filesystem quota was exceeded. /// Filesystem quota was exceeded.
#[unstable(feature = "io_error_more", issue = "86442")] #[unstable(feature = "io_error_more", issue = "86442")]
@ -335,22 +335,22 @@ pub enum ErrorKind {
/// This might arise from a hard limit of the underlying filesystem or file access API, or from /// This might arise from a hard limit of the underlying filesystem or file access API, or from
/// an administratively imposed resource limitation. Simple disk full, and out of quota, have /// an administratively imposed resource limitation. Simple disk full, and out of quota, have
/// their own errors. /// their own errors.
#[unstable(feature = "io_error_more", issue = "86442")] #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
FileTooLarge, FileTooLarge,
/// Resource is busy. /// Resource is busy.
#[unstable(feature = "io_error_more", issue = "86442")] #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
ResourceBusy, ResourceBusy,
/// Executable file is busy. /// Executable file is busy.
/// ///
/// An attempt was made to write to a file which is also in use as a running program. (Not all /// An attempt was made to write to a file which is also in use as a running program. (Not all
/// operating systems detect this situation.) /// operating systems detect this situation.)
#[unstable(feature = "io_error_more", issue = "86442")] #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
ExecutableFileBusy, ExecutableFileBusy,
/// Deadlock (avoided). /// Deadlock (avoided).
/// ///
/// A file locking operation would result in deadlock. This situation is typically detected, if /// A file locking operation would result in deadlock. This situation is typically detected, if
/// at all, on a best-effort basis. /// at all, on a best-effort basis.
#[unstable(feature = "io_error_more", issue = "86442")] #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
Deadlock, Deadlock,
/// Cross-device or cross-filesystem (hard) link or rename. /// Cross-device or cross-filesystem (hard) link or rename.
#[unstable(feature = "io_error_more", issue = "86442")] #[unstable(feature = "io_error_more", issue = "86442")]
@ -358,7 +358,7 @@ pub enum ErrorKind {
/// Too many (hard) links to the same filesystem object. /// Too many (hard) links to the same filesystem object.
/// ///
/// The filesystem does not support making so many hardlinks to the same file. /// The filesystem does not support making so many hardlinks to the same file.
#[unstable(feature = "io_error_more", issue = "86442")] #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
TooManyLinks, TooManyLinks,
/// A filename was invalid. /// A filename was invalid.
/// ///
@ -369,7 +369,7 @@ pub enum ErrorKind {
/// ///
/// When trying to run an external program, a system or process limit on the size of the /// When trying to run an external program, a system or process limit on the size of the
/// arguments would have been exceeded. /// arguments would have been exceeded.
#[unstable(feature = "io_error_more", issue = "86442")] #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
ArgumentListTooLong, ArgumentListTooLong,
/// This operation was interrupted. /// This operation was interrupted.
/// ///

View File

@ -32,7 +32,8 @@ impl Drop for Handler {
target_os = "macos", target_os = "macos",
target_os = "netbsd", target_os = "netbsd",
target_os = "openbsd", target_os = "openbsd",
target_os = "solaris" target_os = "solaris",
target_os = "illumos",
))] ))]
mod imp { mod imp {
#[cfg(not(all(target_os = "linux", target_env = "gnu")))] #[cfg(not(all(target_os = "linux", target_env = "gnu")))]
@ -280,7 +281,7 @@ mod imp {
libc::SIGSTKSZ libc::SIGSTKSZ
} }
#[cfg(target_os = "solaris")] #[cfg(any(target_os = "solaris", target_os = "illumos"))]
unsafe fn get_stack_start() -> Option<*mut libc::c_void> { unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
let mut current_stack: libc::stack_t = crate::mem::zeroed(); let mut current_stack: libc::stack_t = crate::mem::zeroed();
assert_eq!(libc::stack_getbounds(&mut current_stack), 0); assert_eq!(libc::stack_getbounds(&mut current_stack), 0);
@ -486,7 +487,12 @@ mod imp {
Some(guardaddr..guardaddr + page_size) Some(guardaddr..guardaddr + page_size)
} }
#[cfg(any(target_os = "macos", target_os = "openbsd", target_os = "solaris"))] #[cfg(any(
target_os = "macos",
target_os = "openbsd",
target_os = "solaris",
target_os = "illumos",
))]
// FIXME: I am probably not unsafe. // FIXME: I am probably not unsafe.
unsafe fn current_guard() -> Option<Range<usize>> { unsafe fn current_guard() -> Option<Range<usize>> {
let stackptr = get_stack_start()?; let stackptr = get_stack_start()?;
@ -569,7 +575,8 @@ mod imp {
target_os = "macos", target_os = "macos",
target_os = "netbsd", target_os = "netbsd",
target_os = "openbsd", target_os = "openbsd",
target_os = "solaris" target_os = "solaris",
target_os = "illumos",
)))] )))]
mod imp { mod imp {
pub unsafe fn init() {} pub unsafe fn init() {}

View File

@ -27,4 +27,5 @@ assertions = false
# Enable warnings during the LLVM compilation (when LLVM is changed, causing a compilation) # Enable warnings during the LLVM compilation (when LLVM is changed, causing a compilation)
enable-warnings = true enable-warnings = true
# Will download LLVM from CI if available on your platform. # Will download LLVM from CI if available on your platform.
download-ci-llvm = "if-unchanged" # If you intend to modify `src/llvm-project`, use `"if-unchanged"` or `false` instead.
download-ci-llvm = true

View File

@ -1,4 +1,4 @@
Change this file to make users of the `download-ci-llvm` configuration download Change this file to make users of the `download-ci-llvm` configuration download
a new version of LLVM from CI, even if the LLVM submodule hasnt changed. a new version of LLVM from CI, even if the LLVM submodule hasnt changed.
Last change is for: https://github.com/rust-lang/rust/pull/129116 Last change is for: https://github.com/rust-lang/rust/pull/129788

View File

@ -2766,7 +2766,8 @@ impl Config {
); );
} }
b // If download-ci-llvm=true we also want to check that CI llvm is available
b && llvm::is_ci_llvm_available(self, asserts)
} }
Some(StringOrBool::String(s)) if s == "if-unchanged" => if_unchanged(), Some(StringOrBool::String(s)) if s == "if-unchanged" => if_unchanged(),
Some(StringOrBool::String(other)) => { Some(StringOrBool::String(other)) => {

View File

@ -250,4 +250,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
severity: ChangeSeverity::Info, severity: ChangeSeverity::Info,
summary: "New option `llvm.enzyme` to control whether the llvm based autodiff tool (Enzyme) is built.", summary: "New option `llvm.enzyme` to control whether the llvm based autodiff tool (Enzyme) is built.",
}, },
ChangeInfo {
change_id: 129473,
severity: ChangeSeverity::Warning,
summary: "`download-ci-llvm = true` now checks if CI llvm is available and has become the default for the compiler profile",
},
]; ];

View File

@ -0,0 +1,7 @@
use crate::command::Command;
use crate::env_var;
/// Returns a command that can be used to invoke Cargo.
pub fn cargo() -> Command {
Command::new(env_var("BOOTSTRAP_CARGO"))
}

View File

@ -2,6 +2,7 @@
//! such as `cc` or `python`. //! such as `cc` or `python`.
pub mod c_build; pub mod c_build;
pub mod cargo;
pub mod cc; pub mod cc;
pub mod clang; pub mod clang;
pub mod htmldocck; pub mod htmldocck;

View File

@ -36,10 +36,13 @@ pub struct Rustc {
crate::macros::impl_common_helpers!(Rustc); crate::macros::impl_common_helpers!(Rustc);
pub fn rustc_path() -> String {
env_var("RUSTC")
}
#[track_caller] #[track_caller]
fn setup_common() -> Command { fn setup_common() -> Command {
let rustc = env_var("RUSTC"); let mut cmd = Command::new(rustc_path());
let mut cmd = Command::new(rustc);
set_host_rpath(&mut cmd); set_host_rpath(&mut cmd);
cmd cmd
} }

View File

@ -50,6 +50,7 @@ pub use external_deps::{c_build, cc, clang, htmldocck, llvm, python, rustc, rust
// These rely on external dependencies. // These rely on external dependencies.
pub use cc::{cc, cxx, extra_c_flags, extra_cxx_flags, Cc}; pub use cc::{cc, cxx, extra_c_flags, extra_cxx_flags, Cc};
pub use c_build::{build_native_dynamic_lib, build_native_static_lib, build_native_static_lib_optimized, build_native_static_lib_cxx}; pub use c_build::{build_native_dynamic_lib, build_native_static_lib, build_native_static_lib_optimized, build_native_static_lib_cxx};
pub use cargo::cargo;
pub use clang::{clang, Clang}; pub use clang::{clang, Clang};
pub use htmldocck::htmldocck; pub use htmldocck::htmldocck;
pub use llvm::{ pub use llvm::{
@ -58,7 +59,7 @@ pub use llvm::{
LlvmProfdata, LlvmReadobj, LlvmProfdata, LlvmReadobj,
}; };
pub use python::python_command; pub use python::python_command;
pub use rustc::{aux_build, bare_rustc, rustc, Rustc}; pub use rustc::{aux_build, bare_rustc, rustc, rustc_path, Rustc};
pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc}; pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc};
/// [`diff`][mod@diff] is implemented in terms of the [similar] library. /// [`diff`][mod@diff] is implemented in terms of the [similar] library.
@ -98,3 +99,4 @@ pub use assertion_helpers::{
pub use string::{ pub use string::{
count_regex_matches_in_files_with_extension, invalid_utf8_contains, invalid_utf8_not_contains, count_regex_matches_in_files_with_extension, invalid_utf8_contains, invalid_utf8_not_contains,
}; };
use crate::external_deps::cargo;

View File

@ -20,3 +20,4 @@ pub extern "x86-interrupt" fn page_fault_handler(_: u64, _: u64) {
// CHECK: #[[ATTRS]] = // CHECK: #[[ATTRS]] =
// CHECK-NOT: sanitize_address // CHECK-NOT: sanitize_address
// CHECK: !llvm.module.flags

View File

@ -0,0 +1,36 @@
//! Checks if selected rustc crates can be compiled on the stable channel (or a "simulation" of it).
//! These crates are designed to be used by downstream users.
use run_make_support::{cargo, rustc_path, source_root};
fn main() {
// Use the stage0 beta cargo for the compilation (it shouldn't really matter which cargo we use)
cargo()
// Ensure `proc-macro2`'s nightly detection is disabled
.env("RUSTC_STAGE", "0")
.env("RUSTC", rustc_path())
// We want to disallow all nightly features to simulate a stable build
.env("RUSTFLAGS", "-Zallow-features=")
.arg("build")
.arg("--manifest-path")
.arg(source_root().join("Cargo.toml"))
.args(&[
// Avoid depending on transitive rustc crates
"--no-default-features",
// Emit artifacts in this temporary directory, not in the source_root's `target` folder
"--target-dir",
"target",
])
// Check that these crates can be compiled on "stable"
.args(&[
"-p",
"rustc_type_ir",
"-p",
"rustc_next_trait_solver",
"-p",
"rustc_pattern_analysis",
"-p",
"rustc_lexer",
])
.run();
}

View File

@ -2,37 +2,37 @@
#![feature(naked_functions)] #![feature(naked_functions)]
#![crate_type = "lib"] #![crate_type = "lib"]
use std::arch::asm; use std::arch::naked_asm;
#[naked] #[naked]
pub unsafe extern "C" fn inline_none() { pub unsafe extern "C" fn inline_none() {
asm!("", options(noreturn)); naked_asm!("");
} }
#[naked] #[naked]
#[inline] #[inline]
//~^ ERROR [E0736] //~^ ERROR [E0736]
pub unsafe extern "C" fn inline_hint() { pub unsafe extern "C" fn inline_hint() {
asm!("", options(noreturn)); naked_asm!("");
} }
#[naked] #[naked]
#[inline(always)] #[inline(always)]
//~^ ERROR [E0736] //~^ ERROR [E0736]
pub unsafe extern "C" fn inline_always() { pub unsafe extern "C" fn inline_always() {
asm!("", options(noreturn)); naked_asm!("");
} }
#[naked] #[naked]
#[inline(never)] #[inline(never)]
//~^ ERROR [E0736] //~^ ERROR [E0736]
pub unsafe extern "C" fn inline_never() { pub unsafe extern "C" fn inline_never() {
asm!("", options(noreturn)); naked_asm!("");
} }
#[naked] #[naked]
#[cfg_attr(all(), inline(never))] #[cfg_attr(all(), inline(never))]
//~^ ERROR [E0736] //~^ ERROR [E0736]
pub unsafe extern "C" fn conditional_inline_never() { pub unsafe extern "C" fn conditional_inline_never() {
asm!("", options(noreturn)); naked_asm!("");
} }

View File

@ -0,0 +1,27 @@
//@ compile-flags: -Zthreads=16
// original issue: https://github.com/rust-lang/rust/issues/129112
// Previously, the "next" solver asserted that each successful solution is only obtained once.
// This test exhibits a repro that, with next-solver + -Zthreads, triggered that old assert.
// In the presence of multithreaded solving, it's possible to concurrently evaluate things twice,
// which leads to replacing already-solved solutions in the global solution cache!
// We assume this is fine if we check to make sure they are solved the same way each time.
// This test only nondeterministically fails but that's okay, as it will be rerun by CI many times,
// so it should almost always fail before anything is merged. As other thread tests already exist,
// we already face this difficulty, probably. If we need to fix this by reducing the error margin,
// we should improve compiletest.
#[derive(Clone, Eq)] //~ ERROR [E0277]
pub struct Struct<T>(T);
impl<T: Clone, U> PartialEq<U> for Struct<T>
where
U: Into<Struct<T>> + Clone
{
fn eq(&self, _other: &U) -> bool {
todo!()
}
}
fn main() {}

View File

@ -0,0 +1,24 @@
error[E0277]: the trait bound `T: Clone` is not satisfied
--> $DIR/global-cache-and-parallel-frontend.rs:15:17
|
LL | #[derive(Clone, Eq)]
| ^^ the trait `Clone` is not implemented for `T`, which is required by `Struct<T>: PartialEq`
|
note: required for `Struct<T>` to implement `PartialEq`
--> $DIR/global-cache-and-parallel-frontend.rs:18:19
|
LL | impl<T: Clone, U> PartialEq<U> for Struct<T>
| ----- ^^^^^^^^^^^^ ^^^^^^^^^
| |
| unsatisfied trait bound introduced here
note: required by a bound in `Eq`
--> $SRC_DIR/core/src/cmp.rs:LL:COL
= note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `T`
|
LL | pub struct Struct<T: std::clone::Clone>(T);
| +++++++++++++++++++
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.