Merge from rustc

This commit is contained in:
The Miri Cronjob Bot 2025-04-26 04:59:48 +00:00
commit 6c2fa0bce7
221 changed files with 3217 additions and 2142 deletions

View file

@ -91,6 +91,17 @@ jobs:
# Check the `calculate_matrix` job to see how is the matrix defined.
include: ${{ fromJSON(needs.calculate_matrix.outputs.jobs) }}
steps:
- name: Install cargo in AWS CodeBuild
if: matrix.codebuild
run: |
# Check if cargo is installed
if ! command -v cargo &> /dev/null; then
echo "Cargo not found, installing Rust..."
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile=minimal
# Make cargo available in PATH
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
fi
- name: disable git crlf conversion
run: git config --global core.autocrlf false
@ -165,6 +176,8 @@ jobs:
run: src/ci/scripts/install-ninja.sh
- name: enable ipv6 on Docker
# Don't run on codebuild because systemctl is not available
if: ${{ !matrix.codebuild }}
run: src/ci/scripts/enable-docker-ipv6.sh
# Disable automatic line ending conversion (again). On Windows, when we're

View file

@ -4158,7 +4158,6 @@ dependencies = [
"rustc_data_structures",
"rustc_index",
"rustc_macros",
"rustc_serialize",
"rustc_type_ir",
"rustc_type_ir_macros",
"tracing",

View file

@ -75,8 +75,31 @@ See [the rustc-dev-guide for more info][sysllvm].
2. Configure the build settings:
If you're unsure which build configurations to use and need a good default, you
can run the interactive `x.py setup` command. This will guide you through selecting
a config profile, setting up the LSP, configuring a Git hook, etc.
With `configure` script, you can handle multiple configurations in a single
command which is useful to create complex/advanced config files. For example:
```sh
./configure
./configure --build=aarch64-unknown-linux-gnu \
--enable-full-tools \
--enable-profiler \
--enable-sanitizers \
--enable-compiler-docs \
--set target.aarch64-unknown-linux-gnu.linker=clang \
--set target.aarch64-unknown-linux-gnu.ar=/rustroot/bin/llvm-ar \
--set target.aarch64-unknown-linux-gnu.ranlib=/rustroot/bin/llvm-ranlib \
--set llvm.link-shared=true \
--set llvm.thin-lto=true \
--set llvm.libzstd=true \
--set llvm.ninja=false \
--set rust.debug-assertions=false \
--set rust.jemalloc \
--set rust.use-lld=true \
--set rust.lto=thin \
--set rust.codegen-units=1
```
If you plan to use `x.py install` to create an installation, you can either

View file

@ -1927,7 +1927,7 @@ impl AttrArgs {
}
/// Delimited arguments, as used in `#[attr()/[]/{}]` or `mac!()/[]/{}`.
#[derive(Clone, Encodable, Decodable, Debug)]
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
pub struct DelimArgs {
pub dspan: DelimSpan,
pub delim: Delimiter, // Note: `Delimiter::Invisible` never occurs
@ -1942,18 +1942,6 @@ impl DelimArgs {
}
}
impl<CTX> HashStable<CTX> for DelimArgs
where
CTX: crate::HashStableContext,
{
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
let DelimArgs { dspan, delim, tokens } = self;
dspan.hash_stable(ctx, hasher);
delim.hash_stable(ctx, hasher);
tokens.hash_stable(ctx, hasher);
}
}
/// Represents a macro definition.
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
pub struct MacroDef {

View file

@ -6,6 +6,7 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
test(attr(deny(warnings)))
@ -14,7 +15,6 @@
#![feature(associated_type_defaults)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(let_chains)]
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(rustdoc_internals)]

View file

@ -32,12 +32,12 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(exact_size_is_empty)]
#![feature(if_let_guard)]
#![feature(let_chains)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end
@ -916,7 +916,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
fn lower_delim_args(&self, args: &DelimArgs) -> DelimArgs {
DelimArgs { dspan: args.dspan, delim: args.delim, tokens: args.tokens.clone() }
args.clone()
}
/// Lower an associated item constraint.

View file

@ -4,11 +4,11 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(rust_logo)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(iter_is_partitioned)]
#![feature(let_chains)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end

View file

@ -1,7 +1,7 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(rust_logo)]
#![feature(let_chains)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end

View file

@ -3,7 +3,7 @@ use std::collections::BTreeMap;
use std::ops::Deref;
use std::sync::LazyLock;
use rustc_ast::{self as ast, DelimArgs};
use rustc_ast as ast;
use rustc_attr_data_structures::AttributeKind;
use rustc_errors::{DiagCtxtHandle, Diagnostic};
use rustc_feature::Features;
@ -315,11 +315,7 @@ impl<'sess> AttributeParser<'sess> {
fn lower_attr_args(&self, args: &ast::AttrArgs, lower_span: impl Fn(Span) -> Span) -> AttrArgs {
match args {
ast::AttrArgs::Empty => AttrArgs::Empty,
ast::AttrArgs::Delimited(args) => AttrArgs::Delimited(DelimArgs {
dspan: args.dspan,
delim: args.delim,
tokens: args.tokens.clone(),
}),
ast::AttrArgs::Delimited(args) => AttrArgs::Delimited(args.clone()),
// This is an inert key-value attribute - it will never be visible to macros
// after it gets lowered to HIR. Therefore, we can extract literals to handle
// nonterminals in `#[doc]` (e.g. `#[doc = $e]`).

View file

@ -77,8 +77,8 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(rust_logo)]
#![feature(let_chains)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end

View file

@ -49,7 +49,7 @@ impl<'tcx> UniverseInfo<'tcx> {
UniverseInfo::RelateTys { expected, found }
}
pub(crate) fn report_error(
pub(crate) fn report_erroneous_element(
&self,
mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>,
placeholder: ty::PlaceholderRegion,
@ -68,7 +68,7 @@ impl<'tcx> UniverseInfo<'tcx> {
mbcx.buffer_error(err);
}
UniverseInfo::TypeOp(ref type_op_info) => {
type_op_info.report_error(mbcx, placeholder, error_element, cause);
type_op_info.report_erroneous_element(mbcx, placeholder, error_element, cause);
}
UniverseInfo::Other => {
// FIXME: This error message isn't great, but it doesn't show
@ -145,8 +145,11 @@ pub(crate) trait TypeOpInfo<'tcx> {
error_region: Option<ty::Region<'tcx>>,
) -> Option<Diag<'infcx>>;
/// Constraints require that `error_element` appear in the
/// values of `placeholder`, but this cannot be proven to
/// hold. Report an error.
#[instrument(level = "debug", skip(self, mbcx))]
fn report_error(
fn report_erroneous_element(
&self,
mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>,
placeholder: ty::PlaceholderRegion,
@ -190,12 +193,7 @@ pub(crate) trait TypeOpInfo<'tcx> {
let nice_error = self.nice_error(mbcx, cause, placeholder_region, error_region);
debug!(?nice_error);
if let Some(nice_error) = nice_error {
mbcx.buffer_error(nice_error);
} else {
mbcx.buffer_error(self.fallback_error(tcx, span));
}
mbcx.buffer_error(nice_error.unwrap_or_else(|| self.fallback_error(tcx, span)));
}
}
@ -450,7 +448,8 @@ fn try_extract_error_from_region_constraints<'a, 'tcx>(
ty::ReVar(vid) => universe_of_region(vid),
_ => ty::UniverseIndex::ROOT,
};
let matches =
// Are the two regions the same?
let regions_the_same =
|a_region: Region<'tcx>, b_region: Region<'tcx>| match (a_region.kind(), b_region.kind()) {
(RePlaceholder(a_p), RePlaceholder(b_p)) => a_p.bound == b_p.bound,
_ => a_region == b_region,
@ -459,7 +458,7 @@ fn try_extract_error_from_region_constraints<'a, 'tcx>(
|constraint: &Constraint<'tcx>, cause: &SubregionOrigin<'tcx>, exact| match *constraint {
Constraint::RegSubReg(sub, sup)
if ((exact && sup == placeholder_region)
|| (!exact && matches(sup, placeholder_region)))
|| (!exact && regions_the_same(sup, placeholder_region)))
&& sup != sub =>
{
Some((sub, cause.clone()))
@ -468,23 +467,21 @@ fn try_extract_error_from_region_constraints<'a, 'tcx>(
if (exact
&& sup == placeholder_region
&& !universe_of_region(vid).can_name(placeholder_universe))
|| (!exact && matches(sup, placeholder_region)) =>
|| (!exact && regions_the_same(sup, placeholder_region)) =>
{
Some((ty::Region::new_var(infcx.tcx, vid), cause.clone()))
}
_ => None,
};
let mut info = region_constraints
.constraints
.iter()
.find_map(|(constraint, cause)| check(constraint, cause, true));
if info.is_none() {
info = region_constraints
let mut find_culprit = |exact_match: bool| {
region_constraints
.constraints
.iter()
.find_map(|(constraint, cause)| check(constraint, cause, false));
}
let (sub_region, cause) = info?;
.find_map(|(constraint, cause)| check(constraint, cause, exact_match))
};
let (sub_region, cause) = find_culprit(true).or_else(|| find_culprit(false))?;
debug!(?sub_region, "cause = {:#?}", cause);
let error = match (error_region, sub_region.kind()) {

View file

@ -405,7 +405,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let universe = placeholder.universe;
let universe_info = self.regioncx.universe_info(universe);
universe_info.report_error(self, placeholder, error_element, cause);
universe_info.report_erroneous_element(self, placeholder, error_element, cause);
}
RegionErrorKind::RegionError { fr_origin, longer_fr, shorter_fr, is_reported } => {

View file

@ -2,12 +2,12 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(file_buffered)]
#![feature(if_let_guard)]
#![feature(let_chains)]
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(rustc_attrs)]

View file

@ -1628,30 +1628,23 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let longer_fr_scc = self.constraint_sccs.scc(longer_fr);
debug!("check_bound_universal_region: longer_fr_scc={:?}", longer_fr_scc,);
for error_element in self.scc_values.elements_contained_in(longer_fr_scc) {
match error_element {
RegionElement::Location(_) | RegionElement::RootUniversalRegion(_) => {}
// If we have some bound universal region `'a`, then the only
// elements it can contain is itself -- we don't know anything
// else about it!
RegionElement::PlaceholderRegion(placeholder1) => {
if placeholder == placeholder1 {
continue;
}
}
}
// If we have some bound universal region `'a`, then the only
// elements it can contain is itself -- we don't know anything
// else about it!
if let Some(error_element) = self
.scc_values
.elements_contained_in(longer_fr_scc)
.find(|e| *e != RegionElement::PlaceholderRegion(placeholder))
{
// Stop after the first error, it gets too noisy otherwise, and does not provide more information.
errors_buffer.push(RegionErrorKind::BoundUniversalRegionError {
longer_fr,
error_element,
placeholder,
});
// Stop after the first error, it gets too noisy otherwise, and does not provide more
// information.
break;
} else {
debug!("check_bound_universal_region: all bounds satisfied");
}
debug!("check_bound_universal_region: all bounds satisfied");
}
#[instrument(level = "debug", skip(self, infcx, errors_buffer))]
@ -2071,7 +2064,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
constraint.category
};
match category {
let interest = match category {
// Returns usually provide a type to blame and have specially written diagnostics,
// so prioritize them.
ConstraintCategory::Return(_) => 0,
@ -2123,9 +2116,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// specific, and are not used for relations that would make sense to blame.
ConstraintCategory::BoringNoLocation => 6,
// Do not blame internal constraints.
ConstraintCategory::Internal => 7,
ConstraintCategory::IllegalUniverse => 8,
}
ConstraintCategory::IllegalUniverse => 7,
ConstraintCategory::Internal => 8,
};
debug!("constraint {constraint:?} category: {category:?}, interest: {interest:?}");
interest
};
let best_choice = if blame_source {

View file

@ -21,7 +21,7 @@ rustc_index::newtype_index! {
/// An individual element in a region value -- the value of a
/// particular region variable consists of a set of these elements.
#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq)]
pub(crate) enum RegionElement {
/// A point in the control-flow graph.
Location(Location),

View file

@ -5,6 +5,7 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
@ -12,7 +13,6 @@
#![feature(box_patterns)]
#![feature(decl_macro)]
#![feature(if_let_guard)]
#![feature(let_chains)]
#![feature(proc_macro_internals)]
#![feature(proc_macro_quote)]
#![feature(rustdoc_internals)]

View file

@ -41,8 +41,8 @@ use std::sync::Arc;
use cranelift_codegen::isa::TargetIsa;
use cranelift_codegen::settings::{self, Configurable};
use rustc_codegen_ssa::CodegenResults;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_codegen_ssa::{CodegenResults, TargetConfig};
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_session::Session;
@ -178,7 +178,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
}
}
fn target_features_cfg(&self, sess: &Session) -> (Vec<Symbol>, Vec<Symbol>) {
fn target_config(&self, sess: &Session) -> TargetConfig {
// FIXME return the actually used target features. this is necessary for #[cfg(target_feature)]
let target_features = if sess.target.arch == "x86_64" && sess.target.os != "none" {
// x86_64 mandates SSE2 support and rustc requires the x87 feature to be enabled
@ -197,7 +197,16 @@ impl CodegenBackend for CraneliftCodegenBackend {
};
// FIXME do `unstable_target_features` properly
let unstable_target_features = target_features.clone();
(target_features, unstable_target_features)
TargetConfig {
target_features,
unstable_target_features,
// Cranelift does not yet support f16 or f128
has_reliable_f16: false,
has_reliable_f16_math: false,
has_reliable_f128: false,
has_reliable_f128_math: false,
}
}
fn print_version(&self) {

View file

@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2025-04-17"
channel = "nightly-2025-04-25"
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]

View file

@ -165,10 +165,10 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
let mut input_registers = vec![];
for op in rust_operands {
if let InlineAsmOperandRef::In { reg, .. } = *op {
if let ConstraintOrRegister::Register(reg_name) = reg_to_gcc(reg) {
input_registers.push(reg_name);
}
if let InlineAsmOperandRef::In { reg, .. } = *op
&& let ConstraintOrRegister::Register(reg_name) = reg_to_gcc(reg)
{
input_registers.push(reg_name);
}
}

View file

@ -33,12 +33,11 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
}
pub fn const_bitcast(&self, value: RValue<'gcc>, typ: Type<'gcc>) -> RValue<'gcc> {
if value.get_type() == self.bool_type.make_pointer() {
if let Some(pointee) = typ.get_pointee() {
if pointee.dyncast_vector().is_some() {
panic!()
}
}
if value.get_type() == self.bool_type.make_pointer()
&& let Some(pointee) = typ.get_pointee()
&& pointee.dyncast_vector().is_some()
{
panic!()
}
// NOTE: since bitcast makes a value non-constant, don't bitcast if not necessary as some
// SIMD builtins require a constant value.

View file

@ -242,10 +242,10 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
let fn_attrs = self.tcx.codegen_fn_attrs(def_id);
let global = if def_id.is_local() && !self.tcx.is_foreign_item(def_id) {
if let Some(global) = self.get_declared_value(sym) {
if self.val_ty(global) != self.type_ptr_to(gcc_type) {
span_bug!(self.tcx.def_span(def_id), "Conflicting types for static");
}
if let Some(global) = self.get_declared_value(sym)
&& self.val_ty(global) != self.type_ptr_to(gcc_type)
{
span_bug!(self.tcx.def_span(def_id), "Conflicting types for static");
}
let is_tls = fn_attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL);

View file

@ -126,14 +126,15 @@ fn make_mir_scope<'gcc, 'tcx>(
return;
};
if let Some(ref vars) = *variables {
if !vars.contains(scope) && scope_data.inlined.is_none() {
// Do not create a DIScope if there are no variables defined in this
// MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat.
debug_context.scopes[scope] = parent_scope;
instantiated.insert(scope);
return;
}
if let Some(ref vars) = *variables
&& !vars.contains(scope)
&& scope_data.inlined.is_none()
{
// Do not create a DIScope if there are no variables defined in this
// MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat.
debug_context.scopes[scope] = parent_scope;
instantiated.insert(scope);
return;
}
let loc = cx.lookup_debug_loc(scope_data.span.lo());

View file

@ -55,7 +55,7 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<Stri
)
} else if let Some(feature) = feature.strip_prefix('-') {
// FIXME: Why do we not remove implied features on "-" here?
// We do the equivalent above in `target_features_cfg`.
// We do the equivalent above in `target_config`.
// See <https://github.com/rust-lang/rust/issues/134792>.
all_rust_features.push((false, feature));
} else if !feature.is_empty() && diagnostics {
@ -136,14 +136,12 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<Stri
});
features.extend(feats);
if diagnostics {
if let Some(f) = check_tied_features(sess, &featsmap) {
sess.dcx().emit_err(TargetFeatureDisableOrEnable {
features: f,
span: None,
missing_features: None,
});
}
if diagnostics && let Some(f) = check_tied_features(sess, &featsmap) {
sess.dcx().emit_err(TargetFeatureDisableOrEnable {
features: f,
span: None,
missing_features: None,
});
}
features

View file

@ -22,7 +22,7 @@
#![warn(rust_2018_idioms)]
#![warn(unused_lifetimes)]
#![deny(clippy::pattern_type_mismatch)]
#![allow(clippy::needless_lifetimes)]
#![allow(clippy::needless_lifetimes, clippy::uninlined_format_args)]
// Some "regular" crates we want to share with rustc
extern crate object;
@ -102,7 +102,7 @@ use rustc_codegen_ssa::back::write::{
};
use rustc_codegen_ssa::base::codegen_crate;
use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, WriteBackendMethods};
use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen};
use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen, TargetConfig};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::sync::IntoDynSyncSend;
use rustc_errors::DiagCtxtHandle;
@ -260,8 +260,8 @@ impl CodegenBackend for GccCodegenBackend {
.join(sess)
}
fn target_features_cfg(&self, sess: &Session) -> (Vec<Symbol>, Vec<Symbol>) {
target_features_cfg(sess, &self.target_info)
fn target_config(&self, sess: &Session) -> TargetConfig {
target_config(sess, &self.target_info)
}
}
@ -485,10 +485,7 @@ fn to_gcc_opt_level(optlevel: Option<OptLevel>) -> OptimizationLevel {
}
/// Returns the features that should be set in `cfg(target_feature)`.
fn target_features_cfg(
sess: &Session,
target_info: &LockedTargetInfo,
) -> (Vec<Symbol>, Vec<Symbol>) {
fn target_config(sess: &Session, target_info: &LockedTargetInfo) -> TargetConfig {
// TODO(antoyo): use global_gcc_features.
let f = |allow_unstable| {
sess.target
@ -523,5 +520,14 @@ fn target_features_cfg(
let target_features = f(false);
let unstable_target_features = f(true);
(target_features, unstable_target_features)
TargetConfig {
target_features,
unstable_target_features,
// There are no known bugs with GCC support for f16 or f128
has_reliable_f16: true,
has_reliable_f16_math: true,
has_reliable_f128: true,
has_reliable_f128_math: true,
}
}

View file

@ -102,10 +102,10 @@ fn uncached_gcc_type<'gcc, 'tcx>(
let mut name = with_no_trimmed_paths!(layout.ty.to_string());
if let (&ty::Adt(def, _), &Variants::Single { index }) =
(layout.ty.kind(), &layout.variants)
&& def.is_enum()
&& !def.variants().is_empty()
{
if def.is_enum() && !def.variants().is_empty() {
write!(&mut name, "::{}", def.variant(index).name).unwrap();
}
write!(&mut name, "::{}", def.variant(index).name).unwrap();
}
if let (&ty::Coroutine(_, _), &Variants::Single { index }) =
(layout.ty.kind(), &layout.variants)
@ -264,10 +264,10 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
}
fn immediate_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc> {
if let BackendRepr::Scalar(ref scalar) = self.backend_repr {
if scalar.is_bool() {
return cx.type_i1();
}
if let BackendRepr::Scalar(ref scalar) = self.backend_repr
&& scalar.is_bool()
{
return cx.type_i1();
}
self.gcc_type(cx)
}

View file

@ -1,5 +1,7 @@
//! The common code for `tests/lang_tests_*.rs`
#![allow(clippy::uninlined_format_args)]
use std::env::{self, current_dir};
use std::path::{Path, PathBuf};
use std::process::Command;

View file

@ -5,6 +5,7 @@
// stdout: 10
// 10
// 42
// 1
#![feature(no_core)]
#![no_std]
@ -21,6 +22,8 @@ fn int_cast(a: u16, b: i16) -> (u8, u16, u32, usize, i8, i16, i32, isize, u8, u3
)
}
static mut ONE: usize = 1;
#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
let (a, b, c, d, e, f, g, h, i, j) = int_cast(10, 42);
@ -28,6 +31,10 @@ extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
libc::printf(b"%d\n\0" as *const u8 as *const i8, c);
libc::printf(b"%ld\n\0" as *const u8 as *const i8, d);
libc::printf(b"%ld\n\0" as *const u8 as *const i8, j);
let ptr = ONE as *mut usize;
let value = ptr as usize;
libc::printf(b"%ld\n\0" as *const u8 as *const i8, value);
}
0
}

View file

@ -6,6 +6,7 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
@ -15,7 +16,6 @@
#![feature(if_let_guard)]
#![feature(impl_trait_in_assoc_type)]
#![feature(iter_intersperse)]
#![feature(let_chains)]
#![feature(rustdoc_internals)]
#![feature(slice_as_array)]
#![feature(try_blocks)]
@ -29,7 +29,7 @@ use back::owned_target_machine::OwnedTargetMachine;
use back::write::{create_informational_target_machine, create_target_machine};
use context::SimpleCx;
use errors::{AutoDiffWithoutLTO, ParseTargetMachineConfig};
use llvm_util::target_features_cfg;
use llvm_util::target_config;
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_ast::expand::autodiff_attrs::AutoDiffItem;
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule};
@ -37,7 +37,7 @@ use rustc_codegen_ssa::back::write::{
CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryConfig, TargetMachineFactoryFn,
};
use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen};
use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen, TargetConfig};
use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::{DiagCtxtHandle, FatalError};
use rustc_metadata::EncodedMetadata;
@ -338,8 +338,8 @@ impl CodegenBackend for LlvmCodegenBackend {
llvm_util::print_version();
}
fn target_features_cfg(&self, sess: &Session) -> (Vec<Symbol>, Vec<Symbol>) {
target_features_cfg(sess)
fn target_config(&self, sess: &Session) -> TargetConfig {
target_config(sess)
}
fn codegen_crate<'tcx>(

View file

@ -6,6 +6,7 @@ use std::sync::Once;
use std::{ptr, slice, str};
use libc::c_int;
use rustc_codegen_ssa::TargetConfig;
use rustc_codegen_ssa::base::wants_wasm_eh;
use rustc_codegen_ssa::codegen_attrs::check_tied_features;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@ -302,7 +303,7 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
/// Must express features in the way Rust understands them.
///
/// We do not have to worry about RUSTC_SPECIFIC_FEATURES here, those are handled outside codegen.
pub(crate) fn target_features_cfg(sess: &Session) -> (Vec<Symbol>, Vec<Symbol>) {
pub(crate) fn target_config(sess: &Session) -> TargetConfig {
// Add base features for the target.
// We do *not* add the -Ctarget-features there, and instead duplicate the logic for that below.
// The reason is that if LLVM considers a feature implied but we do not, we don't want that to
@ -402,7 +403,89 @@ pub(crate) fn target_features_cfg(sess: &Session) -> (Vec<Symbol>, Vec<Symbol>)
let target_features = f(false);
let unstable_target_features = f(true);
(target_features, unstable_target_features)
let mut cfg = TargetConfig {
target_features,
unstable_target_features,
has_reliable_f16: true,
has_reliable_f16_math: true,
has_reliable_f128: true,
has_reliable_f128_math: true,
};
update_target_reliable_float_cfg(sess, &mut cfg);
cfg
}
/// Determine whether or not experimental float types are reliable based on known bugs.
fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) {
let target_arch = sess.target.arch.as_ref();
let target_os = sess.target.options.os.as_ref();
let target_env = sess.target.options.env.as_ref();
let target_abi = sess.target.options.abi.as_ref();
let target_pointer_width = sess.target.pointer_width;
cfg.has_reliable_f16 = match (target_arch, target_os) {
// Selection failure <https://github.com/llvm/llvm-project/issues/50374>
("s390x", _) => false,
// Unsupported <https://github.com/llvm/llvm-project/issues/94434>
("arm64ec", _) => false,
// MinGW ABI bugs <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115054>
("x86_64", "windows") if target_env == "gnu" && target_abi != "llvm" => false,
// Infinite recursion <https://github.com/llvm/llvm-project/issues/97981>
("csky", _) => false,
("hexagon", _) => false,
("powerpc" | "powerpc64", _) => false,
("sparc" | "sparc64", _) => false,
("wasm32" | "wasm64", _) => false,
// `f16` support only requires that symbols converting to and from `f32` are available. We
// provide these in `compiler-builtins`, so `f16` should be available on all platforms that
// do not have other ABI issues or LLVM crashes.
_ => true,
};
cfg.has_reliable_f128 = match (target_arch, target_os) {
// Unsupported <https://github.com/llvm/llvm-project/issues/94434>
("arm64ec", _) => false,
// Selection bug <https://github.com/llvm/llvm-project/issues/96432>
("mips64" | "mips64r6", _) => false,
// Selection bug <https://github.com/llvm/llvm-project/issues/95471>
("nvptx64", _) => false,
// ABI bugs <https://github.com/rust-lang/rust/issues/125109> et al. (full
// list at <https://github.com/rust-lang/rust/issues/116909>)
("powerpc" | "powerpc64", _) => false,
// ABI unsupported <https://github.com/llvm/llvm-project/issues/41838>
("sparc", _) => false,
// Stack alignment bug <https://github.com/llvm/llvm-project/issues/77401>. NB: tests may
// not fail if our compiler-builtins is linked.
("x86", _) => false,
// MinGW ABI bugs <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115054>
("x86_64", "windows") if target_env == "gnu" && target_abi != "llvm" => false,
// There are no known problems on other platforms, so the only requirement is that symbols
// are available. `compiler-builtins` provides all symbols required for core `f128`
// support, so this should work for everything else.
_ => true,
};
cfg.has_reliable_f16_math = match (target_arch, target_os) {
// x86 has a crash for `powi`: <https://github.com/llvm/llvm-project/issues/105747>
("x86" | "x86_64", _) => false,
// Assume that working `f16` means working `f16` math for most platforms, since
// operations just go through `f32`.
_ => true,
} && cfg.has_reliable_f16;
cfg.has_reliable_f128_math = match (target_arch, target_os) {
// LLVM lowers `fp128` math to `long double` symbols even on platforms where
// `long double` is not IEEE binary128. See
// <https://github.com/llvm/llvm-project/issues/44744>.
//
// This rules out anything that doesn't have `long double` = `binary128`; <= 32 bits
// (ld is `f64`), anything other than Linux (Windows and MacOS use `f64`), and `x86`
// (ld is 80-bit extended precision).
("x86_64", _) => false,
(_, "linux") if target_pointer_width == 64 => true,
_ => false,
} && cfg.has_reliable_f128;
}
pub(crate) fn print_version() {
@ -686,7 +769,7 @@ pub(crate) fn global_llvm_features(
)
} else if let Some(feature) = feature.strip_prefix('-') {
// FIXME: Why do we not remove implied features on "-" here?
// We do the equivalent above in `target_features_cfg`.
// We do the equivalent above in `target_config`.
// See <https://github.com/rust-lang/rust/issues/134792>.
all_rust_features.push((false, feature));
} else if !feature.is_empty() {

View file

@ -2,13 +2,13 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(file_buffered)]
#![feature(if_let_guard)]
#![feature(let_chains)]
#![feature(negative_impls)]
#![feature(rustdoc_internals)]
#![feature(string_from_utf8_lossy_owned)]
@ -235,6 +235,24 @@ pub struct CrateInfo {
pub lint_levels: CodegenLintLevels,
}
/// Target-specific options that get set in `cfg(...)`.
///
/// RUSTC_SPECIFIC_FEATURES should be skipped here, those are handled outside codegen.
pub struct TargetConfig {
/// Options to be set in `cfg(target_features)`.
pub target_features: Vec<Symbol>,
/// Options to be set in `cfg(target_features)`, but including unstable features.
pub unstable_target_features: Vec<Symbol>,
/// Option for `cfg(target_has_reliable_f16)`, true if `f16` basic arithmetic works.
pub has_reliable_f16: bool,
/// Option for `cfg(target_has_reliable_f16_math)`, true if `f16` math calls work.
pub has_reliable_f16_math: bool,
/// Option for `cfg(target_has_reliable_f128)`, true if `f128` basic arithmetic works.
pub has_reliable_f128: bool,
/// Option for `cfg(target_has_reliable_f128_math)`, true if `f128` math calls work.
pub has_reliable_f128_math: bool,
}
#[derive(Encodable, Decodable)]
pub struct CodegenResults {
pub modules: Vec<CompiledModule>,

View file

@ -18,7 +18,7 @@ use super::write::WriteBackendMethods;
use crate::back::archive::ArArchiveBuilderBuilder;
use crate::back::link::link_binary;
use crate::back::write::TargetMachineFactoryFn;
use crate::{CodegenResults, ModuleCodegen};
use crate::{CodegenResults, ModuleCodegen, TargetConfig};
pub trait BackendTypes {
type Value: CodegenObject;
@ -50,8 +50,15 @@ pub trait CodegenBackend {
/// - The second is like the first, but also includes unstable features.
///
/// RUSTC_SPECIFIC_FEATURES should be skipped here, those are handled outside codegen.
fn target_features_cfg(&self, _sess: &Session) -> (Vec<Symbol>, Vec<Symbol>) {
(vec![], vec![])
fn target_config(&self, _sess: &Session) -> TargetConfig {
TargetConfig {
target_features: vec![],
unstable_target_features: vec![],
has_reliable_f16: true,
has_reliable_f16_math: true,
has_reliable_f128: true,
has_reliable_f128_math: true,
}
}
fn print_passes(&self) {}

View file

@ -1,12 +1,12 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(decl_macro)]
#![feature(if_let_guard)]
#![feature(let_chains)]
#![feature(never_type)]
#![feature(rustdoc_internals)]
#![feature(slice_ptr_get)]

View file

@ -39,8 +39,15 @@ impls_dyn_send_neg!(
[std::io::StderrLock<'_>]
);
#[cfg(any(unix, target_os = "hermit", target_os = "wasi", target_os = "solid_asp3"))]
// Consistent with `std`, `os_imp::Env` is `!Sync` in these platforms
#[cfg(any(
unix,
target_os = "hermit",
all(target_vendor = "fortanix", target_env = "sgx"),
target_os = "solid_asp3",
target_os = "wasi",
target_os = "xous"
))]
// Consistent with `std`, `env_imp::Env` is `!Sync` in these platforms
impl !DynSend for std::env::VarsOs {}
macro_rules! already_send {
@ -106,8 +113,15 @@ impls_dyn_sync_neg!(
[std::sync::mpsc::Sender<T> where T]
);
#[cfg(any(unix, target_os = "hermit", target_os = "wasi", target_os = "solid_asp3"))]
// Consistent with `std`, `os_imp::Env` is `!Sync` in these platforms
#[cfg(any(
unix,
target_os = "hermit",
all(target_vendor = "fortanix", target_env = "sgx"),
target_os = "solid_asp3",
target_os = "wasi",
target_os = "xous"
))]
// Consistent with `std`, `env_imp::Env` is `!Sync` in these platforms
impl !DynSync for std::env::VarsOs {}
macro_rules! already_sync {

View file

@ -7,10 +7,10 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(decl_macro)]
#![feature(let_chains)]
#![feature(panic_backtrace_config)]
#![feature(panic_update_hook)]
#![feature(result_flattening)]

View file

@ -7,6 +7,7 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(array_windows)]
@ -17,7 +18,6 @@
#![feature(default_field_values)]
#![feature(error_reporter)]
#![feature(if_let_guard)]
#![feature(let_chains)]
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(rustc_attrs)]

View file

@ -1,11 +1,11 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(rust_logo)]
#![feature(array_windows)]
#![feature(associated_type_defaults)]
#![feature(if_let_guard)]
#![feature(let_chains)]
#![feature(macro_metavar_expr)]
#![feature(map_try_insert)]
#![feature(proc_macro_diagnostic)]

View file

@ -40,6 +40,26 @@ const GATED_CFGS: &[GatedCfg] = &[
// this is consistent with naming of the compiler flag it's for
(sym::fmt_debug, sym::fmt_debug, Features::fmt_debug),
(sym::emscripten_wasm_eh, sym::cfg_emscripten_wasm_eh, Features::cfg_emscripten_wasm_eh),
(
sym::target_has_reliable_f16,
sym::cfg_target_has_reliable_f16_f128,
Features::cfg_target_has_reliable_f16_f128,
),
(
sym::target_has_reliable_f16_math,
sym::cfg_target_has_reliable_f16_f128,
Features::cfg_target_has_reliable_f16_f128,
),
(
sym::target_has_reliable_f128,
sym::cfg_target_has_reliable_f16_f128,
Features::cfg_target_has_reliable_f16_f128,
),
(
sym::target_has_reliable_f128_math,
sym::cfg_target_has_reliable_f16_f128,
Features::cfg_target_has_reliable_f16_f128,
),
];
/// Find a gated cfg determined by the `pred`icate which is given the cfg's name.

View file

@ -205,6 +205,8 @@ declare_features! (
(unstable, anonymous_lifetime_in_impl_trait, "1.63.0", None),
/// Allows access to the emscripten_wasm_eh config, used by panic_unwind and unwind
(internal, cfg_emscripten_wasm_eh, "1.86.0", None),
/// Allows checking whether or not the backend correctly supports unstable float types.
(internal, cfg_target_has_reliable_f16_f128, "CURRENT_RUSTC_VERSION", None),
/// Allows identifying the `compiler_builtins` crate.
(internal, compiler_builtins, "1.13.0", None),
/// Allows writing custom MIR

View file

@ -4,12 +4,12 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(associated_type_defaults)]
#![feature(box_patterns)]
#![feature(closure_track_caller)]
#![feature(debug_closure_helpers)]
#![feature(exhaustive_patterns)]
#![feature(let_chains)]
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(rustc_attrs)]

View file

@ -59,6 +59,7 @@ This API is completely unstable and subject to change.
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
@ -67,7 +68,6 @@ This API is completely unstable and subject to change.
#![feature(if_let_guard)]
#![feature(iter_from_coroutine)]
#![feature(iter_intersperse)]
#![feature(let_chains)]
#![feature(never_type)]
#![feature(rustdoc_internals)]
#![feature(slice_partition_dedup)]

View file

@ -2,7 +2,7 @@
//! the definitions in this file have equivalents in `rustc_ast_pretty`.
// tidy-alphabetical-start
#![feature(let_chains)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![recursion_limit = "256"]
// tidy-alphabetical-end

View file

@ -501,12 +501,25 @@ impl<'a, 'tcx> CastCheck<'tcx> {
.must_apply_modulo_regions()
{
label = false;
err.span_suggestion(
self.span,
"consider using the `From` trait instead",
format!("{}::from({})", self.cast_ty, snippet),
Applicability::MaybeIncorrect,
);
if let ty::Adt(def, args) = self.cast_ty.kind() {
err.span_suggestion_verbose(
self.span,
"consider using the `From` trait instead",
format!(
"{}::from({})",
fcx.tcx.value_path_str_with_args(def.did(), args),
snippet
),
Applicability::MaybeIncorrect,
);
} else {
err.span_suggestion(
self.span,
"consider using the `From` trait instead",
format!("{}::from({})", self.cast_ty, snippet),
Applicability::MaybeIncorrect,
);
};
}
}

View file

@ -1,11 +1,11 @@
// tidy-alphabetical-start
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(array_windows)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![feature(let_chains)]
#![feature(never_type)]
#![feature(try_blocks)]
// tidy-alphabetical-end

View file

@ -16,12 +16,12 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(extend_one)]
#![feature(iterator_try_collect)]
#![feature(let_chains)]
#![feature(rustdoc_internals)]
#![recursion_limit = "512"] // For rustdoc
// tidy-alphabetical-end

View file

@ -1,8 +1,8 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(decl_macro)]
#![feature(file_buffered)]
#![feature(iter_intersperse)]
#![feature(let_chains)]
#![feature(try_blocks)]
// tidy-alphabetical-end

View file

@ -38,14 +38,25 @@ pub(crate) fn add_configuration(
codegen_backend: &dyn CodegenBackend,
) {
let tf = sym::target_feature;
let tf_cfg = codegen_backend.target_config(sess);
let (target_features, unstable_target_features) = codegen_backend.target_features_cfg(sess);
sess.unstable_target_features.extend(tf_cfg.unstable_target_features.iter().copied());
sess.target_features.extend(tf_cfg.target_features.iter().copied());
sess.unstable_target_features.extend(unstable_target_features.iter().copied());
cfg.extend(tf_cfg.target_features.into_iter().map(|feat| (tf, Some(feat))));
sess.target_features.extend(target_features.iter().copied());
cfg.extend(target_features.into_iter().map(|feat| (tf, Some(feat))));
if tf_cfg.has_reliable_f16 {
cfg.insert((sym::target_has_reliable_f16, None));
}
if tf_cfg.has_reliable_f16_math {
cfg.insert((sym::target_has_reliable_f16_math, None));
}
if tf_cfg.has_reliable_f128 {
cfg.insert((sym::target_has_reliable_f128, None));
}
if tf_cfg.has_reliable_f128_math {
cfg.insert((sym::target_has_reliable_f128_math, None));
}
if sess.crt_static(None) {
cfg.insert((tf, Some(sym::crt_dash_static)));

View file

@ -21,6 +21,7 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(array_windows)]
@ -28,7 +29,6 @@
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(iter_order_by)]
#![feature(let_chains)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
#![feature(try_blocks)]

View file

@ -1,7 +1,7 @@
// tidy-alphabetical-start
#![allow(rustc::default_hash_types)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(if_let_guard)]
#![feature(let_chains)]
#![feature(never_type)]
#![feature(proc_macro_diagnostic)]
#![feature(proc_macro_span)]

View file

@ -1,5 +1,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(coroutines)]
@ -8,7 +9,6 @@
#![feature(file_buffered)]
#![feature(if_let_guard)]
#![feature(iter_from_coroutine)]
#![feature(let_chains)]
#![feature(macro_metavar_expr)]
#![feature(min_specialization)]
#![feature(never_type)]

View file

@ -29,6 +29,7 @@
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::potential_query_instability)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(allocator_api)]
@ -48,7 +49,6 @@
#![feature(if_let_guard)]
#![feature(intra_doc_pointers)]
#![feature(iter_from_coroutine)]
#![feature(let_chains)]
#![feature(min_specialization)]
#![feature(negative_impls)]
#![feature(never_type)]

View file

@ -121,11 +121,10 @@ impl<'tcx> Predicate<'tcx> {
/// unsoundly accept some programs. See #91068.
#[inline]
pub fn allow_normalization(self) -> bool {
// Keep this in sync with the one in `rustc_type_ir::inherent`!
match self.kind().skip_binder() {
PredicateKind::Clause(ClauseKind::WellFormed(_))
| PredicateKind::AliasRelate(..)
| PredicateKind::NormalizesTo(..) => false,
PredicateKind::Clause(ClauseKind::WellFormed(_)) | PredicateKind::AliasRelate(..) => {
false
}
PredicateKind::Clause(ClauseKind::Trait(_))
| PredicateKind::Clause(ClauseKind::HostEffect(..))
| PredicateKind::Clause(ClauseKind::RegionOutlives(_))
@ -137,6 +136,7 @@ impl<'tcx> Predicate<'tcx> {
| PredicateKind::Coerce(_)
| PredicateKind::Clause(ClauseKind::ConstEvaluatable(_))
| PredicateKind::ConstEquate(_, _)
| PredicateKind::NormalizesTo(..)
| PredicateKind::Ambiguous => true,
}
}

View file

@ -3,10 +3,10 @@
// tidy-alphabetical-start
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(let_chains)]
#![feature(try_blocks)]
// tidy-alphabetical-end

View file

@ -1,10 +1,10 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(assert_matches)]
#![feature(associated_type_defaults)]
#![feature(box_patterns)]
#![feature(exact_size_is_empty)]
#![feature(file_buffered)]
#![feature(let_chains)]
#![feature(never_type)]
#![feature(try_blocks)]
// tidy-alphabetical-end

View file

@ -87,11 +87,8 @@ impl<'tcx> Visitor<'tcx> for UnnecessaryTransmuteChecker<'_, 'tcx> {
&& let Some((func_def_id, _)) = func.const_fn_def()
&& self.tcx.is_intrinsic(func_def_id, sym::transmute)
&& let span = self.body.source_info(location).span
&& let Some(lint) = self.is_unnecessary_transmute(
func,
self.tcx.sess.source_map().span_to_snippet(arg).expect("ok"),
span,
)
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(arg)
&& let Some(lint) = self.is_unnecessary_transmute(func, snippet, span)
&& let Some(hir_id) = terminator.source_info.scope.lint_root(&self.body.source_scopes)
{
self.tcx.emit_node_span_lint(UNNECESSARY_TRANSMUTES, hir_id, span, lint);

View file

@ -1,4 +1,5 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(array_windows)]
#![feature(assert_matches)]
#![feature(box_patterns)]
@ -7,7 +8,6 @@
#![feature(file_buffered)]
#![feature(if_let_guard)]
#![feature(impl_trait_in_assoc_type)]
#![feature(let_chains)]
#![feature(map_try_insert)]
#![feature(never_type)]
#![feature(try_blocks)]

View file

@ -1,9 +1,9 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(array_windows)]
#![feature(file_buffered)]
#![feature(if_let_guard)]
#![feature(impl_trait_in_assoc_type)]
#![feature(let_chains)]
// tidy-alphabetical-end
use rustc_hir::lang_items::LangItem;

View file

@ -9,7 +9,6 @@ derive-where = "1.2.7"
rustc_data_structures = { path = "../rustc_data_structures", optional = true }
rustc_index = { path = "../rustc_index", default-features = false }
rustc_macros = { path = "../rustc_macros", optional = true }
rustc_serialize = { path = "../rustc_serialize", optional = true }
rustc_type_ir = { path = "../rustc_type_ir", default-features = false }
rustc_type_ir_macros = { path = "../rustc_type_ir_macros" }
tracing = "0.1"
@ -20,7 +19,6 @@ default = ["nightly"]
nightly = [
"dep:rustc_data_structures",
"dep:rustc_macros",
"dep:rustc_serialize",
"rustc_index/nightly",
"rustc_type_ir/nightly",
]

View file

@ -16,6 +16,7 @@
//! relate them structurally.
use rustc_type_ir::inherent::*;
use rustc_type_ir::solve::GoalSource;
use rustc_type_ir::{self as ty, Interner};
use tracing::{instrument, trace};
@ -49,7 +50,10 @@ where
// Structurally normalize the lhs.
let lhs = if let Some(alias) = lhs.to_alias_term() {
let term = self.next_term_infer_of_kind(lhs);
self.add_normalizes_to_goal(goal.with(cx, ty::NormalizesTo { alias, term }));
self.add_goal(
GoalSource::TypeRelating,
goal.with(cx, ty::NormalizesTo { alias, term }),
);
term
} else {
lhs
@ -58,7 +62,10 @@ where
// Structurally normalize the rhs.
let rhs = if let Some(alias) = rhs.to_alias_term() {
let term = self.next_term_infer_of_kind(rhs);
self.add_normalizes_to_goal(goal.with(cx, ty::NormalizesTo { alias, term }));
self.add_goal(
GoalSource::TypeRelating,
goal.with(cx, ty::NormalizesTo { alias, term }),
);
term
} else {
rhs

View file

@ -22,7 +22,7 @@ use tracing::{debug, instrument, trace};
use crate::canonicalizer::Canonicalizer;
use crate::delegate::SolverDelegate;
use crate::resolve::EagerResolver;
use crate::solve::eval_ctxt::{CurrentGoalKind, NestedGoals};
use crate::solve::eval_ctxt::CurrentGoalKind;
use crate::solve::{
CanonicalInput, CanonicalResponse, Certainty, EvalCtxt, ExternalConstraintsData, Goal,
MaybeCause, NestedNormalizationGoals, NoSolution, PredefinedOpaquesData, QueryInput,
@ -112,13 +112,9 @@ where
// by `try_evaluate_added_goals()`.
let (certainty, normalization_nested_goals) = match self.current_goal_kind {
CurrentGoalKind::NormalizesTo => {
let NestedGoals { normalizes_to_goals, goals } =
std::mem::take(&mut self.nested_goals);
if cfg!(debug_assertions) {
assert!(normalizes_to_goals.is_empty());
if goals.is_empty() {
assert!(matches!(goals_certainty, Certainty::Yes));
}
let goals = std::mem::take(&mut self.nested_goals);
if goals.is_empty() {
assert!(matches!(goals_certainty, Certainty::Yes));
}
(certainty, NestedNormalizationGoals(goals))
}

View file

@ -1,8 +1,8 @@
use std::mem;
use std::ops::ControlFlow;
use derive_where::derive_where;
#[cfg(feature = "nightly")]
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
use rustc_macros::HashStable_NoContext;
use rustc_type_ir::data_structures::{HashMap, HashSet, ensure_sufficient_stack};
use rustc_type_ir::fast_reject::DeepRejectCtxt;
use rustc_type_ir::inherent::*;
@ -14,7 +14,6 @@ use rustc_type_ir::{
TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
TypingMode,
};
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
use tracing::{instrument, trace};
use crate::coherence;
@ -114,7 +113,7 @@ where
pub(super) search_graph: &'a mut SearchGraph<D>,
nested_goals: NestedGoals<I>,
nested_goals: Vec<(GoalSource, Goal<I, I::Predicate>)>,
pub(super) origin_span: I::Span,
@ -129,38 +128,6 @@ where
pub(super) inspect: ProofTreeBuilder<D>,
}
#[derive_where(Clone, Debug, Default; I: Interner)]
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
#[cfg_attr(
feature = "nightly",
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
)]
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
/// equate the fresh inference variable with the actual RHS of the predicate.
///
/// This is both to improve caching, and to avoid using the RHS of the
/// projection predicate to influence the normalizes-to candidate we select.
///
/// Forgetting to replace the RHS with a fresh inference variable when we evaluate
/// this goal results in an ICE..
pub normalizes_to_goals: Vec<Goal<I, ty::NormalizesTo<I>>>,
/// The rest of the goals which have not yet processed or remain ambiguous.
pub goals: Vec<(GoalSource, Goal<I, I::Predicate>)>,
}
impl<I: Interner> NestedGoals<I> {
fn new() -> Self {
Self { normalizes_to_goals: Vec::new(), goals: Vec::new() }
}
fn is_empty(&self) -> bool {
self.normalizes_to_goals.is_empty() && self.goals.is_empty()
}
}
#[derive(PartialEq, Eq, Debug, Hash, Clone, Copy)]
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
pub enum GenerateProofTree {
@ -332,7 +299,7 @@ where
let mut ecx = EvalCtxt {
delegate,
search_graph: &mut search_graph,
nested_goals: NestedGoals::new(),
nested_goals: Default::default(),
inspect: ProofTreeBuilder::new_maybe_root(generate_proof_tree),
// Only relevant when canonicalizing the response,
@ -385,7 +352,7 @@ where
predefined_opaques_in_body: input.predefined_opaques_in_body,
max_input_universe: canonical_input.canonical.max_universe,
search_graph,
nested_goals: NestedGoals::new(),
nested_goals: Default::default(),
origin_span: I::Span::dummy(),
tainted: Ok(()),
inspect: canonical_goal_evaluation.new_goal_evaluation_step(var_values),
@ -629,78 +596,83 @@ where
/// Goals for the next step get directly added to the nested goals of the `EvalCtxt`.
fn evaluate_added_goals_step(&mut self) -> Result<Option<Certainty>, NoSolution> {
let cx = self.cx();
let mut goals = core::mem::take(&mut self.nested_goals);
// If this loop did not result in any progress, what's our final certainty.
let mut unchanged_certainty = Some(Certainty::Yes);
for goal in goals.normalizes_to_goals {
// Replace the goal with an unconstrained infer var, so the
// RHS does not affect projection candidate assembly.
let unconstrained_rhs = self.next_term_infer_of_kind(goal.predicate.term);
let unconstrained_goal = goal.with(
cx,
ty::NormalizesTo { alias: goal.predicate.alias, term: unconstrained_rhs },
);
let (NestedNormalizationGoals(nested_goals), _, certainty) = self.evaluate_goal_raw(
GoalEvaluationKind::Nested,
GoalSource::TypeRelating,
unconstrained_goal,
)?;
// Add the nested goals from normalization to our own nested goals.
trace!(?nested_goals);
goals.goals.extend(nested_goals);
// Finally, equate the goal's RHS with the unconstrained var.
for (source, goal) in mem::take(&mut self.nested_goals) {
// We treat normalizes-to goals specially here. 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 equate the fresh inference variable with the
// actual RHS of the predicate.
//
// SUBTLE:
// We structurally relate aliases here. This is necessary
// as we otherwise emit a nested `AliasRelate` goal in case the
// returned term is a rigid alias, resulting in overflow.
// This is both to improve caching, and to avoid using the RHS of the
// projection predicate to influence the normalizes-to candidate we select.
//
// It is correct as both `goal.predicate.term` and `unconstrained_rhs`
// start out as an unconstrained inference variable so any aliases get
// fully normalized when instantiating it.
//
// FIXME: Strictly speaking this may be incomplete if the normalized-to
// type contains an ambiguous alias referencing bound regions. We should
// consider changing this to only use "shallow structural equality".
self.eq_structurally_relating_aliases(
goal.param_env,
goal.predicate.term,
unconstrained_rhs,
)?;
// Forgetting to replace the RHS with a fresh inference variable when we evaluate
// this goal results in an ICE.
if let Some(pred) = goal.predicate.as_normalizes_to() {
// We should never encounter higher-ranked normalizes-to goals.
let pred = pred.no_bound_vars().unwrap();
// Replace the goal with an unconstrained infer var, so the
// RHS does not affect projection candidate assembly.
let unconstrained_rhs = self.next_term_infer_of_kind(pred.term);
let unconstrained_goal =
goal.with(cx, ty::NormalizesTo { alias: pred.alias, term: unconstrained_rhs });
// We only look at the `projection_ty` part here rather than
// looking at the "has changed" return from evaluate_goal,
// because we expect the `unconstrained_rhs` part of the predicate
// to have changed -- that means we actually normalized successfully!
let with_resolved_vars = self.resolve_vars_if_possible(goal);
if goal.predicate.alias != with_resolved_vars.predicate.alias {
unchanged_certainty = None;
}
let (NestedNormalizationGoals(nested_goals), _, certainty) =
self.evaluate_goal_raw(GoalEvaluationKind::Nested, source, unconstrained_goal)?;
// Add the nested goals from normalization to our own nested goals.
trace!(?nested_goals);
self.nested_goals.extend(nested_goals);
match certainty {
Certainty::Yes => {}
Certainty::Maybe(_) => {
self.nested_goals.normalizes_to_goals.push(with_resolved_vars);
unchanged_certainty = unchanged_certainty.map(|c| c.unify_with(certainty));
// Finally, equate the goal's RHS with the unconstrained var.
//
// SUBTLE:
// We structurally relate aliases here. This is necessary
// as we otherwise emit a nested `AliasRelate` goal in case the
// returned term is a rigid alias, resulting in overflow.
//
// It is correct as both `goal.predicate.term` and `unconstrained_rhs`
// start out as an unconstrained inference variable so any aliases get
// fully normalized when instantiating it.
//
// FIXME: Strictly speaking this may be incomplete if the normalized-to
// type contains an ambiguous alias referencing bound regions. We should
// consider changing this to only use "shallow structural equality".
self.eq_structurally_relating_aliases(
goal.param_env,
pred.term,
unconstrained_rhs,
)?;
// We only look at the `projection_ty` part here rather than
// looking at the "has changed" return from evaluate_goal,
// because we expect the `unconstrained_rhs` part of the predicate
// to have changed -- that means we actually normalized successfully!
let with_resolved_vars = self.resolve_vars_if_possible(goal);
if pred.alias != goal.predicate.as_normalizes_to().unwrap().skip_binder().alias {
unchanged_certainty = None;
}
}
}
for (source, goal) in goals.goals {
let (has_changed, certainty) =
self.evaluate_goal(GoalEvaluationKind::Nested, source, goal)?;
if has_changed == HasChanged::Yes {
unchanged_certainty = None;
}
match certainty {
Certainty::Yes => {}
Certainty::Maybe(_) => {
self.nested_goals.push((source, with_resolved_vars));
unchanged_certainty = unchanged_certainty.map(|c| c.unify_with(certainty));
}
}
} else {
let (has_changed, certainty) =
self.evaluate_goal(GoalEvaluationKind::Nested, source, goal)?;
if has_changed == HasChanged::Yes {
unchanged_certainty = None;
}
match certainty {
Certainty::Yes => {}
Certainty::Maybe(_) => {
self.nested_goals.goals.push((source, goal));
unchanged_certainty = unchanged_certainty.map(|c| c.unify_with(certainty));
match certainty {
Certainty::Yes => {}
Certainty::Maybe(_) => {
self.nested_goals.push((source, goal));
unchanged_certainty = unchanged_certainty.map(|c| c.unify_with(certainty));
}
}
}
}
@ -717,23 +689,12 @@ where
self.delegate.cx()
}
#[instrument(level = "trace", skip(self))]
pub(super) fn add_normalizes_to_goal(&mut self, mut goal: Goal<I, ty::NormalizesTo<I>>) {
goal.predicate = goal.predicate.fold_with(&mut ReplaceAliasWithInfer::new(
self,
GoalSource::TypeRelating,
goal.param_env,
));
self.inspect.add_normalizes_to_goal(self.delegate, self.max_input_universe, goal);
self.nested_goals.normalizes_to_goals.push(goal);
}
#[instrument(level = "debug", skip(self))]
pub(super) fn add_goal(&mut self, source: GoalSource, mut goal: Goal<I, I::Predicate>) {
goal.predicate =
goal.predicate.fold_with(&mut ReplaceAliasWithInfer::new(self, source, goal.param_env));
self.inspect.add_goal(self.delegate, self.max_input_universe, source, goal);
self.nested_goals.goals.push((source, goal));
self.nested_goals.push((source, goal));
}
#[instrument(level = "trace", skip(self, goals))]

View file

@ -412,20 +412,6 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
}
}
pub(crate) fn add_normalizes_to_goal(
&mut self,
delegate: &D,
max_input_universe: ty::UniverseIndex,
goal: Goal<I, ty::NormalizesTo<I>>,
) {
self.add_goal(
delegate,
max_input_universe,
GoalSource::TypeRelating,
goal.with(delegate.cx(), goal.predicate),
);
}
pub(crate) fn add_goal(
&mut self,
delegate: &D,

View file

@ -4,13 +4,13 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(array_windows)]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(debug_closure_helpers)]
#![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![feature(let_chains)]
#![feature(string_from_utf8_lossy_owned)]
// tidy-alphabetical-end

View file

@ -683,10 +683,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
if !other_attr.has_any_name(ALLOW_LIST) {
let path = other_attr.path();
let path: Vec<_> = path.iter().map(|s| s.as_str()).collect();
let other_attr_name = path.join("::");
self.dcx().emit_err(errors::NakedFunctionIncompatibleAttribute {
span: other_attr.span(),
naked_span: attr.span(),
attr: other_attr.name().unwrap(),
attr: other_attr_name,
});
return;

View file

@ -1249,7 +1249,7 @@ pub(crate) struct NakedFunctionIncompatibleAttribute {
pub span: Span,
#[label(passes_naked_attribute)]
pub naked_span: Span,
pub attr: Symbol,
pub attr: String,
}
#[derive(Diagnostic)]

View file

@ -6,9 +6,9 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(let_chains)]
#![feature(map_try_insert)]
#![feature(rustdoc_internals)]
#![feature(try_blocks)]

View file

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

View file

@ -1,9 +1,9 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(associated_type_defaults)]
#![feature(let_chains)]
#![feature(rustdoc_internals)]
#![feature(try_blocks)]
// tidy-alphabetical-end

View file

@ -46,6 +46,7 @@ use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::sync::Lock;
use rustc_data_structures::unhash::UnhashMap;
use rustc_index::{Idx, IndexVec};
use rustc_serialize::opaque::mem_encoder::MemEncoder;
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder, IntEncodedWithFixedSize, MemDecoder};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use tracing::{debug, instrument};
@ -105,22 +106,12 @@ impl SerializedDepGraph {
) -> impl Iterator<Item = SerializedDepNodeIndex> + Clone {
let header = self.edge_list_indices[source];
let mut raw = &self.edge_list_data[header.start()..];
// Figure out where the edge list for `source` ends by getting the start index of the next
// edge list, or the end of the array if this is the last edge.
let end = self
.edge_list_indices
.get(source + 1)
.map(|h| h.start())
.unwrap_or_else(|| self.edge_list_data.len() - DEP_NODE_PAD);
// The number of edges for this node is implicitly stored in the combination of the byte
// width and the length.
let bytes_per_index = header.bytes_per_index();
let len = (end - header.start()) / bytes_per_index;
// LLVM doesn't hoist EdgeHeader::mask so we do it ourselves.
let mask = header.mask();
(0..len).map(move |_| {
(0..header.num_edges).map(move |_| {
// Doing this slicing in this order ensures that the first bounds check suffices for
// all the others.
let index = &raw[..DEP_NODE_SIZE];
@ -163,6 +154,7 @@ impl SerializedDepGraph {
#[derive(Debug, Clone, Copy)]
struct EdgeHeader {
repr: usize,
num_edges: u32,
}
impl EdgeHeader {
@ -205,9 +197,14 @@ impl SerializedDepGraph {
let graph_bytes = d.len() - (2 * IntEncodedWithFixedSize::ENCODED_SIZE) - d.position();
let mut nodes = IndexVec::with_capacity(node_count);
let mut fingerprints = IndexVec::with_capacity(node_count);
let mut edge_list_indices = IndexVec::with_capacity(node_count);
let mut nodes = IndexVec::from_elem_n(
DepNode { kind: D::DEP_KIND_NULL, hash: PackedFingerprint::from(Fingerprint::ZERO) },
node_count,
);
let mut fingerprints = IndexVec::from_elem_n(Fingerprint::ZERO, node_count);
let mut edge_list_indices =
IndexVec::from_elem_n(EdgeHeader { repr: 0, num_edges: 0 }, node_count);
// This estimation assumes that all of the encoded bytes are for the edge lists or for the
// fixed-size node headers. But that's not necessarily true; if any edge list has a length
// that spills out of the size we can bit-pack into SerializedNodeHeader then some of the
@ -226,11 +223,14 @@ impl SerializedDepGraph {
let node_header =
SerializedNodeHeader::<D> { bytes: d.read_array(), _marker: PhantomData };
let _i: SerializedDepNodeIndex = nodes.push(node_header.node());
debug_assert_eq!(_i.index(), _index);
let index = node_header.index();
let _i: SerializedDepNodeIndex = fingerprints.push(node_header.fingerprint());
debug_assert_eq!(_i.index(), _index);
let node = &mut nodes[index];
// Make sure there's no duplicate indices in the dep graph.
assert!(node_header.node().kind != D::DEP_KIND_NULL && node.kind == D::DEP_KIND_NULL);
*node = node_header.node();
fingerprints[index] = node_header.fingerprint();
// If the length of this node's edge list is small, the length is stored in the header.
// If it is not, we fall back to another decoder call.
@ -242,12 +242,11 @@ impl SerializedDepGraph {
let edges_len_bytes = node_header.bytes_per_index() * (num_edges as usize);
// The in-memory structure for the edges list stores the byte width of the edges on
// this node with the offset into the global edge data array.
let edges_header = node_header.edges_header(&edge_list_data);
let edges_header = node_header.edges_header(&edge_list_data, num_edges);
edge_list_data.extend(d.read_raw_bytes(edges_len_bytes));
let _i: SerializedDepNodeIndex = edge_list_indices.push(edges_header);
debug_assert_eq!(_i.index(), _index);
edge_list_indices[index] = edges_header;
}
// When we access the edge list data, we do a fixed-size read from the edge list data then
@ -298,9 +297,10 @@ impl SerializedDepGraph {
/// * In whatever bits remain, the length of the edge list for this node, if it fits
struct SerializedNodeHeader<D> {
// 2 bytes for the DepNode
// 4 bytes for the index
// 16 for Fingerprint in DepNode
// 16 for Fingerprint in NodeInfo
bytes: [u8; 34],
bytes: [u8; 38],
_marker: PhantomData<D>,
}
@ -310,6 +310,7 @@ struct Unpacked {
len: Option<u32>,
bytes_per_index: usize,
kind: DepKind,
index: SerializedDepNodeIndex,
hash: PackedFingerprint,
fingerprint: Fingerprint,
}
@ -331,6 +332,7 @@ impl<D: Deps> SerializedNodeHeader<D> {
#[inline]
fn new(
node: DepNode,
index: DepNodeIndex,
fingerprint: Fingerprint,
edge_max_index: u32,
edge_count: usize,
@ -352,10 +354,11 @@ impl<D: Deps> SerializedNodeHeader<D> {
let hash: Fingerprint = node.hash.into();
// Using half-open ranges ensures an unconditional panic if we get the magic numbers wrong.
let mut bytes = [0u8; 34];
let mut bytes = [0u8; 38];
bytes[..2].copy_from_slice(&head.to_le_bytes());
bytes[2..18].copy_from_slice(&hash.to_le_bytes());
bytes[18..].copy_from_slice(&fingerprint.to_le_bytes());
bytes[2..6].copy_from_slice(&index.as_u32().to_le_bytes());
bytes[6..22].copy_from_slice(&hash.to_le_bytes());
bytes[22..].copy_from_slice(&fingerprint.to_le_bytes());
#[cfg(debug_assertions)]
{
@ -372,8 +375,9 @@ impl<D: Deps> SerializedNodeHeader<D> {
#[inline]
fn unpack(&self) -> Unpacked {
let head = u16::from_le_bytes(self.bytes[..2].try_into().unwrap());
let hash = self.bytes[2..18].try_into().unwrap();
let fingerprint = self.bytes[18..].try_into().unwrap();
let index = u32::from_le_bytes(self.bytes[2..6].try_into().unwrap());
let hash = self.bytes[6..22].try_into().unwrap();
let fingerprint = self.bytes[22..].try_into().unwrap();
let kind = head & mask(Self::KIND_BITS) as u16;
let bytes_per_index = (head >> Self::KIND_BITS) & mask(Self::WIDTH_BITS) as u16;
@ -383,6 +387,7 @@ impl<D: Deps> SerializedNodeHeader<D> {
len: len.checked_sub(1),
bytes_per_index: bytes_per_index as usize + 1,
kind: DepKind::new(kind),
index: SerializedDepNodeIndex::from_u32(index),
hash: Fingerprint::from_le_bytes(hash).into(),
fingerprint: Fingerprint::from_le_bytes(fingerprint),
}
@ -398,6 +403,11 @@ impl<D: Deps> SerializedNodeHeader<D> {
self.unpack().bytes_per_index
}
#[inline]
fn index(&self) -> SerializedDepNodeIndex {
self.unpack().index
}
#[inline]
fn fingerprint(&self) -> Fingerprint {
self.unpack().fingerprint
@ -410,9 +420,10 @@ impl<D: Deps> SerializedNodeHeader<D> {
}
#[inline]
fn edges_header(&self, edge_list_data: &[u8]) -> EdgeHeader {
fn edges_header(&self, edge_list_data: &[u8], num_edges: u32) -> EdgeHeader {
EdgeHeader {
repr: (edge_list_data.len() << DEP_NODE_WIDTH_BITS) | (self.bytes_per_index() - 1),
num_edges,
}
}
}
@ -425,10 +436,15 @@ struct NodeInfo {
}
impl NodeInfo {
fn encode<D: Deps>(&self, e: &mut FileEncoder) {
fn encode<D: Deps>(&self, e: &mut MemEncoder, index: DepNodeIndex) {
let NodeInfo { node, fingerprint, ref edges } = *self;
let header =
SerializedNodeHeader::<D>::new(node, fingerprint, edges.max_index(), edges.len());
let header = SerializedNodeHeader::<D>::new(
node,
index,
fingerprint,
edges.max_index(),
edges.len(),
);
e.write_array(header.bytes);
if header.len().is_none() {
@ -450,8 +466,9 @@ impl NodeInfo {
/// This avoids the overhead of constructing `EdgesVec`, which would be needed to call `encode`.
#[inline]
fn encode_promoted<D: Deps>(
e: &mut FileEncoder,
e: &mut MemEncoder,
node: DepNode,
index: DepNodeIndex,
fingerprint: Fingerprint,
prev_index: SerializedDepNodeIndex,
colors: &DepNodeColorMap,
@ -464,7 +481,7 @@ impl NodeInfo {
let edge_max =
edges.clone().map(|i| colors.current(i).unwrap().as_u32()).max().unwrap_or(0);
let header = SerializedNodeHeader::<D>::new(node, fingerprint, edge_max, edge_count);
let header = SerializedNodeHeader::<D>::new(node, index, fingerprint, edge_max, edge_count);
e.write_array(header.bytes);
if header.len().is_none() {
@ -498,6 +515,8 @@ struct EncoderState<D: Deps> {
total_edge_count: usize,
stats: Option<FxHashMap<DepKind, Stat>>,
mem_encoder: MemEncoder,
/// Stores the number of times we've encoded each dep kind.
kind_stats: Vec<u32>,
marker: PhantomData<D>,
@ -511,22 +530,28 @@ impl<D: Deps> EncoderState<D> {
total_edge_count: 0,
total_node_count: 0,
stats: record_stats.then(FxHashMap::default),
mem_encoder: MemEncoder::new(),
kind_stats: iter::repeat(0).take(D::DEP_KIND_MAX as usize + 1).collect(),
marker: PhantomData,
}
}
#[inline]
fn alloc_index(&mut self) -> DepNodeIndex {
let index = DepNodeIndex::new(self.total_node_count);
self.total_node_count += 1;
index
}
#[inline]
fn record(
&mut self,
node: DepNode,
index: DepNodeIndex,
edge_count: usize,
edges: impl FnOnce(&mut Self) -> Vec<DepNodeIndex>,
record_graph: &Option<Lock<DepGraphQuery>>,
) -> DepNodeIndex {
let index = DepNodeIndex::new(self.total_node_count);
self.total_node_count += 1;
self.kind_stats[node.kind.as_usize()] += 1;
self.total_edge_count += edge_count;
@ -558,14 +583,25 @@ impl<D: Deps> EncoderState<D> {
index
}
#[inline]
fn flush_mem_encoder(&mut self) {
let data = &mut self.mem_encoder.data;
if data.len() > 64 * 1024 {
self.encoder.emit_raw_bytes(&data[..]);
data.clear();
}
}
/// Encodes a node to the current graph.
fn encode_node(
&mut self,
node: &NodeInfo,
record_graph: &Option<Lock<DepGraphQuery>>,
) -> DepNodeIndex {
node.encode::<D>(&mut self.encoder);
self.record(node.node, node.edges.len(), |_| node.edges[..].to_vec(), record_graph)
let index = self.alloc_index();
node.encode::<D>(&mut self.mem_encoder, index);
self.flush_mem_encoder();
self.record(node.node, index, node.edges.len(), |_| node.edges[..].to_vec(), record_graph)
}
/// Encodes a node that was promoted from the previous graph. It reads the information directly from
@ -581,20 +617,22 @@ impl<D: Deps> EncoderState<D> {
record_graph: &Option<Lock<DepGraphQuery>>,
colors: &DepNodeColorMap,
) -> DepNodeIndex {
let index = self.alloc_index();
let node = self.previous.index_to_node(prev_index);
let fingerprint = self.previous.fingerprint_by_index(prev_index);
let edge_count = NodeInfo::encode_promoted::<D>(
&mut self.encoder,
&mut self.mem_encoder,
node,
index,
fingerprint,
prev_index,
colors,
&self.previous,
);
self.flush_mem_encoder();
self.record(
node,
index,
edge_count,
|this| {
this.previous
@ -603,12 +641,14 @@ impl<D: Deps> EncoderState<D> {
.collect()
},
record_graph,
)
);
index
}
fn finish(self, profiler: &SelfProfilerRef) -> FileEncodeResult {
let Self {
mut encoder,
mem_encoder,
total_node_count,
total_edge_count,
stats: _,
@ -617,6 +657,8 @@ impl<D: Deps> EncoderState<D> {
previous,
} = self;
encoder.emit_raw_bytes(&mem_encoder.data);
let node_count = total_node_count.try_into().unwrap();
let edge_count = total_edge_count.try_into().unwrap();

View file

@ -1,9 +1,9 @@
// tidy-alphabetical-start
#![allow(rustc::potential_query_instability, internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(assert_matches)]
#![feature(core_intrinsics)]
#![feature(dropck_eyepatch)]
#![feature(let_chains)]
#![feature(min_specialization)]
// tidy-alphabetical-end

View file

@ -10,13 +10,13 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![feature(let_chains)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end

View file

@ -4,7 +4,7 @@
//! compiler.
// tidy-alphabetical-start
#![feature(let_chains)]
#![cfg_attr(bootstrap, feature(let_chains))]
// tidy-alphabetical-end
pub mod cfi;

View file

@ -10,6 +10,8 @@ use crate::int_overflow::DebugStrictAdd;
use crate::leb128;
use crate::serialize::{Decodable, Decoder, Encodable, Encoder};
pub mod mem_encoder;
// -----------------------------------------------------------------------------
// Encoder
// -----------------------------------------------------------------------------

View file

@ -0,0 +1,128 @@
use super::IntEncodedWithFixedSize;
use crate::{Encodable, Encoder, leb128};
pub struct MemEncoder {
pub data: Vec<u8>,
}
impl MemEncoder {
pub fn new() -> MemEncoder {
MemEncoder { data: vec![] }
}
#[inline]
pub fn position(&self) -> usize {
self.data.len()
}
pub fn finish(self) -> Vec<u8> {
self.data
}
/// Write up to `N` bytes to this encoder.
///
/// This function can be used to avoid the overhead of calling memcpy for writes that
/// have runtime-variable length, but are small and have a small fixed upper bound.
///
/// This can be used to do in-place encoding as is done for leb128 (without this function
/// we would need to write to a temporary buffer then memcpy into the encoder), and it can
/// also be used to implement the varint scheme we use for rmeta and dep graph encoding,
/// where we only want to encode the first few bytes of an integer. Note that common
/// architectures support fixed-size writes up to 8 bytes with one instruction, so while this
/// does in some sense do wasted work, we come out ahead.
#[inline]
pub fn write_with<const N: usize>(&mut self, visitor: impl FnOnce(&mut [u8; N]) -> usize) {
self.data.reserve(N);
let old_len = self.data.len();
// SAFETY: The above `reserve` ensures that there is enough
// room to write the encoded value to the vector's internal buffer.
// The memory is also initialized as 0.
let buf = unsafe {
let buf = self.data.as_mut_ptr().add(old_len) as *mut [u8; N];
*buf = [0; N];
&mut *buf
};
let written = visitor(buf);
if written > N {
Self::panic_invalid_write::<N>(written);
}
unsafe { self.data.set_len(old_len + written) };
}
#[cold]
#[inline(never)]
fn panic_invalid_write<const N: usize>(written: usize) {
panic!("MemEncoder::write_with::<{N}> cannot be used to write {written} bytes");
}
/// Helper for calls where [`MemEncoder::write_with`] always writes the whole array.
#[inline]
pub fn write_array<const N: usize>(&mut self, buf: [u8; N]) {
self.write_with(|dest| {
*dest = buf;
N
})
}
}
macro_rules! write_leb128 {
($this_fn:ident, $int_ty:ty, $write_leb_fn:ident) => {
#[inline]
fn $this_fn(&mut self, v: $int_ty) {
self.write_with(|buf| leb128::$write_leb_fn(buf, v))
}
};
}
impl Encoder for MemEncoder {
write_leb128!(emit_usize, usize, write_usize_leb128);
write_leb128!(emit_u128, u128, write_u128_leb128);
write_leb128!(emit_u64, u64, write_u64_leb128);
write_leb128!(emit_u32, u32, write_u32_leb128);
#[inline]
fn emit_u16(&mut self, v: u16) {
self.write_array(v.to_le_bytes());
}
#[inline]
fn emit_u8(&mut self, v: u8) {
self.write_array([v]);
}
write_leb128!(emit_isize, isize, write_isize_leb128);
write_leb128!(emit_i128, i128, write_i128_leb128);
write_leb128!(emit_i64, i64, write_i64_leb128);
write_leb128!(emit_i32, i32, write_i32_leb128);
#[inline]
fn emit_i16(&mut self, v: i16) {
self.write_array(v.to_le_bytes());
}
#[inline]
fn emit_raw_bytes(&mut self, s: &[u8]) {
self.data.extend_from_slice(s);
}
}
// Specialize encoding byte slices. This specialization also applies to encoding `Vec<u8>`s, etc.,
// since the default implementations call `encode` on their slices internally.
impl Encodable<MemEncoder> for [u8] {
fn encode(&self, e: &mut MemEncoder) {
Encoder::emit_usize(e, self.len());
e.emit_raw_bytes(self);
}
}
impl Encodable<MemEncoder> for IntEncodedWithFixedSize {
#[inline]
fn encode(&self, e: &mut MemEncoder) {
let start_pos = e.position();
e.write_array(self.0.to_le_bytes());
let end_pos = e.position();
debug_assert_eq!((end_pos - start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
}
}

View file

@ -142,6 +142,10 @@ pub(crate) fn disallow_cfgs(sess: &Session, user_cfgs: &Cfg) {
| (sym::target_has_atomic, Some(_))
| (sym::target_has_atomic_equal_alignment, Some(_))
| (sym::target_has_atomic_load_store, Some(_))
| (sym::target_has_reliable_f16, None | Some(_))
| (sym::target_has_reliable_f16_math, None | Some(_))
| (sym::target_has_reliable_f128, None | Some(_))
| (sym::target_has_reliable_f128_math, None | Some(_))
| (sym::target_thread_local, None) => disallow(cfg, "--target"),
(sym::fmt_debug, None | Some(_)) => disallow(cfg, "-Z fmt-debug"),
(sym::emscripten_wasm_eh, None | Some(_)) => disallow(cfg, "-Z emscripten_wasm_eh"),

View file

@ -1,8 +1,8 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(default_field_values)]
#![feature(iter_intersperse)]
#![feature(let_chains)]
#![feature(rustc_attrs)]
// To generate CodegenOptionsTargetModifiers and UnstableOptionsTargetModifiers enums
// with macro_rules, it is necessary to use recursive mechanic ("Incremental TT Munchers").

View file

@ -17,6 +17,7 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(array_windows)]
@ -24,7 +25,6 @@
#![feature(core_io_borrowed_buf)]
#![feature(hash_set_entry)]
#![feature(if_let_guard)]
#![feature(let_chains)]
#![feature(map_try_insert)]
#![feature(negative_impls)]
#![feature(read_buf)]

View file

@ -623,6 +623,7 @@ symbols! {
cfg_target_feature,
cfg_target_has_atomic,
cfg_target_has_atomic_equal_alignment,
cfg_target_has_reliable_f16_f128,
cfg_target_thread_local,
cfg_target_vendor,
cfg_trace: "<cfg>", // must not be a valid identifier
@ -2074,6 +2075,10 @@ symbols! {
target_has_atomic,
target_has_atomic_equal_alignment,
target_has_atomic_load_store,
target_has_reliable_f128,
target_has_reliable_f128_math,
target_has_reliable_f16,
target_has_reliable_f16_math,
target_os,
target_pointer_width,
target_thread_local,

View file

@ -89,9 +89,9 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(let_chains)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end

View file

@ -9,12 +9,12 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(debug_closure_helpers)]
#![feature(iter_intersperse)]
#![feature(let_chains)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end

View file

@ -1523,19 +1523,17 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
return None;
};
let trait_assoc_item = self.tcx.opt_associated_item(proj.projection_term.def_id)?;
let trait_assoc_ident = trait_assoc_item.ident(self.tcx);
let mut associated_items = vec![];
self.tcx.for_each_relevant_impl(
self.tcx.trait_of_item(proj.projection_term.def_id)?,
proj.projection_term.self_ty(),
|impl_def_id| {
associated_items.extend(
self.tcx
.associated_items(impl_def_id)
.in_definition_order()
.find(|assoc| assoc.ident(self.tcx) == trait_assoc_ident),
self.tcx.associated_items(impl_def_id).in_definition_order().find(
|assoc| {
assoc.trait_item_def_id == Some(proj.projection_term.def_id)
},
),
);
},
);

View file

@ -14,6 +14,7 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
@ -23,7 +24,6 @@
#![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![feature(iterator_try_reduce)]
#![feature(let_chains)]
#![feature(never_type)]
#![feature(rustdoc_internals)]
#![feature(try_blocks)]

View file

@ -6,6 +6,7 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
@ -13,7 +14,6 @@
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(iterator_try_collect)]
#![feature(let_chains)]
#![feature(never_type)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end

View file

@ -442,6 +442,14 @@ pub trait Predicate<I: Interner<Predicate = Self>>:
{
fn as_clause(self) -> Option<I::Clause>;
fn as_normalizes_to(self) -> Option<ty::Binder<I, ty::NormalizesTo<I>>> {
let kind = self.kind();
match kind.skip_binder() {
ty::PredicateKind::NormalizesTo(pred) => Some(kind.rebind(pred)),
_ => None,
}
}
// FIXME: Eventually uplift the impl out of rustc and make this defaulted.
fn allow_normalization(self) -> bool;
}

View file

@ -1138,6 +1138,10 @@ pub(crate) mod builtin {
issue = "29599",
reason = "`concat_idents` is not stable enough for use and is subject to change"
)]
#[deprecated(
since = "1.88.0",
note = "use `${concat(...)}` with the `macro_metavar_expr_concat` feature instead"
)]
#[rustc_builtin_macro]
#[macro_export]
macro_rules! concat_idents {

View file

@ -162,8 +162,14 @@
//! The [`is_some`] and [`is_none`] methods return [`true`] if the [`Option`]
//! is [`Some`] or [`None`], respectively.
//!
//! The [`is_some_and`] and [`is_none_or`] methods apply the provided function
//! to the contents of the [`Option`] to produce a boolean value.
//! If this is [`None`] then a default result is returned instead without executing the function.
//!
//! [`is_none`]: Option::is_none
//! [`is_some`]: Option::is_some
//! [`is_some_and`]: Option::is_some_and
//! [`is_none_or`]: Option::is_none_or
//!
//! ## Adapters for working with references
//!
@ -177,6 +183,10 @@
//! <code>[Option]<[Pin]<[&]T>></code>
//! * [`as_pin_mut`] converts from <code>[Pin]<[&mut] [Option]\<T>></code> to
//! <code>[Option]<[Pin]<[&mut] T>></code>
//! * [`as_slice`] returns a one-element slice of the contained value, if any.
//! If this is [`None`], an empty slice is returned.
//! * [`as_mut_slice`] returns a mutable one-element slice of the contained value, if any.
//! If this is [`None`], an empty slice is returned.
//!
//! [&]: reference "shared reference"
//! [&mut]: reference "mutable reference"
@ -187,6 +197,8 @@
//! [`as_pin_mut`]: Option::as_pin_mut
//! [`as_pin_ref`]: Option::as_pin_ref
//! [`as_ref`]: Option::as_ref
//! [`as_slice`]: Option::as_slice
//! [`as_mut_slice`]: Option::as_mut_slice
//!
//! ## Extracting the contained value
//!
@ -200,12 +212,15 @@
//! (which must implement the [`Default`] trait)
//! * [`unwrap_or_else`] returns the result of evaluating the provided
//! function
//! * [`unwrap_unchecked`] produces *[undefined behavior]*
//!
//! [`expect`]: Option::expect
//! [`unwrap`]: Option::unwrap
//! [`unwrap_or`]: Option::unwrap_or
//! [`unwrap_or_default`]: Option::unwrap_or_default
//! [`unwrap_or_else`]: Option::unwrap_or_else
//! [`unwrap_unchecked`]: Option::unwrap_unchecked
//! [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
//!
//! ## Transforming contained values
//!
@ -230,8 +245,9 @@
//! * [`filter`] calls the provided predicate function on the contained
//! value `t` if the [`Option`] is [`Some(t)`], and returns [`Some(t)`]
//! if the function returns `true`; otherwise, returns [`None`]
//! * [`flatten`] removes one level of nesting from an
//! [`Option<Option<T>>`]
//! * [`flatten`] removes one level of nesting from an [`Option<Option<T>>`]
//! * [`inspect`] method takes ownership of the [`Option`] and applies
//! the provided function to the contained value by reference if [`Some`]
//! * [`map`] transforms [`Option<T>`] to [`Option<U>`] by applying the
//! provided function to the contained value of [`Some`] and leaving
//! [`None`] values unchanged
@ -239,6 +255,7 @@
//! [`Some(t)`]: Some
//! [`filter`]: Option::filter
//! [`flatten`]: Option::flatten
//! [`inspect`]: Option::inspect
//! [`map`]: Option::map
//!
//! These methods transform [`Option<T>`] to a value of a possibly
@ -621,6 +638,10 @@ impl<T> Option<T> {
///
/// let x: Option<u32> = None;
/// assert_eq!(x.is_some_and(|x| x > 1), false);
///
/// let x: Option<String> = Some("ownership".to_string());
/// assert_eq!(x.as_ref().is_some_and(|x| x.len() > 1), true);
/// println!("still alive {:?}", x);
/// ```
#[must_use]
#[inline]
@ -665,6 +686,10 @@ impl<T> Option<T> {
///
/// let x: Option<u32> = None;
/// assert_eq!(x.is_none_or(|x| x > 1), true);
///
/// let x: Option<String> = Some("ownership".to_string());
/// assert_eq!(x.as_ref().is_none_or(|x| x.len() > 1), true);
/// println!("still alive {:?}", x);
/// ```
#[must_use]
#[inline]

View file

@ -59,6 +59,7 @@ pub use crate::hash::macros::Hash;
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow(deprecated)]
#[cfg_attr(bootstrap, allow(deprecated_in_future))]
#[doc(no_inline)]
pub use crate::{
assert, cfg, column, compile_error, concat, concat_idents, env, file, format_args,

View file

@ -259,8 +259,14 @@
//! The [`is_ok`] and [`is_err`] methods return [`true`] if the [`Result`]
//! is [`Ok`] or [`Err`], respectively.
//!
//! The [`is_ok_and`] and [`is_err_and`] methods apply the provided function
//! to the contents of the [`Result`] to produce a boolean value. If the [`Result`] does not have the expected variant
//! then [`false`] is returned instead without executing the function.
//!
//! [`is_err`]: Result::is_err
//! [`is_ok`]: Result::is_ok
//! [`is_ok_and`]: Result::is_ok_and
//! [`is_err_and`]: Result::is_err_and
//!
//! ## Adapters for working with references
//!
@ -287,6 +293,7 @@
//! (which must implement the [`Default`] trait)
//! * [`unwrap_or_else`] returns the result of evaluating the provided
//! function
//! * [`unwrap_unchecked`] produces *[undefined behavior]*
//!
//! The panicking methods [`expect`] and [`unwrap`] require `E` to
//! implement the [`Debug`] trait.
@ -297,6 +304,8 @@
//! [`unwrap_or`]: Result::unwrap_or
//! [`unwrap_or_default`]: Result::unwrap_or_default
//! [`unwrap_or_else`]: Result::unwrap_or_else
//! [`unwrap_unchecked`]: Result::unwrap_unchecked
//! [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
//!
//! These methods extract the contained value in a [`Result<T, E>`] when it
//! is the [`Err`] variant. They require `T` to implement the [`Debug`]
@ -304,10 +313,13 @@
//!
//! * [`expect_err`] panics with a provided custom message
//! * [`unwrap_err`] panics with a generic message
//! * [`unwrap_err_unchecked`] produces *[undefined behavior]*
//!
//! [`Debug`]: crate::fmt::Debug
//! [`expect_err`]: Result::expect_err
//! [`unwrap_err`]: Result::unwrap_err
//! [`unwrap_err_unchecked`]: Result::unwrap_err_unchecked
//! [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
//!
//! ## Transforming contained values
//!
@ -330,21 +342,29 @@
//! [`Some(v)`]: Option::Some
//! [`transpose`]: Result::transpose
//!
//! This method transforms the contained value of the [`Ok`] variant:
//! These methods transform the contained value of the [`Ok`] variant:
//!
//! * [`map`] transforms [`Result<T, E>`] into [`Result<U, E>`] by applying
//! the provided function to the contained value of [`Ok`] and leaving
//! [`Err`] values unchanged
//! * [`inspect`] takes ownership of the [`Result`], applies the
//! provided function to the contained value by reference,
//! and then returns the [`Result`]
//!
//! [`map`]: Result::map
//! [`inspect`]: Result::inspect
//!
//! This method transforms the contained value of the [`Err`] variant:
//! These methods transform the contained value of the [`Err`] variant:
//!
//! * [`map_err`] transforms [`Result<T, E>`] into [`Result<T, F>`] by
//! applying the provided function to the contained value of [`Err`] and
//! leaving [`Ok`] values unchanged
//! * [`inspect_err`] takes ownership of the [`Result`], applies the
//! provided function to the contained value of [`Err`] by reference,
//! and then returns the [`Result`]
//!
//! [`map_err`]: Result::map_err
//! [`inspect_err`]: Result::inspect_err
//!
//! These methods transform a [`Result<T, E>`] into a value of a possibly
//! different type `U`:
@ -578,6 +598,10 @@ impl<T, E> Result<T, E> {
///
/// let x: Result<u32, &str> = Err("hey");
/// assert_eq!(x.is_ok_and(|x| x > 1), false);
///
/// let x: Result<String, &str> = Ok("ownership".to_string());
/// assert_eq!(x.as_ref().is_ok_and(|x| x.len() > 1), true);
/// println!("still alive {:?}", x);
/// ```
#[must_use]
#[inline]
@ -623,6 +647,10 @@ impl<T, E> Result<T, E> {
///
/// let x: Result<u32, Error> = Ok(123);
/// assert_eq!(x.is_err_and(|x| x.kind() == ErrorKind::NotFound), false);
///
/// let x: Result<u32, String> = Err("ownership".to_string());
/// assert_eq!(x.as_ref().is_err_and(|x| x.len() > 1), true);
/// println!("still alive {:?}", x);
/// ```
#[must_use]
#[inline]

View file

@ -163,4 +163,10 @@ check-cfg = [
# and to the `backtrace` crate which messes-up with Cargo list
# of declared features, we therefor expect any feature cfg
'cfg(feature, values(any()))',
# Internal features aren't marked known config by default, we use these to
# gate tests.
'cfg(target_has_reliable_f16)',
'cfg(target_has_reliable_f16_math)',
'cfg(target_has_reliable_f128)',
'cfg(target_has_reliable_f128_math)',
]

View file

@ -7,12 +7,6 @@ fn main() {
let target_vendor =
env::var("CARGO_CFG_TARGET_VENDOR").expect("CARGO_CFG_TARGET_VENDOR was not set");
let target_env = env::var("CARGO_CFG_TARGET_ENV").expect("CARGO_CFG_TARGET_ENV was not set");
let target_abi = env::var("CARGO_CFG_TARGET_ABI").expect("CARGO_CFG_TARGET_ABI was not set");
let target_pointer_width: u32 = env::var("CARGO_CFG_TARGET_POINTER_WIDTH")
.expect("CARGO_CFG_TARGET_POINTER_WIDTH was not set")
.parse()
.unwrap();
let is_miri = env::var_os("CARGO_CFG_MIRI").is_some();
println!("cargo:rustc-check-cfg=cfg(netbsd10)");
if target_os == "netbsd" && env::var("RUSTC_STD_NETBSD10").is_ok() {
@ -80,108 +74,4 @@ fn main() {
println!("cargo:rustc-cfg=backtrace_in_libstd");
println!("cargo:rustc-env=STD_ENV_ARCH={}", env::var("CARGO_CFG_TARGET_ARCH").unwrap());
// Emit these on platforms that have no known ABI bugs, LLVM selection bugs, lowering bugs,
// missing symbols, or other problems, to determine when tests get run.
// If more broken platforms are found, please update the tracking issue at
// <https://github.com/rust-lang/rust/issues/116909>
//
// Some of these match arms are redundant; the goal is to separate reasons that the type is
// unreliable, even when multiple reasons might fail the same platform.
println!("cargo:rustc-check-cfg=cfg(reliable_f16)");
println!("cargo:rustc-check-cfg=cfg(reliable_f128)");
// This is a step beyond only having the types and basic functions available. Math functions
// aren't consistently available or correct.
println!("cargo:rustc-check-cfg=cfg(reliable_f16_math)");
println!("cargo:rustc-check-cfg=cfg(reliable_f128_math)");
let has_reliable_f16 = match (target_arch.as_str(), target_os.as_str()) {
// We can always enable these in Miri as that is not affected by codegen bugs.
_ if is_miri => true,
// Selection failure <https://github.com/llvm/llvm-project/issues/50374>
("s390x", _) => false,
// Unsupported <https://github.com/llvm/llvm-project/issues/94434>
("arm64ec", _) => false,
// MinGW ABI bugs <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115054>
("x86_64", "windows") if target_env == "gnu" && target_abi != "llvm" => false,
// Infinite recursion <https://github.com/llvm/llvm-project/issues/97981>
("csky", _) => false,
("hexagon", _) => false,
("powerpc" | "powerpc64", _) => false,
("sparc" | "sparc64", _) => false,
("wasm32" | "wasm64", _) => false,
// `f16` support only requires that symbols converting to and from `f32` are available. We
// provide these in `compiler-builtins`, so `f16` should be available on all platforms that
// do not have other ABI issues or LLVM crashes.
_ => true,
};
let has_reliable_f128 = match (target_arch.as_str(), target_os.as_str()) {
// We can always enable these in Miri as that is not affected by codegen bugs.
_ if is_miri => true,
// Unsupported <https://github.com/llvm/llvm-project/issues/94434>
("arm64ec", _) => false,
// Selection bug <https://github.com/llvm/llvm-project/issues/96432>
("mips64" | "mips64r6", _) => false,
// Selection bug <https://github.com/llvm/llvm-project/issues/95471>
("nvptx64", _) => false,
// ABI bugs <https://github.com/rust-lang/rust/issues/125109> et al. (full
// list at <https://github.com/rust-lang/rust/issues/116909>)
("powerpc" | "powerpc64", _) => false,
// ABI unsupported <https://github.com/llvm/llvm-project/issues/41838>
("sparc", _) => false,
// Stack alignment bug <https://github.com/llvm/llvm-project/issues/77401>. NB: tests may
// not fail if our compiler-builtins is linked.
("x86", _) => false,
// MinGW ABI bugs <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115054>
("x86_64", "windows") if target_env == "gnu" && target_abi != "llvm" => false,
// There are no known problems on other platforms, so the only requirement is that symbols
// are available. `compiler-builtins` provides all symbols required for core `f128`
// support, so this should work for everything else.
_ => true,
};
// Configure platforms that have reliable basics but may have unreliable math.
// LLVM is currently adding missing routines, <https://github.com/llvm/llvm-project/issues/93566>
let has_reliable_f16_math = has_reliable_f16
&& match (target_arch.as_str(), target_os.as_str()) {
// FIXME: Disabled on Miri as the intrinsics are not implemented yet.
_ if is_miri => false,
// x86 has a crash for `powi`: <https://github.com/llvm/llvm-project/issues/105747>
("x86" | "x86_64", _) => false,
// Assume that working `f16` means working `f16` math for most platforms, since
// operations just go through `f32`.
_ => true,
};
let has_reliable_f128_math = has_reliable_f128
&& match (target_arch.as_str(), target_os.as_str()) {
// FIXME: Disabled on Miri as the intrinsics are not implemented yet.
_ if is_miri => false,
// LLVM lowers `fp128` math to `long double` symbols even on platforms where
// `long double` is not IEEE binary128. See
// <https://github.com/llvm/llvm-project/issues/44744>.
//
// This rules out anything that doesn't have `long double` = `binary128`; <= 32 bits
// (ld is `f64`), anything other than Linux (Windows and MacOS use `f64`), and `x86`
// (ld is 80-bit extended precision).
("x86_64", _) => false,
(_, "linux") if target_pointer_width == 64 => true,
_ => false,
};
if has_reliable_f16 {
println!("cargo:rustc-cfg=reliable_f16");
}
if has_reliable_f128 {
println!("cargo:rustc-cfg=reliable_f128");
}
if has_reliable_f16_math {
println!("cargo:rustc-cfg=reliable_f16_math");
}
if has_reliable_f128_math {
println!("cargo:rustc-cfg=reliable_f128_math");
}
}

View file

@ -13,7 +13,7 @@
use crate::error::Error;
use crate::ffi::{OsStr, OsString};
use crate::path::{Path, PathBuf};
use crate::sys::os as os_imp;
use crate::sys::{env as env_imp, os as os_imp};
use crate::{fmt, io, sys};
/// Returns the current working directory as a [`PathBuf`].
@ -96,7 +96,7 @@ pub struct Vars {
/// [`env::vars_os()`]: vars_os
#[stable(feature = "env", since = "1.0.0")]
pub struct VarsOs {
inner: os_imp::Env,
inner: env_imp::Env,
}
/// Returns an iterator of (variable, value) pairs of strings, for all the
@ -150,7 +150,7 @@ pub fn vars() -> Vars {
#[must_use]
#[stable(feature = "env", since = "1.0.0")]
pub fn vars_os() -> VarsOs {
VarsOs { inner: os_imp::env() }
VarsOs { inner: env_imp::env() }
}
#[stable(feature = "env", since = "1.0.0")]
@ -259,7 +259,7 @@ pub fn var_os<K: AsRef<OsStr>>(key: K) -> Option<OsString> {
}
fn _var_os(key: &OsStr) -> Option<OsString> {
os_imp::getenv(key)
env_imp::getenv(key)
}
/// The error type for operations interacting with environment variables.
@ -363,7 +363,7 @@ impl Error for VarError {
#[stable(feature = "env", since = "1.0.0")]
pub unsafe fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(key: K, value: V) {
let (key, value) = (key.as_ref(), value.as_ref());
unsafe { os_imp::setenv(key, value) }.unwrap_or_else(|e| {
unsafe { env_imp::setenv(key, value) }.unwrap_or_else(|e| {
panic!("failed to set environment variable `{key:?}` to `{value:?}`: {e}")
})
}
@ -434,7 +434,7 @@ pub unsafe fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(key: K, value: V) {
#[stable(feature = "env", since = "1.0.0")]
pub unsafe fn remove_var<K: AsRef<OsStr>>(key: K) {
let key = key.as_ref();
unsafe { os_imp::unsetenv(key) }
unsafe { env_imp::unsetenv(key) }
.unwrap_or_else(|e| panic!("failed to remove environment variable `{key:?}`: {e}"))
}

View file

@ -22,7 +22,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let f = 3.7_f128;
/// let g = 3.0_f128;
@ -49,7 +53,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let f = 3.01_f128;
/// let g = 4.0_f128;
@ -76,7 +84,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let f = 3.3_f128;
/// let g = -3.3_f128;
@ -108,7 +120,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let f = 3.3_f128;
/// let g = -3.3_f128;
@ -138,7 +154,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let f = 3.7_f128;
/// let g = 3.0_f128;
@ -166,7 +186,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let x = 3.6_f128;
/// let y = -3.6_f128;
@ -203,7 +227,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let m = 10.0_f128;
/// let x = 4.0_f128;
@ -247,7 +275,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let a: f128 = 7.0;
/// let b = 4.0;
@ -289,7 +321,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let a: f128 = 7.0;
/// let b = 4.0;
@ -326,7 +362,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let x = 2.0_f128;
/// let abs_difference = (x.powi(2) - (x * x)).abs();
@ -354,7 +394,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let x = 2.0_f128;
/// let abs_difference = (x.powf(2.0) - (x * x)).abs();
@ -386,7 +430,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let positive = 4.0_f128;
/// let negative = -4.0_f128;
@ -417,7 +465,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let one = 1.0f128;
/// // e^1
@ -448,7 +500,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let f = 2.0f128;
///
@ -479,7 +535,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let one = 1.0f128;
/// // e^1
@ -495,7 +555,11 @@ impl f128 {
/// Non-positive values:
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// assert_eq!(0_f128.ln(), f128::NEG_INFINITY);
/// assert!((-42_f128).ln().is_nan());
@ -526,7 +590,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let five = 5.0f128;
///
@ -540,7 +608,11 @@ impl f128 {
/// Non-positive values:
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// assert_eq!(0_f128.log(10.0), f128::NEG_INFINITY);
/// assert!((-42_f128).log(10.0).is_nan());
@ -567,7 +639,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let two = 2.0f128;
///
@ -581,7 +657,11 @@ impl f128 {
/// Non-positive values:
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// assert_eq!(0_f128.log2(), f128::NEG_INFINITY);
/// assert!((-42_f128).log2().is_nan());
@ -608,7 +688,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let ten = 10.0f128;
///
@ -622,7 +706,11 @@ impl f128 {
/// Non-positive values:
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// assert_eq!(0_f128.log10(), f128::NEG_INFINITY);
/// assert!((-42_f128).log10().is_nan());
@ -651,7 +739,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let x = 8.0f128;
///
@ -687,7 +779,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let x = 2.0f128;
/// let y = 3.0f128;
@ -717,7 +813,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let x = std::f128::consts::FRAC_PI_2;
///
@ -745,7 +845,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let x = 2.0 * std::f128::consts::PI;
///
@ -776,7 +880,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let x = std::f128::consts::FRAC_PI_4;
/// let abs_difference = (x.tan() - 1.0).abs();
@ -808,7 +916,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let f = std::f128::consts::FRAC_PI_2;
///
@ -843,7 +955,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let f = std::f128::consts::FRAC_PI_4;
///
@ -877,7 +993,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let f = 1.0f128;
///
@ -915,7 +1035,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// // Positive angles measured counter-clockwise
/// // from positive x axis
@ -957,7 +1081,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let x = std::f128::consts::FRAC_PI_4;
/// let f = x.sin_cos();
@ -992,7 +1120,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let x = 1e-8_f128;
///
@ -1028,7 +1160,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let x = 1e-8_f128;
///
@ -1043,7 +1179,11 @@ impl f128 {
/// Out-of-range values:
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// assert_eq!((-1.0_f128).ln_1p(), f128::NEG_INFINITY);
/// assert!((-2.0_f128).ln_1p().is_nan());
@ -1072,7 +1212,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let e = std::f128::consts::E;
/// let x = 1.0f128;
@ -1107,7 +1251,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let e = std::f128::consts::E;
/// let x = 1.0f128;
@ -1142,7 +1290,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let e = std::f128::consts::E;
/// let x = 1.0f128;
@ -1174,7 +1326,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let x = 1.0f128;
/// let f = x.sinh().asinh();
@ -1206,7 +1362,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let x = 1.0f128;
/// let f = x.cosh().acosh();
@ -1240,7 +1400,11 @@ impl f128 {
///
/// ```
/// #![feature(f128)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let e = std::f128::consts::E;
/// let f = e.tanh().atanh();
@ -1274,7 +1438,11 @@ impl f128 {
/// ```
/// #![feature(f128)]
/// #![feature(float_gamma)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let x = 5.0f128;
///
@ -1309,7 +1477,11 @@ impl f128 {
/// ```
/// #![feature(f128)]
/// #![feature(float_gamma)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
///
/// let x = 2.0f128;
///
@ -1344,7 +1516,11 @@ impl f128 {
/// ```
/// #![feature(f128)]
/// #![feature(float_erf)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
/// /// The error function relates what percent of a normal distribution lies
/// /// within `x` standard deviations (scaled by `1/sqrt(2)`).
/// fn within_standard_deviations(x: f128) -> f128 {
@ -1383,7 +1559,11 @@ impl f128 {
/// ```
/// #![feature(f128)]
/// #![feature(float_erf)]
/// # #[cfg(reliable_f128_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f128_math)] {
/// let x: f128 = 0.123;
///
/// let one = x.erf() + x.erfc();

View file

@ -22,7 +22,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let f = 3.7_f16;
/// let g = 3.0_f16;
@ -49,7 +53,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let f = 3.01_f16;
/// let g = 4.0_f16;
@ -76,7 +84,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let f = 3.3_f16;
/// let g = -3.3_f16;
@ -108,7 +120,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let f = 3.3_f16;
/// let g = -3.3_f16;
@ -138,7 +154,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let f = 3.7_f16;
/// let g = 3.0_f16;
@ -166,7 +186,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let x = 3.6_f16;
/// let y = -3.6_f16;
@ -203,7 +227,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let m = 10.0_f16;
/// let x = 4.0_f16;
@ -247,7 +275,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let a: f16 = 7.0;
/// let b = 4.0;
@ -289,7 +321,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let a: f16 = 7.0;
/// let b = 4.0;
@ -326,7 +362,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let x = 2.0_f16;
/// let abs_difference = (x.powi(2) - (x * x)).abs();
@ -354,7 +394,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let x = 2.0_f16;
/// let abs_difference = (x.powf(2.0) - (x * x)).abs();
@ -386,7 +430,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let positive = 4.0_f16;
/// let negative = -4.0_f16;
@ -417,7 +465,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let one = 1.0f16;
/// // e^1
@ -448,7 +500,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let f = 2.0f16;
///
@ -479,7 +535,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let one = 1.0f16;
/// // e^1
@ -495,7 +555,11 @@ impl f16 {
/// Non-positive values:
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// assert_eq!(0_f16.ln(), f16::NEG_INFINITY);
/// assert!((-42_f16).ln().is_nan());
@ -526,7 +590,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let five = 5.0f16;
///
@ -540,7 +608,11 @@ impl f16 {
/// Non-positive values:
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// assert_eq!(0_f16.log(10.0), f16::NEG_INFINITY);
/// assert!((-42_f16).log(10.0).is_nan());
@ -567,7 +639,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let two = 2.0f16;
///
@ -581,7 +657,11 @@ impl f16 {
/// Non-positive values:
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// assert_eq!(0_f16.log2(), f16::NEG_INFINITY);
/// assert!((-42_f16).log2().is_nan());
@ -608,7 +688,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let ten = 10.0f16;
///
@ -622,7 +706,11 @@ impl f16 {
/// Non-positive values:
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// assert_eq!(0_f16.log10(), f16::NEG_INFINITY);
/// assert!((-42_f16).log10().is_nan());
@ -650,7 +738,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let x = 8.0f16;
///
@ -685,7 +777,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let x = 2.0f16;
/// let y = 3.0f16;
@ -715,7 +811,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let x = std::f16::consts::FRAC_PI_2;
///
@ -743,7 +843,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let x = 2.0 * std::f16::consts::PI;
///
@ -774,7 +878,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let x = std::f16::consts::FRAC_PI_4;
/// let abs_difference = (x.tan() - 1.0).abs();
@ -806,7 +914,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let f = std::f16::consts::FRAC_PI_2;
///
@ -841,7 +953,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let f = std::f16::consts::FRAC_PI_4;
///
@ -875,7 +991,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let f = 1.0f16;
///
@ -913,7 +1033,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// // Positive angles measured counter-clockwise
/// // from positive x axis
@ -955,7 +1079,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let x = std::f16::consts::FRAC_PI_4;
/// let f = x.sin_cos();
@ -990,7 +1118,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let x = 1e-4_f16;
///
@ -1026,7 +1158,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let x = 1e-4_f16;
///
@ -1041,7 +1177,11 @@ impl f16 {
/// Out-of-range values:
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// assert_eq!((-1.0_f16).ln_1p(), f16::NEG_INFINITY);
/// assert!((-2.0_f16).ln_1p().is_nan());
@ -1070,7 +1210,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let e = std::f16::consts::E;
/// let x = 1.0f16;
@ -1105,7 +1249,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let e = std::f16::consts::E;
/// let x = 1.0f16;
@ -1140,7 +1288,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let e = std::f16::consts::E;
/// let x = 1.0f16;
@ -1172,7 +1324,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let x = 1.0f16;
/// let f = x.sinh().asinh();
@ -1204,7 +1360,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let x = 1.0f16;
/// let f = x.cosh().acosh();
@ -1238,7 +1398,11 @@ impl f16 {
///
/// ```
/// #![feature(f16)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let e = std::f16::consts::E;
/// let f = e.tanh().atanh();
@ -1272,7 +1436,11 @@ impl f16 {
/// ```
/// #![feature(f16)]
/// #![feature(float_gamma)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let x = 5.0f16;
///
@ -1307,7 +1475,11 @@ impl f16 {
/// ```
/// #![feature(f16)]
/// #![feature(float_gamma)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
///
/// let x = 2.0f16;
///
@ -1342,7 +1514,11 @@ impl f16 {
/// ```
/// #![feature(f16)]
/// #![feature(float_erf)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
/// /// The error function relates what percent of a normal distribution lies
/// /// within `x` standard deviations (scaled by `1/sqrt(2)`).
/// fn within_standard_deviations(x: f16) -> f16 {
@ -1381,7 +1557,11 @@ impl f16 {
/// ```
/// #![feature(f16)]
/// #![feature(float_erf)]
/// # #[cfg(reliable_f16_math)] {
/// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))]
/// # #![cfg_attr(not(bootstrap), expect(internal_features))]
/// # #[cfg(not(miri))]
/// # #[cfg(not(bootstrap))]
/// # #[cfg(target_has_reliable_f16_math)] {
/// let x: f16 = 0.123;
///
/// let one = x.erf() + x.erfc();

View file

@ -119,7 +119,7 @@ mod break_keyword {}
#[doc(keyword = "const")]
//
/// Compile-time constants, compile-time evaluable functions, and raw pointers.
/// Compile-time constants, compile-time blocks, compile-time evaluable functions, and raw pointers.
///
/// ## Compile-time constants
///
@ -166,6 +166,12 @@ mod break_keyword {}
///
/// For more detail on `const`, see the [Rust Book] or the [Reference].
///
/// ## Compile-time blocks
///
/// The `const` keyword can also be used to define a block of code that is evaluated at compile time.
/// This is useful for ensuring certain computations are completed before optimizations happen, as well as
/// before runtime. For more details, see the [Reference][const-blocks].
///
/// ## Compile-time evaluable functions
///
/// The other main use of the `const` keyword is in `const fn`. This marks a function as being
@ -184,6 +190,7 @@ mod break_keyword {}
/// [pointer primitive]: pointer
/// [Rust Book]: ../book/ch03-01-variables-and-mutability.html#constants
/// [Reference]: ../reference/items/constant-items.html
/// [const-blocks]: ../reference/expressions/block-expr.html#const-blocks
/// [const-eval]: ../reference/const_eval.html
mod const_keyword {}

View file

@ -709,6 +709,7 @@ pub use core::primitive;
// Re-export built-in macros defined through core.
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow(deprecated)]
#[cfg_attr(bootstrap, allow(deprecated_in_future))]
pub use core::{
assert, assert_matches, cfg, column, compile_error, concat, concat_idents, const_format_args,
env, file, format_args, format_args_nl, include, include_bytes, include_str, line, log_syntax,

View file

@ -46,6 +46,7 @@ pub use crate::result::Result::{self, Err, Ok};
// Re-exported built-in macros
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow(deprecated)]
#[cfg_attr(bootstrap, allow(deprecated_in_future))]
#[doc(no_inline)]
pub use core::prelude::v1::{
assert, cfg, column, compile_error, concat, concat_idents, env, file, format_args,

View file

@ -2,6 +2,16 @@
#![forbid(unsafe_op_in_unsafe_fn)]
#[cfg(any(
all(target_family = "unix", not(any(target_os = "espidf", target_os = "vita"))),
target_family = "windows",
target_os = "hermit",
target_os = "uefi",
target_os = "wasi",
target_os = "xous",
))]
mod common;
cfg_if::cfg_if! {
if #[cfg(any(
all(target_family = "unix", not(any(target_os = "espidf", target_os = "vita"))),

View file

@ -1,14 +1,11 @@
use r_efi::protocols::loaded_image;
pub use super::common::Args;
use crate::env::current_exe;
use crate::ffi::OsString;
use crate::iter::Iterator;
use crate::sys::pal::helpers;
#[path = "common.rs"]
mod common;
pub use common::Args;
pub fn args() -> Args {
let lazy_current_exe = || Vec::from([current_exe().map(Into::into).unwrap_or_default()]);

View file

@ -5,16 +5,13 @@
#![allow(dead_code)] // runtime init functions not used during testing
pub use super::common::Args;
use crate::ffi::CStr;
#[cfg(target_os = "hermit")]
use crate::os::hermit::ffi::OsStringExt;
#[cfg(not(target_os = "hermit"))]
use crate::os::unix::ffi::OsStringExt;
#[path = "common.rs"]
mod common;
pub use common::Args;
/// One-time global initialization.
pub unsafe fn init(argc: isize, argv: *const *const u8) {
unsafe { imp::init(argc, argv) }

View file

@ -1,12 +1,9 @@
#![forbid(unsafe_op_in_unsafe_fn)]
pub use super::common::Args;
use crate::ffi::{CStr, OsStr, OsString};
use crate::os::wasi::ffi::OsStrExt;
#[path = "common.rs"]
mod common;
pub use common::Args;
/// Returns the command line arguments
pub fn args() -> Args {
Args::new(maybe_args().unwrap_or(Vec::new()))

View file

@ -6,6 +6,7 @@
#[cfg(test)]
mod tests;
pub use super::common::Args;
use crate::ffi::{OsStr, OsString};
use crate::num::NonZero;
use crate::os::windows::prelude::*;
@ -18,10 +19,6 @@ use crate::sys_common::AsInner;
use crate::sys_common::wstr::WStrUnits;
use crate::{io, iter, ptr};
#[path = "common.rs"]
mod common;
pub use common::Args;
pub fn args() -> Args {
// SAFETY: `GetCommandLineW` returns a pointer to a null terminated UTF-16
// string so it's safe for `WStrUnits` to use.

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