Auto merge of #121345 - Nilstrieb:rollup-reb0xge, r=Nilstrieb
Rollup of 8 pull requests Successful merges: - #121167 (resolve: Scale back unloading of speculatively loaded crates) - #121196 (Always inline check in `assert_unsafe_precondition` with cfg(debug_assertions)) - #121241 (Implement `NonZero` traits generically.) - #121278 (Remove the "codegen" profile from bootstrap) - #121286 (Rename `ConstPropLint` to `KnownPanicsLint`) - #121291 (target: Revert default to the medium code model on LoongArch targets) - #121302 (Remove `RefMutL` hack in `proc_macro::bridge`) - #121318 (Trigger `unsafe_code` lint on invocations of `global_asm`) Failed merges: - #121206 (Top level error handling) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
bb594538fc
@ -773,7 +773,7 @@ pub(super) fn expand_global_asm<'cx>(
|
|||||||
kind: ast::VisibilityKind::Inherited,
|
kind: ast::VisibilityKind::Inherited,
|
||||||
tokens: None,
|
tokens: None,
|
||||||
},
|
},
|
||||||
span: ecx.with_def_site_ctxt(sp),
|
span: sp,
|
||||||
tokens: None,
|
tokens: None,
|
||||||
})])
|
})])
|
||||||
} else {
|
} else {
|
||||||
|
@ -72,8 +72,11 @@ lint_builtin_explicit_outlives = outlives requirements can be inferred
|
|||||||
|
|
||||||
lint_builtin_export_name_fn = declaration of a function with `export_name`
|
lint_builtin_export_name_fn = declaration of a function with `export_name`
|
||||||
lint_builtin_export_name_method = declaration of a method with `export_name`
|
lint_builtin_export_name_method = declaration of a method with `export_name`
|
||||||
|
|
||||||
lint_builtin_export_name_static = declaration of a static with `export_name`
|
lint_builtin_export_name_static = declaration of a static with `export_name`
|
||||||
|
|
||||||
|
lint_builtin_global_asm = usage of `core::arch::global_asm`
|
||||||
|
lint_builtin_global_macro_unsafety = using this macro is unsafe even though it does not need an `unsafe` block
|
||||||
|
|
||||||
lint_builtin_impl_unsafe_method = implementation of an `unsafe` method
|
lint_builtin_impl_unsafe_method = implementation of an `unsafe` method
|
||||||
|
|
||||||
lint_builtin_incomplete_features = the feature `{$name}` is incomplete and may not be safe to use and/or cause compiler crashes
|
lint_builtin_incomplete_features = the feature `{$name}` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
@ -393,6 +393,10 @@ fn check_item(&mut self, cx: &EarlyContext<'_>, it: &ast::Item) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ast::ItemKind::GlobalAsm(..) => {
|
||||||
|
self.report_unsafe(cx, it.span, BuiltinUnsafe::GlobalAsm);
|
||||||
|
}
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,6 +114,9 @@ pub enum BuiltinUnsafe {
|
|||||||
DeclUnsafeMethod,
|
DeclUnsafeMethod,
|
||||||
#[diag(lint_builtin_impl_unsafe_method)]
|
#[diag(lint_builtin_impl_unsafe_method)]
|
||||||
ImplUnsafeMethod,
|
ImplUnsafeMethod,
|
||||||
|
#[diag(lint_builtin_global_asm)]
|
||||||
|
#[note(lint_builtin_global_macro_unsafety)]
|
||||||
|
GlobalAsm,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(LintDiagnostic)]
|
#[derive(LintDiagnostic)]
|
||||||
|
@ -1070,16 +1070,6 @@ pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> Option<CrateN
|
|||||||
pub fn maybe_process_path_extern(&mut self, name: Symbol) -> Option<CrateNum> {
|
pub fn maybe_process_path_extern(&mut self, name: Symbol) -> Option<CrateNum> {
|
||||||
self.maybe_resolve_crate(name, CrateDepKind::Explicit, None).ok()
|
self.maybe_resolve_crate(name, CrateDepKind::Explicit, None).ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unload_unused_crates(&mut self) {
|
|
||||||
for opt_cdata in &mut self.cstore.metas {
|
|
||||||
if let Some(cdata) = opt_cdata
|
|
||||||
&& !cdata.used()
|
|
||||||
{
|
|
||||||
*opt_cdata = None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn global_allocator_spans(krate: &ast::Crate) -> Vec<Span> {
|
fn global_allocator_spans(krate: &ast::Crate) -> Vec<Span> {
|
||||||
|
@ -519,6 +519,16 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
|
|||||||
tcx.untracked().cstore.freeze();
|
tcx.untracked().cstore.freeze();
|
||||||
tcx.arena.alloc_from_iter(CStore::from_tcx(tcx).iter_crate_data().map(|(cnum, _)| cnum))
|
tcx.arena.alloc_from_iter(CStore::from_tcx(tcx).iter_crate_data().map(|(cnum, _)| cnum))
|
||||||
},
|
},
|
||||||
|
used_crates: |tcx, ()| {
|
||||||
|
// The list of loaded crates is now frozen in query cache,
|
||||||
|
// so make sure cstore is not mutably accessed from here on.
|
||||||
|
tcx.untracked().cstore.freeze();
|
||||||
|
tcx.arena.alloc_from_iter(
|
||||||
|
CStore::from_tcx(tcx)
|
||||||
|
.iter_crate_data()
|
||||||
|
.filter_map(|(cnum, data)| data.used().then_some(cnum)),
|
||||||
|
)
|
||||||
|
},
|
||||||
..providers.queries
|
..providers.queries
|
||||||
};
|
};
|
||||||
provide_extern(&mut providers.extern_queries);
|
provide_extern(&mut providers.extern_queries);
|
||||||
|
@ -1872,6 +1872,13 @@
|
|||||||
eval_always
|
eval_always
|
||||||
desc { "fetching all foreign CrateNum instances" }
|
desc { "fetching all foreign CrateNum instances" }
|
||||||
}
|
}
|
||||||
|
// Crates that are loaded non-speculatively (not for diagnostics or doc links).
|
||||||
|
// FIXME: This is currently only used for collecting lang items, but should be used instead of
|
||||||
|
// `crates` in most other cases too.
|
||||||
|
query used_crates(_: ()) -> &'tcx [CrateNum] {
|
||||||
|
eval_always
|
||||||
|
desc { "fetching `CrateNum`s for all crates loaded non-speculatively" }
|
||||||
|
}
|
||||||
|
|
||||||
/// A list of all traits in a crate, used by rustdoc and error reporting.
|
/// A list of all traits in a crate, used by rustdoc and error reporting.
|
||||||
query traits(_: CrateNum) -> &'tcx [DefId] {
|
query traits(_: CrateNum) -> &'tcx [DefId] {
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
//! Propagates constants for early reporting of statically known
|
//! A lint that checks for known panics like
|
||||||
//! assertion failures
|
//! overflows, division by zero,
|
||||||
|
//! out-of-bound access etc.
|
||||||
|
//! Uses const propagation to determine the
|
||||||
|
//! values of operands during checks.
|
||||||
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
@ -21,9 +24,9 @@
|
|||||||
use crate::errors::{AssertLint, AssertLintKind};
|
use crate::errors::{AssertLint, AssertLintKind};
|
||||||
use crate::MirLint;
|
use crate::MirLint;
|
||||||
|
|
||||||
pub struct ConstPropLint;
|
pub struct KnownPanicsLint;
|
||||||
|
|
||||||
impl<'tcx> MirLint<'tcx> for ConstPropLint {
|
impl<'tcx> MirLint<'tcx> for KnownPanicsLint {
|
||||||
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
|
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
|
||||||
if body.tainted_by_errors.is_some() {
|
if body.tainted_by_errors.is_some() {
|
||||||
return;
|
return;
|
||||||
@ -37,31 +40,28 @@ fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
|
|||||||
// Only run const prop on functions, methods, closures and associated constants
|
// Only run const prop on functions, methods, closures and associated constants
|
||||||
if !is_fn_like && !is_assoc_const {
|
if !is_fn_like && !is_assoc_const {
|
||||||
// skip anon_const/statics/consts because they'll be evaluated by miri anyway
|
// skip anon_const/statics/consts because they'll be evaluated by miri anyway
|
||||||
trace!("ConstPropLint skipped for {:?}", def_id);
|
trace!("KnownPanicsLint skipped for {:?}", def_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(welseywiser) const prop doesn't work on coroutines because of query cycles
|
// FIXME(welseywiser) const prop doesn't work on coroutines because of query cycles
|
||||||
// computing their layout.
|
// computing their layout.
|
||||||
if tcx.is_coroutine(def_id.to_def_id()) {
|
if tcx.is_coroutine(def_id.to_def_id()) {
|
||||||
trace!("ConstPropLint skipped for coroutine {:?}", def_id);
|
trace!("KnownPanicsLint skipped for coroutine {:?}", def_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace!("ConstPropLint starting for {:?}", def_id);
|
trace!("KnownPanicsLint starting for {:?}", def_id);
|
||||||
|
|
||||||
// FIXME(oli-obk, eddyb) Optimize locals (or even local paths) to hold
|
|
||||||
// constants, instead of just checking for const-folding succeeding.
|
|
||||||
// That would require a uniform one-def no-mutation analysis
|
|
||||||
// and RPO (or recursing when needing the value of a local).
|
|
||||||
let mut linter = ConstPropagator::new(body, tcx);
|
let mut linter = ConstPropagator::new(body, tcx);
|
||||||
linter.visit_body(body);
|
linter.visit_body(body);
|
||||||
|
|
||||||
trace!("ConstPropLint done for {:?}", def_id);
|
trace!("KnownPanicsLint done for {:?}", def_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finds optimization opportunities on the MIR.
|
/// Visits MIR nodes, performs const propagation
|
||||||
|
/// and runs lint checks as it goes
|
||||||
struct ConstPropagator<'mir, 'tcx> {
|
struct ConstPropagator<'mir, 'tcx> {
|
||||||
ecx: InterpCx<'mir, 'tcx, DummyMachine>,
|
ecx: InterpCx<'mir, 'tcx, DummyMachine>,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
@ -238,7 +238,7 @@ fn use_ecx<F, T>(&mut self, f: F) -> Option<T>
|
|||||||
// dedicated error variants should be introduced instead.
|
// dedicated error variants should be introduced instead.
|
||||||
assert!(
|
assert!(
|
||||||
!error.kind().formatted_string(),
|
!error.kind().formatted_string(),
|
||||||
"const-prop encountered formatting error: {}",
|
"known panics lint encountered formatting error: {}",
|
||||||
format_interp_error(self.ecx.tcx.dcx(), error),
|
format_interp_error(self.ecx.tcx.dcx(), error),
|
||||||
);
|
);
|
||||||
None
|
None
|
||||||
@ -253,7 +253,7 @@ fn eval_constant(&mut self, c: &ConstOperand<'tcx>) -> Option<ImmTy<'tcx>> {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalization needed b/c const prop lint runs in
|
// Normalization needed b/c known panics lint runs in
|
||||||
// `mir_drops_elaborated_and_const_checked`, which happens before
|
// `mir_drops_elaborated_and_const_checked`, which happens before
|
||||||
// optimized MIR. Only after optimizing the MIR can we guarantee
|
// optimized MIR. Only after optimizing the MIR can we guarantee
|
||||||
// that the `RevealAll` pass has happened and that the body's consts
|
// that the `RevealAll` pass has happened and that the body's consts
|
||||||
@ -864,6 +864,8 @@ pub enum ConstPropMode {
|
|||||||
NoPropagation,
|
NoPropagation,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A visitor that determines locals in a MIR body
|
||||||
|
/// that can be const propagated
|
||||||
pub struct CanConstProp {
|
pub struct CanConstProp {
|
||||||
can_const_prop: IndexVec<Local, ConstPropMode>,
|
can_const_prop: IndexVec<Local, ConstPropMode>,
|
||||||
// False at the beginning. Once set, no more assignments are allowed to that local.
|
// False at the beginning. Once set, no more assignments are allowed to that local.
|
@ -59,7 +59,6 @@
|
|||||||
mod add_subtyping_projections;
|
mod add_subtyping_projections;
|
||||||
pub mod cleanup_post_borrowck;
|
pub mod cleanup_post_borrowck;
|
||||||
mod const_debuginfo;
|
mod const_debuginfo;
|
||||||
mod const_prop_lint;
|
|
||||||
mod copy_prop;
|
mod copy_prop;
|
||||||
mod coroutine;
|
mod coroutine;
|
||||||
mod cost_checker;
|
mod cost_checker;
|
||||||
@ -83,6 +82,7 @@
|
|||||||
pub mod inline;
|
pub mod inline;
|
||||||
mod instsimplify;
|
mod instsimplify;
|
||||||
mod jump_threading;
|
mod jump_threading;
|
||||||
|
mod known_panics_lint;
|
||||||
mod large_enums;
|
mod large_enums;
|
||||||
mod lint;
|
mod lint;
|
||||||
mod lower_intrinsics;
|
mod lower_intrinsics;
|
||||||
@ -533,7 +533,7 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
|||||||
&elaborate_box_derefs::ElaborateBoxDerefs,
|
&elaborate_box_derefs::ElaborateBoxDerefs,
|
||||||
&coroutine::StateTransform,
|
&coroutine::StateTransform,
|
||||||
&add_retag::AddRetag,
|
&add_retag::AddRetag,
|
||||||
&Lint(const_prop_lint::ConstPropLint),
|
&Lint(known_panics_lint::KnownPanicsLint),
|
||||||
];
|
];
|
||||||
pm::run_passes_no_validate(tcx, body, passes, Some(MirPhase::Runtime(RuntimePhase::Initial)));
|
pm::run_passes_no_validate(tcx, body, passes, Some(MirPhase::Runtime(RuntimePhase::Initial)));
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,7 @@ fn get_lang_items(tcx: TyCtxt<'_>, (): ()) -> LanguageItems {
|
|||||||
let mut collector = LanguageItemCollector::new(tcx, resolver);
|
let mut collector = LanguageItemCollector::new(tcx, resolver);
|
||||||
|
|
||||||
// Collect lang items in other crates.
|
// Collect lang items in other crates.
|
||||||
for &cnum in tcx.crates(()).iter() {
|
for &cnum in tcx.used_crates(()).iter() {
|
||||||
for &(def_id, lang_item) in tcx.defined_lang_items(cnum).iter() {
|
for &(def_id, lang_item) in tcx.defined_lang_items(cnum).iter() {
|
||||||
collector.collect_item(lang_item, def_id, None);
|
collector.collect_item(lang_item, def_id, None);
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS};
|
use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS};
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
|
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
|
||||||
use rustc_hir::{PrimTy, TraitCandidate};
|
use rustc_hir::{PrimTy, TraitCandidate};
|
||||||
use rustc_metadata::creader::CStore;
|
|
||||||
use rustc_middle::middle::resolve_bound_vars::Set1;
|
use rustc_middle::middle::resolve_bound_vars::Set1;
|
||||||
use rustc_middle::{bug, span_bug};
|
use rustc_middle::{bug, span_bug};
|
||||||
use rustc_session::config::{CrateType, ResolveDocLinks};
|
use rustc_session::config::{CrateType, ResolveDocLinks};
|
||||||
@ -4574,10 +4573,6 @@ fn resolve_and_cache_rustdoc_path(&mut self, path_str: &str, ns: Namespace) -> O
|
|||||||
// Encoding foreign def ids in proc macro crate metadata will ICE.
|
// Encoding foreign def ids in proc macro crate metadata will ICE.
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
// Doc paths should be resolved speculatively and should not produce any
|
|
||||||
// diagnostics, but if they are indeed resolved, then we need to keep the
|
|
||||||
// corresponding crate alive.
|
|
||||||
CStore::from_tcx_mut(self.r.tcx).set_used_recursively(def_id.krate);
|
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
});
|
});
|
||||||
|
@ -1651,7 +1651,6 @@ pub fn resolve_crate(&mut self, krate: &Crate) {
|
|||||||
self.tcx
|
self.tcx
|
||||||
.sess
|
.sess
|
||||||
.time("resolve_postprocess", || self.crate_loader(|c| c.postprocess(krate)));
|
.time("resolve_postprocess", || self.crate_loader(|c| c.postprocess(krate)));
|
||||||
self.crate_loader(|c| c.unload_unused_crates());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Make sure we don't mutate the cstore from here on.
|
// Make sure we don't mutate the cstore from here on.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::spec::{base, CodeModel, Target, TargetOptions};
|
use crate::spec::{base, Target, TargetOptions};
|
||||||
|
|
||||||
pub fn target() -> Target {
|
pub fn target() -> Target {
|
||||||
Target {
|
Target {
|
||||||
@ -7,7 +7,6 @@ pub fn target() -> Target {
|
|||||||
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(),
|
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(),
|
||||||
arch: "loongarch64".into(),
|
arch: "loongarch64".into(),
|
||||||
options: TargetOptions {
|
options: TargetOptions {
|
||||||
code_model: Some(CodeModel::Medium),
|
|
||||||
cpu: "generic".into(),
|
cpu: "generic".into(),
|
||||||
features: "+f,+d".into(),
|
features: "+f,+d".into(),
|
||||||
llvm_abiname: "lp64d".into(),
|
llvm_abiname: "lp64d".into(),
|
||||||
|
@ -16,7 +16,7 @@ pub fn target() -> Target {
|
|||||||
max_atomic_width: Some(64),
|
max_atomic_width: Some(64),
|
||||||
relocation_model: RelocModel::Static,
|
relocation_model: RelocModel::Static,
|
||||||
panic_strategy: PanicStrategy::Abort,
|
panic_strategy: PanicStrategy::Abort,
|
||||||
code_model: Some(CodeModel::Medium),
|
code_model: Some(CodeModel::Small),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ pub fn target() -> Target {
|
|||||||
max_atomic_width: Some(64),
|
max_atomic_width: Some(64),
|
||||||
relocation_model: RelocModel::Static,
|
relocation_model: RelocModel::Static,
|
||||||
panic_strategy: PanicStrategy::Abort,
|
panic_strategy: PanicStrategy::Abort,
|
||||||
code_model: Some(CodeModel::Medium),
|
code_model: Some(CodeModel::Small),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -2575,6 +2575,7 @@ pub const fn is_val_statically_known<T: Copy>(_arg: T) -> bool {
|
|||||||
/// assertions disabled. This intrinsic is primarily used by [`assert_unsafe_precondition`].
|
/// assertions disabled. This intrinsic is primarily used by [`assert_unsafe_precondition`].
|
||||||
#[rustc_const_unstable(feature = "delayed_debug_assertions", issue = "none")]
|
#[rustc_const_unstable(feature = "delayed_debug_assertions", issue = "none")]
|
||||||
#[unstable(feature = "core_intrinsics", issue = "none")]
|
#[unstable(feature = "core_intrinsics", issue = "none")]
|
||||||
|
#[inline(always)]
|
||||||
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
|
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
|
||||||
pub(crate) const fn debug_assertions() -> bool {
|
pub(crate) const fn debug_assertions() -> bool {
|
||||||
cfg!(debug_assertions)
|
cfg!(debug_assertions)
|
||||||
@ -2659,7 +2660,13 @@ pub(crate) const fn debug_assertions() -> bool {
|
|||||||
macro_rules! assert_unsafe_precondition {
|
macro_rules! assert_unsafe_precondition {
|
||||||
($message:expr, ($($name:ident:$ty:ty = $arg:expr),*$(,)?) => $e:expr $(,)?) => {
|
($message:expr, ($($name:ident:$ty:ty = $arg:expr),*$(,)?) => $e:expr $(,)?) => {
|
||||||
{
|
{
|
||||||
#[inline(never)]
|
// When the standard library is compiled with debug assertions, we want the check to inline for better performance.
|
||||||
|
// This is important when working on the compiler, which is compiled with debug assertions locally.
|
||||||
|
// When not compiled with debug assertions (so the precompiled std) we outline the check to minimize the compile
|
||||||
|
// time impact when debug assertions are disabled.
|
||||||
|
// It is not clear whether that is the best solution, see #120848.
|
||||||
|
#[cfg_attr(debug_assertions, inline(always))]
|
||||||
|
#[cfg_attr(not(debug_assertions), inline(never))]
|
||||||
#[rustc_nounwind]
|
#[rustc_nounwind]
|
||||||
fn precondition_check($($name:$ty),*) {
|
fn precondition_check($($name:$ty),*) {
|
||||||
if !$e {
|
if !$e {
|
||||||
|
@ -81,6 +81,217 @@ impl const ZeroablePrimitive for $primitive {}
|
|||||||
#[rustc_diagnostic_item = "NonZero"]
|
#[rustc_diagnostic_item = "NonZero"]
|
||||||
pub struct NonZero<T: ZeroablePrimitive>(T);
|
pub struct NonZero<T: ZeroablePrimitive>(T);
|
||||||
|
|
||||||
|
macro_rules! impl_nonzero_fmt {
|
||||||
|
($Trait:ident) => {
|
||||||
|
#[stable(feature = "nonzero", since = "1.28.0")]
|
||||||
|
impl<T> fmt::$Trait for NonZero<T>
|
||||||
|
where
|
||||||
|
T: ZeroablePrimitive + fmt::$Trait,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
self.get().fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_nonzero_fmt!(Debug);
|
||||||
|
impl_nonzero_fmt!(Display);
|
||||||
|
impl_nonzero_fmt!(Binary);
|
||||||
|
impl_nonzero_fmt!(Octal);
|
||||||
|
impl_nonzero_fmt!(LowerHex);
|
||||||
|
impl_nonzero_fmt!(UpperHex);
|
||||||
|
|
||||||
|
#[stable(feature = "nonzero", since = "1.28.0")]
|
||||||
|
impl<T> Clone for NonZero<T>
|
||||||
|
where
|
||||||
|
T: ZeroablePrimitive,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
// SAFETY: The contained value is non-zero.
|
||||||
|
unsafe { Self(self.0) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "nonzero", since = "1.28.0")]
|
||||||
|
impl<T> Copy for NonZero<T> where T: ZeroablePrimitive {}
|
||||||
|
|
||||||
|
#[stable(feature = "nonzero", since = "1.28.0")]
|
||||||
|
impl<T> PartialEq for NonZero<T>
|
||||||
|
where
|
||||||
|
T: ZeroablePrimitive + PartialEq,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.get() == other.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn ne(&self, other: &Self) -> bool {
|
||||||
|
self.get() != other.get()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "structural_match", issue = "31434")]
|
||||||
|
impl<T> StructuralPartialEq for NonZero<T> where T: ZeroablePrimitive + StructuralPartialEq {}
|
||||||
|
|
||||||
|
#[stable(feature = "nonzero", since = "1.28.0")]
|
||||||
|
impl<T> Eq for NonZero<T> where T: ZeroablePrimitive + Eq {}
|
||||||
|
|
||||||
|
#[stable(feature = "nonzero", since = "1.28.0")]
|
||||||
|
impl<T> PartialOrd for NonZero<T>
|
||||||
|
where
|
||||||
|
T: ZeroablePrimitive + PartialOrd,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
self.get().partial_cmp(&other.get())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn lt(&self, other: &Self) -> bool {
|
||||||
|
self.get() < other.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn le(&self, other: &Self) -> bool {
|
||||||
|
self.get() <= other.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn gt(&self, other: &Self) -> bool {
|
||||||
|
self.get() > other.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn ge(&self, other: &Self) -> bool {
|
||||||
|
self.get() >= other.get()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "nonzero", since = "1.28.0")]
|
||||||
|
impl<T> Ord for NonZero<T>
|
||||||
|
where
|
||||||
|
T: ZeroablePrimitive + Ord,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
self.get().cmp(&other.get())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn max(self, other: Self) -> Self {
|
||||||
|
// SAFETY: The maximum of two non-zero values is still non-zero.
|
||||||
|
unsafe { Self(self.get().max(other.get())) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn min(self, other: Self) -> Self {
|
||||||
|
// SAFETY: The minimum of two non-zero values is still non-zero.
|
||||||
|
unsafe { Self(self.get().min(other.get())) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn clamp(self, min: Self, max: Self) -> Self {
|
||||||
|
// SAFETY: A non-zero value clamped between two non-zero values is still non-zero.
|
||||||
|
unsafe { Self(self.get().clamp(min.get(), max.get())) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "nonzero", since = "1.28.0")]
|
||||||
|
impl<T> Hash for NonZero<T>
|
||||||
|
where
|
||||||
|
T: ZeroablePrimitive + Hash,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn hash<H>(&self, state: &mut H)
|
||||||
|
where
|
||||||
|
H: Hasher,
|
||||||
|
{
|
||||||
|
self.get().hash(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "from_nonzero", since = "1.31.0")]
|
||||||
|
impl<T> From<NonZero<T>> for T
|
||||||
|
where
|
||||||
|
T: ZeroablePrimitive,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn from(nonzero: NonZero<T>) -> Self {
|
||||||
|
// Call `get` method to keep range information.
|
||||||
|
nonzero.get()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
||||||
|
impl<T> BitOr for NonZero<T>
|
||||||
|
where
|
||||||
|
T: ZeroablePrimitive + BitOr<Output = T>,
|
||||||
|
{
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn bitor(self, rhs: Self) -> Self::Output {
|
||||||
|
// SAFETY: Bitwise OR of two non-zero values is still non-zero.
|
||||||
|
unsafe { Self(self.get() | rhs.get()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
||||||
|
impl<T> BitOr<T> for NonZero<T>
|
||||||
|
where
|
||||||
|
T: ZeroablePrimitive + BitOr<Output = T>,
|
||||||
|
{
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn bitor(self, rhs: T) -> Self::Output {
|
||||||
|
// SAFETY: Bitwise OR of a non-zero value with anything is still non-zero.
|
||||||
|
unsafe { Self(self.get() | rhs) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
||||||
|
impl<T> BitOr<NonZero<T>> for T
|
||||||
|
where
|
||||||
|
T: ZeroablePrimitive + BitOr<Output = T>,
|
||||||
|
{
|
||||||
|
type Output = NonZero<T>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn bitor(self, rhs: NonZero<T>) -> Self::Output {
|
||||||
|
// SAFETY: Bitwise OR of anything with a non-zero value is still non-zero.
|
||||||
|
unsafe { NonZero(self | rhs.get()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
||||||
|
impl<T> BitOrAssign for NonZero<T>
|
||||||
|
where
|
||||||
|
T: ZeroablePrimitive,
|
||||||
|
Self: BitOr<Output = Self>,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn bitor_assign(&mut self, rhs: Self) {
|
||||||
|
*self = *self | rhs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
||||||
|
impl<T> BitOrAssign<T> for NonZero<T>
|
||||||
|
where
|
||||||
|
T: ZeroablePrimitive,
|
||||||
|
Self: BitOr<T, Output = Self>,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn bitor_assign(&mut self, rhs: T) {
|
||||||
|
*self = *self | rhs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> NonZero<T>
|
impl<T> NonZero<T>
|
||||||
where
|
where
|
||||||
T: ZeroablePrimitive,
|
T: ZeroablePrimitive,
|
||||||
@ -183,20 +394,6 @@ pub const fn get(self) -> T {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_nonzero_fmt {
|
|
||||||
( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
|
|
||||||
$(
|
|
||||||
#[$stability]
|
|
||||||
impl fmt::$Trait for $Ty {
|
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
self.get().fmt(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! nonzero_integer {
|
macro_rules! nonzero_integer {
|
||||||
(
|
(
|
||||||
#[$stability:meta]
|
#[$stability:meta]
|
||||||
@ -549,171 +746,6 @@ pub const fn saturating_pow(self, other: u32) -> Self {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[$stability]
|
|
||||||
impl Clone for $Ty {
|
|
||||||
#[inline]
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
// SAFETY: The contained value is non-zero.
|
|
||||||
unsafe { Self(self.0) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[$stability]
|
|
||||||
impl Copy for $Ty {}
|
|
||||||
|
|
||||||
#[$stability]
|
|
||||||
impl PartialEq for $Ty {
|
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.0 == other.0
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn ne(&self, other: &Self) -> bool {
|
|
||||||
self.0 != other.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unstable(feature = "structural_match", issue = "31434")]
|
|
||||||
impl StructuralPartialEq for $Ty {}
|
|
||||||
|
|
||||||
#[$stability]
|
|
||||||
impl Eq for $Ty {}
|
|
||||||
|
|
||||||
#[$stability]
|
|
||||||
impl PartialOrd for $Ty {
|
|
||||||
#[inline]
|
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
|
||||||
self.0.partial_cmp(&other.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn lt(&self, other: &Self) -> bool {
|
|
||||||
self.0 < other.0
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn le(&self, other: &Self) -> bool {
|
|
||||||
self.0 <= other.0
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn gt(&self, other: &Self) -> bool {
|
|
||||||
self.0 > other.0
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn ge(&self, other: &Self) -> bool {
|
|
||||||
self.0 >= other.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[$stability]
|
|
||||||
impl Ord for $Ty {
|
|
||||||
#[inline]
|
|
||||||
fn cmp(&self, other: &Self) -> Ordering {
|
|
||||||
self.0.cmp(&other.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn max(self, other: Self) -> Self {
|
|
||||||
// SAFETY: The maximum of two non-zero values is still non-zero.
|
|
||||||
unsafe { Self(self.0.max(other.0)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn min(self, other: Self) -> Self {
|
|
||||||
// SAFETY: The minimum of two non-zero values is still non-zero.
|
|
||||||
unsafe { Self(self.0.min(other.0)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn clamp(self, min: Self, max: Self) -> Self {
|
|
||||||
// SAFETY: A non-zero value clamped between two non-zero values is still non-zero.
|
|
||||||
unsafe { Self(self.0.clamp(min.0, max.0)) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[$stability]
|
|
||||||
impl Hash for $Ty {
|
|
||||||
#[inline]
|
|
||||||
fn hash<H>(&self, state: &mut H)
|
|
||||||
where
|
|
||||||
H: Hasher,
|
|
||||||
{
|
|
||||||
self.0.hash(state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "from_nonzero", since = "1.31.0")]
|
|
||||||
impl From<$Ty> for $Int {
|
|
||||||
#[doc = concat!("Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`")]
|
|
||||||
#[inline]
|
|
||||||
fn from(nonzero: $Ty) -> Self {
|
|
||||||
// Call nonzero to keep information range information
|
|
||||||
// from get method.
|
|
||||||
nonzero.get()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
|
||||||
impl BitOr for $Ty {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn bitor(self, rhs: Self) -> Self::Output {
|
|
||||||
// SAFETY: since `self` and `rhs` are both nonzero, the
|
|
||||||
// result of the bitwise-or will be nonzero.
|
|
||||||
unsafe { Self::new_unchecked(self.get() | rhs.get()) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
|
||||||
impl BitOr<$Int> for $Ty {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn bitor(self, rhs: $Int) -> Self::Output {
|
|
||||||
// SAFETY: since `self` is nonzero, the result of the
|
|
||||||
// bitwise-or will be nonzero regardless of the value of
|
|
||||||
// `rhs`.
|
|
||||||
unsafe { Self::new_unchecked(self.get() | rhs) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
|
||||||
impl BitOr<$Ty> for $Int {
|
|
||||||
type Output = $Ty;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn bitor(self, rhs: $Ty) -> Self::Output {
|
|
||||||
// SAFETY: since `rhs` is nonzero, the result of the
|
|
||||||
// bitwise-or will be nonzero regardless of the value of
|
|
||||||
// `self`.
|
|
||||||
unsafe { $Ty::new_unchecked(self | rhs.get()) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
|
||||||
impl BitOrAssign for $Ty {
|
|
||||||
#[inline]
|
|
||||||
fn bitor_assign(&mut self, rhs: Self) {
|
|
||||||
*self = *self | rhs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
|
|
||||||
impl BitOrAssign<$Int> for $Ty {
|
|
||||||
#[inline]
|
|
||||||
fn bitor_assign(&mut self, rhs: $Int) {
|
|
||||||
*self = *self | rhs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_nonzero_fmt! {
|
|
||||||
#[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "nonzero_parse", since = "1.35.0")]
|
#[stable(feature = "nonzero_parse", since = "1.35.0")]
|
||||||
impl FromStr for $Ty {
|
impl FromStr for $Ty {
|
||||||
type Err = ParseIntError;
|
type Err = ParseIntError;
|
||||||
|
@ -296,12 +296,7 @@ impl BridgeState<'_> {
|
|||||||
/// N.B., while `f` is running, the thread-local state
|
/// N.B., while `f` is running, the thread-local state
|
||||||
/// is `BridgeState::InUse`.
|
/// is `BridgeState::InUse`.
|
||||||
fn with<R>(f: impl FnOnce(&mut BridgeState<'_>) -> R) -> R {
|
fn with<R>(f: impl FnOnce(&mut BridgeState<'_>) -> R) -> R {
|
||||||
BRIDGE_STATE.with(|state| {
|
BRIDGE_STATE.with(|state| state.replace(BridgeState::InUse, f))
|
||||||
state.replace(BridgeState::InUse, |mut state| {
|
|
||||||
// FIXME(#52812) pass `f` directly to `replace` when `RefMutL` is gone
|
|
||||||
f(&mut *state)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::{Deref, DerefMut};
|
|
||||||
|
|
||||||
/// Type lambda application, with a lifetime.
|
/// Type lambda application, with a lifetime.
|
||||||
#[allow(unused_lifetimes)]
|
#[allow(unused_lifetimes)]
|
||||||
@ -15,23 +14,6 @@ pub trait LambdaL: for<'a> ApplyL<'a> {}
|
|||||||
|
|
||||||
impl<T: for<'a> ApplyL<'a>> LambdaL for T {}
|
impl<T: for<'a> ApplyL<'a>> LambdaL for T {}
|
||||||
|
|
||||||
// HACK(eddyb) work around projection limitations with a newtype
|
|
||||||
// FIXME(#52812) replace with `&'a mut <T as ApplyL<'b>>::Out`
|
|
||||||
pub struct RefMutL<'a, 'b, T: LambdaL>(&'a mut <T as ApplyL<'b>>::Out);
|
|
||||||
|
|
||||||
impl<'a, 'b, T: LambdaL> Deref for RefMutL<'a, 'b, T> {
|
|
||||||
type Target = <T as ApplyL<'b>>::Out;
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'b, T: LambdaL> DerefMut for RefMutL<'a, 'b, T> {
|
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ScopedCell<T: LambdaL>(Cell<<T as ApplyL<'static>>::Out>);
|
pub struct ScopedCell<T: LambdaL>(Cell<<T as ApplyL<'static>>::Out>);
|
||||||
|
|
||||||
impl<T: LambdaL> ScopedCell<T> {
|
impl<T: LambdaL> ScopedCell<T> {
|
||||||
@ -46,7 +28,7 @@ pub const fn new(value: <T as ApplyL<'static>>::Out) -> Self {
|
|||||||
pub fn replace<'a, R>(
|
pub fn replace<'a, R>(
|
||||||
&self,
|
&self,
|
||||||
replacement: <T as ApplyL<'a>>::Out,
|
replacement: <T as ApplyL<'a>>::Out,
|
||||||
f: impl for<'b, 'c> FnOnce(RefMutL<'b, 'c, T>) -> R,
|
f: impl for<'b, 'c> FnOnce(&'b mut <T as ApplyL<'c>>::Out) -> R,
|
||||||
) -> R {
|
) -> R {
|
||||||
/// Wrapper that ensures that the cell always gets filled
|
/// Wrapper that ensures that the cell always gets filled
|
||||||
/// (with the original state, optionally changed by `f`),
|
/// (with the original state, optionally changed by `f`),
|
||||||
@ -71,7 +53,7 @@ fn drop(&mut self) {
|
|||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
|
|
||||||
f(RefMutL(put_back_on_drop.value.as_mut().unwrap()))
|
f(put_back_on_drop.value.as_mut().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the value in `self` to `value` while running `f`.
|
/// Sets the value in `self` to `value` while running `f`.
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
# These defaults are meant for contributors to the compiler who modify codegen or LLVM
|
|
||||||
[build]
|
|
||||||
# Contributors working on the compiler will probably expect compiler docs to be generated.
|
|
||||||
compiler-docs = true
|
|
||||||
|
|
||||||
[llvm]
|
|
||||||
# This enables debug-assertions in LLVM,
|
|
||||||
# catching logic errors in codegen much earlier in the process.
|
|
||||||
assertions = true
|
|
||||||
# enable warnings during the llvm compilation
|
|
||||||
enable-warnings = true
|
|
||||||
# build llvm from source
|
|
||||||
download-ci-llvm = "if-unchanged"
|
|
||||||
|
|
||||||
[rust]
|
|
||||||
# This enables `RUSTC_LOG=debug`, avoiding confusing situations
|
|
||||||
# where adding `debug!()` appears to do nothing.
|
|
||||||
# However, it makes running the compiler slightly slower.
|
|
||||||
debug-logging = true
|
|
||||||
# This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower.
|
|
||||||
incremental = true
|
|
||||||
# Print backtrace on internal compiler errors during bootstrap
|
|
||||||
backtrace-on-ice = true
|
|
||||||
# Make the compiler and standard library faster to build, at the expense of a ~20% runtime slowdown.
|
|
||||||
lto = "off"
|
|
||||||
# Forces frame pointers to be used with `-Cforce-frame-pointers`.
|
|
||||||
# This can be helpful for profiling at a small performance cost.
|
|
||||||
frame-pointers = true
|
|
@ -19,5 +19,10 @@ lto = "off"
|
|||||||
frame-pointers = true
|
frame-pointers = true
|
||||||
|
|
||||||
[llvm]
|
[llvm]
|
||||||
|
# This enables debug-assertions in LLVM,
|
||||||
|
# catching logic errors in codegen much earlier in the process.
|
||||||
|
assertions = true
|
||||||
|
# Enable warnings during the LLVM compilation (when LLVM is changed, causing a compilation)
|
||||||
|
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"
|
download-ci-llvm = "if-unchanged"
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||||
pub enum Profile {
|
pub enum Profile {
|
||||||
Compiler,
|
Compiler,
|
||||||
Codegen,
|
|
||||||
Library,
|
Library,
|
||||||
Tools,
|
Tools,
|
||||||
Dist,
|
Dist,
|
||||||
@ -48,7 +47,7 @@ fn include_path(&self, src_path: &Path) -> PathBuf {
|
|||||||
pub fn all() -> impl Iterator<Item = Self> {
|
pub fn all() -> impl Iterator<Item = Self> {
|
||||||
use Profile::*;
|
use Profile::*;
|
||||||
// N.B. these are ordered by how they are displayed, not alphabetically
|
// N.B. these are ordered by how they are displayed, not alphabetically
|
||||||
[Library, Compiler, Codegen, Tools, Dist, None].iter().copied()
|
[Library, Compiler, Tools, Dist, None].iter().copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn purpose(&self) -> String {
|
pub fn purpose(&self) -> String {
|
||||||
@ -56,7 +55,6 @@ pub fn purpose(&self) -> String {
|
|||||||
match self {
|
match self {
|
||||||
Library => "Contribute to the standard library",
|
Library => "Contribute to the standard library",
|
||||||
Compiler => "Contribute to the compiler itself",
|
Compiler => "Contribute to the compiler itself",
|
||||||
Codegen => "Contribute to the compiler, and also modify LLVM or codegen",
|
|
||||||
Tools => "Contribute to tools which depend on the compiler, but do not modify it directly (e.g. rustdoc, clippy, miri)",
|
Tools => "Contribute to tools which depend on the compiler, but do not modify it directly (e.g. rustdoc, clippy, miri)",
|
||||||
Dist => "Install Rust from source",
|
Dist => "Install Rust from source",
|
||||||
None => "Do not modify `config.toml`"
|
None => "Do not modify `config.toml`"
|
||||||
@ -75,7 +73,6 @@ pub fn all_for_help(indent: &str) -> String {
|
|||||||
pub fn as_str(&self) -> &'static str {
|
pub fn as_str(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Profile::Compiler => "compiler",
|
Profile::Compiler => "compiler",
|
||||||
Profile::Codegen => "codegen",
|
|
||||||
Profile::Library => "library",
|
Profile::Library => "library",
|
||||||
Profile::Tools => "tools",
|
Profile::Tools => "tools",
|
||||||
Profile::Dist => "dist",
|
Profile::Dist => "dist",
|
||||||
@ -91,12 +88,15 @@ fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|||||||
match s {
|
match s {
|
||||||
"lib" | "library" => Ok(Profile::Library),
|
"lib" | "library" => Ok(Profile::Library),
|
||||||
"compiler" => Ok(Profile::Compiler),
|
"compiler" => Ok(Profile::Compiler),
|
||||||
"llvm" | "codegen" => Ok(Profile::Codegen),
|
|
||||||
"maintainer" | "dist" | "user" => Ok(Profile::Dist),
|
"maintainer" | "dist" | "user" => Ok(Profile::Dist),
|
||||||
"tools" | "tool" | "rustdoc" | "clippy" | "miri" | "rustfmt" | "rls" => {
|
"tools" | "tool" | "rustdoc" | "clippy" | "miri" | "rustfmt" | "rls" => {
|
||||||
Ok(Profile::Tools)
|
Ok(Profile::Tools)
|
||||||
}
|
}
|
||||||
"none" => Ok(Profile::None),
|
"none" => Ok(Profile::None),
|
||||||
|
"llvm" | "codegen" => Err(format!(
|
||||||
|
"the \"llvm\" and \"codegen\" profiles have been removed,\
|
||||||
|
use \"compiler\" instead which has the same functionality"
|
||||||
|
)),
|
||||||
_ => Err(format!("unknown profile: '{s}'")),
|
_ => Err(format!("unknown profile: '{s}'")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -170,22 +170,13 @@ fn make_run(run: RunConfig<'_>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run(self, builder: &Builder<'_>) {
|
fn run(self, builder: &Builder<'_>) {
|
||||||
// During ./x.py setup once you select the codegen profile.
|
setup(&builder.build.config, self);
|
||||||
// The submodule will be downloaded. It does not work in the
|
|
||||||
// tarball case since they don't include Git and submodules
|
|
||||||
// are already included.
|
|
||||||
if !builder.rust_info().is_from_tarball() {
|
|
||||||
if self == Profile::Codegen {
|
|
||||||
builder.update_submodule(&Path::new("src/llvm-project"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setup(&builder.build.config, self)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup(config: &Config, profile: Profile) {
|
pub fn setup(config: &Config, profile: Profile) {
|
||||||
let suggestions: &[&str] = match profile {
|
let suggestions: &[&str] = match profile {
|
||||||
Profile::Codegen | Profile::Compiler | Profile::None => &["check", "build", "test"],
|
Profile::Compiler | Profile::None => &["check", "build", "test"],
|
||||||
Profile::Tools => &[
|
Profile::Tools => &[
|
||||||
"check",
|
"check",
|
||||||
"build",
|
"build",
|
||||||
|
@ -124,4 +124,9 @@ pub fn find_recent_config_change_ids(current_id: usize) -> Vec<ChangeInfo> {
|
|||||||
severity: ChangeSeverity::Info,
|
severity: ChangeSeverity::Info,
|
||||||
summary: "A new `rust.frame-pointers` option has been introduced and made the default in the compiler and codegen profiles.",
|
summary: "A new `rust.frame-pointers` option has been introduced and made the default in the compiler and codegen profiles.",
|
||||||
},
|
},
|
||||||
|
ChangeInfo {
|
||||||
|
change_id: 121278,
|
||||||
|
severity: ChangeSeverity::Warning,
|
||||||
|
summary: "The \"codegen\"/\"llvm\" profile has been removed and replaced with \"compiler\", use it instead for the same behavior.",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
@ -9,8 +9,6 @@ error[E0472]: inline assembly is unsupported on this target
|
|||||||
|
|
|
|
||||||
LL | global_asm!("");
|
LL | global_asm!("");
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
= note: this error originates in the macro `global_asm` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -191,7 +191,14 @@ error[E0223]: ambiguous associated type
|
|||||||
--> $DIR/bad-assoc-ty.rs:33:10
|
--> $DIR/bad-assoc-ty.rs:33:10
|
||||||
|
|
|
|
||||||
LL | type H = Fn(u8) -> (u8)::Output;
|
LL | type H = Fn(u8) -> (u8)::Output;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<(dyn Fn(u8) -> u8 + 'static) as IntoFuture>::Output`
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: use fully-qualified syntax
|
||||||
|
|
|
||||||
|
LL | type H = <(dyn Fn(u8) -> u8 + 'static) as BitOr>::Output;
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
LL | type H = <(dyn Fn(u8) -> u8 + 'static) as IntoFuture>::Output;
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error[E0223]: ambiguous associated type
|
error[E0223]: ambiguous associated type
|
||||||
--> $DIR/bad-assoc-ty.rs:39:19
|
--> $DIR/bad-assoc-ty.rs:39:19
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
error: extern location for std does not exist:
|
error: extern location for std does not exist:
|
||||||
|
|
||||||
|
error: `#[panic_handler]` function required, but not found
|
||||||
|
|
||||||
|
error: unwinding panics are not supported without std
|
||||||
|
|
|
||||||
|
= help: using nightly cargo, use -Zbuild-std with panic="abort" to avoid unwinding
|
||||||
|
= note: since the core library is usually precompiled with panic="unwind", rebuilding your crate with panic="abort" may not be enough to fix the problem
|
||||||
|
|
||||||
error: requires `sized` lang_item
|
error: requires `sized` lang_item
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ LL | format!("{:X}", "3");
|
|||||||
i128
|
i128
|
||||||
usize
|
usize
|
||||||
u8
|
u8
|
||||||
and 20 others
|
and 9 others
|
||||||
= note: required for `&str` to implement `UpperHex`
|
= note: required for `&str` to implement `UpperHex`
|
||||||
note: required by a bound in `core::fmt::rt::Argument::<'a>::new_upper_hex`
|
note: required by a bound in `core::fmt::rt::Argument::<'a>::new_upper_hex`
|
||||||
--> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
|
--> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
|
||||||
|
20
tests/ui/lint/unsafe_code/lint-global-asm-as-unsafe.rs
Normal file
20
tests/ui/lint/unsafe_code/lint-global-asm-as-unsafe.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
//@ needs-asm-support
|
||||||
|
#![deny(unsafe_code)]
|
||||||
|
|
||||||
|
use std::arch::global_asm;
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
mod allowed_unsafe {
|
||||||
|
std::arch::global_asm!("");
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! unsafe_in_macro {
|
||||||
|
() => {
|
||||||
|
global_asm!(""); //~ ERROR: usage of `core::arch::global_asm`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
global_asm!(""); //~ ERROR: usage of `core::arch::global_asm`
|
||||||
|
unsafe_in_macro!();
|
||||||
|
|
||||||
|
fn main() {}
|
27
tests/ui/lint/unsafe_code/lint-global-asm-as-unsafe.stderr
Normal file
27
tests/ui/lint/unsafe_code/lint-global-asm-as-unsafe.stderr
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
error: usage of `core::arch::global_asm`
|
||||||
|
--> $DIR/lint-global-asm-as-unsafe.rs:17:1
|
||||||
|
|
|
||||||
|
LL | global_asm!("");
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: using this macro is unsafe even though it does not need an `unsafe` block
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/lint-global-asm-as-unsafe.rs:2:9
|
||||||
|
|
|
||||||
|
LL | #![deny(unsafe_code)]
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: usage of `core::arch::global_asm`
|
||||||
|
--> $DIR/lint-global-asm-as-unsafe.rs:13:9
|
||||||
|
|
|
||||||
|
LL | global_asm!("");
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
...
|
||||||
|
LL | unsafe_in_macro!();
|
||||||
|
| ------------------ in this macro invocation
|
||||||
|
|
|
||||||
|
= note: using this macro is unsafe even though it does not need an `unsafe` block
|
||||||
|
= note: this error originates in the macro `unsafe_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
@ -46,7 +46,6 @@ LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(
|
|||||||
= note: multiple `impl`s satisfying `u32: From<_>` found in the `core` crate:
|
= note: multiple `impl`s satisfying `u32: From<_>` found in the `core` crate:
|
||||||
- impl From<Char> for u32;
|
- impl From<Char> for u32;
|
||||||
- impl From<Ipv4Addr> for u32;
|
- impl From<Ipv4Addr> for u32;
|
||||||
- impl From<NonZero<u32>> for u32;
|
|
||||||
- impl From<bool> for u32;
|
- impl From<bool> for u32;
|
||||||
- impl From<char> for u32;
|
- impl From<char> for u32;
|
||||||
- impl From<u16> for u32;
|
- impl From<u16> for u32;
|
||||||
|
@ -11,7 +11,6 @@ LL | Ok(Err(123_i32)?)
|
|||||||
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
|
||||||
= help: the following other types implement trait `From<T>`:
|
= help: the following other types implement trait `From<T>`:
|
||||||
<u8 as From<bool>>
|
<u8 as From<bool>>
|
||||||
<u8 as From<NonZero<u8>>>
|
|
||||||
<u8 as From<Char>>
|
<u8 as From<Char>>
|
||||||
= note: required for `Result<u64, u8>` to implement `FromResidual<Result<Infallible, i32>>`
|
= note: required for `Result<u64, u8>` to implement `FromResidual<Result<Infallible, i32>>`
|
||||||
|
|
||||||
|
@ -627,11 +627,6 @@ This PR modifies `config.example.toml`.
|
|||||||
If appropriate, please update `CONFIG_CHANGE_HISTORY` in `src/bootstrap/src/utils/change_tracker.rs`.
|
If appropriate, please update `CONFIG_CHANGE_HISTORY` in `src/bootstrap/src/utils/change_tracker.rs`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
[mentions."src/bootstrap/defaults/config.compiler.toml"]
|
|
||||||
message = "This PR changes src/bootstrap/defaults/config.compiler.toml. If appropriate, please also update `config.codegen.toml` so the defaults are in sync."
|
|
||||||
[mentions."src/bootstrap/defaults/config.codegen.toml"]
|
|
||||||
message = "This PR changes src/bootstrap/defaults/config.codegen.toml. If appropriate, please also update `config.compiler.toml` so the defaults are in sync."
|
|
||||||
|
|
||||||
[mentions."src/bootstrap/src/core/build_steps/llvm.rs"]
|
[mentions."src/bootstrap/src/core/build_steps/llvm.rs"]
|
||||||
message = "This PR changes how LLVM is built. Consider updating src/bootstrap/download-ci-llvm-stamp."
|
message = "This PR changes how LLVM is built. Consider updating src/bootstrap/download-ci-llvm-stamp."
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user