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:
commit
9af8985e05
56 changed files with 406 additions and 441 deletions
|
@ -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"] }
|
||||
|
|
|
@ -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!(),
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(&[
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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"] }
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
///
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) }
|
||||
},
|
||||
)
|
||||
}};
|
||||
|
|
|
@ -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)) }
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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)'
|
||||
|
|
|
@ -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>
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue