Auto merge of #137497 - tgross35:rollup-1oeclrr, r=tgross35

Rollup of 8 pull requests

Successful merges:

 - #136439 (Misc. `rustc_codegen_ssa` cleanups 🧹)
 - #136543 (intrinsics: unify rint, roundeven, nearbyint in a single round_ties_even intrinsic)
 - #136637 (Add binary_format to rustc target specs)
 - #137099 (Fix rustdoc test directives that were accidentally ignored 🧐)
 - #137297 (Update `compiler-builtins` to 0.1.147)
 - #137451 (FIx `sym` -> `syn` typo in tail-expr-drop-order type opt-out)
 - #137452 (bootstrap: add module docs for core:metadata)
 - #137483 (rename sub_ptr to offset_from_unsigned)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-02-23 23:49:11 +00:00
commit 9af8985e05
56 changed files with 406 additions and 441 deletions

View file

@ -16,8 +16,8 @@ index 7165c3e48af..968552ad435 100644
[dependencies]
core = { path = "../core", public = true }
-compiler_builtins = { version = "=0.1.146", features = ['rustc-dep-of-std'] }
+compiler_builtins = { version = "=0.1.146", features = ['rustc-dep-of-std', 'no-f16-f128'] }
-compiler_builtins = { version = "=0.1.147", features = ['rustc-dep-of-std'] }
+compiler_builtins = { version = "=0.1.147", features = ['rustc-dep-of-std', 'no-f16-f128'] }
[dev-dependencies]
rand = { version = "0.8.5", default-features = false, features = ["alloc"] }

View file

@ -340,14 +340,10 @@ fn codegen_float_intrinsic_call<'tcx>(
sym::ceilf64 => ("ceil", 1, fx.tcx.types.f64, types::F64),
sym::truncf32 => ("truncf", 1, fx.tcx.types.f32, types::F32),
sym::truncf64 => ("trunc", 1, fx.tcx.types.f64, types::F64),
sym::rintf32 => ("rintf", 1, fx.tcx.types.f32, types::F32),
sym::rintf64 => ("rint", 1, fx.tcx.types.f64, types::F64),
sym::round_ties_even_f32 => ("rintf", 1, fx.tcx.types.f32, types::F32),
sym::round_ties_even_f64 => ("rint", 1, fx.tcx.types.f64, types::F64),
sym::roundf32 => ("roundf", 1, fx.tcx.types.f32, types::F32),
sym::roundf64 => ("round", 1, fx.tcx.types.f64, types::F64),
sym::roundevenf32 => ("roundevenf", 1, fx.tcx.types.f32, types::F32),
sym::roundevenf64 => ("roundeven", 1, fx.tcx.types.f64, types::F64),
sym::nearbyintf32 => ("nearbyintf", 1, fx.tcx.types.f32, types::F32),
sym::nearbyintf64 => ("nearbyint", 1, fx.tcx.types.f64, types::F64),
sym::sinf32 => ("sinf", 1, fx.tcx.types.f32, types::F32),
sym::sinf64 => ("sin", 1, fx.tcx.types.f64, types::F64),
sym::cosf32 => ("cosf", 1, fx.tcx.types.f32, types::F32),
@ -399,8 +395,8 @@ fn codegen_float_intrinsic_call<'tcx>(
| sym::ceilf64
| sym::truncf32
| sym::truncf64
| sym::nearbyintf32
| sym::nearbyintf64
| sym::round_ties_even_f32
| sym::round_ties_even_f64
| sym::sqrtf32
| sym::sqrtf64 => {
let val = match intrinsic {
@ -408,7 +404,9 @@ fn codegen_float_intrinsic_call<'tcx>(
sym::floorf32 | sym::floorf64 => fx.bcx.ins().floor(args[0]),
sym::ceilf32 | sym::ceilf64 => fx.bcx.ins().ceil(args[0]),
sym::truncf32 | sym::truncf64 => fx.bcx.ins().trunc(args[0]),
sym::nearbyintf32 | sym::nearbyintf64 => fx.bcx.ins().nearest(args[0]),
sym::round_ties_even_f32 | sym::round_ties_even_f64 => {
fx.bcx.ins().nearest(args[0])
}
sym::sqrtf32 | sym::sqrtf64 => fx.bcx.ins().sqrt(args[0]),
_ => unreachable!(),
};

View file

@ -84,14 +84,11 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
sym::ceilf64 => "ceil",
sym::truncf32 => "truncf",
sym::truncf64 => "trunc",
sym::rintf32 => "rintf",
sym::rintf64 => "rint",
sym::nearbyintf32 => "nearbyintf",
sym::nearbyintf64 => "nearbyint",
// We match the LLVM backend and lower this to `rint`.
sym::round_ties_even_f32 => "rintf",
sym::round_ties_even_f64 => "rint",
sym::roundf32 => "roundf",
sym::roundf64 => "round",
sym::roundevenf32 => "roundevenf",
sym::roundevenf64 => "roundeven",
sym::abort => "abort",
_ => return None,
};

View file

@ -127,15 +127,14 @@ fn get_simple_intrinsic<'ll>(
sym::truncf64 => "llvm.trunc.f64",
sym::truncf128 => "llvm.trunc.f128",
sym::rintf16 => "llvm.rint.f16",
sym::rintf32 => "llvm.rint.f32",
sym::rintf64 => "llvm.rint.f64",
sym::rintf128 => "llvm.rint.f128",
sym::nearbyintf16 => "llvm.nearbyint.f16",
sym::nearbyintf32 => "llvm.nearbyint.f32",
sym::nearbyintf64 => "llvm.nearbyint.f64",
sym::nearbyintf128 => "llvm.nearbyint.f128",
// We could use any of `rint`, `nearbyint`, or `roundeven`
// for this -- they are all identical in semantics when
// assuming the default FP environment.
// `rint` is what we used for $forever.
sym::round_ties_even_f16 => "llvm.rint.f16",
sym::round_ties_even_f32 => "llvm.rint.f32",
sym::round_ties_even_f64 => "llvm.rint.f64",
sym::round_ties_even_f128 => "llvm.rint.f128",
sym::roundf16 => "llvm.round.f16",
sym::roundf32 => "llvm.round.f32",
@ -144,11 +143,6 @@ fn get_simple_intrinsic<'ll>(
sym::ptr_mask => "llvm.ptrmask",
sym::roundevenf16 => "llvm.roundeven.f16",
sym::roundevenf32 => "llvm.roundeven.f32",
sym::roundevenf64 => "llvm.roundeven.f64",
sym::roundevenf128 => "llvm.roundeven.f128",
_ => return None,
};
Some(cx.get_intrinsic(llvm_name))

View file

@ -244,22 +244,17 @@ pub fn each_linked_rlib(
fmts
} else {
for combination in info.dependency_formats.iter().combinations(2) {
let (ty1, list1) = &combination[0];
let (ty2, list2) = &combination[1];
if list1 != list2 {
return Err(errors::LinkRlibError::IncompatibleDependencyFormats {
ty1: format!("{ty1:?}"),
ty2: format!("{ty2:?}"),
list1: format!("{list1:?}"),
list2: format!("{list2:?}"),
});
}
let mut dep_formats = info.dependency_formats.iter();
let (ty1, list1) = dep_formats.next().ok_or(errors::LinkRlibError::MissingFormat)?;
if let Some((ty2, list2)) = dep_formats.find(|(_, list2)| list1 != *list2) {
return Err(errors::LinkRlibError::IncompatibleDependencyFormats {
ty1: format!("{ty1:?}"),
ty2: format!("{ty2:?}"),
list1: format!("{list1:?}"),
list2: format!("{list2:?}"),
});
}
if info.dependency_formats.is_empty() {
return Err(errors::LinkRlibError::MissingFormat);
}
info.dependency_formats.first().unwrap().1
list1
};
let used_dep_crates = info.used_crates.iter();
@ -626,10 +621,9 @@ fn link_staticlib(
let mut all_rust_dylibs = vec![];
for &cnum in crates {
match fmts.get(cnum) {
Some(&Linkage::Dynamic) => {}
_ => continue,
}
let Some(Linkage::Dynamic) = fmts.get(cnum) else {
continue;
};
let crate_name = codegen_results.crate_info.crate_name[&cnum];
let used_crate_source = &codegen_results.crate_info.used_crate_source[&cnum];
if let Some((path, _)) = &used_crate_source.dylib {

View file

@ -252,15 +252,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
// Unsupported architecture.
_ => return None,
};
let binary_format = if sess.target.is_like_osx {
BinaryFormat::MachO
} else if sess.target.is_like_windows {
BinaryFormat::Coff
} else if sess.target.is_like_aix {
BinaryFormat::Xcoff
} else {
BinaryFormat::Elf
};
let binary_format = sess.target.binary_format.to_object();
let mut file = write::Object::new(binary_format, architecture, endianness);
file.set_sub_architecture(sub_architecture);

View file

@ -573,10 +573,10 @@ fn produce_final_output_artifacts(
};
let copy_if_one_unit = |output_type: OutputType, keep_numbered: bool| {
if compiled_modules.modules.len() == 1 {
if let [module] = &compiled_modules.modules[..] {
// 1) Only one codegen unit. In this case it's no difficulty
// to copy `foo.0.x` to `foo.x`.
let module_name = Some(&compiled_modules.modules[0].name[..]);
let module_name = Some(&module.name[..]);
let path = crate_output.temp_path(output_type, module_name);
let output = crate_output.path(output_type);
if !output_type.is_text_output() && output.is_tty() {
@ -708,8 +708,8 @@ fn produce_final_output_artifacts(
}
if sess.opts.json_artifact_notifications {
if compiled_modules.modules.len() == 1 {
compiled_modules.modules[0].for_each_output(|_path, ty| {
if let [module] = &compiled_modules.modules[..] {
module.for_each_output(|_path, ty| {
if sess.opts.output_types.contains_key(&ty) {
let descr = ty.shorthand();
// for single cgu file is renamed to drop cgu specific suffix
@ -865,7 +865,7 @@ pub(crate) fn compute_per_cgu_lto_type(
// require LTO so the request for LTO is always unconditionally
// passed down to the backend, but we don't actually want to do
// anything about it yet until we've got a final product.
let is_rlib = sess_crate_types.len() == 1 && sess_crate_types[0] == CrateType::Rlib;
let is_rlib = matches!(sess_crate_types, [CrateType::Rlib]);
match sess_lto {
Lto::ThinLocal if !linker_does_lto && !is_allocator => ComputedLtoType::Thin,
@ -1538,8 +1538,9 @@ fn start_executing_work<B: ExtraBackendMethods>(
// Spin up what work we can, only doing this while we've got available
// parallelism slots and work left to spawn.
if codegen_state != Aborted {
while !work_items.is_empty() && running_with_own_token < tokens.len() {
let (item, _) = work_items.pop().unwrap();
while running_with_own_token < tokens.len()
&& let Some((item, _)) = work_items.pop()
{
spawn_work(
&cgcx,
&mut llvm_start_time,

View file

@ -1,7 +1,6 @@
use std::str::FromStr;
use rustc_abi::ExternAbi;
use rustc_ast::attr::list_contains_name;
use rustc_ast::expand::autodiff_attrs::{
AutoDiffAttrs, DiffActivity, DiffMode, valid_input_activity, valid_ret_activity,
};
@ -377,24 +376,20 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
let segments =
set.path.segments.iter().map(|x| x.ident.name).collect::<Vec<_>>();
match segments.as_slice() {
[sym::arm, sym::a32] | [sym::arm, sym::t32] => {
if !tcx.sess.target.has_thumb_interworking {
struct_span_code_err!(
tcx.dcx(),
attr.span,
E0779,
"target does not support `#[instruction_set]`"
)
.emit();
None
} else if segments[1] == sym::a32 {
Some(InstructionSetAttr::ArmA32)
} else if segments[1] == sym::t32 {
Some(InstructionSetAttr::ArmT32)
} else {
unreachable!()
}
[sym::arm, sym::a32 | sym::t32]
if !tcx.sess.target.has_thumb_interworking =>
{
struct_span_code_err!(
tcx.dcx(),
attr.span,
E0779,
"target does not support `#[instruction_set]`"
)
.emit();
None
}
[sym::arm, sym::a32] => Some(InstructionSetAttr::ArmA32),
[sym::arm, sym::t32] => Some(InstructionSetAttr::ArmT32),
_ => {
struct_span_code_err!(
tcx.dcx(),
@ -435,7 +430,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
&& let Some((sym::align, literal)) = item.singleton_lit_list()
{
rustc_attr_parsing::parse_alignment(&literal.kind)
.map_err(|msg| {
.inspect_err(|msg| {
struct_span_code_err!(
tcx.dcx(),
literal.span,
@ -536,25 +531,27 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
}
if attr.is_word() {
InlineAttr::Hint
} else if let Some(ref items) = attr.meta_item_list() {
inline_span = Some(attr.span);
if items.len() != 1 {
struct_span_code_err!(tcx.dcx(), attr.span, E0534, "expected one argument").emit();
InlineAttr::None
} else if list_contains_name(items, sym::always) {
InlineAttr::Always
} else if list_contains_name(items, sym::never) {
InlineAttr::Never
} else {
struct_span_code_err!(tcx.dcx(), items[0].span(), E0535, "invalid argument")
.with_help("valid inline arguments are `always` and `never`")
.emit();
return InlineAttr::Hint;
}
let Some(ref items) = attr.meta_item_list() else {
return ia;
};
InlineAttr::None
}
inline_span = Some(attr.span);
let [item] = &items[..] else {
struct_span_code_err!(tcx.dcx(), attr.span, E0534, "expected one argument").emit();
return InlineAttr::None;
};
if item.has_name(sym::always) {
InlineAttr::Always
} else if item.has_name(sym::never) {
InlineAttr::Never
} else {
ia
struct_span_code_err!(tcx.dcx(), item.span(), E0535, "invalid argument")
.with_help("valid inline arguments are `always` and `never`")
.emit();
InlineAttr::None
}
});
codegen_fn_attrs.inline = attrs.iter().fold(codegen_fn_attrs.inline, |ia, attr| {
@ -586,23 +583,25 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
let err = |sp, s| struct_span_code_err!(tcx.dcx(), sp, E0722, "{}", s).emit();
if attr.is_word() {
err(attr.span, "expected one argument");
ia
} else if let Some(ref items) = attr.meta_item_list() {
inline_span = Some(attr.span);
if items.len() != 1 {
err(attr.span, "expected one argument");
OptimizeAttr::Default
} else if list_contains_name(items, sym::size) {
OptimizeAttr::Size
} else if list_contains_name(items, sym::speed) {
OptimizeAttr::Speed
} else if list_contains_name(items, sym::none) {
OptimizeAttr::DoNotOptimize
} else {
err(items[0].span(), "invalid argument");
OptimizeAttr::Default
}
return ia;
}
let Some(ref items) = attr.meta_item_list() else {
return OptimizeAttr::Default;
};
inline_span = Some(attr.span);
let [item] = &items[..] else {
err(attr.span, "expected one argument");
return OptimizeAttr::Default;
};
if item.has_name(sym::size) {
OptimizeAttr::Size
} else if item.has_name(sym::speed) {
OptimizeAttr::Speed
} else if item.has_name(sym::none) {
OptimizeAttr::DoNotOptimize
} else {
err(item.span(), "invalid argument");
OptimizeAttr::Default
}
});
@ -644,25 +643,20 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
// llvm/llvm-project#70563).
if !codegen_fn_attrs.target_features.is_empty()
&& matches!(codegen_fn_attrs.inline, InlineAttr::Always)
&& let Some(span) = inline_span
{
if let Some(span) = inline_span {
tcx.dcx().span_err(span, "cannot use `#[inline(always)]` with `#[target_feature]`");
}
tcx.dcx().span_err(span, "cannot use `#[inline(always)]` with `#[target_feature]`");
}
if !codegen_fn_attrs.no_sanitize.is_empty() && codegen_fn_attrs.inline.always() {
if let (Some(no_sanitize_span), Some(inline_span)) = (no_sanitize_span, inline_span) {
let hir_id = tcx.local_def_id_to_hir_id(did);
tcx.node_span_lint(
lint::builtin::INLINE_NO_SANITIZE,
hir_id,
no_sanitize_span,
|lint| {
lint.primary_message("`no_sanitize` will have no effect after inlining");
lint.span_note(inline_span, "inlining requested here");
},
)
}
if !codegen_fn_attrs.no_sanitize.is_empty()
&& codegen_fn_attrs.inline.always()
&& let (Some(no_sanitize_span), Some(inline_span)) = (no_sanitize_span, inline_span)
{
let hir_id = tcx.local_def_id_to_hir_id(did);
tcx.node_span_lint(lint::builtin::INLINE_NO_SANITIZE, hir_id, no_sanitize_span, |lint| {
lint.primary_message("`no_sanitize` will have no effect after inlining");
lint.span_note(inline_span, "inlining requested here");
})
}
// Weak lang items have the same semantics as "std internal" symbols in the
@ -692,10 +686,10 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
// Any linkage to LLVM intrinsics for now forcibly marks them all as never
// unwinds since LLVM sometimes can't handle codegen which `invoke`s
// intrinsic functions.
if let Some(name) = &codegen_fn_attrs.link_name {
if name.as_str().starts_with("llvm.") {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND;
}
if let Some(name) = &codegen_fn_attrs.link_name
&& name.as_str().starts_with("llvm.")
{
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND;
}
if let Some(features) = check_tied_features(
@ -756,18 +750,13 @@ fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &hir::Attribute) -> Option<u16> {
use rustc_ast::{LitIntType, LitKind, MetaItemLit};
let meta_item_list = attr.meta_item_list();
let meta_item_list = meta_item_list.as_deref();
let sole_meta_list = match meta_item_list {
Some([item]) => item.lit(),
Some(_) => {
tcx.dcx().emit_err(errors::InvalidLinkOrdinalNargs { span: attr.span });
return None;
}
_ => None,
let meta_item_list = attr.meta_item_list()?;
let [sole_meta_list] = &meta_item_list[..] else {
tcx.dcx().emit_err(errors::InvalidLinkOrdinalNargs { span: attr.span });
return None;
};
if let Some(MetaItemLit { kind: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }) =
sole_meta_list
sole_meta_list.lit()
{
// According to the table at
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header, the

View file

@ -1003,8 +1003,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let destination = target.map(|target| (return_dest, target));
// Split the rust-call tupled arguments off.
let (first_args, untuple) = if abi == ExternAbi::RustCall && !args.is_empty() {
let (tup, args) = args.split_last().unwrap();
let (first_args, untuple) = if abi == ExternAbi::RustCall
&& let Some((tup, args)) = args.split_last()
{
(args, Some(tup))
} else {
(args, None)

View file

@ -8,7 +8,7 @@ use rustc_middle::ty::{Instance, Ty, TyCtxt};
use rustc_middle::{bug, span_bug, ty};
use rustc_span::sym;
use rustc_target::callconv::{ArgAbi, FnAbi, PassMode};
use rustc_target::spec::WasmCAbi;
use rustc_target::spec::{BinaryFormat, WasmCAbi};
use crate::common;
use crate::traits::{AsmCodegenMethods, BuilderMethods, GlobalAsmOperandRef, MiscCodegenMethods};
@ -104,27 +104,6 @@ fn inline_to_global_operand<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
}
}
enum AsmBinaryFormat {
Elf,
Macho,
Coff,
Wasm,
}
impl AsmBinaryFormat {
fn from_target(target: &rustc_target::spec::Target) -> Self {
if target.is_like_windows {
Self::Coff
} else if target.is_like_osx {
Self::Macho
} else if target.is_like_wasm {
Self::Wasm
} else {
Self::Elf
}
}
}
fn prefix_and_suffix<'tcx>(
tcx: TyCtxt<'tcx>,
instance: Instance<'tcx>,
@ -134,7 +113,7 @@ fn prefix_and_suffix<'tcx>(
) -> (String, String) {
use std::fmt::Write;
let asm_binary_format = AsmBinaryFormat::from_target(&tcx.sess.target);
let asm_binary_format = &tcx.sess.target.binary_format;
let is_arm = tcx.sess.target.arch == "arm";
let is_thumb = tcx.sess.unstable_target_features.contains(&sym::thumb_mode);
@ -178,10 +157,13 @@ fn prefix_and_suffix<'tcx>(
}
Linkage::LinkOnceAny | Linkage::LinkOnceODR | Linkage::WeakAny | Linkage::WeakODR => {
match asm_binary_format {
AsmBinaryFormat::Elf | AsmBinaryFormat::Coff | AsmBinaryFormat::Wasm => {
BinaryFormat::Elf
| BinaryFormat::Coff
| BinaryFormat::Wasm
| BinaryFormat::Xcoff => {
writeln!(w, ".weak {asm_name}")?;
}
AsmBinaryFormat::Macho => {
BinaryFormat::MachO => {
writeln!(w, ".globl {asm_name}")?;
writeln!(w, ".weak_definition {asm_name}")?;
}
@ -207,7 +189,7 @@ fn prefix_and_suffix<'tcx>(
let mut begin = String::new();
let mut end = String::new();
match asm_binary_format {
AsmBinaryFormat::Elf => {
BinaryFormat::Elf | BinaryFormat::Xcoff => {
let section = link_section.unwrap_or(format!(".text.{asm_name}"));
let progbits = match is_arm {
@ -239,7 +221,7 @@ fn prefix_and_suffix<'tcx>(
writeln!(end, "{}", arch_suffix).unwrap();
}
}
AsmBinaryFormat::Macho => {
BinaryFormat::MachO => {
let section = link_section.unwrap_or("__TEXT,__text".to_string());
writeln!(begin, ".pushsection {},regular,pure_instructions", section).unwrap();
writeln!(begin, ".balign {align}").unwrap();
@ -255,7 +237,7 @@ fn prefix_and_suffix<'tcx>(
writeln!(end, "{}", arch_suffix).unwrap();
}
}
AsmBinaryFormat::Coff => {
BinaryFormat::Coff => {
let section = link_section.unwrap_or(format!(".text.{asm_name}"));
writeln!(begin, ".pushsection {},\"xr\"", section).unwrap();
writeln!(begin, ".balign {align}").unwrap();
@ -272,7 +254,7 @@ fn prefix_and_suffix<'tcx>(
writeln!(end, "{}", arch_suffix).unwrap();
}
}
AsmBinaryFormat::Wasm => {
BinaryFormat::Wasm => {
let section = link_section.unwrap_or(format!(".text.{asm_name}"));
writeln!(begin, ".section {section},\"\",@").unwrap();

View file

@ -140,6 +140,10 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
| sym::fmul_algebraic
| sym::fdiv_algebraic
| sym::frem_algebraic
| sym::round_ties_even_f16
| sym::round_ties_even_f32
| sym::round_ties_even_f64
| sym::round_ties_even_f128
| sym::const_eval_select => hir::Safety::Safe,
_ => hir::Safety::Unsafe,
};
@ -416,26 +420,16 @@ pub fn check_intrinsic_type(
sym::truncf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
sym::truncf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
sym::rintf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
sym::rintf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
sym::rintf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
sym::rintf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
sym::nearbyintf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
sym::nearbyintf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
sym::nearbyintf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
sym::nearbyintf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
sym::round_ties_even_f16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
sym::round_ties_even_f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
sym::round_ties_even_f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
sym::round_ties_even_f128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
sym::roundf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
sym::roundf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
sym::roundf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
sym::roundf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
sym::roundevenf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
sym::roundevenf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
sym::roundevenf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
sym::roundevenf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
sym::volatile_load | sym::unaligned_volatile_load => {
(1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0))
}

View file

@ -186,7 +186,7 @@ fn true_significant_drop_ty<'tcx>(
debug!(?name_str);
match name_str[..] {
// These are the types from Rust core ecosystem
["sym" | "proc_macro2", ..]
["syn" | "proc_macro2", ..]
| ["core" | "std", "task", "LocalWaker" | "Waker"]
| ["core" | "std", "task", "wake", "LocalWaker" | "Waker"] => Some(smallvec![]),
// These are important types from Rust ecosystem

View file

@ -280,13 +280,13 @@ impl<'a> MemDecoder<'a> {
#[inline]
pub fn len(&self) -> usize {
// SAFETY: This recovers the length of the original slice, only using members we never modify.
unsafe { self.end.sub_ptr(self.start) }
unsafe { self.end.offset_from_unsigned(self.start) }
}
#[inline]
pub fn remaining(&self) -> usize {
// SAFETY: This type guarantees current <= end.
unsafe { self.end.sub_ptr(self.current) }
unsafe { self.end.offset_from_unsigned(self.current) }
}
#[cold]
@ -400,7 +400,7 @@ impl<'a> Decoder for MemDecoder<'a> {
#[inline]
fn position(&self) -> usize {
// SAFETY: This type guarantees start <= current
unsafe { self.current.sub_ptr(self.start) }
unsafe { self.current.offset_from_unsigned(self.start) }
}
}

View file

@ -1367,10 +1367,6 @@ symbols! {
native_link_modifiers_whole_archive,
natvis_file,
ne,
nearbyintf128,
nearbyintf16,
nearbyintf32,
nearbyintf64,
needs_allocator,
needs_drop,
needs_panic_runtime,
@ -1688,20 +1684,16 @@ symbols! {
return_position_impl_trait_in_trait,
return_type_notation,
rhs,
rintf128,
rintf16,
rintf32,
rintf64,
riscv_target_feature,
rlib,
ropi,
ropi_rwpi: "ropi-rwpi",
rotate_left,
rotate_right,
roundevenf128,
roundevenf16,
roundevenf32,
roundevenf64,
round_ties_even_f128,
round_ties_even_f16,
round_ties_even_f32,
round_ties_even_f64,
roundf128,
roundf16,
roundf32,

View file

@ -1,6 +1,8 @@
use rustc_abi::Endian;
use crate::spec::{Cc, CodeModel, LinkOutputKind, LinkerFlavor, TargetOptions, crt_objects, cvs};
use crate::spec::{
BinaryFormat, Cc, CodeModel, LinkOutputKind, LinkerFlavor, TargetOptions, crt_objects, cvs,
};
pub(crate) fn opts() -> TargetOptions {
TargetOptions {
@ -21,6 +23,7 @@ pub(crate) fn opts() -> TargetOptions {
linker: Some("ld".into()),
eh_frame_header: false,
is_like_aix: true,
binary_format: BinaryFormat::Xcoff,
default_dwarf_version: 3,
function_sections: true,
pre_link_objects: crt_objects::new(&[

View file

@ -2,8 +2,8 @@ use std::borrow::Cow;
use std::env;
use crate::spec::{
Cc, DebuginfoKind, FloatAbi, FramePointer, LinkerFlavor, Lld, RustcAbi, SplitDebuginfo,
StackProbeType, StaticCow, TargetOptions, cvs,
BinaryFormat, Cc, DebuginfoKind, FloatAbi, FramePointer, LinkerFlavor, Lld, RustcAbi,
SplitDebuginfo, StackProbeType, StaticCow, TargetOptions, cvs,
};
#[cfg(test)]
@ -116,6 +116,7 @@ pub(crate) fn base(
dynamic_linking: true,
families: cvs!["unix"],
is_like_osx: true,
binary_format: BinaryFormat::MachO,
// LLVM notes that macOS 10.11+ and iOS 9+ default
// to v4, so we do the same.
// https://github.com/llvm/llvm-project/blob/378778a0d10c2f8d5df8ceff81f95b6002984a4b/clang/lib/Driver/ToolChains/Darwin.cpp#L1203

View file

@ -1,6 +1,8 @@
use std::borrow::Cow;
use crate::spec::{Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions, cvs};
use crate::spec::{
BinaryFormat, Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions, cvs,
};
pub(crate) fn opts() -> TargetOptions {
let mut pre_link_args = TargetOptions::link_args(
@ -32,6 +34,7 @@ pub(crate) fn opts() -> TargetOptions {
exe_suffix: ".exe".into(),
families: cvs!["unix"],
is_like_windows: true,
binary_format: BinaryFormat::Coff,
allows_weak_linkage: false,
pre_link_args,
late_link_args,

View file

@ -1,6 +1,6 @@
use std::borrow::Cow;
use crate::spec::{DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions};
use crate::spec::{BinaryFormat, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions};
pub(crate) fn opts() -> TargetOptions {
// Suppress the verbose logo and authorship debugging output, which would needlessly
@ -12,6 +12,7 @@ pub(crate) fn opts() -> TargetOptions {
dll_tls_export: false,
is_like_windows: true,
is_like_msvc: true,
binary_format: BinaryFormat::Coff,
pre_link_args,
abi_return_struct_as_int: true,
emit_debug_gdb_scripts: false,

View file

@ -1,6 +1,6 @@
use crate::spec::{
Cc, LinkSelfContainedDefault, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel,
add_link_args, cvs,
BinaryFormat, Cc, LinkSelfContainedDefault, LinkerFlavor, PanicStrategy, RelocModel,
TargetOptions, TlsModel, add_link_args, cvs,
};
pub(crate) fn options() -> TargetOptions {
@ -53,6 +53,7 @@ pub(crate) fn options() -> TargetOptions {
TargetOptions {
is_like_wasm: true,
binary_format: BinaryFormat::Wasm,
families: cvs!["wasm"],
// we allow dynamic linking, but only cdylibs. Basically we allow a

View file

@ -1,8 +1,8 @@
use std::borrow::Cow;
use crate::spec::{
Cc, DebuginfoKind, LinkSelfContainedDefault, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions,
add_link_args, crt_objects, cvs,
BinaryFormat, Cc, DebuginfoKind, LinkSelfContainedDefault, LinkerFlavor, Lld, SplitDebuginfo,
TargetOptions, add_link_args, crt_objects, cvs,
};
pub(crate) fn opts() -> TargetOptions {
@ -90,6 +90,7 @@ pub(crate) fn opts() -> TargetOptions {
exe_suffix: ".exe".into(),
families: cvs!["windows"],
is_like_windows: true,
binary_format: BinaryFormat::Coff,
allows_weak_linkage: false,
pre_link_args,
pre_link_objects: crt_objects::pre_mingw(),

View file

@ -1,6 +1,8 @@
use std::borrow::Cow;
use crate::spec::{Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions, cvs};
use crate::spec::{
BinaryFormat, Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions, cvs,
};
pub(crate) fn opts() -> TargetOptions {
// We cannot use `-nodefaultlibs` because compiler-rt has to be passed
@ -30,6 +32,7 @@ pub(crate) fn opts() -> TargetOptions {
exe_suffix: ".exe".into(),
families: cvs!["windows"],
is_like_windows: true,
binary_format: BinaryFormat::Coff,
allows_weak_linkage: false,
pre_link_args,
late_link_args,

View file

@ -103,6 +103,19 @@ impl Target {
base.$key_name = Some(s);
}
} );
($key_name:ident, BinaryFormat) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|f| f.as_str().and_then(|s| {
match s.parse::<super::BinaryFormat>() {
Ok(binary_format) => base.$key_name = binary_format,
_ => return Some(Err(format!(
"'{s}' is not a valid value for binary_format. \
Use 'coff', 'elf', 'mach-o', 'wasm' or 'xcoff' "
))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, MergeFunctions) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
@ -585,6 +598,7 @@ impl Target {
key!(is_like_msvc, bool);
key!(is_like_wasm, bool);
key!(is_like_android, bool);
key!(binary_format, BinaryFormat)?;
key!(default_dwarf_version, u32);
key!(allows_weak_linkage, bool);
key!(has_rpath, bool);
@ -762,6 +776,7 @@ impl ToJson for Target {
target_option_val!(is_like_msvc);
target_option_val!(is_like_wasm);
target_option_val!(is_like_android);
target_option_val!(binary_format);
target_option_val!(default_dwarf_version);
target_option_val!(allows_weak_linkage);
target_option_val!(has_rpath);

View file

@ -1644,6 +1644,55 @@ impl fmt::Display for StackProtector {
}
}
#[derive(PartialEq, Clone, Debug)]
pub enum BinaryFormat {
Coff,
Elf,
MachO,
Wasm,
Xcoff,
}
impl BinaryFormat {
/// Returns [`object::BinaryFormat`] for given `BinaryFormat`
pub fn to_object(&self) -> object::BinaryFormat {
match self {
Self::Coff => object::BinaryFormat::Coff,
Self::Elf => object::BinaryFormat::Elf,
Self::MachO => object::BinaryFormat::MachO,
Self::Wasm => object::BinaryFormat::Wasm,
Self::Xcoff => object::BinaryFormat::Xcoff,
}
}
}
impl FromStr for BinaryFormat {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"coff" => Ok(Self::Coff),
"elf" => Ok(Self::Elf),
"mach-o" => Ok(Self::MachO),
"wasm" => Ok(Self::Wasm),
"xcoff" => Ok(Self::Xcoff),
_ => Err(()),
}
}
}
impl ToJson for BinaryFormat {
fn to_json(&self) -> Json {
match self {
Self::Coff => "coff",
Self::Elf => "elf",
Self::MachO => "mach-o",
Self::Wasm => "wasm",
Self::Xcoff => "xcoff",
}
.to_json()
}
}
macro_rules! supported_targets {
( $(($tuple:literal, $module:ident),)+ ) => {
mod targets {
@ -2381,6 +2430,8 @@ pub struct TargetOptions {
pub is_like_wasm: bool,
/// Whether a target toolchain is like Android, implying a Linux kernel and a Bionic libc
pub is_like_android: bool,
/// Target's binary file format. Defaults to BinaryFormat::Elf
pub binary_format: BinaryFormat,
/// Default supported version of DWARF on this platform.
/// Useful because some platforms (osx, bsd) only want up to DWARF2.
pub default_dwarf_version: u32,
@ -2756,6 +2807,7 @@ impl Default for TargetOptions {
is_like_msvc: false,
is_like_wasm: false,
is_like_android: false,
binary_format: BinaryFormat::Elf,
default_dwarf_version: 4,
allows_weak_linkage: true,
has_rpath: false,

View file

@ -61,9 +61,9 @@ dependencies = [
[[package]]
name = "compiler_builtins"
version = "0.1.146"
version = "0.1.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a97117b1434b79833f39a5fabdf82f890bd98c1988334dea1cb67f7e627fa311"
checksum = "7170335a76fbcba350c3ea795c15df3b2c02934e35e502e82c4dd7837d4d0161"
dependencies = [
"cc",
"rustc-std-workspace-core",

View file

@ -12,7 +12,7 @@ edition = "2021"
[dependencies]
core = { path = "../core", public = true }
compiler_builtins = { version = "=0.1.146", features = ['rustc-dep-of-std'] }
compiler_builtins = { version = "=0.1.147", features = ['rustc-dep-of-std'] }
[dev-dependencies]
rand = { version = "0.9.0", default-features = false, features = ["alloc"] }

View file

@ -232,7 +232,7 @@ impl<T, A: Allocator> Drop for Drain<'_, T, A> {
// it from the original vec but also avoid creating a &mut to the front since that could
// invalidate raw pointers to it which some unsafe code might rely on.
let vec_ptr = vec.as_mut().as_mut_ptr();
let drop_offset = drop_ptr.sub_ptr(vec_ptr);
let drop_offset = drop_ptr.offset_from_unsigned(vec_ptr);
let to_drop = ptr::slice_from_raw_parts_mut(vec_ptr.add(drop_offset), drop_len);
ptr::drop_in_place(to_drop);
}

View file

@ -379,7 +379,7 @@ where
let sink =
self.try_fold::<_, _, Result<_, !>>(sink, write_in_place_with_drop(end)).into_ok();
// iteration succeeded, don't drop head
unsafe { ManuallyDrop::new(sink).dst.sub_ptr(dst_buf) }
unsafe { ManuallyDrop::new(sink).dst.offset_from_unsigned(dst_buf) }
}
}

View file

@ -14,7 +14,7 @@ pub(super) struct InPlaceDrop<T> {
impl<T> InPlaceDrop<T> {
fn len(&self) -> usize {
unsafe { self.dst.sub_ptr(self.inner) }
unsafe { self.dst.offset_from_unsigned(self.inner) }
}
}

View file

@ -179,7 +179,7 @@ impl<T, A: Allocator> IntoIter<T, A> {
// say that they're all at the beginning of the "allocation".
0..this.len()
} else {
this.ptr.sub_ptr(this.buf)..this.end.sub_ptr(buf)
this.ptr.offset_from_unsigned(this.buf)..this.end.offset_from_unsigned(buf)
};
let cap = this.cap;
let alloc = ManuallyDrop::take(&mut this.alloc);
@ -230,7 +230,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
let exact = if T::IS_ZST {
self.end.addr().wrapping_sub(self.ptr.as_ptr().addr())
} else {
unsafe { non_null!(self.end, T).sub_ptr(self.ptr) }
unsafe { non_null!(self.end, T).offset_from_unsigned(self.ptr) }
};
(exact, Some(exact))
}

View file

@ -2731,110 +2731,124 @@ pub unsafe fn truncf128(_x: f128) -> f128 {
unreachable!()
}
/// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust,
/// so this rounds half-way cases to the number with an even least significant digit.
///
/// May raise an inexact floating-point exception if the argument is not an integer.
/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions
/// cannot actually be utilized from Rust code.
/// In other words, this intrinsic is equivalent in behavior to `nearbyintf16` and `roundevenf16`.
/// Returns the nearest integer to an `f16`. Rounds half-way cases to the number with an even
/// least significant digit.
///
/// The stabilized version of this intrinsic is
/// [`f16::round_ties_even`](../../std/primitive.f16.html#method.round_ties_even)
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[rustc_nounwind]
pub unsafe fn rintf16(_x: f16) -> f16 {
#[cfg(not(bootstrap))]
pub fn round_ties_even_f16(_x: f16) -> f16 {
unreachable!()
}
/// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust,
/// so this rounds half-way cases to the number with an even least significant digit.
///
/// May raise an inexact floating-point exception if the argument is not an integer.
/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions
/// cannot actually be utilized from Rust code.
/// In other words, this intrinsic is equivalent in behavior to `nearbyintf32` and `roundevenf32`.
/// To be removed on next bootstrap bump.
#[cfg(bootstrap)]
pub fn round_ties_even_f16(x: f16) -> f16 {
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[rustc_nounwind]
unsafe fn rintf16(_x: f16) -> f16 {
unreachable!()
}
// SAFETY: this intrinsic isn't actually unsafe
unsafe { rintf16(x) }
}
/// Returns the nearest integer to an `f32`. Rounds half-way cases to the number with an even
/// least significant digit.
///
/// The stabilized version of this intrinsic is
/// [`f32::round_ties_even`](../../std/primitive.f32.html#method.round_ties_even)
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[rustc_nounwind]
pub unsafe fn rintf32(_x: f32) -> f32 {
#[cfg(not(bootstrap))]
pub fn round_ties_even_f32(_x: f32) -> f32 {
unreachable!()
}
/// Returns the nearest integer to an `f64`. Changing the rounding mode is not possible in Rust,
/// so this rounds half-way cases to the number with an even least significant digit.
///
/// May raise an inexact floating-point exception if the argument is not an integer.
/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions
/// cannot actually be utilized from Rust code.
/// In other words, this intrinsic is equivalent in behavior to `nearbyintf64` and `roundevenf64`.
/// To be removed on next bootstrap bump.
#[cfg(bootstrap)]
pub fn round_ties_even_f32(x: f32) -> f32 {
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[rustc_nounwind]
unsafe fn rintf32(_x: f32) -> f32 {
unreachable!()
}
// SAFETY: this intrinsic isn't actually unsafe
unsafe { rintf32(x) }
}
/// Provided for compatibility with stdarch. DO NOT USE.
#[inline(always)]
pub unsafe fn rintf32(x: f32) -> f32 {
round_ties_even_f32(x)
}
/// Returns the nearest integer to an `f64`. Rounds half-way cases to the number with an even
/// least significant digit.
///
/// The stabilized version of this intrinsic is
/// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even)
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[rustc_nounwind]
pub unsafe fn rintf64(_x: f64) -> f64 {
#[cfg(not(bootstrap))]
pub fn round_ties_even_f64(_x: f64) -> f64 {
unreachable!()
}
/// Returns the nearest integer to an `f128`. Changing the rounding mode is not possible in Rust,
/// so this rounds half-way cases to the number with an even least significant digit.
///
/// May raise an inexact floating-point exception if the argument is not an integer.
/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions
/// cannot actually be utilized from Rust code.
/// In other words, this intrinsic is equivalent in behavior to `nearbyintf128` and `roundevenf128`.
/// To be removed on next bootstrap bump.
#[cfg(bootstrap)]
pub fn round_ties_even_f64(x: f64) -> f64 {
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[rustc_nounwind]
unsafe fn rintf64(_x: f64) -> f64 {
unreachable!()
}
// SAFETY: this intrinsic isn't actually unsafe
unsafe { rintf64(x) }
}
/// Provided for compatibility with stdarch. DO NOT USE.
#[inline(always)]
pub unsafe fn rintf64(x: f64) -> f64 {
round_ties_even_f64(x)
}
/// Returns the nearest integer to an `f128`. Rounds half-way cases to the number with an even
/// least significant digit.
///
/// The stabilized version of this intrinsic is
/// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even)
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[rustc_nounwind]
pub unsafe fn rintf128(_x: f128) -> f128 {
#[cfg(not(bootstrap))]
pub fn round_ties_even_f128(_x: f128) -> f128 {
unreachable!()
}
/// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust,
/// so this rounds half-way cases to the number with an even least significant digit.
///
/// This intrinsic does not have a stable counterpart.
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[rustc_nounwind]
pub unsafe fn nearbyintf16(_x: f16) -> f16 {
unreachable!()
}
/// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust,
/// so this rounds half-way cases to the number with an even least significant digit.
///
/// This intrinsic does not have a stable counterpart.
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[rustc_nounwind]
pub unsafe fn nearbyintf32(_x: f32) -> f32 {
unreachable!()
}
/// Returns the nearest integer to an `f64`. Changing the rounding mode is not possible in Rust,
/// so this rounds half-way cases to the number with an even least significant digit.
///
/// This intrinsic does not have a stable counterpart.
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[rustc_nounwind]
pub unsafe fn nearbyintf64(_x: f64) -> f64 {
unreachable!()
}
/// Returns the nearest integer to an `f128`. Changing the rounding mode is not possible in Rust,
/// so this rounds half-way cases to the number with an even least significant digit.
///
/// This intrinsic does not have a stable counterpart.
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[rustc_nounwind]
pub unsafe fn nearbyintf128(_x: f128) -> f128 {
unreachable!()
/// To be removed on next bootstrap bump.
#[cfg(bootstrap)]
pub fn round_ties_even_f128(x: f128) -> f128 {
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[rustc_nounwind]
unsafe fn rintf128(_x: f128) -> f128 {
unreachable!()
}
// SAFETY: this intrinsic isn't actually unsafe
unsafe { rintf128(x) }
}
/// Returns the nearest integer to an `f16`. Rounds half-way cases away from zero.
@ -2878,47 +2892,6 @@ pub unsafe fn roundf128(_x: f128) -> f128 {
unreachable!()
}
/// Returns the nearest integer to an `f16`. Rounds half-way cases to the number
/// with an even least significant digit.
///
/// This intrinsic does not have a stable counterpart.
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[rustc_nounwind]
pub unsafe fn roundevenf16(_x: f16) -> f16 {
unreachable!()
}
/// Returns the nearest integer to an `f32`. Rounds half-way cases to the number
/// with an even least significant digit.
///
/// This intrinsic does not have a stable counterpart.
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[rustc_nounwind]
pub unsafe fn roundevenf32(_x: f32) -> f32 {
unreachable!()
}
/// Returns the nearest integer to an `f64`. Rounds half-way cases to the number
/// with an even least significant digit.
///
/// This intrinsic does not have a stable counterpart.
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[rustc_nounwind]
pub unsafe fn roundevenf64(_x: f64) -> f64 {
unreachable!()
}
/// Returns the nearest integer to an `f128`. Rounds half-way cases to the number
/// with an even least significant digit.
///
/// This intrinsic does not have a stable counterpart.
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[rustc_nounwind]
pub unsafe fn roundevenf128(_x: f128) -> f128 {
unreachable!()
}
/// Float addition that allows optimizations based on algebraic rules.
/// May assume inputs are finite.
///

View file

@ -724,7 +724,7 @@ impl<T: ?Sized> *const T {
/// that their safety preconditions are met:
/// ```rust
/// # unsafe fn blah(ptr: *const i32, origin: *const i32, count: usize) -> bool { unsafe {
/// ptr.sub_ptr(origin) == count
/// ptr.offset_from_unsigned(origin) == count
/// # &&
/// origin.add(count) == ptr
/// # &&
@ -755,20 +755,20 @@ impl<T: ?Sized> *const T {
/// let ptr1: *const i32 = &a[1];
/// let ptr2: *const i32 = &a[3];
/// unsafe {
/// assert_eq!(ptr2.sub_ptr(ptr1), 2);
/// assert_eq!(ptr2.offset_from_unsigned(ptr1), 2);
/// assert_eq!(ptr1.add(2), ptr2);
/// assert_eq!(ptr2.sub(2), ptr1);
/// assert_eq!(ptr2.sub_ptr(ptr2), 0);
/// assert_eq!(ptr2.offset_from_unsigned(ptr2), 0);
/// }
///
/// // This would be incorrect, as the pointers are not correctly ordered:
/// // ptr1.sub_ptr(ptr2)
/// // ptr1.offset_from_unsigned(ptr2)
/// ```
#[stable(feature = "ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")]
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn sub_ptr(self, origin: *const T) -> usize
pub const unsafe fn offset_from_unsigned(self, origin: *const T) -> usize
where
T: Sized,
{
@ -786,7 +786,7 @@ impl<T: ?Sized> *const T {
ub_checks::assert_unsafe_precondition!(
check_language_ub,
"ptr::sub_ptr requires `self >= origin`",
"ptr::offset_from_unsigned requires `self >= origin`",
(
this: *const () = self as *const (),
origin: *const () = origin as *const (),
@ -804,7 +804,7 @@ impl<T: ?Sized> *const T {
/// units of **bytes**.
///
/// This is purely a convenience for casting to a `u8` pointer and
/// using [`sub_ptr`][pointer::sub_ptr] on it. See that method for
/// using [`sub_ptr`][pointer::offset_from_unsigned] on it. See that method for
/// documentation and safety requirements.
///
/// For non-`Sized` pointees this operation considers only the data pointers,
@ -813,9 +813,9 @@ impl<T: ?Sized> *const T {
#[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")]
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: *const U) -> usize {
pub const unsafe fn byte_offset_from_unsigned<U: ?Sized>(self, origin: *const U) -> usize {
// SAFETY: the caller must uphold the safety contract for `sub_ptr`.
unsafe { self.cast::<u8>().sub_ptr(origin.cast::<u8>()) }
unsafe { self.cast::<u8>().offset_from_unsigned(origin.cast::<u8>()) }
}
/// Returns whether two pointers are guaranteed to be equal.

View file

@ -896,7 +896,7 @@ impl<T: ?Sized> *mut T {
/// that their safety preconditions are met:
/// ```rust
/// # unsafe fn blah(ptr: *mut i32, origin: *mut i32, count: usize) -> bool { unsafe {
/// ptr.sub_ptr(origin) == count
/// ptr.offset_from_unsigned(origin) == count
/// # &&
/// origin.add(count) == ptr
/// # &&
@ -929,10 +929,10 @@ impl<T: ?Sized> *mut T {
/// let ptr1: *mut i32 = p.add(1);
/// let ptr2: *mut i32 = p.add(3);
///
/// assert_eq!(ptr2.sub_ptr(ptr1), 2);
/// assert_eq!(ptr2.offset_from_unsigned(ptr1), 2);
/// assert_eq!(ptr1.add(2), ptr2);
/// assert_eq!(ptr2.sub(2), ptr1);
/// assert_eq!(ptr2.sub_ptr(ptr2), 0);
/// assert_eq!(ptr2.offset_from_unsigned(ptr2), 0);
/// }
///
/// // This would be incorrect, as the pointers are not correctly ordered:
@ -941,12 +941,12 @@ impl<T: ?Sized> *mut T {
#[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")]
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn sub_ptr(self, origin: *const T) -> usize
pub const unsafe fn offset_from_unsigned(self, origin: *const T) -> usize
where
T: Sized,
{
// SAFETY: the caller must uphold the safety contract for `sub_ptr`.
unsafe { (self as *const T).sub_ptr(origin) }
unsafe { (self as *const T).offset_from_unsigned(origin) }
}
/// Calculates the distance between two pointers within the same allocation, *where it's known that
@ -954,7 +954,7 @@ impl<T: ?Sized> *mut T {
/// units of **bytes**.
///
/// This is purely a convenience for casting to a `u8` pointer and
/// using [`sub_ptr`][pointer::sub_ptr] on it. See that method for
/// using [`sub_ptr`][pointer::offset_from_unsigned] on it. See that method for
/// documentation and safety requirements.
///
/// For non-`Sized` pointees this operation considers only the data pointers,
@ -963,9 +963,9 @@ impl<T: ?Sized> *mut T {
#[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")]
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: *mut U) -> usize {
pub const unsafe fn byte_offset_from_unsigned<U: ?Sized>(self, origin: *mut U) -> usize {
// SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`.
unsafe { (self as *const T).byte_sub_ptr(origin) }
unsafe { (self as *const T).byte_offset_from_unsigned(origin) }
}
/// Adds an unsigned offset to a pointer.

View file

@ -857,7 +857,7 @@ impl<T: ?Sized> NonNull<T> {
/// that their safety preconditions are met:
/// ```rust
/// # unsafe fn blah(ptr: std::ptr::NonNull<u32>, origin: std::ptr::NonNull<u32>, count: usize) -> bool { unsafe {
/// ptr.sub_ptr(origin) == count
/// ptr.offset_from_unsigned(origin) == count
/// # &&
/// origin.add(count) == ptr
/// # &&
@ -890,25 +890,25 @@ impl<T: ?Sized> NonNull<T> {
/// let ptr1: NonNull<u32> = NonNull::from(&a[1]);
/// let ptr2: NonNull<u32> = NonNull::from(&a[3]);
/// unsafe {
/// assert_eq!(ptr2.sub_ptr(ptr1), 2);
/// assert_eq!(ptr2.offset_from_unsigned(ptr1), 2);
/// assert_eq!(ptr1.add(2), ptr2);
/// assert_eq!(ptr2.sub(2), ptr1);
/// assert_eq!(ptr2.sub_ptr(ptr2), 0);
/// assert_eq!(ptr2.offset_from_unsigned(ptr2), 0);
/// }
///
/// // This would be incorrect, as the pointers are not correctly ordered:
/// // ptr1.sub_ptr(ptr2)
/// // ptr1.offset_from_unsigned(ptr2)
/// ```
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
#[stable(feature = "ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")]
pub const unsafe fn sub_ptr(self, subtracted: NonNull<T>) -> usize
pub const unsafe fn offset_from_unsigned(self, subtracted: NonNull<T>) -> usize
where
T: Sized,
{
// SAFETY: the caller must uphold the safety contract for `sub_ptr`.
unsafe { self.as_ptr().sub_ptr(subtracted.as_ptr()) }
unsafe { self.as_ptr().offset_from_unsigned(subtracted.as_ptr()) }
}
/// Calculates the distance between two pointers within the same allocation, *where it's known that
@ -916,7 +916,7 @@ impl<T: ?Sized> NonNull<T> {
/// units of **bytes**.
///
/// This is purely a convenience for casting to a `u8` pointer and
/// using [`sub_ptr`][NonNull::sub_ptr] on it. See that method for
/// using [`sub_ptr`][NonNull::offset_from_unsigned] on it. See that method for
/// documentation and safety requirements.
///
/// For non-`Sized` pointees this operation considers only the data pointers,
@ -925,9 +925,9 @@ impl<T: ?Sized> NonNull<T> {
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
#[stable(feature = "ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")]
pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: NonNull<U>) -> usize {
pub const unsafe fn byte_offset_from_unsigned<U: ?Sized>(self, origin: NonNull<U>) -> usize {
// SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`.
unsafe { self.as_ptr().byte_sub_ptr(origin.as_ptr()) }
unsafe { self.as_ptr().byte_offset_from_unsigned(origin.as_ptr()) }
}
/// Reads the value from `self` without moving it. This leaves the

View file

@ -54,7 +54,7 @@ macro_rules! len {
// To get rid of some bounds checks (see `position`), we use ptr_sub instead of
// offset_from (Tested by `codegen/slice-position-bounds-check`.)
// SAFETY: by the type invariant pointers are aligned and `start <= end`
unsafe { end.sub_ptr($self.ptr) }
unsafe { end.offset_from_unsigned($self.ptr) }
},
)
}};

View file

@ -272,7 +272,7 @@ pub const fn from_mut<T>(s: &mut T) -> &mut [T] {
#[rustc_const_unstable(feature = "const_slice_from_ptr_range", issue = "89792")]
pub const unsafe fn from_ptr_range<'a, T>(range: Range<*const T>) -> &'a [T] {
// SAFETY: the caller must uphold the safety contract for `from_ptr_range`.
unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) }
unsafe { from_raw_parts(range.start, range.end.offset_from_unsigned(range.start)) }
}
/// Forms a mutable slice from a pointer range.
@ -342,5 +342,5 @@ pub const unsafe fn from_ptr_range<'a, T>(range: Range<*const T>) -> &'a [T] {
#[rustc_const_unstable(feature = "const_slice_from_mut_ptr_range", issue = "89792")]
pub const unsafe fn from_mut_ptr_range<'a, T>(range: Range<*mut T>) -> &'a mut [T] {
// SAFETY: the caller must uphold the safety contract for `from_mut_ptr_range`.
unsafe { from_raw_parts_mut(range.start, range.end.sub_ptr(range.start)) }
unsafe { from_raw_parts_mut(range.start, range.end.offset_from_unsigned(range.start)) }
}

View file

@ -31,9 +31,9 @@ pub fn choose_pivot<T, F: FnMut(&T, &T) -> bool>(v: &[T], is_less: &mut F) -> us
let c = v_base.add(len_div_8 * 7); // [7*floor(n/8), 8*floor(n/8))
if len < PSEUDO_MEDIAN_REC_THRESHOLD {
median3(&*a, &*b, &*c, is_less).sub_ptr(v_base)
median3(&*a, &*b, &*c, is_less).offset_from_unsigned(v_base)
} else {
median3_rec(a, b, c, len_div_8, is_less).sub_ptr(v_base)
median3_rec(a, b, c, len_div_8, is_less).offset_from_unsigned(v_base)
}
}
}

View file

@ -143,7 +143,7 @@ impl<T> Drop for MergeState<T> {
// leave the input slice `v` with each original element and all possible
// modifications observed.
unsafe {
let len = self.end.sub_ptr(self.start);
let len = self.end.offset_from_unsigned(self.start);
ptr::copy_nonoverlapping(self.start, self.dst, len);
}
}

View file

@ -224,7 +224,7 @@ where
left = left.add(1);
}
left.sub_ptr(v_base)
left.offset_from_unsigned(v_base)
// `gap_opt` goes out of scope and overwrites the last wrong-side element on the right side
// with the first wrong-side element of the left side that was initially overwritten by the

View file

@ -18,7 +18,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
panic_unwind = { path = "../panic_unwind", optional = true }
panic_abort = { path = "../panic_abort" }
core = { path = "../core", public = true }
compiler_builtins = { version = "=0.1.146" }
compiler_builtins = { version = "=0.1.147" }
unwind = { path = "../unwind" }
hashbrown = { version = "0.15", default-features = false, features = [
'rustc-dep-of-std',

View file

@ -126,7 +126,7 @@ impl f128 {
#[unstable(feature = "f128", issue = "116909")]
#[must_use = "method returns a new number and does not mutate the original value"]
pub fn round_ties_even(self) -> f128 {
unsafe { intrinsics::rintf128(self) }
intrinsics::round_ties_even_f128(self)
}
/// Returns the integer part of `self`.

View file

@ -126,7 +126,7 @@ impl f16 {
#[unstable(feature = "f16", issue = "116909")]
#[must_use = "method returns a new number and does not mutate the original value"]
pub fn round_ties_even(self) -> f16 {
unsafe { intrinsics::rintf16(self) }
intrinsics::round_ties_even_f16(self)
}
/// Returns the integer part of `self`.

View file

@ -122,7 +122,7 @@ impl f32 {
#[stable(feature = "round_ties_even", since = "1.77.0")]
#[inline]
pub fn round_ties_even(self) -> f32 {
unsafe { intrinsics::rintf32(self) }
intrinsics::round_ties_even_f32(self)
}
/// Returns the integer part of `self`.

View file

@ -122,7 +122,7 @@ impl f64 {
#[stable(feature = "round_ties_even", since = "1.77.0")]
#[inline]
pub fn round_ties_even(self) -> f64 {
unsafe { intrinsics::rintf64(self) }
intrinsics::round_ties_even_f64(self)
}
/// Returns the integer part of `self`.

View file

@ -1,3 +1,10 @@
//! This module interacts with Cargo metadata to collect and store information about
//! the packages in the Rust workspace.
//!
//! It runs `cargo metadata` to gather details about each package, including its name,
//! source, dependencies, targets, and available features. The collected metadata is then
//! used to update the `Build` structure, ensuring proper dependency resolution and
//! compilation flow.
use std::collections::BTreeMap;
use std::path::PathBuf;

View file

@ -145,7 +145,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.write_scalar(Scalar::from_bool(branch), dest)?;
}
"floorf16" | "ceilf16" | "truncf16" | "roundf16" | "rintf16" => {
"floorf16" | "ceilf16" | "truncf16" | "roundf16" | "round_ties_even_f16" => {
let [f] = check_arg_count(args)?;
let f = this.read_scalar(f)?.to_f16()?;
let mode = match intrinsic_name {
@ -153,14 +153,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
"ceilf16" => Round::TowardPositive,
"truncf16" => Round::TowardZero,
"roundf16" => Round::NearestTiesToAway,
"rintf16" => Round::NearestTiesToEven,
"round_ties_even_f16" => Round::NearestTiesToEven,
_ => bug!(),
};
let res = f.round_to_integral(mode).value;
let res = this.adjust_nan(res, &[f]);
this.write_scalar(res, dest)?;
}
"floorf32" | "ceilf32" | "truncf32" | "roundf32" | "rintf32" => {
"floorf32" | "ceilf32" | "truncf32" | "roundf32" | "round_ties_even_f32" => {
let [f] = check_arg_count(args)?;
let f = this.read_scalar(f)?.to_f32()?;
let mode = match intrinsic_name {
@ -168,14 +168,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
"ceilf32" => Round::TowardPositive,
"truncf32" => Round::TowardZero,
"roundf32" => Round::NearestTiesToAway,
"rintf32" => Round::NearestTiesToEven,
"round_ties_even_f32" => Round::NearestTiesToEven,
_ => bug!(),
};
let res = f.round_to_integral(mode).value;
let res = this.adjust_nan(res, &[f]);
this.write_scalar(res, dest)?;
}
"floorf64" | "ceilf64" | "truncf64" | "roundf64" | "rintf64" => {
"floorf64" | "ceilf64" | "truncf64" | "roundf64" | "round_ties_even_f64" => {
let [f] = check_arg_count(args)?;
let f = this.read_scalar(f)?.to_f64()?;
let mode = match intrinsic_name {
@ -183,14 +183,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
"ceilf64" => Round::TowardPositive,
"truncf64" => Round::TowardZero,
"roundf64" => Round::NearestTiesToAway,
"rintf64" => Round::NearestTiesToEven,
"round_ties_even_f64" => Round::NearestTiesToEven,
_ => bug!(),
};
let res = f.round_to_integral(mode).value;
let res = this.adjust_nan(res, &[f]);
this.write_scalar(res, dest)?;
}
"floorf128" | "ceilf128" | "truncf128" | "roundf128" | "rintf128" => {
"floorf128" | "ceilf128" | "truncf128" | "roundf128" | "round_ties_even_f128" => {
let [f] = check_arg_count(args)?;
let f = this.read_scalar(f)?.to_f128()?;
let mode = match intrinsic_name {
@ -198,7 +198,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
"ceilf128" => Round::TowardPositive,
"truncf128" => Round::TowardZero,
"roundf128" => Round::NearestTiesToAway,
"rintf128" => Round::NearestTiesToEven,
"round_ties_even_f128" => Round::NearestTiesToEven,
_ => bug!(),
};
let res = f.round_to_integral(mode).value;

View file

@ -3,5 +3,5 @@ fn main() {
let arr = [0u8; 8];
let ptr1 = arr.as_ptr();
let ptr2 = ptr1.wrapping_add(4);
let _val = unsafe { ptr1.sub_ptr(ptr2) }; //~ERROR: first pointer has smaller address than second
let _val = unsafe { ptr1.offset_from_unsigned(ptr2) }; //~ERROR: first pointer has smaller address than second
}

View file

@ -1,8 +1,8 @@
error: Undefined Behavior: `ptr_offset_from_unsigned` called when first pointer has smaller address than second: $ADDR < $ADDR
--> tests/fail/intrinsics/ptr_offset_from_unsigned_neg.rs:LL:CC
|
LL | let _val = unsafe { ptr1.sub_ptr(ptr2) };
| ^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called when first pointer has smaller address than second: $ADDR < $ADDR
LL | let _val = unsafe { ptr1.offset_from_unsigned(ptr2) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called when first pointer has smaller address than second: $ADDR < $ADDR
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information

View file

@ -21,7 +21,7 @@ fn smoke() {
let _val = ptr.wrapping_sub(0);
let _val = unsafe { ptr.sub(0) };
let _val = unsafe { ptr.offset_from(ptr) };
let _val = unsafe { ptr.sub_ptr(ptr) };
let _val = unsafe { ptr.offset_from_unsigned(ptr) };
}
fn test_offset_from() {
@ -32,14 +32,14 @@ fn test_offset_from() {
let y = x.offset(12);
assert_eq!(y.offset_from(x), 12);
assert_eq!(y.sub_ptr(x), 12);
assert_eq!(y.offset_from_unsigned(x), 12);
assert_eq!(x.offset_from(y), -12);
assert_eq!((y as *const u32).offset_from(x as *const u32), 12 / 4);
assert_eq!((x as *const u32).offset_from(y as *const u32), -12 / 4);
let x = (((x as usize) * 2) / 2) as *const u8;
assert_eq!(y.offset_from(x), 12);
assert_eq!(y.sub_ptr(x), 12);
assert_eq!(y.offset_from_unsigned(x), 12);
assert_eq!(x.offset_from(y), -12);
}
}

View file

@ -1,18 +0,0 @@
#![crate_type = "lib"]
#![feature(core_intrinsics)]
use std::intrinsics;
// CHECK-LABEL: @nearbyintf32
#[no_mangle]
pub unsafe fn nearbyintf32(a: f32) -> f32 {
// CHECK: llvm.nearbyint.f32
intrinsics::nearbyintf32(a)
}
// CHECK-LABEL: @nearbyintf64
#[no_mangle]
pub unsafe fn nearbyintf64(a: f64) -> f64 {
// CHECK: llvm.nearbyint.f64
intrinsics::nearbyintf64(a)
}

View file

@ -24,14 +24,14 @@ impl Foo<u32> {
}
impl<T> Bar for Foo<T> {
// @has - '//*[@id="associatedtype.Item"]//h4[@class="code-header"]' 'type Item = T'
//@ has - '//*[@id="associatedtype.Item"]//h4[@class="code-header"]' 'type Item = T'
type Item=T;
//@ has - '//*[@id="method.quux"]//h4[@class="code-header"]' 'fn quux(self)'
fn quux(self) {}
}
impl<'a, T> Bar for &'a Foo<T> {
// @has - '//*[@id="associatedtype.Item-1"]//h4[@class="code-header"]' "type Item = &'a T"
//@ has - '//*[@id="associatedtype.Item-1"]//h4[@class="code-header"]' "type Item = &'a T"
type Item=&'a T;
//@ has - '//*[@id="method.quux-1"]//h4[@class="code-header"]' 'fn quux(self)'

View file

@ -1 +1 @@
<li><div class="item-name"><a class="struct" href="struct.CreateSubscriptionPaymentSettingsPaymentMethodOptionsCustomerBalanceBankTransferEuBankTransfer.html" title="struct extremely_long_typename::CreateSubscriptionPaymentSettingsPaymentMethodOptionsCustomerBalanceBankTransferEuBankTransfer">Create<wbr />Subscription<wbr />Payment<wbr />Settings<wbr />Payment<wbr />Method<wbr />Options<wbr />Customer<wbr />Balance<wbr />Bank<wbr />Transfer<wbr />EuBank<wbr />Transfer</a></div></li>
<dt><a class="struct" href="struct.CreateSubscriptionPaymentSettingsPaymentMethodOptionsCustomerBalanceBankTransferEuBankTransfer.html" title="struct extremely_long_typename::CreateSubscriptionPaymentSettingsPaymentMethodOptionsCustomerBalanceBankTransferEuBankTransfer">Create<wbr />Subscription<wbr />Payment<wbr />Settings<wbr />Payment<wbr />Method<wbr />Options<wbr />Customer<wbr />Balance<wbr />Bank<wbr />Transfer<wbr />EuBank<wbr />Transfer</a></dt>

View file

@ -3,5 +3,5 @@
// the item table has it line wrapped.
// There should be some reasonably-placed `<wbr>` tags in the snapshot file.
// @snapshot extremely_long_typename "extremely_long_typename/index.html" '//ul[@class="item-table"]/li'
//@ snapshot extremely_long_typename "extremely_long_typename/index.html" '//dl[@class="item-table"]/dt'
pub struct CreateSubscriptionPaymentSettingsPaymentMethodOptionsCustomerBalanceBankTransferEuBankTransfer;

View file

@ -2,28 +2,28 @@
#![crate_name = "foo"]
// @has 'foo/index.html'
//@ has 'foo/index.html'
// First we check that both the static and the function have a "sup" element
// to tell they're unsafe.
// @count - '//ul[@class="item-table"]//sup[@title="unsafe static"]' 1
// @has - '//ul[@class="item-table"]//sup[@title="unsafe static"]' '⚠'
// @count - '//ul[@class="item-table"]//sup[@title="unsafe function"]' 1
// @has - '//ul[@class="item-table"]//sup[@title="unsafe function"]' '⚠'
//@ count - '//dl[@class="item-table"]//sup[@title="unsafe static"]' 1
//@ has - '//dl[@class="item-table"]//sup[@title="unsafe static"]' '⚠'
//@ count - '//dl[@class="item-table"]//sup[@title="unsafe function"]' 1
//@ has - '//dl[@class="item-table"]//sup[@title="unsafe function"]' '⚠'
unsafe extern "C" {
// @has 'foo/static.FOO.html'
// @has - '//pre[@class="rust item-decl"]' 'pub static FOO: i32'
//@ has 'foo/static.FOO.html'
//@ has - '//pre[@class="rust item-decl"]' 'pub static FOO: i32'
pub safe static FOO: i32;
// @has 'foo/static.BAR.html'
// @has - '//pre[@class="rust item-decl"]' 'pub unsafe static BAR: i32'
//@ has 'foo/static.BAR.html'
//@ has - '//pre[@class="rust item-decl"]' 'pub unsafe static BAR: i32'
pub static BAR: i32;
// @has 'foo/fn.foo.html'
// @has - '//pre[@class="rust item-decl"]' 'pub extern "C" fn foo()'
//@ has 'foo/fn.foo.html'
//@ has - '//pre[@class="rust item-decl"]' 'pub extern "C" fn foo()'
pub safe fn foo();
// @has 'foo/fn.bar.html'
// @has - '//pre[@class="rust item-decl"]' 'pub unsafe extern "C" fn bar()'
//@ has 'foo/fn.bar.html'
//@ has - '//pre[@class="rust item-decl"]' 'pub unsafe extern "C" fn bar()'
pub fn bar();
}

View file

@ -104,7 +104,7 @@ error[E0080]: could not evaluate static initializer
|
= note: the evaluated program panicked at 'assertion failed: 0 < pointee_size && pointee_size <= isize::MAX as usize', $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
note: inside `std::ptr::const_ptr::<impl *const ()>::sub_ptr`
note: inside `std::ptr::const_ptr::<impl *const ()>::offset_from_unsigned`
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
note: inside `from_ptr_range::<'_, ()>`
--> $SRC_DIR/core/src/slice/raw.rs:LL:COL
@ -192,7 +192,7 @@ error[E0080]: could not evaluate static initializer
|
= note: `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation
|
note: inside `std::ptr::const_ptr::<impl *const u32>::sub_ptr`
note: inside `std::ptr::const_ptr::<impl *const u32>::offset_from_unsigned`
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
note: inside `from_ptr_range::<'_, u32>`
--> $SRC_DIR/core/src/slice/raw.rs:LL:COL
@ -207,7 +207,7 @@ error[E0080]: could not evaluate static initializer
|
= note: `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation
|
note: inside `std::ptr::const_ptr::<impl *const u32>::sub_ptr`
note: inside `std::ptr::const_ptr::<impl *const u32>::offset_from_unsigned`
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
note: inside `from_ptr_range::<'_, u32>`
--> $SRC_DIR/core/src/slice/raw.rs:LL:COL

View file

@ -44,7 +44,7 @@ pub const OFFSET_EQUAL_INTS: isize = {
pub const OFFSET_UNSIGNED: usize = {
let a = ['a', 'b', 'c'];
let ptr = a.as_ptr();
unsafe { ptr.add(2).sub_ptr(ptr) }
unsafe { ptr.add(2).offset_from_unsigned(ptr) }
};
fn main() {

View file

@ -1,11 +0,0 @@
//@ run-pass
#![feature(core_intrinsics)]
use std::intrinsics::*;
fn main() {
unsafe {
assert_eq!(nearbyintf32(5.234f32), 5f32);
assert_eq!(nearbyintf64(6.777f64), 7f64);
}
}