Merge from rustc

This commit is contained in:
The Miri Cronjob Bot 2024-08-30 05:09:57 +00:00
commit 23f4eae905
245 changed files with 2369 additions and 1107 deletions

View file

@ -21,7 +21,6 @@
#![feature(decl_macro)]
#![feature(dropck_eyepatch)]
#![feature(maybe_uninit_slice)]
#![feature(new_uninit)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
#![feature(strict_provenance)]

View file

@ -4,9 +4,10 @@ use std::borrow::Cow;
use rustc_ast::visit::Visitor;
use rustc_ast::*;
use rustc_data_structures::fx::FxIndexMap;
use rustc_hir as hir;
use rustc_session::config::FmtDebug;
use rustc_span::symbol::{kw, Ident};
use rustc_span::{sym, Span, Symbol};
use {rustc_ast as ast, rustc_hir as hir};
use super::LoweringContext;
@ -243,7 +244,10 @@ fn make_argument<'hir>(
hir::LangItem::FormatArgument,
match ty {
Format(Display) => sym::new_display,
Format(Debug) => sym::new_debug,
Format(Debug) => match ctx.tcx.sess.opts.unstable_opts.fmt_debug {
FmtDebug::Full | FmtDebug::Shallow => sym::new_debug,
FmtDebug::None => sym::new_debug_noop,
},
Format(LowerExp) => sym::new_lower_exp,
Format(UpperExp) => sym::new_upper_exp,
Format(Octal) => sym::new_octal,

View file

@ -1,5 +1,6 @@
use rustc_ast::{self as ast, EnumDef, MetaItem};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_session::config::FmtDebug;
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
use thin_vec::{thin_vec, ThinVec};
@ -49,6 +50,11 @@ fn show_substructure(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) ->
// We want to make sure we have the ctxt set so that we can use unstable methods
let span = cx.with_def_site_ctxt(span);
let fmt_detail = cx.sess.opts.unstable_opts.fmt_debug;
if fmt_detail == FmtDebug::None {
return BlockOrExpr::new_expr(cx.expr_ok(span, cx.expr_tuple(span, ThinVec::new())));
}
let (ident, vdata, fields) = match substr.fields {
Struct(vdata, fields) => (substr.type_ident, *vdata, fields),
EnumMatching(_, v, fields) => (v.ident, &v.data, fields),
@ -61,6 +67,13 @@ fn show_substructure(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) ->
let name = cx.expr_str(span, ident.name);
let fmt = substr.nonselflike_args[0].clone();
// Fieldless enums have been special-cased earlier
if fmt_detail == FmtDebug::Shallow {
let fn_path_write_str = cx.std_path(&[sym::fmt, sym::Formatter, sym::write_str]);
let expr = cx.expr_call_global(span, fn_path_write_str, thin_vec![fmt, name]);
return BlockOrExpr::new_expr(expr);
}
// Struct and tuples are similar enough that we use the same code for both,
// with some extra pieces for structs due to the field names.
let (is_struct, args_per_field) = match vdata {

View file

@ -11,7 +11,6 @@ use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident};
use rustc_span::{Span, Symbol};
use smallvec::{smallvec, SmallVec};
use thin_vec::{thin_vec, ThinVec};
macro_rules! path {
@ -68,43 +67,63 @@ pub(crate) fn expand_deriving_smart_ptr(
};
// Convert generic parameters (from the struct) into generic args.
let mut pointee_param = None;
let mut multiple_pointee_diag: SmallVec<[_; 2]> = smallvec![];
let self_params = generics
let self_params: Vec<_> = generics
.params
.iter()
.map(|p| match p.kind {
GenericParamKind::Lifetime => GenericArg::Lifetime(cx.lifetime(p.span(), p.ident)),
GenericParamKind::Type { .. } => GenericArg::Type(cx.ty_ident(p.span(), p.ident)),
GenericParamKind::Const { .. } => GenericArg::Const(cx.const_ident(p.span(), p.ident)),
})
.collect();
let type_params: Vec<_> = generics
.params
.iter()
.enumerate()
.map(|(idx, p)| match p.kind {
GenericParamKind::Lifetime => GenericArg::Lifetime(cx.lifetime(p.span(), p.ident)),
GenericParamKind::Type { .. } => {
if p.attrs().iter().any(|attr| attr.has_name(sym::pointee)) {
if pointee_param.is_some() {
multiple_pointee_diag.push(cx.dcx().struct_span_err(
p.span(),
"`SmartPointer` can only admit one type as pointee",
));
} else {
pointee_param = Some(idx);
}
}
GenericArg::Type(cx.ty_ident(p.span(), p.ident))
.filter_map(|(idx, p)| {
if let GenericParamKind::Type { .. } = p.kind {
Some((idx, p.span(), p.attrs().iter().any(|attr| attr.has_name(sym::pointee))))
} else {
None
}
GenericParamKind::Const { .. } => GenericArg::Const(cx.const_ident(p.span(), p.ident)),
})
.collect::<Vec<_>>();
let Some(pointee_param_idx) = pointee_param else {
.collect();
let pointee_param_idx = if type_params.is_empty() {
// `#[derive(SmartPointer)]` requires at least one generic type on the target `struct`
cx.dcx().struct_span_err(
span,
"At least one generic type should be designated as `#[pointee]` in order to derive `SmartPointer` traits",
"`SmartPointer` can only be derived on `struct`s that are generic over at least one type",
).emit();
return;
};
if !multiple_pointee_diag.is_empty() {
for diag in multiple_pointee_diag {
diag.emit();
} else if type_params.len() == 1 {
// Regardless of the only type param being designed as `#[pointee]` or not, we can just use it as such
type_params[0].0
} else {
let mut pointees = type_params
.iter()
.filter_map(|&(idx, span, is_pointee)| is_pointee.then_some((idx, span)))
.fuse();
match (pointees.next(), pointees.next()) {
(Some((idx, _span)), None) => idx,
(None, _) => {
cx.dcx().struct_span_err(
span,
"exactly one generic type parameter must be marked as #[pointee] to derive SmartPointer traits",
).emit();
return;
}
(Some((_, one)), Some((_, another))) => {
cx.dcx()
.struct_span_err(
vec![one, another],
"only one type parameter can be marked as `#[pointee]` when deriving SmartPointer traits",
)
.emit();
return;
}
}
return;
}
};
// Create the type of `self`.
let path = cx.path_all(span, false, vec![name_ident], self_params.clone());

View file

@ -521,13 +521,20 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
let function_features = function_features
.iter()
.flat_map(|feat| {
llvm_util::to_llvm_features(cx.tcx.sess, feat).into_iter().map(|f| format!("+{f}"))
})
// Convert to LLVMFeatures and filter out unavailable ones
.flat_map(|feat| llvm_util::to_llvm_features(cx.tcx.sess, feat))
// Convert LLVMFeatures & dependencies to +<feats>s
.flat_map(|feat| feat.into_iter().map(|f| format!("+{f}")))
.chain(codegen_fn_attrs.instruction_set.iter().map(|x| match x {
InstructionSetAttr::ArmA32 => "-thumb-mode".to_string(),
InstructionSetAttr::ArmT32 => "+thumb-mode".to_string(),
}))
// HACK: LLVM versions 19+ do not have the FPMR feature and treat it as always enabled
// It only exists as a feature in LLVM 18, cannot be passed down for any other version
.chain(match &*cx.tcx.sess.target.arch {
"aarch64" if llvm_util::get_version().0 == 18 => vec!["+fpmr".to_string()],
_ => vec![],
})
.collect::<Vec<String>>();
if cx.tcx.sess.target.is_like_wasm {

View file

@ -571,6 +571,7 @@ pub(crate) unsafe fn llvm_optimize(
cgcx.opts.cg.linker_plugin_lto.enabled(),
config.no_prepopulate_passes,
config.verify_llvm_ir,
config.lint_llvm_ir,
using_thin_buffers,
config.merge_functions,
unroll_loops,

View file

@ -2225,6 +2225,7 @@ unsafe extern "C" {
IsLinkerPluginLTO: bool,
NoPrepopulatePasses: bool,
VerifyIR: bool,
LintIR: bool,
UseThinLTOBuffers: bool,
MergeFunctions: bool,
UnrollLoops: bool,

View file

@ -209,7 +209,7 @@ impl<'a> IntoIterator for LLVMFeature<'a> {
// Though note that Rust can also be build with an external precompiled version of LLVM
// which might lead to failures if the oldest tested / supported LLVM version
// doesn't yet support the relevant intrinsics
pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> LLVMFeature<'a> {
pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFeature<'a>> {
let arch = if sess.target.arch == "x86_64" {
"x86"
} else if sess.target.arch == "arm64ec" {
@ -218,40 +218,59 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> LLVMFeature<'a
&*sess.target.arch
};
match (arch, s) {
("x86", "sse4.2") => {
LLVMFeature::with_dependency("sse4.2", TargetFeatureFoldStrength::EnableOnly("crc32"))
}
("x86", "pclmulqdq") => LLVMFeature::new("pclmul"),
("x86", "rdrand") => LLVMFeature::new("rdrnd"),
("x86", "bmi1") => LLVMFeature::new("bmi"),
("x86", "cmpxchg16b") => LLVMFeature::new("cx16"),
("x86", "lahfsahf") => LLVMFeature::new("sahf"),
("aarch64", "rcpc2") => LLVMFeature::new("rcpc-immo"),
("aarch64", "dpb") => LLVMFeature::new("ccpp"),
("aarch64", "dpb2") => LLVMFeature::new("ccdp"),
("aarch64", "frintts") => LLVMFeature::new("fptoint"),
("aarch64", "fcma") => LLVMFeature::new("complxnum"),
("aarch64", "pmuv3") => LLVMFeature::new("perfmon"),
("aarch64", "paca") => LLVMFeature::new("pauth"),
("aarch64", "pacg") => LLVMFeature::new("pauth"),
("x86", "sse4.2") => Some(LLVMFeature::with_dependency(
"sse4.2",
TargetFeatureFoldStrength::EnableOnly("crc32"),
)),
("x86", "pclmulqdq") => Some(LLVMFeature::new("pclmul")),
("x86", "rdrand") => Some(LLVMFeature::new("rdrnd")),
("x86", "bmi1") => Some(LLVMFeature::new("bmi")),
("x86", "cmpxchg16b") => Some(LLVMFeature::new("cx16")),
("x86", "lahfsahf") => Some(LLVMFeature::new("sahf")),
("aarch64", "rcpc2") => Some(LLVMFeature::new("rcpc-immo")),
("aarch64", "dpb") => Some(LLVMFeature::new("ccpp")),
("aarch64", "dpb2") => Some(LLVMFeature::new("ccdp")),
("aarch64", "frintts") => Some(LLVMFeature::new("fptoint")),
("aarch64", "fcma") => Some(LLVMFeature::new("complxnum")),
("aarch64", "pmuv3") => Some(LLVMFeature::new("perfmon")),
("aarch64", "paca") => Some(LLVMFeature::new("pauth")),
("aarch64", "pacg") => Some(LLVMFeature::new("pauth")),
("aarch64", "sve-b16b16") => Some(LLVMFeature::new("b16b16")),
("aarch64", "flagm2") => Some(LLVMFeature::new("altnzcv")),
// Rust ties fp and neon together.
("aarch64", "neon") => {
LLVMFeature::with_dependency("neon", TargetFeatureFoldStrength::Both("fp-armv8"))
Some(LLVMFeature::with_dependency("neon", TargetFeatureFoldStrength::Both("fp-armv8")))
}
// In LLVM neon implicitly enables fp, but we manually enable
// neon when a feature only implicitly enables fp
("aarch64", "fhm") => LLVMFeature::new("fp16fml"),
("aarch64", "fp16") => LLVMFeature::new("fullfp16"),
("aarch64", "fhm") => Some(LLVMFeature::new("fp16fml")),
("aarch64", "fp16") => Some(LLVMFeature::new("fullfp16")),
// Filter out features that are not supported by the current LLVM version
("aarch64", "faminmax") if get_version().0 < 18 => None,
("aarch64", "fp8") if get_version().0 < 18 => None,
("aarch64", "fp8dot2") if get_version().0 < 18 => None,
("aarch64", "fp8dot4") if get_version().0 < 18 => None,
("aarch64", "fp8fma") if get_version().0 < 18 => None,
("aarch64", "fpmr") if get_version().0 != 18 => None,
("aarch64", "lut") if get_version().0 < 18 => None,
("aarch64", "sme-f8f16") if get_version().0 < 18 => None,
("aarch64", "sme-f8f32") if get_version().0 < 18 => None,
("aarch64", "sme-fa64") if get_version().0 < 18 => None,
("aarch64", "sme-lutv2") if get_version().0 < 18 => None,
("aarch64", "ssve-fp8dot2") if get_version().0 < 18 => None,
("aarch64", "ssve-fp8dot4") if get_version().0 < 18 => None,
("aarch64", "ssve-fp8fma") if get_version().0 < 18 => None,
("aarch64", "v9.5a") if get_version().0 < 18 => None,
// In LLVM 18, `unaligned-scalar-mem` was merged with `unaligned-vector-mem` into a single feature called
// `fast-unaligned-access`. In LLVM 19, it was split back out.
("riscv32" | "riscv64", "unaligned-scalar-mem") if get_version().0 == 18 => {
LLVMFeature::new("fast-unaligned-access")
Some(LLVMFeature::new("fast-unaligned-access"))
}
// For LLVM 18, enable the evex512 target feature if a avx512 target feature is enabled.
("x86", s) if get_version().0 >= 18 && s.starts_with("avx512") => {
LLVMFeature::with_dependency(s, TargetFeatureFoldStrength::EnableOnly("evex512"))
Some(LLVMFeature::with_dependency(s, TargetFeatureFoldStrength::EnableOnly("evex512")))
}
(_, s) => LLVMFeature::new(s),
(_, s) => Some(LLVMFeature::new(s)),
}
}
@ -291,13 +310,17 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
return true;
}
// check that all features in a given smallvec are enabled
for llvm_feature in to_llvm_features(sess, feature) {
let cstr = SmallCStr::new(llvm_feature);
if !unsafe { llvm::LLVMRustHasFeature(&target_machine, cstr.as_ptr()) } {
return false;
if let Some(feat) = to_llvm_features(sess, feature) {
for llvm_feature in feat {
let cstr = SmallCStr::new(llvm_feature);
if !unsafe { llvm::LLVMRustHasFeature(&target_machine, cstr.as_ptr()) } {
return false;
}
}
true
} else {
false
}
true
})
.map(|(feature, _, _)| Symbol::intern(feature)),
);
@ -386,9 +409,9 @@ fn print_target_features(out: &mut String, sess: &Session, tm: &llvm::TargetMach
.target
.supported_target_features()
.iter()
.map(|(feature, _gate, _implied)| {
.filter_map(|(feature, _gate, _implied)| {
// LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these strings.
let llvm_feature = to_llvm_features(sess, *feature).llvm_feature_name;
let llvm_feature = to_llvm_features(sess, *feature)?.llvm_feature_name;
let desc =
match llvm_target_features.binary_search_by_key(&llvm_feature, |(f, _d)| f).ok() {
Some(index) => {
@ -398,7 +421,7 @@ fn print_target_features(out: &mut String, sess: &Session, tm: &llvm::TargetMach
None => "",
};
(*feature, desc)
Some((*feature, desc))
})
.collect::<Vec<_>>();
@ -595,7 +618,7 @@ pub(crate) fn global_llvm_features(
if feature_state.is_none() {
let rust_feature =
supported_features.iter().find_map(|&(rust_feature, _, _)| {
let llvm_features = to_llvm_features(sess, rust_feature);
let llvm_features = to_llvm_features(sess, rust_feature)?;
if llvm_features.contains(feature)
&& !llvm_features.contains(rust_feature)
{
@ -641,7 +664,7 @@ pub(crate) fn global_llvm_features(
// passing requests down to LLVM. This means that all in-language
// features also work on the command line instead of having two
// different names when the LLVM name and the Rust name differ.
let llvm_feature = to_llvm_features(sess, feature);
let llvm_feature = to_llvm_features(sess, feature)?;
Some(
std::iter::once(format!(
@ -691,6 +714,9 @@ fn backend_feature_name<'a>(sess: &Session, s: &'a str) -> Option<&'a str> {
let feature = s
.strip_prefix(&['+', '-'][..])
.unwrap_or_else(|| sess.dcx().emit_fatal(InvalidTargetFeaturePrefix { feature: s }));
if s.is_empty() {
return None;
}
// Rustc-specific feature requests like `+crt-static` or `-crt-static`
// are not passed down to LLVM.
if RUSTC_SPECIFIC_FEATURES.contains(&feature) {

View file

@ -112,6 +112,7 @@ pub struct ModuleConfig {
// Miscellaneous flags. These are mostly copied from command-line
// options.
pub verify_llvm_ir: bool,
pub lint_llvm_ir: bool,
pub no_prepopulate_passes: bool,
pub no_builtins: bool,
pub time_module: bool,
@ -237,6 +238,7 @@ impl ModuleConfig {
bc_cmdline: sess.target.bitcode_llvm_cmdline.to_string(),
verify_llvm_ir: sess.verify_llvm_ir(),
lint_llvm_ir: sess.opts.unstable_opts.lint_llvm_ir,
no_prepopulate_passes: sess.opts.cg.no_prepopulate_passes,
no_builtins: no_builtins || sess.target.no_builtins,

View file

@ -37,6 +37,8 @@ const GATED_CFGS: &[GatedCfg] = &[
(sym::relocation_model, sym::cfg_relocation_model, cfg_fn!(cfg_relocation_model)),
(sym::sanitizer_cfi_generalize_pointers, sym::cfg_sanitizer_cfi, cfg_fn!(cfg_sanitizer_cfi)),
(sym::sanitizer_cfi_normalize_integers, sym::cfg_sanitizer_cfi, cfg_fn!(cfg_sanitizer_cfi)),
// this is consistent with naming of the compiler flag it's for
(sym::fmt_debug, sym::fmt_debug, cfg_fn!(fmt_debug)),
];
/// Find a gated cfg determined by the `pred`icate which is given the cfg's name.

View file

@ -302,6 +302,7 @@ declare_features! (
// FIXME: Document these and merge with the list below.
// Unstable `#[target_feature]` directives.
(unstable, aarch64_unstable_target_feature, "CURRENT_RUSTC_VERSION", Some(44839)),
(unstable, aarch64_ver_target_feature, "1.27.0", Some(44839)),
(unstable, arm_target_feature, "1.27.0", Some(44839)),
(unstable, avx512_target_feature, "1.27.0", Some(44839)),
@ -470,6 +471,8 @@ declare_features! (
(unstable, ffi_const, "1.45.0", Some(58328)),
/// Allows the use of `#[ffi_pure]` on foreign functions.
(unstable, ffi_pure, "1.45.0", Some(58329)),
/// Controlling the behavior of fmt::Debug
(unstable, fmt_debug, "CURRENT_RUSTC_VERSION", Some(129709)),
/// Allows using `#[repr(align(...))]` on function items
(unstable, fn_align, "1.53.0", Some(82232)),
/// Support delegating implementation of functions to other already implemented functions.

View file

@ -1,7 +1,7 @@
// tidy-alphabetical-start
#![cfg_attr(all(feature = "nightly", test), feature(stmt_expr_attributes))]
#![cfg_attr(feature = "nightly", allow(internal_features))]
#![cfg_attr(feature = "nightly", feature(extend_one, new_uninit, step_trait, test))]
#![cfg_attr(feature = "nightly", feature(extend_one, step_trait, test))]
#![cfg_attr(feature = "nightly", feature(new_zeroed_alloc))]
#![warn(unreachable_pub)]
// tidy-alphabetical-end

View file

@ -10,11 +10,11 @@ use rustc_errors::{registry, ColorConfig};
use rustc_session::config::{
build_configuration, build_session_options, rustc_optgroups, BranchProtection, CFGuard, Cfg,
CollapseMacroDebuginfo, CoverageLevel, CoverageOptions, DebugInfo, DumpMonoStatsFormat,
ErrorOutputType, ExternEntry, ExternLocation, Externs, FunctionReturn, InliningThreshold,
Input, InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail,
LtoCli, NextSolverConfig, OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey,
PacRet, Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip,
SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
ErrorOutputType, ExternEntry, ExternLocation, Externs, FmtDebug, FunctionReturn,
InliningThreshold, Input, InstrumentCoverage, InstrumentXRay, LinkSelfContained,
LinkerPluginLto, LocationDetail, LtoCli, NextSolverConfig, OomStrategy, Options, OutFileName,
OutputType, OutputTypes, PAuthKey, PacRet, Passes, PatchableFunctionEntry, Polonius,
ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
};
use rustc_session::lint::Level;
use rustc_session::search_paths::SearchPath;
@ -780,6 +780,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(fewer_names, Some(true));
tracked!(fixed_x18, true);
tracked!(flatten_format_args, false);
tracked!(fmt_debug, FmtDebug::Shallow);
tracked!(force_unstable_if_unmarked, true);
tracked!(fuel, Some(("abc".to_string(), 99)));
tracked!(function_return, FunctionReturn::ThunkExtern);
@ -794,6 +795,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(instrument_xray, Some(InstrumentXRay::default()));
tracked!(link_directives, false);
tracked!(link_only, true);
tracked!(lint_llvm_ir, true);
tracked!(llvm_module_flag, vec![("bar".to_string(), 123, "max".to_string())]);
tracked!(llvm_plugins, vec![String::from("plugin_name")]);
tracked!(location_detail, LocationDetail { file: true, line: false, column: false });

View file

@ -713,7 +713,7 @@ extern "C" LLVMRustResult LLVMRustOptimize(
LLVMModuleRef ModuleRef, LLVMTargetMachineRef TMRef,
LLVMRustPassBuilderOptLevel OptLevelRust, LLVMRustOptStage OptStage,
bool IsLinkerPluginLTO, bool NoPrepopulatePasses, bool VerifyIR,
bool UseThinLTOBuffers, bool MergeFunctions, bool UnrollLoops,
bool LintIR, bool UseThinLTOBuffers, bool MergeFunctions, bool UnrollLoops,
bool SLPVectorize, bool LoopVectorize, bool DisableSimplifyLibCalls,
bool EmitLifetimeMarkers, LLVMRustSanitizerOptions *SanitizerOptions,
const char *PGOGenPath, const char *PGOUsePath, bool InstrumentCoverage,
@ -842,6 +842,13 @@ extern "C" LLVMRustResult LLVMRustOptimize(
});
}
if (LintIR) {
PipelineStartEPCallbacks.push_back(
[](ModulePassManager &MPM, OptimizationLevel Level) {
MPM.addPass(createModuleToFunctionPassAdaptor(LintPass()));
});
}
if (InstrumentGCOV) {
PipelineStartEPCallbacks.push_back(
[](ModulePassManager &MPM, OptimizationLevel Level) {

View file

@ -55,7 +55,7 @@ use synstructure::Structure;
///
/// See rustc dev guide for more examples on using the `#[derive(Diagnostic)]`:
/// <https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-structs.html>
pub fn diagnostic_derive(mut s: Structure<'_>) -> TokenStream {
pub(super) fn diagnostic_derive(mut s: Structure<'_>) -> TokenStream {
s.underscore_const(true);
DiagnosticDerive::new(s).into_tokens()
}
@ -102,7 +102,7 @@ pub fn diagnostic_derive(mut s: Structure<'_>) -> TokenStream {
///
/// See rustc dev guide for more examples on using the `#[derive(LintDiagnostic)]`:
/// <https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-structs.html#reference>
pub fn lint_diagnostic_derive(mut s: Structure<'_>) -> TokenStream {
pub(super) fn lint_diagnostic_derive(mut s: Structure<'_>) -> TokenStream {
s.underscore_const(true);
LintDiagnosticDerive::new(s).into_tokens()
}
@ -153,7 +153,7 @@ pub fn lint_diagnostic_derive(mut s: Structure<'_>) -> TokenStream {
///
/// diag.subdiagnostic(RawIdentifierSuggestion { span, applicability, ident });
/// ```
pub fn subdiagnostic_derive(mut s: Structure<'_>) -> TokenStream {
pub(super) fn subdiagnostic_derive(mut s: Structure<'_>) -> TokenStream {
s.underscore_const(true);
SubdiagnosticDerive::new().into_tokens(s)
}

View file

@ -6,6 +6,7 @@
#![feature(proc_macro_diagnostic)]
#![feature(proc_macro_span)]
#![feature(proc_macro_tracked_env)]
#![warn(unreachable_pub)]
// tidy-alphabetical-end
use proc_macro::TokenStream;

View file

@ -1,7 +1,7 @@
use quote::quote;
use syn::parse_quote;
pub fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
pub(super) fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
s.add_bounds(synstructure::AddBounds::Generics);
s.bind_with(|_| synstructure::BindStyle::Move);
s.underscore_const(true);

View file

@ -307,7 +307,7 @@ fn add_query_desc_cached_impl(
});
}
pub fn rustc_queries(input: TokenStream) -> TokenStream {
pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
let queries = parse_macro_input!(input as List<Query>);
let mut query_stream = quote! {};

View file

@ -3,7 +3,9 @@ use quote::{quote, quote_spanned};
use syn::parse_quote;
use syn::spanned::Spanned;
pub fn type_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
pub(super) fn type_decodable_derive(
mut s: synstructure::Structure<'_>,
) -> proc_macro2::TokenStream {
let decoder_ty = quote! { __D };
let bound = if s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
quote! { <I = ::rustc_middle::ty::TyCtxt<'tcx>> }
@ -20,7 +22,9 @@ pub fn type_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:
decodable_body(s, decoder_ty)
}
pub fn meta_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
pub(super) fn meta_decodable_derive(
mut s: synstructure::Structure<'_>,
) -> proc_macro2::TokenStream {
if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
s.add_impl_generic(parse_quote! { 'tcx });
}
@ -32,7 +36,7 @@ pub fn meta_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:
decodable_body(s, decoder_ty)
}
pub fn decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
pub(super) fn decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
let decoder_ty = quote! { __D };
s.add_impl_generic(parse_quote! { #decoder_ty: ::rustc_span::SpanDecoder });
s.add_bounds(synstructure::AddBounds::Generics);
@ -41,7 +45,9 @@ pub fn decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Toke
decodable_body(s, decoder_ty)
}
pub fn decodable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
pub(super) fn decodable_generic_derive(
mut s: synstructure::Structure<'_>,
) -> proc_macro2::TokenStream {
let decoder_ty = quote! { __D };
s.add_impl_generic(parse_quote! { #decoder_ty: ::rustc_serialize::Decoder });
s.add_bounds(synstructure::AddBounds::Generics);
@ -123,7 +129,9 @@ fn decode_field(field: &syn::Field) -> proc_macro2::TokenStream {
quote_spanned! { field_span=> #decode_inner_method(#__decoder) }
}
pub fn type_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
pub(super) fn type_encodable_derive(
mut s: synstructure::Structure<'_>,
) -> proc_macro2::TokenStream {
let bound = if s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
quote! { <I = ::rustc_middle::ty::TyCtxt<'tcx>> }
} else if s.ast().generics.type_params().any(|ty| ty.ident == "I") {
@ -140,7 +148,9 @@ pub fn type_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:
encodable_body(s, encoder_ty, false)
}
pub fn meta_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
pub(super) fn meta_encodable_derive(
mut s: synstructure::Structure<'_>,
) -> proc_macro2::TokenStream {
if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
s.add_impl_generic(parse_quote! { 'tcx });
}
@ -152,7 +162,7 @@ pub fn meta_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:
encodable_body(s, encoder_ty, true)
}
pub fn encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
pub(super) fn encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
let encoder_ty = quote! { __E };
s.add_impl_generic(parse_quote! { #encoder_ty: ::rustc_span::SpanEncoder });
s.add_bounds(synstructure::AddBounds::Generics);
@ -161,7 +171,9 @@ pub fn encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Toke
encodable_body(s, encoder_ty, false)
}
pub fn encodable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
pub(super) fn encodable_generic_derive(
mut s: synstructure::Structure<'_>,
) -> proc_macro2::TokenStream {
let encoder_ty = quote! { __E };
s.add_impl_generic(parse_quote! { #encoder_ty: ::rustc_serialize::Encoder });
s.add_bounds(synstructure::AddBounds::Generics);

View file

@ -131,7 +131,7 @@ impl Errors {
}
}
pub fn symbols(input: TokenStream) -> TokenStream {
pub(super) fn symbols(input: TokenStream) -> TokenStream {
let (mut output, errors) = symbols_with_errors(input);
// If we generated any errors, then report them as compiler_error!() macro calls.

View file

@ -1,7 +1,7 @@
use quote::{quote, ToTokens};
use syn::parse_quote;
pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
pub(super) fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
if let syn::Data::Union(_) = s.ast().data {
panic!("cannot derive on union")
}

View file

@ -1,7 +1,9 @@
use quote::quote;
use syn::parse_quote;
pub fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
pub(super) fn type_visitable_derive(
mut s: synstructure::Structure<'_>,
) -> proc_macro2::TokenStream {
if let syn::Data::Union(_) = s.ast().data {
panic!("cannot derive on union")
}

View file

@ -16,6 +16,7 @@
#![feature(proc_macro_internals)]
#![feature(rustdoc_internals)]
#![feature(trusted_len)]
#![warn(unreachable_pub)]
// tidy-alphabetical-end
extern crate proc_macro;

View file

@ -56,13 +56,13 @@ impl std::ops::Deref for MetadataBlob {
impl MetadataBlob {
/// Runs the [`MemDecoder`] validation and if it passes, constructs a new [`MetadataBlob`].
pub fn new(slice: OwnedSlice) -> Result<Self, ()> {
pub(crate) fn new(slice: OwnedSlice) -> Result<Self, ()> {
if MemDecoder::new(&slice, 0).is_ok() { Ok(Self(slice)) } else { Err(()) }
}
/// Since this has passed the validation of [`MetadataBlob::new`], this returns bytes which are
/// known to pass the [`MemDecoder`] validation.
pub fn bytes(&self) -> &OwnedSlice {
pub(crate) fn bytes(&self) -> &OwnedSlice {
&self.0
}
}
@ -332,12 +332,12 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
}
#[inline]
pub fn blob(&self) -> &'a MetadataBlob {
pub(crate) fn blob(&self) -> &'a MetadataBlob {
self.blob
}
#[inline]
pub fn cdata(&self) -> CrateMetadataRef<'a> {
fn cdata(&self) -> CrateMetadataRef<'a> {
debug_assert!(self.cdata.is_some(), "missing CrateMetadata in DecodeContext");
self.cdata.unwrap()
}
@ -377,7 +377,7 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
}
#[inline]
pub fn read_raw_bytes(&mut self, len: usize) -> &[u8] {
fn read_raw_bytes(&mut self, len: usize) -> &[u8] {
self.opaque.read_raw_bytes(len)
}
}
@ -962,7 +962,7 @@ impl CrateRoot {
}
}
impl<'a, 'tcx> CrateMetadataRef<'a> {
impl<'a> CrateMetadataRef<'a> {
fn missing(self, descr: &str, id: DefIndex) -> ! {
bug!("missing `{descr}` for {:?}", self.local_def_id(id))
}
@ -1036,7 +1036,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.decode((self, sess))
}
fn load_proc_macro(self, id: DefIndex, tcx: TyCtxt<'tcx>) -> SyntaxExtension {
fn load_proc_macro<'tcx>(self, id: DefIndex, tcx: TyCtxt<'tcx>) -> SyntaxExtension {
let (name, kind, helper_attrs) = match *self.raw_proc_macro(id) {
ProcMacro::CustomDerive { trait_name, attributes, client } => {
let helper_attrs =
@ -1070,7 +1070,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
)
}
fn get_explicit_item_bounds(
fn get_explicit_item_bounds<'tcx>(
self,
index: DefIndex,
tcx: TyCtxt<'tcx>,
@ -1084,7 +1084,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
ty::EarlyBinder::bind(&*output)
}
fn get_explicit_item_super_predicates(
fn get_explicit_item_super_predicates<'tcx>(
self,
index: DefIndex,
tcx: TyCtxt<'tcx>,
@ -1141,7 +1141,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
)
}
fn get_adt_def(self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::AdtDef<'tcx> {
fn get_adt_def<'tcx>(self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::AdtDef<'tcx> {
let kind = self.def_kind(item_id);
let did = self.local_def_id(item_id);
@ -1225,12 +1225,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
/// Iterates over the stability implications in the given crate (when a `#[unstable]` attribute
/// has an `implied_by` meta item, then the mapping from the implied feature to the actual
/// feature is a stability implication).
fn get_stability_implications(self, tcx: TyCtxt<'tcx>) -> &'tcx [(Symbol, Symbol)] {
fn get_stability_implications<'tcx>(self, tcx: TyCtxt<'tcx>) -> &'tcx [(Symbol, Symbol)] {
tcx.arena.alloc_from_iter(self.root.stability_implications.decode(self))
}
/// Iterates over the lang items in the given crate.
fn get_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, LangItem)] {
fn get_lang_items<'tcx>(self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, LangItem)] {
tcx.arena.alloc_from_iter(
self.root
.lang_items
@ -1239,7 +1239,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
)
}
fn get_stripped_cfg_items(self, cnum: CrateNum, tcx: TyCtxt<'tcx>) -> &'tcx [StrippedCfgItem] {
fn get_stripped_cfg_items<'tcx>(
self,
cnum: CrateNum,
tcx: TyCtxt<'tcx>,
) -> &'tcx [StrippedCfgItem] {
let item_names = self
.root
.stripped_cfg_items
@ -1412,7 +1416,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.decode((self, sess))
}
fn get_inherent_implementations_for_type(
fn get_inherent_implementations_for_type<'tcx>(
self,
tcx: TyCtxt<'tcx>,
id: DefIndex,
@ -1439,7 +1443,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
})
}
fn get_incoherent_impls(self, tcx: TyCtxt<'tcx>, simp: SimplifiedType) -> &'tcx [DefId] {
fn get_incoherent_impls<'tcx>(self, tcx: TyCtxt<'tcx>, simp: SimplifiedType) -> &'tcx [DefId] {
if let Some(impls) = self.cdata.incoherent_impls.get(&simp) {
tcx.arena.alloc_from_iter(impls.decode(self).map(|idx| self.local_def_id(idx)))
} else {
@ -1447,7 +1451,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
}
}
fn get_implementations_of_trait(
fn get_implementations_of_trait<'tcx>(
self,
tcx: TyCtxt<'tcx>,
trait_def_id: DefId,
@ -1491,7 +1495,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
self.root.foreign_modules.decode((self, sess))
}
fn get_dylib_dependency_formats(
fn get_dylib_dependency_formats<'tcx>(
self,
tcx: TyCtxt<'tcx>,
) -> &'tcx [(CrateNum, LinkagePreference)] {
@ -1503,11 +1507,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
)
}
fn get_missing_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [LangItem] {
fn get_missing_lang_items<'tcx>(self, tcx: TyCtxt<'tcx>) -> &'tcx [LangItem] {
tcx.arena.alloc_from_iter(self.root.lang_items_missing.decode(self))
}
fn exported_symbols(
fn exported_symbols<'tcx>(
self,
tcx: TyCtxt<'tcx>,
) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {

View file

@ -17,7 +17,7 @@ parameterized_over_tcx! {
impl DefPathHashMapRef<'_> {
#[inline]
pub fn def_path_hash_to_def_index(&self, def_path_hash: &DefPathHash) -> DefIndex {
pub(crate) fn def_path_hash_to_def_index(&self, def_path_hash: &DefPathHash) -> DefIndex {
match *self {
DefPathHashMapRef::OwnedFromMetadata(ref map) => {
map.get(&def_path_hash.local_hash()).unwrap()

View file

@ -2309,7 +2309,7 @@ fn encode_root_position(mut file: &File, pos: usize) -> Result<(), std::io::Erro
Ok(())
}
pub fn provide(providers: &mut Providers) {
pub(crate) fn provide(providers: &mut Providers) {
*providers = Providers {
doc_link_resolutions: |tcx, def_id| {
tcx.resolutions(())

View file

@ -61,8 +61,9 @@ use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalModDefId, ModDefId, LO
use rustc_hir::definitions::DefPathHash;
use rustc_hir::{HirId, ItemLocalId, OwnerId};
pub use rustc_query_system::dep_graph::dep_node::DepKind;
pub use rustc_query_system::dep_graph::DepNode;
use rustc_query_system::dep_graph::FingerprintStyle;
pub use rustc_query_system::dep_graph::{DepContext, DepNode, DepNodeParams};
pub(crate) use rustc_query_system::dep_graph::{DepContext, DepNodeParams};
use rustc_span::symbol::Symbol;
use crate::mir::mono::MonoItem;
@ -101,7 +102,7 @@ macro_rules! define_dep_nodes {
// This checks that the discriminants of the variants have been assigned consecutively
// from 0 so that they can be used as a dense index.
pub const DEP_KIND_VARIANTS: u16 = {
pub(crate) const DEP_KIND_VARIANTS: u16 = {
let deps = &[$(dep_kinds::$variant,)*];
let mut i = 0;
while i < deps.len() {

View file

@ -53,7 +53,6 @@
#![feature(min_specialization)]
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(new_uninit)]
#![feature(ptr_alignment_type)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
@ -63,6 +62,7 @@
#![feature(try_blocks)]
#![feature(type_alias_impl_trait)]
#![feature(yeet_expr)]
#![warn(unreachable_pub)]
// tidy-alphabetical-end
#[cfg(test)]

View file

@ -18,9 +18,9 @@ pub struct BasicBlocks<'tcx> {
}
// Typically 95%+ of basic blocks have 4 or fewer predecessors.
pub type Predecessors = IndexVec<BasicBlock, SmallVec<[BasicBlock; 4]>>;
type Predecessors = IndexVec<BasicBlock, SmallVec<[BasicBlock; 4]>>;
pub type SwitchSources = FxHashMap<(BasicBlock, BasicBlock), SmallVec<[Option<u128>; 1]>>;
type SwitchSources = FxHashMap<(BasicBlock, BasicBlock), SmallVec<[Option<u128>; 1]>>;
#[derive(Clone, Default, Debug)]
struct Cache {

View file

@ -2,7 +2,7 @@ use gsgdt::{Edge, Graph, Node, NodeStyle};
use rustc_middle::mir::*;
/// Convert an MIR function into a gsgdt Graph
pub fn mir_fn_to_generic_graph<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Graph {
pub(crate) fn mir_fn_to_generic_graph<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Graph {
let def_id = body.source.def_id();
let def_name = graphviz_safe_def_name(def_id);
let graph_name = format!("Mir_{def_name}");

View file

@ -243,7 +243,7 @@ impl hash::Hash for InitMaskMaterialized {
}
impl InitMaskMaterialized {
pub const BLOCK_SIZE: u64 = 64;
const BLOCK_SIZE: u64 = 64;
fn new(size: Size, state: bool) -> Self {
let mut m = InitMaskMaterialized { blocks: vec![] };

View file

@ -396,7 +396,7 @@ impl<'tcx> CodegenUnit<'tcx> {
// The codegen tests rely on items being process in the same order as
// they appear in the file, so for local items, we sort by node_id first
#[derive(PartialEq, Eq, PartialOrd, Ord)]
pub struct ItemSortKey<'tcx>(Option<usize>, SymbolName<'tcx>);
struct ItemSortKey<'tcx>(Option<usize>, SymbolName<'tcx>);
fn item_sort_key<'tcx>(tcx: TyCtxt<'tcx>, item: MonoItem<'tcx>) -> ItemSortKey<'tcx> {
ItemSortKey(

View file

@ -2190,7 +2190,7 @@ macro_rules! sty_debug_print {
all_infer: usize,
}
pub fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
let mut total = DebugStat {
total: 0,
lt_infer: 0,

View file

@ -1027,7 +1027,7 @@ impl UnsafeOpKind {
}
}
pub fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
// Closures and inline consts are handled by their owner, if it has a body
// Also, don't safety check custom MIR
if tcx.is_typeck_child(def.to_def_id()) || tcx.has_attr(def, sym::custom_mir) {

View file

@ -8,6 +8,7 @@
#![feature(if_let_guard)]
#![feature(let_chains)]
#![feature(try_blocks)]
#![warn(unreachable_pub)]
// tidy-alphabetical-end
mod build;

View file

@ -24,7 +24,7 @@ use crate::errors::{
};
use crate::framework::BitSetExt;
pub type EntrySets<'tcx, A> = IndexVec<BasicBlock, <A as AnalysisDomain<'tcx>>::Domain>;
type EntrySets<'tcx, A> = IndexVec<BasicBlock, <A as AnalysisDomain<'tcx>>::Domain>;
/// A dataflow analysis that has converged to fixpoint.
#[derive(Clone)]

View file

@ -510,7 +510,7 @@ impl<T: Idx> GenKill<T> for lattice::Dual<BitSet<T>> {
// NOTE: DO NOT CHANGE VARIANT ORDER. The derived `Ord` impls rely on the current order.
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum Effect {
enum Effect {
/// The "before" effect (e.g., `apply_before_statement_effect`) for a statement (or
/// terminator).
Before,
@ -520,7 +520,7 @@ pub enum Effect {
}
impl Effect {
pub const fn at_index(self, statement_index: usize) -> EffectIndex {
const fn at_index(self, statement_index: usize) -> EffectIndex {
EffectIndex { effect: self, statement_index }
}
}

View file

@ -5,6 +5,7 @@
#![feature(exact_size_is_empty)]
#![feature(let_chains)]
#![feature(try_blocks)]
#![warn(unreachable_pub)]
// tidy-alphabetical-end
use rustc_middle::ty;

View file

@ -15,12 +15,12 @@ use rustc_middle::mir::{Local, Operand, PlaceElem, ProjectionElem};
use rustc_middle::ty::Ty;
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct AbstractOperand;
pub(crate) struct AbstractOperand;
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct AbstractType;
pub type AbstractElem = ProjectionElem<AbstractOperand, AbstractType>;
pub(crate) struct AbstractType;
pub(crate) type AbstractElem = ProjectionElem<AbstractOperand, AbstractType>;
pub trait Lift {
pub(crate) trait Lift {
type Abstract;
fn lift(&self) -> Self::Abstract;
}

View file

@ -135,6 +135,14 @@ pub(crate) fn mir_callgraph_reachable<'tcx>(
}
false
}
// FIXME(-Znext-solver): Remove this hack when trait solver overflow can return an error.
// In code like that pointed out in #128887, the type complexity we ask the solver to deal with
// grows as we recurse into the call graph. If we use the same recursion limit here and in the
// solver, the solver hits the limit first and emits a fatal error. But if we use a reduced
// limit, we will hit the limit first and give up on looking for inlining. And in any case,
// the default recursion limits are quite generous for us. If we need to recurse 64 times
// into the call graph, we're probably not going to find any useful MIR inlining.
let recursion_limit = tcx.recursion_limit() / 2;
process(
tcx,
param_env,
@ -143,7 +151,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>(
&mut Vec::new(),
&mut FxHashSet::default(),
&mut FxHashMap::default(),
tcx.recursion_limit(),
recursion_limit,
)
}

View file

@ -242,12 +242,12 @@ use tracing::{debug, instrument, trace};
use crate::errors::{self, EncounteredErrorWhileInstantiating, NoOptimizedMir, RecursionLimit};
#[derive(PartialEq)]
pub enum MonoItemCollectionStrategy {
pub(crate) enum MonoItemCollectionStrategy {
Eager,
Lazy,
}
pub struct UsageMap<'tcx> {
pub(crate) struct UsageMap<'tcx> {
// Maps every mono item to the mono items used by it.
used_map: UnordMap<MonoItem<'tcx>, Vec<MonoItem<'tcx>>>,
@ -306,13 +306,17 @@ impl<'tcx> UsageMap<'tcx> {
assert!(self.used_map.insert(user_item, used_items).is_none());
}
pub fn get_user_items(&self, item: MonoItem<'tcx>) -> &[MonoItem<'tcx>] {
pub(crate) fn get_user_items(&self, item: MonoItem<'tcx>) -> &[MonoItem<'tcx>] {
self.user_map.get(&item).map(|items| items.as_slice()).unwrap_or(&[])
}
/// Internally iterate over all inlined items used by `item`.
pub fn for_each_inlined_used_item<F>(&self, tcx: TyCtxt<'tcx>, item: MonoItem<'tcx>, mut f: F)
where
pub(crate) fn for_each_inlined_used_item<F>(
&self,
tcx: TyCtxt<'tcx>,
item: MonoItem<'tcx>,
mut f: F,
) where
F: FnMut(MonoItem<'tcx>),
{
let used_items = self.used_map.get(&item).unwrap();
@ -1615,6 +1619,6 @@ pub(crate) fn collect_crate_mono_items<'tcx>(
(mono_items, state.usage_map.into_inner())
}
pub fn provide(providers: &mut Providers) {
pub(crate) fn provide(providers: &mut Providers) {
providers.hooks.should_codegen_locally = should_codegen_locally;
}

View file

@ -8,7 +8,7 @@ use crate::fluent_generated as fluent;
#[derive(Diagnostic)]
#[diag(monomorphize_recursion_limit)]
pub struct RecursionLimit {
pub(crate) struct RecursionLimit {
#[primary_span]
pub span: Span,
pub shrunk: String,
@ -22,13 +22,13 @@ pub struct RecursionLimit {
#[derive(Diagnostic)]
#[diag(monomorphize_no_optimized_mir)]
pub struct NoOptimizedMir {
pub(crate) struct NoOptimizedMir {
#[note]
pub span: Span,
pub crate_name: Symbol,
}
pub struct UnusedGenericParamsHint {
pub(crate) struct UnusedGenericParamsHint {
pub span: Span,
pub param_spans: Vec<Span>,
pub param_names: Vec<String>,
@ -53,7 +53,7 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for UnusedGenericParamsHint {
#[derive(LintDiagnostic)]
#[diag(monomorphize_large_assignments)]
#[note]
pub struct LargeAssignmentsLint {
pub(crate) struct LargeAssignmentsLint {
#[label]
pub span: Span,
pub size: u64,
@ -62,7 +62,7 @@ pub struct LargeAssignmentsLint {
#[derive(Diagnostic)]
#[diag(monomorphize_symbol_already_defined)]
pub struct SymbolAlreadyDefined {
pub(crate) struct SymbolAlreadyDefined {
#[primary_span]
pub span: Option<Span>,
pub symbol: String,
@ -70,13 +70,13 @@ pub struct SymbolAlreadyDefined {
#[derive(Diagnostic)]
#[diag(monomorphize_couldnt_dump_mono_stats)]
pub struct CouldntDumpMonoStats {
pub(crate) struct CouldntDumpMonoStats {
pub error: String,
}
#[derive(Diagnostic)]
#[diag(monomorphize_encountered_error_while_instantiating)]
pub struct EncounteredErrorWhileInstantiating {
pub(crate) struct EncounteredErrorWhileInstantiating {
#[primary_span]
pub span: Span,
pub formatted_item: String,
@ -85,10 +85,10 @@ pub struct EncounteredErrorWhileInstantiating {
#[derive(Diagnostic)]
#[diag(monomorphize_start_not_found)]
#[help]
pub struct StartNotFound;
pub(crate) struct StartNotFound;
#[derive(Diagnostic)]
#[diag(monomorphize_unknown_cgu_collection_mode)]
pub struct UnknownCguCollectionMode<'a> {
pub(crate) struct UnknownCguCollectionMode<'a> {
pub mode: &'a str,
}

View file

@ -1,5 +1,6 @@
// tidy-alphabetical-start
#![feature(array_windows)]
#![warn(unreachable_pub)]
// tidy-alphabetical-end
use rustc_hir::lang_items::LangItem;

View file

@ -1300,7 +1300,7 @@ fn dump_mono_items_stats<'tcx>(
Ok(())
}
pub fn provide(providers: &mut Providers) {
pub(crate) fn provide(providers: &mut Providers) {
providers.collect_and_partition_mono_items = collect_and_partition_mono_items;
providers.is_codegened_item = |tcx, def_id| {

View file

@ -19,7 +19,7 @@ use tracing::{debug, instrument};
use crate::errors::UnusedGenericParamsHint;
/// Provide implementations of queries relating to polymorphization analysis.
pub fn provide(providers: &mut Providers) {
pub(crate) fn provide(providers: &mut Providers) {
providers.unused_generic_params = unused_generic_params;
}

View file

@ -4,6 +4,10 @@
//! but were uplifted in the process of making the new trait solver generic.
//! So if you got to this crate from the old solver, it's totally normal.
// tidy-alphabetical-start
#![warn(unreachable_pub)]
// tidy-alphabetical-end
pub mod canonicalizer;
pub mod coherence;
pub mod delegate;

View file

@ -92,7 +92,7 @@ where
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
// FIXME: This can be made crate-private once `EvalCtxt` also lives in this crate.
pub struct NestedGoals<I: Interner> {
struct NestedGoals<I: Interner> {
/// These normalizes-to goals are treated specially during the evaluation
/// loop. In each iteration we take the RHS of the projection, replace it with
/// a fresh inference variable, and only after evaluating that goal do we
@ -109,11 +109,11 @@ pub struct NestedGoals<I: Interner> {
}
impl<I: Interner> NestedGoals<I> {
pub fn new() -> Self {
fn new() -> Self {
Self { normalizes_to_goals: Vec::new(), goals: Vec::new() }
}
pub fn is_empty(&self) -> bool {
fn is_empty(&self) -> bool {
self.normalizes_to_goals.is_empty() && self.goals.is_empty()
}
}

View file

@ -222,13 +222,13 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
self.state.as_deref_mut()
}
pub fn take_and_enter_probe(&mut self) -> ProofTreeBuilder<D> {
pub(crate) fn take_and_enter_probe(&mut self) -> ProofTreeBuilder<D> {
let mut nested = ProofTreeBuilder { state: self.state.take(), _infcx: PhantomData };
nested.enter_probe();
nested
}
pub fn finalize(self) -> Option<inspect::GoalEvaluation<I>> {
pub(crate) fn finalize(self) -> Option<inspect::GoalEvaluation<I>> {
match *self.state? {
DebugSolver::GoalEvaluation(wip_goal_evaluation) => {
Some(wip_goal_evaluation.finalize())
@ -237,22 +237,22 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
}
}
pub fn new_maybe_root(generate_proof_tree: GenerateProofTree) -> ProofTreeBuilder<D> {
pub(crate) fn new_maybe_root(generate_proof_tree: GenerateProofTree) -> ProofTreeBuilder<D> {
match generate_proof_tree {
GenerateProofTree::No => ProofTreeBuilder::new_noop(),
GenerateProofTree::Yes => ProofTreeBuilder::new_root(),
}
}
pub fn new_root() -> ProofTreeBuilder<D> {
fn new_root() -> ProofTreeBuilder<D> {
ProofTreeBuilder::new(DebugSolver::Root)
}
pub fn new_noop() -> ProofTreeBuilder<D> {
fn new_noop() -> ProofTreeBuilder<D> {
ProofTreeBuilder { state: None, _infcx: PhantomData }
}
pub fn is_noop(&self) -> bool {
pub(crate) fn is_noop(&self) -> bool {
self.state.is_none()
}
@ -272,7 +272,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
})
}
pub fn new_canonical_goal_evaluation(
pub(crate) fn new_canonical_goal_evaluation(
&mut self,
goal: CanonicalInput<I>,
) -> ProofTreeBuilder<D> {
@ -284,7 +284,10 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
})
}
pub fn canonical_goal_evaluation(&mut self, canonical_goal_evaluation: ProofTreeBuilder<D>) {
pub(crate) fn canonical_goal_evaluation(
&mut self,
canonical_goal_evaluation: ProofTreeBuilder<D>,
) {
if let Some(this) = self.as_mut() {
match (this, *canonical_goal_evaluation.state.unwrap()) {
(
@ -299,7 +302,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
}
}
pub fn canonical_goal_evaluation_overflow(&mut self) {
pub(crate) fn canonical_goal_evaluation_overflow(&mut self) {
if let Some(this) = self.as_mut() {
match this {
DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation) => {
@ -310,7 +313,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
}
}
pub fn goal_evaluation(&mut self, goal_evaluation: ProofTreeBuilder<D>) {
pub(crate) fn goal_evaluation(&mut self, goal_evaluation: ProofTreeBuilder<D>) {
if let Some(this) = self.as_mut() {
match this {
DebugSolver::Root => *this = *goal_evaluation.state.unwrap(),
@ -322,7 +325,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
}
}
pub fn new_goal_evaluation_step(
pub(crate) fn new_goal_evaluation_step(
&mut self,
var_values: ty::CanonicalVarValues<I>,
instantiated_goal: QueryInput<I, I::Predicate>,
@ -340,7 +343,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
})
}
pub fn goal_evaluation_step(&mut self, goal_evaluation_step: ProofTreeBuilder<D>) {
pub(crate) fn goal_evaluation_step(&mut self, goal_evaluation_step: ProofTreeBuilder<D>) {
if let Some(this) = self.as_mut() {
match (this, *goal_evaluation_step.state.unwrap()) {
(
@ -354,7 +357,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
}
}
pub fn add_var_value<T: Into<I::GenericArg>>(&mut self, arg: T) {
pub(crate) fn add_var_value<T: Into<I::GenericArg>>(&mut self, arg: T) {
match self.as_mut() {
None => {}
Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => {
@ -364,7 +367,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
}
}
pub fn enter_probe(&mut self) {
fn enter_probe(&mut self) {
match self.as_mut() {
None => {}
Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => {
@ -381,7 +384,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
}
}
pub fn probe_kind(&mut self, probe_kind: inspect::ProbeKind<I>) {
pub(crate) fn probe_kind(&mut self, probe_kind: inspect::ProbeKind<I>) {
match self.as_mut() {
None => {}
Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => {
@ -392,7 +395,11 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
}
}
pub fn probe_final_state(&mut self, delegate: &D, max_input_universe: ty::UniverseIndex) {
pub(crate) fn probe_final_state(
&mut self,
delegate: &D,
max_input_universe: ty::UniverseIndex,
) {
match self.as_mut() {
None => {}
Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => {
@ -409,7 +416,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
}
}
pub fn add_normalizes_to_goal(
pub(crate) fn add_normalizes_to_goal(
&mut self,
delegate: &D,
max_input_universe: ty::UniverseIndex,
@ -423,7 +430,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
);
}
pub fn add_goal(
pub(crate) fn add_goal(
&mut self,
delegate: &D,
max_input_universe: ty::UniverseIndex,
@ -469,7 +476,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
}
}
pub fn make_canonical_response(&mut self, shallow_certainty: Certainty) {
pub(crate) fn make_canonical_response(&mut self, shallow_certainty: Certainty) {
match self.as_mut() {
Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => {
state
@ -482,7 +489,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
}
}
pub fn finish_probe(mut self) -> ProofTreeBuilder<D> {
pub(crate) fn finish_probe(mut self) -> ProofTreeBuilder<D> {
match self.as_mut() {
None => {}
Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => {
@ -497,7 +504,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
self
}
pub fn query_result(&mut self, result: QueryResult<I>) {
pub(crate) fn query_result(&mut self, result: QueryResult<I>) {
if let Some(this) = self.as_mut() {
match this {
DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation) => {

View file

@ -97,7 +97,7 @@ where
/// Checks whether each generic argument is simply a unique generic placeholder.
///
/// FIXME: Interner argument is needed to constrain the `I` parameter.
pub fn uses_unique_placeholders_ignoring_regions<I: Interner>(
fn uses_unique_placeholders_ignoring_regions<I: Interner>(
_cx: I,
args: I::GenericArgs,
) -> Result<(), NotUniqueParam<I>> {
@ -130,7 +130,7 @@ pub fn uses_unique_placeholders_ignoring_regions<I: Interner>(
}
// FIXME: This should check for dupes and non-params first, then infer vars.
pub enum NotUniqueParam<I: Interner> {
enum NotUniqueParam<I: Interner> {
DuplicateParam(I::GenericArg),
NotParam(I::GenericArg),
}

View file

@ -260,7 +260,7 @@ pub(crate) struct NotAsNegationOperator {
}
#[derive(Subdiagnostic)]
pub enum NotAsNegationOperatorSub {
pub(crate) enum NotAsNegationOperatorSub {
#[suggestion(
parse_unexpected_token_after_not_default,
style = "verbose",
@ -424,7 +424,7 @@ pub(crate) enum IfExpressionMissingThenBlockSub {
#[derive(Diagnostic)]
#[diag(parse_ternary_operator)]
#[help]
pub struct TernaryOperator {
pub(crate) struct TernaryOperator {
#[primary_span]
pub span: Span,
}
@ -1088,7 +1088,7 @@ pub(crate) enum ExpectedIdentifierFound {
}
impl ExpectedIdentifierFound {
pub fn new(token_descr: Option<TokenDescription>, span: Span) -> Self {
pub(crate) fn new(token_descr: Option<TokenDescription>, span: Span) -> Self {
(match token_descr {
Some(TokenDescription::ReservedIdentifier) => {
ExpectedIdentifierFound::ReservedIdentifier
@ -1659,7 +1659,7 @@ pub(crate) struct SelfArgumentPointer {
#[derive(Diagnostic)]
#[diag(parse_unexpected_token_after_dot)]
pub struct UnexpectedTokenAfterDot<'a> {
pub(crate) struct UnexpectedTokenAfterDot<'a> {
#[primary_span]
pub span: Span,
pub actual: Cow<'a, str>,
@ -1928,7 +1928,7 @@ pub(crate) enum UnexpectedTokenAfterStructName {
}
impl UnexpectedTokenAfterStructName {
pub fn new(span: Span, token: Token) -> Self {
pub(crate) fn new(span: Span, token: Token) -> Self {
match TokenDescription::from_token(&token) {
Some(TokenDescription::ReservedIdentifier) => Self::ReservedIdentifier { span, token },
Some(TokenDescription::Keyword) => Self::Keyword { span, token },
@ -2006,7 +2006,7 @@ pub(crate) enum TopLevelOrPatternNotAllowed {
#[derive(Diagnostic)]
#[diag(parse_cannot_be_raw_ident)]
pub struct CannotBeRawIdent {
pub(crate) struct CannotBeRawIdent {
#[primary_span]
pub span: Span,
pub ident: Symbol,
@ -2014,14 +2014,14 @@ pub struct CannotBeRawIdent {
#[derive(Diagnostic)]
#[diag(parse_keyword_lifetime)]
pub struct KeywordLifetime {
pub(crate) struct KeywordLifetime {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(parse_invalid_label)]
pub struct InvalidLabel {
pub(crate) struct InvalidLabel {
#[primary_span]
pub span: Span,
pub name: Symbol,
@ -2029,7 +2029,7 @@ pub struct InvalidLabel {
#[derive(Diagnostic)]
#[diag(parse_cr_doc_comment)]
pub struct CrDocComment {
pub(crate) struct CrDocComment {
#[primary_span]
pub span: Span,
pub block: bool,
@ -2037,14 +2037,14 @@ pub struct CrDocComment {
#[derive(Diagnostic)]
#[diag(parse_no_digits_literal, code = E0768)]
pub struct NoDigitsLiteral {
pub(crate) struct NoDigitsLiteral {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(parse_invalid_digit_literal)]
pub struct InvalidDigitLiteral {
pub(crate) struct InvalidDigitLiteral {
#[primary_span]
pub span: Span,
pub base: u32,
@ -2052,14 +2052,14 @@ pub struct InvalidDigitLiteral {
#[derive(Diagnostic)]
#[diag(parse_empty_exponent_float)]
pub struct EmptyExponentFloat {
pub(crate) struct EmptyExponentFloat {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(parse_float_literal_unsupported_base)]
pub struct FloatLiteralUnsupportedBase {
pub(crate) struct FloatLiteralUnsupportedBase {
#[primary_span]
pub span: Span,
pub base: &'static str,
@ -2068,7 +2068,7 @@ pub struct FloatLiteralUnsupportedBase {
#[derive(Diagnostic)]
#[diag(parse_unknown_prefix)]
#[note]
pub struct UnknownPrefix<'a> {
pub(crate) struct UnknownPrefix<'a> {
#[primary_span]
#[label]
pub span: Span,
@ -2079,12 +2079,12 @@ pub struct UnknownPrefix<'a> {
#[derive(Subdiagnostic)]
#[note(parse_macro_expands_to_adt_field)]
pub struct MacroExpandsToAdtField<'a> {
pub(crate) struct MacroExpandsToAdtField<'a> {
pub adt_ty: &'a str,
}
#[derive(Subdiagnostic)]
pub enum UnknownPrefixSugg {
pub(crate) enum UnknownPrefixSugg {
#[suggestion(
parse_suggestion_br,
code = "br",
@ -2114,7 +2114,7 @@ pub enum UnknownPrefixSugg {
#[derive(Diagnostic)]
#[diag(parse_too_many_hashes)]
pub struct TooManyHashes {
pub(crate) struct TooManyHashes {
#[primary_span]
pub span: Span,
pub num: u32,
@ -2122,7 +2122,7 @@ pub struct TooManyHashes {
#[derive(Diagnostic)]
#[diag(parse_unknown_start_of_token)]
pub struct UnknownTokenStart {
pub(crate) struct UnknownTokenStart {
#[primary_span]
pub span: Span,
pub escaped: String,
@ -2135,7 +2135,7 @@ pub struct UnknownTokenStart {
}
#[derive(Subdiagnostic)]
pub enum TokenSubstitution {
pub(crate) enum TokenSubstitution {
#[suggestion(
parse_sugg_quotes,
code = "{suggestion}",
@ -2168,16 +2168,16 @@ pub enum TokenSubstitution {
#[derive(Subdiagnostic)]
#[note(parse_note_repeats)]
pub struct UnknownTokenRepeat {
pub(crate) struct UnknownTokenRepeat {
pub repeats: usize,
}
#[derive(Subdiagnostic)]
#[help(parse_help_null)]
pub struct UnknownTokenNull;
pub(crate) struct UnknownTokenNull;
#[derive(Diagnostic)]
pub enum UnescapeError {
pub(crate) enum UnescapeError {
#[diag(parse_invalid_unicode_escape)]
#[help]
InvalidUnicodeEscape {
@ -2322,7 +2322,7 @@ pub enum UnescapeError {
}
#[derive(Subdiagnostic)]
pub enum MoreThanOneCharSugg {
pub(crate) enum MoreThanOneCharSugg {
#[suggestion(
parse_consider_normalized,
code = "{normalized}",
@ -2370,7 +2370,7 @@ pub enum MoreThanOneCharSugg {
}
#[derive(Subdiagnostic)]
pub enum MoreThanOneCharNote {
pub(crate) enum MoreThanOneCharNote {
#[note(parse_followed_by)]
AllCombining {
#[primary_span]
@ -2388,7 +2388,7 @@ pub enum MoreThanOneCharNote {
}
#[derive(Subdiagnostic)]
pub enum NoBraceUnicodeSub {
pub(crate) enum NoBraceUnicodeSub {
#[suggestion(
parse_use_braces,
code = "{suggestion}",
@ -2703,7 +2703,7 @@ pub(crate) struct InvalidDynKeyword {
}
#[derive(Subdiagnostic)]
pub enum HelpUseLatestEdition {
pub(crate) enum HelpUseLatestEdition {
#[help(parse_help_set_edition_cargo)]
#[note(parse_note_edition_guide)]
Cargo { edition: Edition },
@ -2713,7 +2713,7 @@ pub enum HelpUseLatestEdition {
}
impl HelpUseLatestEdition {
pub fn new() -> Self {
pub(crate) fn new() -> Self {
let edition = LATEST_STABLE_EDITION;
if rustc_session::utils::was_invoked_from_cargo() {
Self::Cargo { edition }
@ -2725,7 +2725,7 @@ impl HelpUseLatestEdition {
#[derive(Diagnostic)]
#[diag(parse_box_syntax_removed)]
pub struct BoxSyntaxRemoved {
pub(crate) struct BoxSyntaxRemoved {
#[primary_span]
pub span: Span,
#[subdiagnostic]
@ -2738,7 +2738,7 @@ pub struct BoxSyntaxRemoved {
applicability = "machine-applicable",
style = "verbose"
)]
pub struct AddBoxNew {
pub(crate) struct AddBoxNew {
#[suggestion_part(code = "Box::new(")]
pub box_kw_and_lo: Span,
#[suggestion_part(code = ")")]
@ -3190,7 +3190,7 @@ pub(crate) struct DotDotRangeAttribute {
#[derive(Diagnostic)]
#[diag(parse_invalid_attr_unsafe)]
#[note]
pub struct InvalidAttrUnsafe {
pub(crate) struct InvalidAttrUnsafe {
#[primary_span]
#[label]
pub span: Span,
@ -3199,7 +3199,7 @@ pub struct InvalidAttrUnsafe {
#[derive(Diagnostic)]
#[diag(parse_unsafe_attr_outside_unsafe)]
pub struct UnsafeAttrOutsideUnsafe {
pub(crate) struct UnsafeAttrOutsideUnsafe {
#[primary_span]
#[label]
pub span: Span,
@ -3212,7 +3212,7 @@ pub struct UnsafeAttrOutsideUnsafe {
parse_unsafe_attr_outside_unsafe_suggestion,
applicability = "machine-applicable"
)]
pub struct UnsafeAttrOutsideUnsafeSuggestion {
pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion {
#[suggestion_part(code = "unsafe(")]
pub left: Span,
#[suggestion_part(code = ")")]
@ -3221,7 +3221,7 @@ pub struct UnsafeAttrOutsideUnsafeSuggestion {
#[derive(Diagnostic)]
#[diag(parse_binder_before_modifiers)]
pub struct BinderBeforeModifiers {
pub(crate) struct BinderBeforeModifiers {
#[primary_span]
pub binder_span: Span,
#[label]
@ -3230,7 +3230,7 @@ pub struct BinderBeforeModifiers {
#[derive(Diagnostic)]
#[diag(parse_binder_and_polarity)]
pub struct BinderAndPolarity {
pub(crate) struct BinderAndPolarity {
#[primary_span]
pub polarity_span: Span,
#[label]
@ -3240,7 +3240,7 @@ pub struct BinderAndPolarity {
#[derive(Diagnostic)]
#[diag(parse_modifiers_and_polarity)]
pub struct PolarityAndModifiers {
pub(crate) struct PolarityAndModifiers {
#[primary_span]
pub polarity_span: Span,
#[label]

View file

@ -11,6 +11,7 @@
#![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![feature(let_chains)]
#![warn(unreachable_pub)]
// tidy-alphabetical-end
use std::path::Path;

View file

@ -13,6 +13,7 @@
html_playground_url = "https://play.rust-lang.org/",
test(attr(deny(warnings)))
)]
#![warn(unreachable_pub)]
// tidy-alphabetical-end
use std::{iter, str, string};

View file

@ -95,6 +95,6 @@ fn debugger_visualizers(tcx: TyCtxt<'_>, _: LocalCrate) -> Vec<DebuggerVisualize
visitor.visualizers
}
pub fn provide(providers: &mut Providers) {
pub(crate) fn provide(providers: &mut Providers) {
providers.debugger_visualizers = debugger_visualizers;
}

View file

@ -90,7 +90,7 @@ fn all_diagnostic_items(tcx: TyCtxt<'_>, (): ()) -> DiagnosticItems {
items
}
pub fn provide(providers: &mut Providers) {
pub(crate) fn provide(providers: &mut Providers) {
providers.diagnostic_items = diagnostic_items;
providers.all_diagnostic_items = all_diagnostic_items;
}

File diff suppressed because it is too large Load diff

View file

@ -359,6 +359,6 @@ impl<'ast, 'tcx> visit::Visitor<'ast> for LanguageItemCollector<'ast, 'tcx> {
}
}
pub fn provide(providers: &mut Providers) {
pub(crate) fn provide(providers: &mut Providers) {
providers.get_lang_items = get_lang_items;
}

View file

@ -12,6 +12,7 @@
#![feature(map_try_insert)]
#![feature(rustdoc_internals)]
#![feature(try_blocks)]
#![warn(unreachable_pub)]
// tidy-alphabetical-end
use rustc_middle::query::Providers;

View file

@ -16,7 +16,7 @@ use rustc_span::{sym, Span};
use crate::errors::{FeaturePreviouslyDeclared, FeatureStableTwice};
pub struct LibFeatureCollector<'tcx> {
struct LibFeatureCollector<'tcx> {
tcx: TyCtxt<'tcx>,
lib_features: LibFeatures,
}
@ -153,6 +153,6 @@ fn lib_features(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> LibFeatures {
collector.lib_features
}
pub fn provide(providers: &mut Providers) {
pub(crate) fn provide(providers: &mut Providers) {
providers.lib_features = lib_features;
}

View file

@ -178,7 +178,7 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) {
lsets.warn_about_unused_args(&body, entry_ln);
}
pub fn provide(providers: &mut Providers) {
pub(crate) fn provide(providers: &mut Providers) {
*providers = Providers { check_liveness, ..*providers };
}

View file

@ -500,6 +500,6 @@ fn reachable_set(tcx: TyCtxt<'_>, (): ()) -> LocalDefIdSet {
reachable_context.reachable_symbols
}
pub fn provide(providers: &mut Providers) {
pub(crate) fn provide(providers: &mut Providers) {
*providers = Providers { reachable_set, ..*providers };
}

View file

@ -9,7 +9,7 @@ use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_span::Span;
pub fn provide(providers: &mut Providers) {
pub(crate) fn provide(providers: &mut Providers) {
providers.upvars_mentioned = |tcx, def_id| {
if !tcx.is_closure_like(def_id) {
return None;

View file

@ -15,7 +15,11 @@ use crate::errors::{
/// Checks the crate for usage of weak lang items, returning a vector of all the
/// lang items required by this crate, but not defined yet.
pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems, krate: &ast::Crate) {
pub(crate) fn check_crate(
tcx: TyCtxt<'_>,
items: &mut lang_items::LanguageItems,
krate: &ast::Crate,
) {
// These are never called by user code, they're generated by the compiler.
// They will never implicitly be added to the `missing` array unless we do
// so here.

View file

@ -6,6 +6,7 @@
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(feature = "rustc", feature(let_chains))]
#![warn(unreachable_pub)]
// tidy-alphabetical-end
pub mod constructor;

View file

@ -5,7 +5,7 @@ use rustc_span::{Span, Symbol};
#[derive(Diagnostic)]
#[diag(privacy_field_is_private, code = E0451)]
pub struct FieldIsPrivate {
pub(crate) struct FieldIsPrivate {
#[primary_span]
pub span: Span,
pub field_name: Symbol,
@ -16,7 +16,7 @@ pub struct FieldIsPrivate {
}
#[derive(Subdiagnostic)]
pub enum FieldIsPrivateLabel {
pub(crate) enum FieldIsPrivateLabel {
#[label(privacy_field_is_private_is_update_syntax_label)]
IsUpdateSyntax {
#[primary_span]
@ -32,7 +32,7 @@ pub enum FieldIsPrivateLabel {
#[derive(Diagnostic)]
#[diag(privacy_item_is_private)]
pub struct ItemIsPrivate<'a> {
pub(crate) struct ItemIsPrivate<'a> {
#[primary_span]
#[label]
pub span: Span,
@ -42,7 +42,7 @@ pub struct ItemIsPrivate<'a> {
#[derive(Diagnostic)]
#[diag(privacy_unnamed_item_is_private)]
pub struct UnnamedItemIsPrivate {
pub(crate) struct UnnamedItemIsPrivate {
#[primary_span]
pub span: Span,
pub kind: &'static str,
@ -50,7 +50,7 @@ pub struct UnnamedItemIsPrivate {
#[derive(Diagnostic)]
#[diag(privacy_in_public_interface, code = E0446)]
pub struct InPublicInterface<'a> {
pub(crate) struct InPublicInterface<'a> {
#[primary_span]
#[label]
pub span: Span,
@ -63,7 +63,7 @@ pub struct InPublicInterface<'a> {
#[derive(Diagnostic)]
#[diag(privacy_report_effective_visibility)]
pub struct ReportEffectiveVisibility {
pub(crate) struct ReportEffectiveVisibility {
#[primary_span]
pub span: Span,
pub descr: String,
@ -71,7 +71,7 @@ pub struct ReportEffectiveVisibility {
#[derive(LintDiagnostic)]
#[diag(privacy_from_private_dep_in_public_interface)]
pub struct FromPrivateDependencyInPublicInterface<'a> {
pub(crate) struct FromPrivateDependencyInPublicInterface<'a> {
pub kind: &'a str,
pub descr: DiagArgFromDisplay<'a>,
pub krate: Symbol,
@ -79,7 +79,7 @@ pub struct FromPrivateDependencyInPublicInterface<'a> {
#[derive(LintDiagnostic)]
#[diag(privacy_unnameable_types_lint)]
pub struct UnnameableTypesLint<'a> {
pub(crate) struct UnnameableTypesLint<'a> {
#[label]
pub span: Span,
pub kind: &'a str,
@ -93,7 +93,7 @@ pub struct UnnameableTypesLint<'a> {
// See https://rust-lang.github.io/rfcs/2145-type-privacy.html for more details.
#[derive(LintDiagnostic)]
#[diag(privacy_private_interface_or_bounds_lint)]
pub struct PrivateInterfacesOrBoundsLint<'a> {
pub(crate) struct PrivateInterfacesOrBoundsLint<'a> {
#[label(privacy_item_label)]
pub item_span: Span,
pub item_kind: &'a str,

View file

@ -6,6 +6,7 @@
#![feature(let_chains)]
#![feature(rustdoc_internals)]
#![feature(try_blocks)]
#![warn(unreachable_pub)]
// tidy-alphabetical-end
mod errors;
@ -1497,7 +1498,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> {
self.effective_visibilities.effective_vis(def_id).copied()
}
pub fn check_item(&mut self, id: ItemId) {
fn check_item(&mut self, id: ItemId) {
let tcx = self.tcx;
let def_id = id.owner_id.def_id;
let item_visibility = tcx.local_visibility(def_id);

View file

@ -8,6 +8,7 @@
#![feature(min_specialization)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
#![warn(unreachable_pub)]
// tidy-alphabetical-end
use field_offset::offset_of;

View file

@ -541,7 +541,7 @@ macro_rules! expand_if_cached {
/// Don't show the backtrace for query system by default
/// use `RUST_BACKTRACE=full` to show all the backtraces
#[inline(never)]
pub fn __rust_begin_short_backtrace<F, T>(f: F) -> T
pub(crate) fn __rust_begin_short_backtrace<F, T>(f: F) -> T
where
F: FnOnce() -> T,
{
@ -557,17 +557,17 @@ macro_rules! define_queries {
$($(#[$attr:meta])*
[$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
pub(crate) mod query_impl { $(pub mod $name {
pub(crate) mod query_impl { $(pub(crate) mod $name {
use super::super::*;
use std::marker::PhantomData;
pub mod get_query_incr {
pub(crate) mod get_query_incr {
use super::*;
// Adding `__rust_end_short_backtrace` marker to backtraces so that we emit the frames
// when `RUST_BACKTRACE=1`, add a new mod with `$name` here is to allow duplicate naming
#[inline(never)]
pub fn __rust_end_short_backtrace<'tcx>(
pub(crate) fn __rust_end_short_backtrace<'tcx>(
tcx: TyCtxt<'tcx>,
span: Span,
key: queries::$name::Key<'tcx>,
@ -585,11 +585,11 @@ macro_rules! define_queries {
}
}
pub mod get_query_non_incr {
pub(crate) mod get_query_non_incr {
use super::*;
#[inline(never)]
pub fn __rust_end_short_backtrace<'tcx>(
pub(crate) fn __rust_end_short_backtrace<'tcx>(
tcx: TyCtxt<'tcx>,
span: Span,
key: queries::$name::Key<'tcx>,
@ -604,7 +604,9 @@ macro_rules! define_queries {
}
}
pub fn dynamic_query<'tcx>() -> DynamicQuery<'tcx, queries::$name::Storage<'tcx>> {
pub(crate) fn dynamic_query<'tcx>()
-> DynamicQuery<'tcx, queries::$name::Storage<'tcx>>
{
DynamicQuery {
name: stringify!($name),
eval_always: is_eval_always!([$($modifiers)*]),
@ -667,7 +669,7 @@ macro_rules! define_queries {
}
#[derive(Copy, Clone, Default)]
pub struct QueryType<'tcx> {
pub(crate) struct QueryType<'tcx> {
data: PhantomData<&'tcx ()>
}
@ -696,7 +698,7 @@ macro_rules! define_queries {
}
}
pub fn try_collect_active_jobs<'tcx>(tcx: TyCtxt<'tcx>, qmap: &mut QueryMap) {
pub(crate) fn try_collect_active_jobs<'tcx>(tcx: TyCtxt<'tcx>, qmap: &mut QueryMap) {
let make_query = |tcx, key| {
let kind = rustc_middle::dep_graph::dep_kinds::$name;
let name = stringify!($name);
@ -711,11 +713,17 @@ macro_rules! define_queries {
// don't `unwrap()` here, just manually check for `None` and do best-effort error
// reporting.
if res.is_none() {
tracing::warn!("Failed to collect active jobs for query with name `{}`!", stringify!($name));
tracing::warn!(
"Failed to collect active jobs for query with name `{}`!",
stringify!($name)
);
}
}
pub fn alloc_self_profile_query_strings<'tcx>(tcx: TyCtxt<'tcx>, string_cache: &mut QueryKeyStringCache) {
pub(crate) fn alloc_self_profile_query_strings<'tcx>(
tcx: TyCtxt<'tcx>,
string_cache: &mut QueryKeyStringCache
) {
$crate::profiling_support::alloc_self_profile_query_strings_for_query_cache(
tcx,
stringify!($name),
@ -725,7 +733,7 @@ macro_rules! define_queries {
}
item_if_cached! { [$($modifiers)*] {
pub fn encode_query_results<'tcx>(
pub(crate) fn encode_query_results<'tcx>(
tcx: TyCtxt<'tcx>,
encoder: &mut CacheEncoder<'_, 'tcx>,
query_result_index: &mut EncodedDepNodeIndex
@ -739,7 +747,7 @@ macro_rules! define_queries {
}
}}
pub fn query_key_hash_verify<'tcx>(tcx: TyCtxt<'tcx>) {
pub(crate) fn query_key_hash_verify<'tcx>(tcx: TyCtxt<'tcx>) {
$crate::plumbing::query_key_hash_verify(
query_impl::$name::QueryType::config(tcx),
QueryCtxt::new(tcx),
@ -795,7 +803,7 @@ macro_rules! define_queries {
use rustc_query_system::dep_graph::FingerprintStyle;
// We use this for most things when incr. comp. is turned off.
pub fn Null<'tcx>() -> DepKindStruct<'tcx> {
pub(crate) fn Null<'tcx>() -> DepKindStruct<'tcx> {
DepKindStruct {
is_anon: false,
is_eval_always: false,
@ -807,7 +815,7 @@ macro_rules! define_queries {
}
// We use this for the forever-red node.
pub fn Red<'tcx>() -> DepKindStruct<'tcx> {
pub(crate) fn Red<'tcx>() -> DepKindStruct<'tcx> {
DepKindStruct {
is_anon: false,
is_eval_always: false,
@ -818,7 +826,7 @@ macro_rules! define_queries {
}
}
pub fn TraitSelect<'tcx>() -> DepKindStruct<'tcx> {
pub(crate) fn TraitSelect<'tcx>() -> DepKindStruct<'tcx> {
DepKindStruct {
is_anon: true,
is_eval_always: false,
@ -829,7 +837,7 @@ macro_rules! define_queries {
}
}
pub fn CompileCodegenUnit<'tcx>() -> DepKindStruct<'tcx> {
pub(crate) fn CompileCodegenUnit<'tcx>() -> DepKindStruct<'tcx> {
DepKindStruct {
is_anon: false,
is_eval_always: false,
@ -840,7 +848,7 @@ macro_rules! define_queries {
}
}
pub fn CompileMonoItem<'tcx>() -> DepKindStruct<'tcx> {
pub(crate) fn CompileMonoItem<'tcx>() -> DepKindStruct<'tcx> {
DepKindStruct {
is_anon: false,
is_eval_always: false,

View file

@ -617,14 +617,14 @@ impl<D: Deps> EncoderState<D> {
}
}
pub struct GraphEncoder<D: Deps> {
pub(crate) struct GraphEncoder<D: Deps> {
profiler: SelfProfilerRef,
status: Lock<Option<EncoderState<D>>>,
record_graph: Option<Lock<DepGraphQuery>>,
}
impl<D: Deps> GraphEncoder<D> {
pub fn new(
pub(crate) fn new(
encoder: FileEncoder,
prev_node_count: usize,
record_graph: bool,
@ -723,7 +723,7 @@ impl<D: Deps> GraphEncoder<D> {
)
}
pub fn finish(&self) -> FileEncodeResult {
pub(crate) fn finish(&self) -> FileEncodeResult {
let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph_finish");
self.status.lock().take().unwrap().finish(&self.profiler)

View file

@ -5,7 +5,7 @@ use rustc_span::{Span, Symbol};
#[derive(Subdiagnostic)]
#[note(query_system_cycle_stack_middle)]
pub struct CycleStack {
pub(crate) struct CycleStack {
#[primary_span]
pub span: Span,
pub desc: String,
@ -20,7 +20,7 @@ pub enum HandleCycleError {
}
#[derive(Subdiagnostic)]
pub enum StackCount {
pub(crate) enum StackCount {
#[note(query_system_cycle_stack_single)]
Single,
#[note(query_system_cycle_stack_multiple)]
@ -28,7 +28,7 @@ pub enum StackCount {
}
#[derive(Subdiagnostic)]
pub enum Alias {
pub(crate) enum Alias {
#[note(query_system_cycle_recursive_ty_alias)]
#[help(query_system_cycle_recursive_ty_alias_help1)]
#[help(query_system_cycle_recursive_ty_alias_help2)]
@ -39,7 +39,7 @@ pub enum Alias {
#[derive(Subdiagnostic)]
#[note(query_system_cycle_usage)]
pub struct CycleUsage {
pub(crate) struct CycleUsage {
#[primary_span]
pub span: Span,
pub usage: String,
@ -47,7 +47,7 @@ pub struct CycleUsage {
#[derive(Diagnostic)]
#[diag(query_system_cycle, code = E0391)]
pub struct Cycle {
pub(crate) struct Cycle {
#[primary_span]
pub span: Span,
pub stack_bottom: String,
@ -65,14 +65,14 @@ pub struct Cycle {
#[derive(Diagnostic)]
#[diag(query_system_reentrant)]
pub struct Reentrant;
pub(crate) struct Reentrant;
#[derive(Diagnostic)]
#[diag(query_system_increment_compilation)]
#[help]
#[note(query_system_increment_compilation_note1)]
#[note(query_system_increment_compilation_note2)]
pub struct IncrementCompilation {
pub(crate) struct IncrementCompilation {
pub run_cmd: String,
pub dep_node: String,
}

View file

@ -5,6 +5,7 @@
#![feature(hash_raw_entry)]
#![feature(let_chains)]
#![feature(min_specialization)]
#![warn(unreachable_pub)]
// tidy-alphabetical-end
pub mod cache;

View file

@ -21,6 +21,7 @@
#![feature(let_chains)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
#![warn(unreachable_pub)]
// tidy-alphabetical-end
use std::cell::{Cell, RefCell};

View file

@ -22,7 +22,9 @@ use rustc_feature::UnstableFeatures;
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST, LATEST_STABLE_EDITION};
use rustc_span::source_map::FilePathMapping;
use rustc_span::{FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm};
use rustc_span::{
sym, FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm, Symbol,
};
use rustc_target::spec::{
FramePointer, LinkSelfContainedComponents, LinkerFeatures, SplitDebuginfo, Target, TargetTriple,
};
@ -402,6 +404,23 @@ impl LocationDetail {
}
}
/// Values for the `-Z fmt-debug` flag.
#[derive(Copy, Clone, PartialEq, Hash, Debug)]
pub enum FmtDebug {
/// Derive fully-featured implementation
Full,
/// Print only type name, without fields
Shallow,
/// `#[derive(Debug)]` and `{:?}` are no-ops
None,
}
impl FmtDebug {
pub(crate) fn all() -> [Symbol; 3] {
[sym::full, sym::none, sym::shallow]
}
}
#[derive(Clone, PartialEq, Hash, Debug)]
pub enum SwitchWithOptPath {
Enabled(Option<PathBuf>),
@ -2994,7 +3013,7 @@ pub(crate) mod dep_tracking {
use super::{
BranchProtection, CFGuard, CFProtection, CollapseMacroDebuginfo, CoverageOptions,
CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FunctionReturn,
CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, FunctionReturn,
InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail,
LtoCli, NextSolverConfig, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes,
PatchableFunctionEntry, Polonius, RemapPathScopeComponents, ResolveDocLinks,
@ -3088,6 +3107,7 @@ pub(crate) mod dep_tracking {
OutputType,
RealFileName,
LocationDetail,
FmtDebug,
BranchProtection,
OomStrategy,
LanguageIdentifier,

View file

@ -31,7 +31,7 @@ use rustc_span::symbol::{sym, Symbol};
use rustc_target::abi::Align;
use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet, Target, TargetTriple, TARGETS};
use crate::config::CrateType;
use crate::config::{CrateType, FmtDebug};
use crate::Session;
/// The parsed `--cfg` options that define the compilation environment of the
@ -142,6 +142,7 @@ pub(crate) fn disallow_cfgs(sess: &Session, user_cfgs: &Cfg) {
| (sym::target_has_atomic_equal_alignment, Some(_))
| (sym::target_has_atomic_load_store, Some(_))
| (sym::target_thread_local, None) => disallow(cfg, "--target"),
(sym::fmt_debug, None | Some(_)) => disallow(cfg, "-Z fmt-debug"),
_ => {}
}
}
@ -179,6 +180,20 @@ pub(crate) fn default_configuration(sess: &Session) -> Cfg {
ins_none!(sym::debug_assertions);
}
if sess.is_nightly_build() {
match sess.opts.unstable_opts.fmt_debug {
FmtDebug::Full => {
ins_sym!(sym::fmt_debug, sym::full);
}
FmtDebug::Shallow => {
ins_sym!(sym::fmt_debug, sym::shallow);
}
FmtDebug::None => {
ins_sym!(sym::fmt_debug, sym::none);
}
}
}
if sess.overflow_checks() {
ins_none!(sym::overflow_checks);
}
@ -326,6 +341,8 @@ impl CheckCfg {
ins!(sym::debug_assertions, no_values);
ins!(sym::fmt_debug, empty_values).extend(FmtDebug::all());
// These four are never set by rustc, but we set them anyway; they
// should not trigger the lint because `cargo clippy`, `cargo doc`,
// `cargo test`, `cargo miri run` and `cargo fmt` (respectively)

View file

@ -408,6 +408,7 @@ mod desc {
pub const parse_linker_plugin_lto: &str =
"either a boolean (`yes`, `no`, `on`, `off`, etc), or the path to the linker plugin";
pub const parse_location_detail: &str = "either `none`, or a comma separated list of location details to track: `file`, `line`, or `column`";
pub const parse_fmt_debug: &str = "either `full`, `shallow`, or `none`";
pub const parse_switch_with_opt_path: &str =
"an optional path to the profiling data output directory";
pub const parse_merge_functions: &str = "one of: `disabled`, `trampolines`, or `aliases`";
@ -589,6 +590,16 @@ mod parse {
}
}
pub(crate) fn parse_fmt_debug(opt: &mut FmtDebug, v: Option<&str>) -> bool {
*opt = match v {
Some("full") => FmtDebug::Full,
Some("shallow") => FmtDebug::Shallow,
Some("none") => FmtDebug::None,
_ => return false,
};
true
}
pub(crate) fn parse_location_detail(ld: &mut LocationDetail, v: Option<&str>) -> bool {
if let Some(v) = v {
ld.line = false;
@ -1724,6 +1735,9 @@ options! {
flatten_format_args: bool = (true, parse_bool, [TRACKED],
"flatten nested format_args!() and literals into a simplified format_args!() call \
(default: yes)"),
fmt_debug: FmtDebug = (FmtDebug::Full, parse_fmt_debug, [TRACKED],
"how detailed `#[derive(Debug)]` should be. `full` prints types recursively, \
`shallow` prints only type names, `none` prints nothing and disables `{:?}`. (default: `full`)"),
force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED],
"force all crates to be `rustc_private` unstable (default: no)"),
fuel: Option<(String, u64)> = (None, parse_optimization_fuel, [TRACKED],
@ -1797,6 +1811,8 @@ options! {
"link the `.rlink` file generated by `-Z no-link` (default: no)"),
linker_features: LinkerFeaturesCli = (LinkerFeaturesCli::default(), parse_linker_features, [UNTRACKED],
"a comma-separated list of linker features to enable (+) or disable (-): `lld`"),
lint_llvm_ir: bool = (false, parse_bool, [TRACKED],
"lint LLVM IR (default: no)"),
lint_mir: bool = (false, parse_bool, [UNTRACKED],
"lint MIR before and after each transformation"),
llvm_module_flag: Vec<(String, u32, String)> = (Vec::new(), parse_llvm_module_flag, [TRACKED],

View file

@ -26,7 +26,6 @@
#![feature(let_chains)]
#![feature(min_specialization)]
#![feature(negative_impls)]
#![feature(new_uninit)]
#![feature(read_buf)]
#![feature(round_char_boundary)]
#![feature(rustc_attrs)]

View file

@ -356,6 +356,7 @@ symbols! {
_task_context,
a32,
aarch64_target_feature,
aarch64_unstable_target_feature,
aarch64_ver_target_feature,
abi,
abi_amdgpu_kernel,
@ -535,6 +536,7 @@ symbols! {
cfg_attr_multi,
cfg_doctest,
cfg_eval,
cfg_fmt_debug,
cfg_hide,
cfg_overflow_checks,
cfg_panic,
@ -894,6 +896,7 @@ symbols! {
fmaf32,
fmaf64,
fmt,
fmt_debug,
fmul_algebraic,
fmul_fast,
fn_align,
@ -937,6 +940,7 @@ symbols! {
fs_create_dir,
fsub_algebraic,
fsub_fast,
full,
fundamental,
fused_iterator,
future,
@ -1280,6 +1284,7 @@ symbols! {
new_binary,
new_const,
new_debug,
new_debug_noop,
new_display,
new_lower_exp,
new_lower_hex,
@ -1714,6 +1719,7 @@ symbols! {
semitransparent,
sha512_sm_x86,
shadow_call_stack,
shallow,
shl,
shl_assign,
shorter_tail_lifetimes,
@ -1897,6 +1903,7 @@ symbols! {
three_way_compare,
thumb2,
thumb_mode: "thumb-mode",
time,
tmm_reg,
to_owned_method,
to_string,

View file

@ -7,7 +7,7 @@ pub fn target() -> Target {
llvm_target: "aarch64-unknown-unknown-musl".into(),
metadata: crate::spec::TargetMetadata {
description: Some("ARM64 Trusty".into()),
tier: Some(2),
tier: Some(3),
host_tools: Some(false),
std: Some(false),
},

View file

@ -8,7 +8,7 @@ pub fn target() -> Target {
llvm_target: "armv7-unknown-unknown-gnueabi".into(),
metadata: crate::spec::TargetMetadata {
description: Some("Armv7-A Trusty".into()),
tier: Some(2),
tier: Some(3),
host_tools: Some(false),
std: Some(false),
},

View file

@ -28,7 +28,7 @@ pub fn target() -> Target {
code_model: Some(CodeModel::Medium),
emit_debug_gdb_scripts: false,
eh_frame_header: false,
supported_sanitizers: SanitizerSet::KERNELADDRESS,
supported_sanitizers: SanitizerSet::KERNELADDRESS | SanitizerSet::SHADOWCALLSTACK,
..Default::default()
},
}

View file

@ -27,7 +27,7 @@ pub fn target() -> Target {
code_model: Some(CodeModel::Medium),
emit_debug_gdb_scripts: false,
eh_frame_header: false,
supported_sanitizers: SanitizerSet::KERNELADDRESS,
supported_sanitizers: SanitizerSet::KERNELADDRESS | SanitizerSet::SHADOWCALLSTACK,
..Default::default()
},
}

View file

@ -99,6 +99,8 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("bti", Stable, &[]),
// FEAT_CRC
("crc", Stable, &[]),
// FEAT_CSSC
("cssc", Unstable(sym::aarch64_unstable_target_feature), &[]),
// FEAT_DIT
("dit", Stable, &[]),
// FEAT_DotProd
@ -107,21 +109,37 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("dpb", Stable, &[]),
// FEAT_DPB2
("dpb2", Stable, &["dpb"]),
// FEAT_ECV
("ecv", Unstable(sym::aarch64_unstable_target_feature), &[]),
// FEAT_F32MM
("f32mm", Stable, &["sve"]),
// FEAT_F64MM
("f64mm", Stable, &["sve"]),
// FEAT_FAMINMAX
("faminmax", Unstable(sym::aarch64_unstable_target_feature), &[]),
// FEAT_FCMA
("fcma", Stable, &["neon"]),
// FEAT_FHM
("fhm", Stable, &["fp16"]),
// FEAT_FLAGM
("flagm", Stable, &[]),
// FEAT_FLAGM2
("flagm2", Unstable(sym::aarch64_unstable_target_feature), &[]),
// FEAT_FP16
// Rust ties FP and Neon: https://github.com/rust-lang/rust/pull/91608
("fp16", Stable, &["neon"]),
// FEAT_FP8
("fp8", Unstable(sym::aarch64_unstable_target_feature), &["faminmax", "lut", "bf16"]),
// FEAT_FP8DOT2
("fp8dot2", Unstable(sym::aarch64_unstable_target_feature), &["fp8dot4"]),
// FEAT_FP8DOT4
("fp8dot4", Unstable(sym::aarch64_unstable_target_feature), &["fp8fma"]),
// FEAT_FP8FMA
("fp8fma", Unstable(sym::aarch64_unstable_target_feature), &["fp8"]),
// FEAT_FRINTTS
("frintts", Stable, &[]),
// FEAT_HBC
("hbc", Unstable(sym::aarch64_unstable_target_feature), &[]),
// FEAT_I8MM
("i8mm", Stable, &[]),
// FEAT_JSCVT
@ -131,6 +149,14 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("lor", Stable, &[]),
// FEAT_LSE
("lse", Stable, &[]),
// FEAT_LSE128
("lse128", Unstable(sym::aarch64_unstable_target_feature), &["lse"]),
// FEAT_LSE2
("lse2", Unstable(sym::aarch64_unstable_target_feature), &[]),
// FEAT_LUT
("lut", Unstable(sym::aarch64_unstable_target_feature), &[]),
// FEAT_MOPS
("mops", Unstable(sym::aarch64_unstable_target_feature), &[]),
// FEAT_MTE & FEAT_MTE2
("mte", Stable, &[]),
// FEAT_AdvSimd & FEAT_FP
@ -143,14 +169,16 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("pan", Stable, &[]),
// FEAT_PMUv3
("pmuv3", Stable, &[]),
// FEAT_RAND
// FEAT_RNG
("rand", Stable, &[]),
// FEAT_RAS & FEAT_RASv1p1
("ras", Stable, &[]),
// FEAT_RCPC
// FEAT_LRCPC
("rcpc", Stable, &[]),
// FEAT_RCPC2
// FEAT_LRCPC2
("rcpc2", Stable, &["rcpc"]),
// FEAT_LRCPC3
("rcpc3", Unstable(sym::aarch64_unstable_target_feature), &["rcpc2"]),
// FEAT_RDM
("rdm", Stable, &["neon"]),
// FEAT_SB
@ -161,10 +189,36 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("sha3", Stable, &["sha2"]),
// FEAT_SM3 & FEAT_SM4
("sm4", Stable, &["neon"]),
// FEAT_SME
("sme", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
// FEAT_SME_F16F16
("sme-f16f16", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]),
// FEAT_SME_F64F64
("sme-f64f64", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
// FEAT_SME_F8F16
("sme-f8f16", Unstable(sym::aarch64_unstable_target_feature), &["sme-f8f32"]),
// FEAT_SME_F8F32
("sme-f8f32", Unstable(sym::aarch64_unstable_target_feature), &["sme2", "fp8"]),
// FEAT_SME_FA64
("sme-fa64", Unstable(sym::aarch64_unstable_target_feature), &["sme", "sve2"]),
// FEAT_SME_I16I64
("sme-i16i64", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
// FEAT_SME_LUTv2
("sme-lutv2", Unstable(sym::aarch64_unstable_target_feature), &[]),
// FEAT_SME2
("sme2", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
// FEAT_SME2p1
("sme2p1", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]),
// FEAT_SPE
("spe", Stable, &[]),
// FEAT_SSBS & FEAT_SSBS2
("ssbs", Stable, &[]),
// FEAT_SSVE_FP8FDOT2
("ssve-fp8dot2", Unstable(sym::aarch64_unstable_target_feature), &["ssve-fp8dot4"]),
// FEAT_SSVE_FP8FDOT4
("ssve-fp8dot4", Unstable(sym::aarch64_unstable_target_feature), &["ssve-fp8fma"]),
// FEAT_SSVE_FP8FMA
("ssve-fp8fma", Unstable(sym::aarch64_unstable_target_feature), &["sme2", "fp8"]),
// FEAT_SVE
// It was decided that SVE requires Neon: https://github.com/rust-lang/rust/pull/91608
//
@ -173,9 +227,11 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
//
// "For backwards compatibility, Neon and VFP are required in the latest architectures."
("sve", Stable, &["neon"]),
// FEAT_SVE_B16B16 (SVE or SME Instructions)
("sve-b16b16", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
// FEAT_SVE2
("sve2", Stable, &["sve"]),
// FEAT_SVE2_AES
// FEAT_SVE_AES & FEAT_SVE_PMULL128
("sve2-aes", Stable, &["sve2", "aes"]),
// FEAT_SVE2_BitPerm
("sve2-bitperm", Stable, &["sve2"]),
@ -183,6 +239,8 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("sve2-sha3", Stable, &["sve2", "sha3"]),
// FEAT_SVE2_SM4
("sve2-sm4", Stable, &["sve2", "sm4"]),
// FEAT_SVE2p1
("sve2p1", Unstable(sym::aarch64_unstable_target_feature), &["sve2"]),
// FEAT_TME
("tme", Stable, &[]),
(
@ -199,9 +257,19 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("v8.4a", Unstable(sym::aarch64_ver_target_feature), &["v8.3a", "dotprod", "dit", "flagm"]),
("v8.5a", Unstable(sym::aarch64_ver_target_feature), &["v8.4a", "ssbs", "sb", "dpb2", "bti"]),
("v8.6a", Unstable(sym::aarch64_ver_target_feature), &["v8.5a", "bf16", "i8mm"]),
("v8.7a", Unstable(sym::aarch64_ver_target_feature), &[]),
("v8.7a", Unstable(sym::aarch64_ver_target_feature), &["v8.6a", "wfxt"]),
("v8.8a", Unstable(sym::aarch64_ver_target_feature), &["v8.7a", "hbc", "mops"]),
("v8.9a", Unstable(sym::aarch64_ver_target_feature), &["v8.8a", "cssc"]),
("v9.1a", Unstable(sym::aarch64_ver_target_feature), &["v9a", "v8.6a"]),
("v9.2a", Unstable(sym::aarch64_ver_target_feature), &["v9.1a", "v8.7a"]),
("v9.3a", Unstable(sym::aarch64_ver_target_feature), &["v9.2a", "v8.8a"]),
("v9.4a", Unstable(sym::aarch64_ver_target_feature), &["v9.3a", "v8.9a"]),
("v9.5a", Unstable(sym::aarch64_ver_target_feature), &["v9.4a"]),
("v9a", Unstable(sym::aarch64_ver_target_feature), &["v8.5a", "sve2"]),
// FEAT_VHE
("vh", Stable, &[]),
// FEAT_WFxT
("wfxt", Unstable(sym::aarch64_unstable_target_feature), &[]),
// tidy-alphabetical-end
];

View file

@ -446,6 +446,8 @@ trait_selection_type_annotations_needed = {$source_kind ->
}
.label = type must be known at this point
trait_selection_type_annotations_needed_error_time = this is an inference error on crate `time` caused by an API change in Rust 1.80.0; update `time` to version `>=0.3.35` by calling `cargo update`
trait_selection_types_declared_different = these two types are declared with different lifetimes...
trait_selection_unable_to_construct_constant_value = unable to construct a constant value for the unevaluated constant {$unevaluated}

View file

@ -6,7 +6,7 @@ use rustc_errors::codes::*;
use rustc_errors::{Diag, IntoDiagArg};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, LetStmt, LocalSource};
use rustc_middle::bug;
@ -18,7 +18,7 @@ use rustc_middle::ty::{
TypeFoldable, TypeFolder, TypeSuperFoldable, TypeckResults,
};
use rustc_span::symbol::{sym, Ident};
use rustc_span::{BytePos, Span, DUMMY_SP};
use rustc_span::{BytePos, FileName, Span, DUMMY_SP};
use crate::error_reporting::TypeErrCtxt;
use crate::errors::{
@ -384,6 +384,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
bad_label,
was_written: false,
path: Default::default(),
time_version: false,
}),
TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
span,
@ -577,6 +578,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}
}
}
let time_version =
self.detect_old_time_crate_version(failure_span, &kind, &mut infer_subdiags);
match error_code {
TypeAnnotationNeeded::E0282 => self.dcx().create_err(AnnotationRequired {
span,
@ -588,6 +593,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
bad_label: None,
was_written: path.is_some(),
path: path.unwrap_or_default(),
time_version,
}),
TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
span,
@ -613,6 +619,42 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}),
}
}
/// Detect the inference regression on crate `time` <= 0.3.35 and emit a more targeted error.
/// <https://github.com/rust-lang/rust/issues/127343>
// FIXME: we should figure out a more generic version of doing this, ideally in cargo itself.
fn detect_old_time_crate_version(
&self,
span: Option<Span>,
kind: &InferSourceKind<'_>,
// We will clear the non-actionable suggestion from the error to reduce noise.
infer_subdiags: &mut Vec<SourceKindSubdiag<'_>>,
) -> bool {
// FIXME(#129461): We are time-boxing this code in the compiler. It'll start failing
// compilation once we promote 1.89 to beta, which will happen in 9 months from now.
#[cfg(not(version("1.89")))]
const fn version_check() {}
#[cfg(version("1.89"))]
const fn version_check() {
panic!("remove this check as presumably the ecosystem has moved from needing it");
}
const { version_check() };
// Only relevant when building the `time` crate.
if self.infcx.tcx.crate_name(LOCAL_CRATE) == sym::time
&& let Some(span) = span
&& let InferSourceKind::LetBinding { pattern_name, .. } = kind
&& let Some(name) = pattern_name
&& name.as_str() == "items"
&& let FileName::Real(file) = self.infcx.tcx.sess.source_map().span_to_filename(span)
{
let path = file.local_path_if_available().to_string_lossy();
if path.contains("format_description") && path.contains("parse") {
infer_subdiags.clear();
return true;
}
}
false
}
}
#[derive(Debug)]

View file

@ -205,6 +205,8 @@ pub struct AnnotationRequired<'a> {
#[note(trait_selection_full_type_written)]
pub was_written: bool,
pub path: PathBuf,
#[note(trait_selection_type_annotations_needed_error_time)]
pub time_version: bool,
}
// Copy of `AnnotationRequired` for E0283

View file

@ -19,6 +19,7 @@
#![feature(assert_matches)]
#![feature(associated_type_defaults)]
#![feature(box_patterns)]
#![feature(cfg_version)]
#![feature(control_flow_enum)]
#![feature(extract_if)]
#![feature(if_let_guard)]

View file

@ -465,6 +465,22 @@ impl Location {
}
}
/// Location of the statement at the given index for a given basic block. Assumes that `stmt_idx`
/// and `bb_idx` are valid for a given body.
pub fn statement_location(body: &Body, bb_idx: &BasicBlockIdx, stmt_idx: usize) -> Location {
let bb = &body.blocks[*bb_idx];
let stmt = &bb.statements[stmt_idx];
Location(stmt.span)
}
/// Location of the terminator for a given basic block. Assumes that `bb_idx` is valid for a given
/// body.
pub fn terminator_location(body: &Body, bb_idx: &BasicBlockIdx) -> Location {
let bb = &body.blocks[*bb_idx];
let terminator = &bb.terminator;
Location(terminator.span)
}
/// Reference to a place used to represent a partial projection.
pub struct PlaceRef<'a> {
pub local: Local,

View file

@ -58,9 +58,9 @@ dependencies = [
[[package]]
name = "compiler_builtins"
version = "0.1.121"
version = "0.1.123"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce956e6dc07082ec481f0935a51e83b343f8ca51be560452c0ebf830d0bdf5a5"
checksum = "b47fcbecb558bdad78c7d3a998523c60a50dd6cd046d5fe74163e309e878fff7"
dependencies = [
"cc",
"rustc-std-workspace-core",

View file

@ -10,7 +10,7 @@ edition = "2021"
[dependencies]
core = { path = "../core" }
compiler_builtins = { version = "0.1.121", features = ['rustc-dep-of-std'] }
compiler_builtins = { version = "0.1.123", features = ['rustc-dep-of-std'] }
[dev-dependencies]
rand = { version = "0.8.5", default-features = false, features = ["alloc"] }

View file

@ -262,8 +262,6 @@ impl<T> Box<T> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
///
/// let mut five = Box::<u32>::new_uninit();
///
/// let five = unsafe {
@ -276,7 +274,7 @@ impl<T> Box<T> {
/// assert_eq!(*five, 5)
/// ```
#[cfg(not(no_global_oom_handling))]
#[unstable(feature = "new_uninit", issue = "63291")]
#[stable(feature = "new_uninit", since = "CURRENT_RUSTC_VERSION")]
#[must_use]
#[inline]
pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
@ -292,7 +290,6 @@ impl<T> Box<T> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(new_zeroed_alloc)]
///
/// let zero = Box::<u32>::new_zeroed();
@ -350,7 +347,7 @@ impl<T> Box<T> {
/// # Examples
///
/// ```
/// #![feature(allocator_api, new_uninit)]
/// #![feature(allocator_api)]
///
/// let mut five = Box::<u32>::try_new_uninit()?;
///
@ -380,7 +377,7 @@ impl<T> Box<T> {
/// # Examples
///
/// ```
/// #![feature(allocator_api, new_uninit)]
/// #![feature(allocator_api)]
///
/// let zero = Box::<u32>::try_new_zeroed()?;
/// let zero = unsafe { zero.assume_init() };
@ -460,7 +457,7 @@ impl<T, A: Allocator> Box<T, A> {
/// # Examples
///
/// ```
/// #![feature(allocator_api, new_uninit)]
/// #![feature(allocator_api)]
///
/// use std::alloc::System;
///
@ -498,7 +495,7 @@ impl<T, A: Allocator> Box<T, A> {
/// # Examples
///
/// ```
/// #![feature(allocator_api, new_uninit)]
/// #![feature(allocator_api)]
///
/// use std::alloc::System;
///
@ -538,7 +535,7 @@ impl<T, A: Allocator> Box<T, A> {
/// # Examples
///
/// ```
/// #![feature(allocator_api, new_uninit)]
/// #![feature(allocator_api)]
///
/// use std::alloc::System;
///
@ -576,7 +573,7 @@ impl<T, A: Allocator> Box<T, A> {
/// # Examples
///
/// ```
/// #![feature(allocator_api, new_uninit)]
/// #![feature(allocator_api)]
///
/// use std::alloc::System;
///
@ -654,8 +651,6 @@ impl<T> Box<[T]> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
///
/// let mut values = Box::<[u32]>::new_uninit_slice(3);
///
/// let values = unsafe {
@ -670,7 +665,7 @@ impl<T> Box<[T]> {
/// assert_eq!(*values, [1, 2, 3])
/// ```
#[cfg(not(no_global_oom_handling))]
#[unstable(feature = "new_uninit", issue = "63291")]
#[stable(feature = "new_uninit", since = "CURRENT_RUSTC_VERSION")]
#[must_use]
pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> {
unsafe { RawVec::with_capacity(len).into_box(len) }
@ -686,7 +681,6 @@ impl<T> Box<[T]> {
///
/// ```
/// #![feature(new_zeroed_alloc)]
/// #![feature(new_uninit)]
///
/// let values = Box::<[u32]>::new_zeroed_slice(3);
/// let values = unsafe { values.assume_init() };
@ -708,7 +702,7 @@ impl<T> Box<[T]> {
/// # Examples
///
/// ```
/// #![feature(allocator_api, new_uninit)]
/// #![feature(allocator_api)]
///
/// let mut values = Box::<[u32]>::try_new_uninit_slice(3)?;
/// let values = unsafe {
@ -746,7 +740,7 @@ impl<T> Box<[T]> {
/// # Examples
///
/// ```
/// #![feature(allocator_api, new_uninit)]
/// #![feature(allocator_api)]
///
/// let values = Box::<[u32]>::try_new_zeroed_slice(3)?;
/// let values = unsafe { values.assume_init() };
@ -778,7 +772,7 @@ impl<T, A: Allocator> Box<[T], A> {
/// # Examples
///
/// ```
/// #![feature(allocator_api, new_uninit)]
/// #![feature(allocator_api)]
///
/// use std::alloc::System;
///
@ -812,7 +806,7 @@ impl<T, A: Allocator> Box<[T], A> {
/// # Examples
///
/// ```
/// #![feature(allocator_api, new_uninit)]
/// #![feature(allocator_api)]
///
/// use std::alloc::System;
///
@ -837,7 +831,7 @@ impl<T, A: Allocator> Box<[T], A> {
/// # Examples
///
/// ```
/// #![feature(allocator_api, new_uninit)]
/// #![feature(allocator_api)]
///
/// use std::alloc::System;
///
@ -880,7 +874,7 @@ impl<T, A: Allocator> Box<[T], A> {
/// # Examples
///
/// ```
/// #![feature(allocator_api, new_uninit)]
/// #![feature(allocator_api)]
///
/// use std::alloc::System;
///
@ -927,8 +921,6 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
///
/// let mut five = Box::<u32>::new_uninit();
///
/// let five: Box<u32> = unsafe {
@ -940,7 +932,7 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
///
/// assert_eq!(*five, 5)
/// ```
#[unstable(feature = "new_uninit", issue = "63291")]
#[stable(feature = "new_uninit", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub unsafe fn assume_init(self) -> Box<T, A> {
let (raw, alloc) = Box::into_raw_with_allocator(self);
@ -958,7 +950,6 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
///
/// ```
/// #![feature(box_uninit_write)]
/// #![feature(new_uninit)]
///
/// let big_box = Box::<[usize; 1024]>::new_uninit();
///
@ -1001,8 +992,6 @@ impl<T, A: Allocator> Box<[mem::MaybeUninit<T>], A> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
///
/// let mut values = Box::<[u32]>::new_uninit_slice(3);
///
/// let values = unsafe {
@ -1016,7 +1005,7 @@ impl<T, A: Allocator> Box<[mem::MaybeUninit<T>], A> {
///
/// assert_eq!(*values, [1, 2, 3])
/// ```
#[unstable(feature = "new_uninit", issue = "63291")]
#[stable(feature = "new_uninit", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub unsafe fn assume_init(self) -> Box<[T], A> {
let (raw, alloc) = Box::into_raw_with_allocator(self);

View file

@ -93,7 +93,6 @@
// tidy-alphabetical-start
#![cfg_attr(not(no_global_oom_handling), feature(const_alloc_error))]
#![cfg_attr(not(no_global_oom_handling), feature(const_btree_len))]
#![cfg_attr(test, feature(new_uninit))]
#![feature(alloc_layout_extra)]
#![feature(allocator_api)]
#![feature(array_chunks)]

View file

@ -503,7 +503,6 @@ impl<T> Rc<T> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(get_mut_unchecked)]
///
/// use std::rc::Rc;
@ -518,7 +517,7 @@ impl<T> Rc<T> {
/// assert_eq!(*five, 5)
/// ```
#[cfg(not(no_global_oom_handling))]
#[unstable(feature = "new_uninit", issue = "63291")]
#[stable(feature = "new_uninit", since = "CURRENT_RUSTC_VERSION")]
#[must_use]
pub fn new_uninit() -> Rc<mem::MaybeUninit<T>> {
unsafe {
@ -540,7 +539,6 @@ impl<T> Rc<T> {
///
/// ```
/// #![feature(new_zeroed_alloc)]
/// #![feature(new_uninit)]
///
/// use std::rc::Rc;
///
@ -594,7 +592,7 @@ impl<T> Rc<T> {
/// # Examples
///
/// ```
/// #![feature(allocator_api, new_uninit)]
/// #![feature(allocator_api)]
/// #![feature(get_mut_unchecked)]
///
/// use std::rc::Rc;
@ -630,7 +628,7 @@ impl<T> Rc<T> {
/// # Examples
///
/// ```
/// #![feature(allocator_api, new_uninit)]
/// #![feature(allocator_api)]
///
/// use std::rc::Rc;
///
@ -692,7 +690,6 @@ impl<T, A: Allocator> Rc<T, A> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(get_mut_unchecked)]
/// #![feature(allocator_api)]
///
@ -736,7 +733,6 @@ impl<T, A: Allocator> Rc<T, A> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(allocator_api)]
///
/// use std::rc::Rc;
@ -799,7 +795,7 @@ impl<T, A: Allocator> Rc<T, A> {
/// # Examples
///
/// ```
/// #![feature(allocator_api, new_uninit)]
/// #![feature(allocator_api)]
/// #![feature(get_mut_unchecked)]
///
/// use std::rc::Rc;
@ -843,7 +839,7 @@ impl<T, A: Allocator> Rc<T, A> {
/// # Examples
///
/// ```
/// #![feature(allocator_api, new_uninit)]
/// #![feature(allocator_api)]
///
/// use std::rc::Rc;
/// use std::alloc::System;
@ -967,7 +963,6 @@ impl<T> Rc<[T]> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(get_mut_unchecked)]
///
/// use std::rc::Rc;
@ -985,7 +980,7 @@ impl<T> Rc<[T]> {
/// assert_eq!(*values, [1, 2, 3])
/// ```
#[cfg(not(no_global_oom_handling))]
#[unstable(feature = "new_uninit", issue = "63291")]
#[stable(feature = "new_uninit", since = "CURRENT_RUSTC_VERSION")]
#[must_use]
pub fn new_uninit_slice(len: usize) -> Rc<[mem::MaybeUninit<T>]> {
unsafe { Rc::from_ptr(Rc::allocate_for_slice(len)) }
@ -1000,7 +995,6 @@ impl<T> Rc<[T]> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(new_zeroed_alloc)]
///
/// use std::rc::Rc;
@ -1035,7 +1029,6 @@ impl<T, A: Allocator> Rc<[T], A> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(get_mut_unchecked)]
/// #![feature(allocator_api)]
///
@ -1072,7 +1065,6 @@ impl<T, A: Allocator> Rc<[T], A> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(allocator_api)]
///
/// use std::rc::Rc;
@ -1122,7 +1114,6 @@ impl<T, A: Allocator> Rc<mem::MaybeUninit<T>, A> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(get_mut_unchecked)]
///
/// use std::rc::Rc;
@ -1136,7 +1127,7 @@ impl<T, A: Allocator> Rc<mem::MaybeUninit<T>, A> {
///
/// assert_eq!(*five, 5)
/// ```
#[unstable(feature = "new_uninit", issue = "63291")]
#[stable(feature = "new_uninit", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub unsafe fn assume_init(self) -> Rc<T, A> {
let (ptr, alloc) = Rc::into_inner_with_allocator(self);
@ -1160,7 +1151,6 @@ impl<T, A: Allocator> Rc<[mem::MaybeUninit<T>], A> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(get_mut_unchecked)]
///
/// use std::rc::Rc;
@ -1177,7 +1167,7 @@ impl<T, A: Allocator> Rc<[mem::MaybeUninit<T>], A> {
///
/// assert_eq!(*values, [1, 2, 3])
/// ```
#[unstable(feature = "new_uninit", issue = "63291")]
#[stable(feature = "new_uninit", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub unsafe fn assume_init(self) -> Rc<[T], A> {
let (ptr, alloc) = Rc::into_inner_with_allocator(self);

View file

@ -335,7 +335,7 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Weak<U, A>> f
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Weak<U>> for Weak<T> {}
#[stable(feature = "arc_weak", since = "1.4.0")]
impl<T: ?Sized> fmt::Debug for Weak<T> {
impl<T: ?Sized, A: Allocator> fmt::Debug for Weak<T, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "(Weak)")
}
@ -505,7 +505,6 @@ impl<T> Arc<T> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(get_mut_unchecked)]
///
/// use std::sync::Arc;
@ -521,7 +520,7 @@ impl<T> Arc<T> {
/// ```
#[cfg(not(no_global_oom_handling))]
#[inline]
#[unstable(feature = "new_uninit", issue = "63291")]
#[stable(feature = "new_uninit", since = "CURRENT_RUSTC_VERSION")]
#[must_use]
pub fn new_uninit() -> Arc<mem::MaybeUninit<T>> {
unsafe {
@ -543,7 +542,6 @@ impl<T> Arc<T> {
///
/// ```
/// #![feature(new_zeroed_alloc)]
/// #![feature(new_uninit)]
///
/// use std::sync::Arc;
///
@ -614,7 +612,7 @@ impl<T> Arc<T> {
/// # Examples
///
/// ```
/// #![feature(new_uninit, allocator_api)]
/// #![feature(allocator_api)]
/// #![feature(get_mut_unchecked)]
///
/// use std::sync::Arc;
@ -650,7 +648,7 @@ impl<T> Arc<T> {
/// # Examples
///
/// ```
/// #![feature(new_uninit, allocator_api)]
/// #![feature( allocator_api)]
///
/// use std::sync::Arc;
///
@ -711,7 +709,6 @@ impl<T, A: Allocator> Arc<T, A> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(get_mut_unchecked)]
/// #![feature(allocator_api)]
///
@ -755,7 +752,6 @@ impl<T, A: Allocator> Arc<T, A> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(allocator_api)]
///
/// use std::sync::Arc;
@ -845,7 +841,7 @@ impl<T, A: Allocator> Arc<T, A> {
/// # Examples
///
/// ```
/// #![feature(new_uninit, allocator_api)]
/// #![feature(allocator_api)]
/// #![feature(get_mut_unchecked)]
///
/// use std::sync::Arc;
@ -889,7 +885,7 @@ impl<T, A: Allocator> Arc<T, A> {
/// # Examples
///
/// ```
/// #![feature(new_uninit, allocator_api)]
/// #![feature(allocator_api)]
///
/// use std::sync::Arc;
/// use std::alloc::System;
@ -1101,7 +1097,6 @@ impl<T> Arc<[T]> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(get_mut_unchecked)]
///
/// use std::sync::Arc;
@ -1120,7 +1115,7 @@ impl<T> Arc<[T]> {
/// ```
#[cfg(not(no_global_oom_handling))]
#[inline]
#[unstable(feature = "new_uninit", issue = "63291")]
#[stable(feature = "new_uninit", since = "CURRENT_RUSTC_VERSION")]
#[must_use]
pub fn new_uninit_slice(len: usize) -> Arc<[mem::MaybeUninit<T>]> {
unsafe { Arc::from_ptr(Arc::allocate_for_slice(len)) }
@ -1136,7 +1131,6 @@ impl<T> Arc<[T]> {
///
/// ```
/// #![feature(new_zeroed_alloc)]
/// #![feature(new_uninit)]
///
/// use std::sync::Arc;
///
@ -1172,7 +1166,6 @@ impl<T, A: Allocator> Arc<[T], A> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(get_mut_unchecked)]
/// #![feature(allocator_api)]
///
@ -1208,7 +1201,6 @@ impl<T, A: Allocator> Arc<[T], A> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(allocator_api)]
///
/// use std::sync::Arc;
@ -1257,7 +1249,6 @@ impl<T, A: Allocator> Arc<mem::MaybeUninit<T>, A> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(get_mut_unchecked)]
///
/// use std::sync::Arc;
@ -1271,7 +1262,7 @@ impl<T, A: Allocator> Arc<mem::MaybeUninit<T>, A> {
///
/// assert_eq!(*five, 5)
/// ```
#[unstable(feature = "new_uninit", issue = "63291")]
#[stable(feature = "new_uninit", since = "CURRENT_RUSTC_VERSION")]
#[must_use = "`self` will be dropped if the result is not used"]
#[inline]
pub unsafe fn assume_init(self) -> Arc<T, A> {
@ -1296,7 +1287,6 @@ impl<T, A: Allocator> Arc<[mem::MaybeUninit<T>], A> {
/// # Examples
///
/// ```
/// #![feature(new_uninit)]
/// #![feature(get_mut_unchecked)]
///
/// use std::sync::Arc;
@ -1313,7 +1303,7 @@ impl<T, A: Allocator> Arc<[mem::MaybeUninit<T>], A> {
///
/// assert_eq!(*values, [1, 2, 3])
/// ```
#[unstable(feature = "new_uninit", issue = "63291")]
#[stable(feature = "new_uninit", since = "CURRENT_RUSTC_VERSION")]
#[must_use = "`self` will be dropped if the result is not used"]
#[inline]
pub unsafe fn assume_init(self) -> Arc<[T], A> {

View file

@ -15,7 +15,6 @@
#![feature(exact_size_is_empty)]
#![feature(linked_list_cursors)]
#![feature(map_try_insert)]
#![feature(new_uninit)]
#![feature(pattern)]
#![feature(trusted_len)]
#![feature(try_reserve_kind)]

View file

@ -8,6 +8,7 @@
#![feature(iter_array_chunks)]
#![feature(iter_next_chunk)]
#![feature(iter_advance_by)]
#![feature(isqrt)]
extern crate test;

View file

@ -0,0 +1,62 @@
use rand::Rng;
use test::{black_box, Bencher};
macro_rules! int_sqrt_bench {
($t:ty, $predictable:ident, $random:ident, $random_small:ident, $random_uniform:ident) => {
#[bench]
fn $predictable(bench: &mut Bencher) {
bench.iter(|| {
for n in 0..(<$t>::BITS / 8) {
for i in 1..=(100 as $t) {
let x = black_box(i << (n * 8));
black_box(x.isqrt());
}
}
});
}
#[bench]
fn $random(bench: &mut Bencher) {
let mut rng = crate::bench_rng();
/* Exponentially distributed random numbers from the whole range of the type. */
let numbers: Vec<$t> =
(0..256).map(|_| rng.gen::<$t>() >> rng.gen_range(0..<$t>::BITS)).collect();
bench.iter(|| {
for x in &numbers {
black_box(black_box(x).isqrt());
}
});
}
#[bench]
fn $random_small(bench: &mut Bencher) {
let mut rng = crate::bench_rng();
/* Exponentially distributed random numbers from the range 0..256. */
let numbers: Vec<$t> =
(0..256).map(|_| (rng.gen::<u8>() >> rng.gen_range(0..u8::BITS)) as $t).collect();
bench.iter(|| {
for x in &numbers {
black_box(black_box(x).isqrt());
}
});
}
#[bench]
fn $random_uniform(bench: &mut Bencher) {
let mut rng = crate::bench_rng();
/* Exponentially distributed random numbers from the whole range of the type. */
let numbers: Vec<$t> = (0..256).map(|_| rng.gen::<$t>()).collect();
bench.iter(|| {
for x in &numbers {
black_box(black_box(x).isqrt());
}
});
}
};
}
int_sqrt_bench! {u8, u8_sqrt_predictable, u8_sqrt_random, u8_sqrt_random_small, u8_sqrt_uniform}
int_sqrt_bench! {u16, u16_sqrt_predictable, u16_sqrt_random, u16_sqrt_random_small, u16_sqrt_uniform}
int_sqrt_bench! {u32, u32_sqrt_predictable, u32_sqrt_random, u32_sqrt_random_small, u32_sqrt_uniform}
int_sqrt_bench! {u64, u64_sqrt_predictable, u64_sqrt_random, u64_sqrt_random_small, u64_sqrt_uniform}
int_sqrt_bench! {u128, u128_sqrt_predictable, u128_sqrt_random, u128_sqrt_random_small, u128_sqrt_uniform}

View file

@ -2,6 +2,7 @@ mod dec2flt;
mod flt2dec;
mod int_log;
mod int_pow;
mod int_sqrt;
use std::str::FromStr;

View file

@ -118,6 +118,10 @@ impl<'a> Argument<'a> {
Self::new(x, Debug::fmt)
}
#[inline(always)]
pub fn new_debug_noop<'b, T: Debug>(x: &'b T) -> Argument<'_> {
Self::new(x, |_, _| Ok(()))
}
#[inline(always)]
pub fn new_octal<'b, T: Octal>(x: &'b T) -> Argument<'_> {
Self::new(x, Octal::fmt)
}

View file

@ -1641,7 +1641,33 @@ macro_rules! int_impl {
if self < 0 {
None
} else {
Some((self as $UnsignedT).isqrt() as Self)
// SAFETY: Input is nonnegative in this `else` branch.
let result = unsafe {
crate::num::int_sqrt::$ActualT(self as $ActualT) as $SelfT
};
// Inform the optimizer what the range of outputs is. If
// testing `core` crashes with no panic message and a
// `num::int_sqrt::i*` test failed, it's because your edits
// caused these assertions to become false.
//
// SAFETY: Integer square root is a monotonically nondecreasing
// function, which means that increasing the input will never
// cause the output to decrease. Thus, since the input for
// nonnegative signed integers is bounded by
// `[0, <$ActualT>::MAX]`, sqrt(n) will be bounded by
// `[sqrt(0), sqrt(<$ActualT>::MAX)]`.
unsafe {
// SAFETY: `<$ActualT>::MAX` is nonnegative.
const MAX_RESULT: $SelfT = unsafe {
crate::num::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT
};
crate::hint::assert_unchecked(result >= 0);
crate::hint::assert_unchecked(result <= MAX_RESULT);
}
Some(result)
}
}
@ -2862,15 +2888,11 @@ macro_rules! int_impl {
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
#[track_caller]
pub const fn isqrt(self) -> Self {
// I would like to implement it as
// ```
// self.checked_isqrt().expect("argument of integer square root must be non-negative")
// ```
// but `expect` is not yet stable as a `const fn`.
match self.checked_isqrt() {
Some(sqrt) => sqrt,
None => panic!("argument of integer square root must be non-negative"),
None => crate::num::int_sqrt::panic_for_negative_argument(),
}
}

View file

@ -0,0 +1,316 @@
//! These functions use the [Karatsuba square root algorithm][1] to compute the
//! [integer square root](https://en.wikipedia.org/wiki/Integer_square_root)
//! for the primitive integer types.
//!
//! The signed integer functions can only handle **nonnegative** inputs, so
//! that must be checked before calling those.
//!
//! [1]: <https://web.archive.org/web/20230511212802/https://inria.hal.science/inria-00072854v1/file/RR-3805.pdf>
//! "Paul Zimmermann. Karatsuba Square Root. \[Research Report\] RR-3805,
//! INRIA. 1999, pp.8. (inria-00072854)"
/// This array stores the [integer square roots](
/// https://en.wikipedia.org/wiki/Integer_square_root) and remainders of each
/// [`u8`](prim@u8) value. For example, `U8_ISQRT_WITH_REMAINDER[17]` will be
/// `(4, 1)` because the integer square root of 17 is 4 and because 17 is 1
/// higher than 4 squared.
const U8_ISQRT_WITH_REMAINDER: [(u8, u8); 256] = {
let mut result = [(0, 0); 256];
let mut n: usize = 0;
let mut isqrt_n: usize = 0;
while n < result.len() {
result[n] = (isqrt_n as u8, (n - isqrt_n.pow(2)) as u8);
n += 1;
if n == (isqrt_n + 1).pow(2) {
isqrt_n += 1;
}
}
result
};
/// Returns the [integer square root](
/// https://en.wikipedia.org/wiki/Integer_square_root) of any [`u8`](prim@u8)
/// input.
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn u8(n: u8) -> u8 {
U8_ISQRT_WITH_REMAINDER[n as usize].0
}
/// Generates an `i*` function that returns the [integer square root](
/// https://en.wikipedia.org/wiki/Integer_square_root) of any **nonnegative**
/// input of a specific signed integer type.
macro_rules! signed_fn {
($SignedT:ident, $UnsignedT:ident) => {
/// Returns the [integer square root](
/// https://en.wikipedia.org/wiki/Integer_square_root) of any
/// **nonnegative**
#[doc = concat!("[`", stringify!($SignedT), "`](prim@", stringify!($SignedT), ")")]
/// input.
///
/// # Safety
///
/// This results in undefined behavior when the input is negative.
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const unsafe fn $SignedT(n: $SignedT) -> $SignedT {
debug_assert!(n >= 0, "Negative input inside `isqrt`.");
$UnsignedT(n as $UnsignedT) as $SignedT
}
};
}
signed_fn!(i8, u8);
signed_fn!(i16, u16);
signed_fn!(i32, u32);
signed_fn!(i64, u64);
signed_fn!(i128, u128);
/// Generates a `u*` function that returns the [integer square root](
/// https://en.wikipedia.org/wiki/Integer_square_root) of any input of
/// a specific unsigned integer type.
macro_rules! unsigned_fn {
($UnsignedT:ident, $HalfBitsT:ident, $stages:ident) => {
/// Returns the [integer square root](
/// https://en.wikipedia.org/wiki/Integer_square_root) of any
#[doc = concat!("[`", stringify!($UnsignedT), "`](prim@", stringify!($UnsignedT), ")")]
/// input.
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn $UnsignedT(mut n: $UnsignedT) -> $UnsignedT {
if n <= <$HalfBitsT>::MAX as $UnsignedT {
$HalfBitsT(n as $HalfBitsT) as $UnsignedT
} else {
// The normalization shift satisfies the Karatsuba square root
// algorithm precondition "a₃ ≥ b/4" where a₃ is the most
// significant quarter of `n`'s bits and b is the number of
// values that can be represented by that quarter of the bits.
//
// b/4 would then be all 0s except the second most significant
// bit (010...0) in binary. Since a₃ must be at least b/4, a₃'s
// most significant bit or its neighbor must be a 1. Since a₃'s
// most significant bits are `n`'s most significant bits, the
// same applies to `n`.
//
// The reason to shift by an even number of bits is because an
// even number of bits produces the square root shifted to the
// left by half of the normalization shift:
//
// sqrt(n << (2 * p))
// sqrt(2.pow(2 * p) * n)
// sqrt(2.pow(2 * p)) * sqrt(n)
// 2.pow(p) * sqrt(n)
// sqrt(n) << p
//
// Shifting by an odd number of bits leaves an ugly sqrt(2)
// multiplied in:
//
// sqrt(n << (2 * p + 1))
// sqrt(2.pow(2 * p + 1) * n)
// sqrt(2 * 2.pow(2 * p) * n)
// sqrt(2) * sqrt(2.pow(2 * p)) * sqrt(n)
// sqrt(2) * 2.pow(p) * sqrt(n)
// sqrt(2) * (sqrt(n) << p)
const EVEN_MAKING_BITMASK: u32 = !1;
let normalization_shift = n.leading_zeros() & EVEN_MAKING_BITMASK;
n <<= normalization_shift;
let s = $stages(n);
let denormalization_shift = normalization_shift >> 1;
s >> denormalization_shift
}
}
};
}
/// Generates the first stage of the computation after normalization.
///
/// # Safety
///
/// `$n` must be nonzero.
macro_rules! first_stage {
($original_bits:literal, $n:ident) => {{
debug_assert!($n != 0, "`$n` is zero in `first_stage!`.");
const N_SHIFT: u32 = $original_bits - 8;
let n = $n >> N_SHIFT;
let (s, r) = U8_ISQRT_WITH_REMAINDER[n as usize];
// Inform the optimizer that `s` is nonzero. This will allow it to
// avoid generating code to handle division-by-zero panics in the next
// stage.
//
// SAFETY: If the original `$n` is zero, the top of the `unsigned_fn`
// macro recurses instead of continuing to this point, so the original
// `$n` wasn't a 0 if we've reached here.
//
// Then the `unsigned_fn` macro normalizes `$n` so that at least one of
// its two most-significant bits is a 1.
//
// Then this stage puts the eight most-significant bits of `$n` into
// `n`. This means that `n` here has at least one 1 bit in its two
// most-significant bits, making `n` nonzero.
//
// `U8_ISQRT_WITH_REMAINDER[n as usize]` will give a nonzero `s` when
// given a nonzero `n`.
unsafe { crate::hint::assert_unchecked(s != 0) };
(s, r)
}};
}
/// Generates a middle stage of the computation.
///
/// # Safety
///
/// `$s` must be nonzero.
macro_rules! middle_stage {
($original_bits:literal, $ty:ty, $n:ident, $s:ident, $r:ident) => {{
debug_assert!($s != 0, "`$s` is zero in `middle_stage!`.");
const N_SHIFT: u32 = $original_bits - <$ty>::BITS;
let n = ($n >> N_SHIFT) as $ty;
const HALF_BITS: u32 = <$ty>::BITS >> 1;
const QUARTER_BITS: u32 = <$ty>::BITS >> 2;
const LOWER_HALF_1_BITS: $ty = (1 << HALF_BITS) - 1;
const LOWEST_QUARTER_1_BITS: $ty = (1 << QUARTER_BITS) - 1;
let lo = n & LOWER_HALF_1_BITS;
let numerator = (($r as $ty) << QUARTER_BITS) | (lo >> QUARTER_BITS);
let denominator = ($s as $ty) << 1;
let q = numerator / denominator;
let u = numerator % denominator;
let mut s = ($s << QUARTER_BITS) as $ty + q;
let (mut r, overflow) =
((u << QUARTER_BITS) | (lo & LOWEST_QUARTER_1_BITS)).overflowing_sub(q * q);
if overflow {
r = r.wrapping_add(2 * s - 1);
s -= 1;
}
// Inform the optimizer that `s` is nonzero. This will allow it to
// avoid generating code to handle division-by-zero panics in the next
// stage.
//
// SAFETY: If the original `$n` is zero, the top of the `unsigned_fn`
// macro recurses instead of continuing to this point, so the original
// `$n` wasn't a 0 if we've reached here.
//
// Then the `unsigned_fn` macro normalizes `$n` so that at least one of
// its two most-significant bits is a 1.
//
// Then these stages take as many of the most-significant bits of `$n`
// as will fit in this stage's type. For example, the stage that
// handles `u32` deals with the 32 most-significant bits of `$n`. This
// means that each stage has at least one 1 bit in `n`'s two
// most-significant bits, making `n` nonzero.
//
// Then this stage will produce the correct integer square root for
// that `n` value. Since `n` is nonzero, `s` will also be nonzero.
unsafe { crate::hint::assert_unchecked(s != 0) };
(s, r)
}};
}
/// Generates the last stage of the computation before denormalization.
///
/// # Safety
///
/// `$s` must be nonzero.
macro_rules! last_stage {
($ty:ty, $n:ident, $s:ident, $r:ident) => {{
debug_assert!($s != 0, "`$s` is zero in `last_stage!`.");
const HALF_BITS: u32 = <$ty>::BITS >> 1;
const QUARTER_BITS: u32 = <$ty>::BITS >> 2;
const LOWER_HALF_1_BITS: $ty = (1 << HALF_BITS) - 1;
let lo = $n & LOWER_HALF_1_BITS;
let numerator = (($r as $ty) << QUARTER_BITS) | (lo >> QUARTER_BITS);
let denominator = ($s as $ty) << 1;
let q = numerator / denominator;
let mut s = ($s << QUARTER_BITS) as $ty + q;
let (s_squared, overflow) = s.overflowing_mul(s);
if overflow || s_squared > $n {
s -= 1;
}
s
}};
}
/// Takes the normalized [`u16`](prim@u16) input and gets its normalized
/// [integer square root](https://en.wikipedia.org/wiki/Integer_square_root).
///
/// # Safety
///
/// `n` must be nonzero.
#[inline]
const fn u16_stages(n: u16) -> u16 {
let (s, r) = first_stage!(16, n);
last_stage!(u16, n, s, r)
}
/// Takes the normalized [`u32`](prim@u32) input and gets its normalized
/// [integer square root](https://en.wikipedia.org/wiki/Integer_square_root).
///
/// # Safety
///
/// `n` must be nonzero.
#[inline]
const fn u32_stages(n: u32) -> u32 {
let (s, r) = first_stage!(32, n);
let (s, r) = middle_stage!(32, u16, n, s, r);
last_stage!(u32, n, s, r)
}
/// Takes the normalized [`u64`](prim@u64) input and gets its normalized
/// [integer square root](https://en.wikipedia.org/wiki/Integer_square_root).
///
/// # Safety
///
/// `n` must be nonzero.
#[inline]
const fn u64_stages(n: u64) -> u64 {
let (s, r) = first_stage!(64, n);
let (s, r) = middle_stage!(64, u16, n, s, r);
let (s, r) = middle_stage!(64, u32, n, s, r);
last_stage!(u64, n, s, r)
}
/// Takes the normalized [`u128`](prim@u128) input and gets its normalized
/// [integer square root](https://en.wikipedia.org/wiki/Integer_square_root).
///
/// # Safety
///
/// `n` must be nonzero.
#[inline]
const fn u128_stages(n: u128) -> u128 {
let (s, r) = first_stage!(128, n);
let (s, r) = middle_stage!(128, u16, n, s, r);
let (s, r) = middle_stage!(128, u32, n, s, r);
let (s, r) = middle_stage!(128, u64, n, s, r);
last_stage!(u128, n, s, r)
}
unsigned_fn!(u16, u8, u16_stages);
unsigned_fn!(u32, u16, u32_stages);
unsigned_fn!(u64, u32, u64_stages);
unsigned_fn!(u128, u64, u128_stages);
/// Instantiate this panic logic once, rather than for all the isqrt methods
/// on every single primitive type.
#[cold]
#[track_caller]
pub const fn panic_for_negative_argument() -> ! {
panic!("argument of integer square root cannot be negative")
}

View file

@ -41,6 +41,7 @@ mod uint_macros; // import uint_impl!
mod error;
mod int_log10;
mod int_sqrt;
mod nonzero;
mod overflow_panic;
mod saturating;

Some files were not shown because too many files have changed in this diff Show more