Merge from rustc
This commit is contained in:
commit
65e76849ac
183 changed files with 2692 additions and 874 deletions
|
|
@ -35,6 +35,7 @@ use minicore::*;
|
|||
pub fn return_f32(x: f32) -> f32 {
|
||||
// CHECK: movss {{.*}}(%ebp), %xmm0
|
||||
// CHECK-NEXT: popl %ebp
|
||||
// linux-NEXT: .cfi_def_cfa
|
||||
// CHECK-NEXT: retl
|
||||
x
|
||||
}
|
||||
|
|
@ -44,6 +45,7 @@ pub fn return_f32(x: f32) -> f32 {
|
|||
pub fn return_f64(x: f64) -> f64 {
|
||||
// CHECK: movsd {{.*}}(%ebp), %xmm0
|
||||
// CHECK-NEXT: popl %ebp
|
||||
// linux-NEXT: .cfi_def_cfa
|
||||
// CHECK-NEXT: retl
|
||||
x
|
||||
}
|
||||
|
|
@ -313,9 +315,13 @@ pub unsafe fn call_other_f64(x: &mut (usize, f64)) {
|
|||
#[no_mangle]
|
||||
pub fn return_f16(x: f16) -> f16 {
|
||||
// CHECK: pushl %ebp
|
||||
// linux-NEXT: .cfi_def_cfa_offset
|
||||
// linux-NEXT: .cfi_offset
|
||||
// CHECK-NEXT: movl %esp, %ebp
|
||||
// linux-NEXT: .cfi_def_cfa_register
|
||||
// CHECK-NEXT: pinsrw $0, 8(%ebp), %xmm0
|
||||
// CHECK-NEXT: popl %ebp
|
||||
// linux-NEXT: .cfi_def_cfa
|
||||
// CHECK-NEXT: retl
|
||||
x
|
||||
}
|
||||
|
|
@ -324,10 +330,14 @@ pub fn return_f16(x: f16) -> f16 {
|
|||
#[no_mangle]
|
||||
pub fn return_f128(x: f128) -> f128 {
|
||||
// CHECK: pushl %ebp
|
||||
// linux-NEXT: .cfi_def_cfa_offset
|
||||
// linux-NEXT: .cfi_offset
|
||||
// CHECK-NEXT: movl %esp, %ebp
|
||||
// linux-NEXT: .cfi_def_cfa_register
|
||||
// linux-NEXT: movaps 8(%ebp), %xmm0
|
||||
// win-NEXT: movups 8(%ebp), %xmm0
|
||||
// CHECK-NEXT: popl %ebp
|
||||
// linux-NEXT: .cfi_def_cfa
|
||||
// CHECK-NEXT: retl
|
||||
x
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0
|
||||
//
|
||||
// 32bit MSVC does not align things properly so we suppress high alignment annotations (#112480)
|
||||
//@ ignore-i686-pc-windows-msvc
|
||||
//@ ignore-i686-pc-windows-gnu
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
|
|
|
|||
45
tests/codegen/autodiff/identical_fnc.rs
Normal file
45
tests/codegen/autodiff/identical_fnc.rs
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
//@ compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=fat
|
||||
//@ no-prefer-dynamic
|
||||
//@ needs-enzyme
|
||||
//
|
||||
// Each autodiff invocation creates a new placeholder function, which we will replace on llvm-ir
|
||||
// level. If a user tries to differentiate two identical functions within the same compilation unit,
|
||||
// then LLVM might merge them in release mode before AD. In that case we can't rewrite one of the
|
||||
// merged placeholder function anymore, and compilation would fail. We prevent this by disabling
|
||||
// LLVM's merge_function pass before AD. Here we implicetely test that our solution keeps working.
|
||||
// We also explicetly test that we keep running merge_function after AD, by checking for two
|
||||
// identical function calls in the LLVM-IR, while having two different calls in the Rust code.
|
||||
#![feature(autodiff)]
|
||||
|
||||
use std::autodiff::autodiff;
|
||||
|
||||
#[autodiff(d_square, Reverse, Duplicated, Active)]
|
||||
fn square(x: &f64) -> f64 {
|
||||
x * x
|
||||
}
|
||||
|
||||
#[autodiff(d_square2, Reverse, Duplicated, Active)]
|
||||
fn square2(x: &f64) -> f64 {
|
||||
x * x
|
||||
}
|
||||
|
||||
// CHECK:; identical_fnc::main
|
||||
// CHECK-NEXT:; Function Attrs:
|
||||
// CHECK-NEXT:define internal void @_ZN13identical_fnc4main17hf4dbc69c8d2f9130E()
|
||||
// CHECK-NEXT:start:
|
||||
// CHECK-NOT:br
|
||||
// CHECK-NOT:ret
|
||||
// CHECK:; call identical_fnc::d_square
|
||||
// CHECK-NEXT: call fastcc void @_ZN13identical_fnc8d_square17h4c364207a2f8e06dE(double %x.val, ptr noalias noundef nonnull align 8 dereferenceable(8) %dx1)
|
||||
// CHECK-NEXT:; call identical_fnc::d_square
|
||||
// CHECK-NEXT: call fastcc void @_ZN13identical_fnc8d_square17h4c364207a2f8e06dE(double %x.val, ptr noalias noundef nonnull align 8 dereferenceable(8) %dx2)
|
||||
|
||||
fn main() {
|
||||
let x = std::hint::black_box(3.0);
|
||||
let mut dx1 = std::hint::black_box(1.0);
|
||||
let mut dx2 = std::hint::black_box(1.0);
|
||||
let _ = d_square(&x, &mut dx1, 1.0);
|
||||
let _ = d_square2(&x, &mut dx2, 1.0);
|
||||
assert_eq!(dx1, 6.0);
|
||||
assert_eq!(dx2, 6.0);
|
||||
}
|
||||
23
tests/codegen/autodiff/inline.rs
Normal file
23
tests/codegen/autodiff/inline.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
//@ compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=fat -Zautodiff=NoPostopt
|
||||
//@ no-prefer-dynamic
|
||||
//@ needs-enzyme
|
||||
|
||||
#![feature(autodiff)]
|
||||
|
||||
use std::autodiff::autodiff;
|
||||
|
||||
#[autodiff(d_square, Reverse, Duplicated, Active)]
|
||||
fn square(x: &f64) -> f64 {
|
||||
x * x
|
||||
}
|
||||
|
||||
// CHECK: ; inline::d_square
|
||||
// CHECK-NEXT: ; Function Attrs: alwaysinline
|
||||
// CHECK-NOT: noinline
|
||||
// CHECK-NEXT: define internal fastcc void @_ZN6inline8d_square17h021c74e92c259cdeE
|
||||
fn main() {
|
||||
let x = std::hint::black_box(3.0);
|
||||
let mut dx1 = std::hint::black_box(1.0);
|
||||
let _ = d_square(&x, &mut dx1, 1.0);
|
||||
assert_eq!(dx1, 6.0);
|
||||
}
|
||||
|
|
@ -1,4 +1,7 @@
|
|||
//@ compile-flags: -C no-prepopulate-passes
|
||||
// 32bit MSVC does not align things properly so we suppress high alignment annotations (#112480)
|
||||
//@ ignore-i686-pc-windows-msvc
|
||||
//@ ignore-i686-pc-windows-gnu
|
||||
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ fn get_item<'a>(
|
|||
fn main() {
|
||||
let path = "alloc_input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
let args = &[
|
||||
"rustc".to_string(),
|
||||
"--crate-type=lib".to_string(),
|
||||
"--crate-name".to_string(),
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ fn get_item<'a>(
|
|||
fn main() {
|
||||
let path = "alloc_input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
let args = &[
|
||||
"rustc".to_string(),
|
||||
"--edition=2021".to_string(),
|
||||
"--crate-name".to_string(),
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ fn check_items<T: CrateDef>(items: &[T], expected: &[&str]) {
|
|||
fn main() {
|
||||
let path = "assoc_items.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
let args = &[
|
||||
"rustc".to_string(),
|
||||
"--crate-type=lib".to_string(),
|
||||
"--crate-name".to_string(),
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ fn get_item<'a>(
|
|||
fn main() {
|
||||
let path = "attribute_input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
let args = &[
|
||||
"rustc".to_string(),
|
||||
"--crate-type=lib".to_string(),
|
||||
"--crate-name".to_string(),
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ impl<'a> MirVisitor for Visitor<'a> {
|
|||
fn main() {
|
||||
let path = "binop_input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec!["rustc".to_string(), "--crate-type=lib".to_string(), path.to_string()];
|
||||
let args = &["rustc".to_string(), "--crate-type=lib".to_string(), path.to_string()];
|
||||
run!(args, test_binops).unwrap();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ fn contains<T: CrateDef + std::fmt::Debug>(items: &[T], expected: &[&str]) {
|
|||
fn main() {
|
||||
let path = "crate_definitions.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
let args = &[
|
||||
"rustc".to_string(),
|
||||
"--crate-type=lib".to_string(),
|
||||
"--crate-name".to_string(),
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ fn check_fn_def(ty: Ty) {
|
|||
fn main() {
|
||||
let path = "defs_ty_input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
let args = &[
|
||||
"rustc".to_string(),
|
||||
"-Cpanic=abort".to_string(),
|
||||
"--crate-name".to_string(),
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ fn get_instances(body: mir::Body) -> Vec<Instance> {
|
|||
fn main() {
|
||||
let path = "defs_input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
let args = &[
|
||||
"rustc".to_string(),
|
||||
"-Cpanic=abort".to_string(),
|
||||
"--crate-name".to_string(),
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ fn test_foreign() -> ControlFlow<()> {
|
|||
fn main() {
|
||||
let path = "foreign_input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
let args = &[
|
||||
"rustc".to_string(),
|
||||
"-Cpanic=abort".to_string(),
|
||||
"--crate-type=lib".to_string(),
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ fn test_body(body: mir::Body) {
|
|||
fn main() {
|
||||
let path = "instance_input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
let args = &[
|
||||
"rustc".to_string(),
|
||||
"-Cpanic=abort".to_string(),
|
||||
"--crate-type=lib".to_string(),
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ impl<'a> MirVisitor for CallsVisitor<'a> {
|
|||
fn main() {
|
||||
let path = "binop_input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec!["rustc".to_string(), "--crate-type=lib".to_string(), path.to_string()];
|
||||
let args = &["rustc".to_string(), "--crate-type=lib".to_string(), path.to_string()];
|
||||
run!(args, test_intrinsics).unwrap();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ fn test_item_kind() -> ControlFlow<()> {
|
|||
fn main() {
|
||||
let path = "item_kind_input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
let args = &[
|
||||
"rustc".to_string(),
|
||||
"-Cpanic=abort".to_string(),
|
||||
"--crate-type=lib".to_string(),
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ fn check_ty(ty: Ty) {
|
|||
fn main() {
|
||||
let path = "normalization_input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
let args = &[
|
||||
"rustc".to_string(),
|
||||
"-Cpanic=abort".to_string(),
|
||||
"--crate-type=lib".to_string(),
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ fn assert_impl(impl_names: &HashSet<String>, target: &str) {
|
|||
fn main() {
|
||||
let path = "trait_queries.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
let args = &[
|
||||
"rustc".to_string(),
|
||||
"--crate-type=lib".to_string(),
|
||||
"--crate-name".to_string(),
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ fn get_item<'a>(
|
|||
fn main() {
|
||||
let path = "transform_input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
let args = &[
|
||||
"rustc".to_string(),
|
||||
"--crate-type=lib".to_string(),
|
||||
"--crate-name".to_string(),
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ impl<'a> MirVisitor for PlaceVisitor<'a> {
|
|||
fn main() {
|
||||
let path = "ty_fold_input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
let args = &[
|
||||
"rustc".to_string(),
|
||||
"-Cpanic=abort".to_string(),
|
||||
"--crate-name".to_string(),
|
||||
|
|
|
|||
|
|
@ -25,40 +25,42 @@ use std::io::Write;
|
|||
fn main() {
|
||||
let path = "input_compilation_result_test.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec!["rustc".to_string(), path.to_string()];
|
||||
test_continue(args.clone());
|
||||
test_break(args.clone());
|
||||
test_failed(args.clone());
|
||||
test_skipped(args.clone());
|
||||
let args = &["rustc".to_string(), path.to_string()];
|
||||
test_continue(args);
|
||||
test_break(args);
|
||||
test_failed(args);
|
||||
test_skipped(args);
|
||||
test_captured(args)
|
||||
}
|
||||
|
||||
fn test_continue(args: Vec<String>) {
|
||||
fn test_continue(args: &[String]) {
|
||||
let result = run!(args, || ControlFlow::Continue::<(), bool>(true));
|
||||
assert_eq!(result, Ok(true));
|
||||
}
|
||||
|
||||
fn test_break(args: Vec<String>) {
|
||||
fn test_break(args: &[String]) {
|
||||
let result = run!(args, || ControlFlow::Break::<bool, i32>(false));
|
||||
assert_eq!(result, Err(stable_mir::CompilerError::Interrupted(false)));
|
||||
}
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
fn test_skipped(mut args: Vec<String>) {
|
||||
fn test_skipped(args: &[String]) {
|
||||
let mut args = args.to_vec();
|
||||
args.push("--version".to_string());
|
||||
let result = run!(args, || unreachable!() as ControlFlow<()>);
|
||||
let result = run!(&args, || unreachable!() as ControlFlow<()>);
|
||||
assert_eq!(result, Err(stable_mir::CompilerError::Skipped));
|
||||
}
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
fn test_failed(mut args: Vec<String>) {
|
||||
fn test_failed(args: &[String]) {
|
||||
let mut args = args.to_vec();
|
||||
args.push("--cfg=broken".to_string());
|
||||
let result = run!(args, || unreachable!() as ControlFlow<()>);
|
||||
let result = run!(&args, || unreachable!() as ControlFlow<()>);
|
||||
assert_eq!(result, Err(stable_mir::CompilerError::Failed));
|
||||
}
|
||||
|
||||
/// Test that we are able to pass a closure and set the return according to the captured value.
|
||||
fn test_captured(args: Vec<String>) {
|
||||
fn test_captured(args: &[String]) {
|
||||
let captured = "10".to_string();
|
||||
let result = run!(args, || ControlFlow::Continue::<(), usize>(captured.len()));
|
||||
assert_eq!(result, Ok(captured.len()));
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ fn get_item<'a>(
|
|||
fn main() {
|
||||
let path = "input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
let args = &[
|
||||
"rustc".to_string(),
|
||||
"--crate-type=lib".to_string(),
|
||||
"--crate-name".to_string(),
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ fn get_item<'a>(
|
|||
fn main() {
|
||||
let path = "input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
let args = &[
|
||||
"rustc".to_string(),
|
||||
"--crate-type=lib".to_string(),
|
||||
"--crate-name".to_string(),
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ fn test_translation(tcx: TyCtxt<'_>) -> ControlFlow<()> {
|
|||
fn main() {
|
||||
let path = "internal_input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
let args = &[
|
||||
"rustc".to_string(),
|
||||
"--crate-name".to_string(),
|
||||
CRATE_NAME.to_string(),
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ fn serialize_to_json(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
|
|||
fn main() {
|
||||
let path = "internal_input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
let args = &[
|
||||
"rustc".to_string(),
|
||||
"--crate-name".to_string(),
|
||||
CRATE_NAME.to_string(),
|
||||
|
|
|
|||
|
|
@ -183,14 +183,14 @@ impl mir::MutMirVisitor for TestMutVisitor {
|
|||
fn main() {
|
||||
let path = "sim_visitor_input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
let args = &[
|
||||
"rustc".to_string(),
|
||||
"-Cpanic=abort".to_string(),
|
||||
"--crate-name".to_string(),
|
||||
CRATE_NAME.to_string(),
|
||||
path.to_string(),
|
||||
];
|
||||
run!(args.clone(), test_visitor).unwrap();
|
||||
run!(args, test_visitor).unwrap();
|
||||
run!(args, test_mut_visitor).unwrap();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
//@ ignore-endian-big
|
||||
// ignore-tidy-linelength
|
||||
//@ normalize-stderr: "╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼" -> "╾ALLOC_ID$1╼"
|
||||
#![allow(invalid_value)]
|
||||
#![allow(invalid_value, unnecessary_transmutes)]
|
||||
#![feature(never_type, rustc_attrs, ptr_metadata, slice_from_ptr_range, const_slice_from_ptr_range)]
|
||||
|
||||
use std::mem;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#![allow(unnecessary_transmutes)]
|
||||
use std::mem;
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/transmute-const-promotion.rs:4:37
|
||||
--> $DIR/transmute-const-promotion.rs:5:37
|
||||
|
|
||||
LL | let x: &'static u32 = unsafe { &mem::transmute(3.0f32) };
|
||||
| ------------ ^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#![allow(unnecessary_transmutes)]
|
||||
use std::mem;
|
||||
|
||||
static FOO: bool = unsafe { mem::transmute(3u8) };
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/transmute-const.rs:3:1
|
||||
--> $DIR/transmute-const.rs:4:1
|
||||
|
|
||||
LL | static FOO: bool = unsafe { mem::transmute(3u8) };
|
||||
| ^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP"
|
||||
//@ normalize-stderr: "0x0+" -> "0x0"
|
||||
#![feature(never_type)]
|
||||
#![allow(invalid_value)]
|
||||
#![allow(invalid_value, unnecessary_transmutes)]
|
||||
|
||||
use std::mem;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// ignore-tidy-linelength
|
||||
#![allow(unused)]
|
||||
#![allow(unused, unnecessary_transmutes)]
|
||||
#![feature(ptr_metadata)]
|
||||
|
||||
use std::{ptr, mem};
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
//@ [no_flag] check-pass
|
||||
//@ [with_flag] compile-flags: -Zextra-const-ub-checks
|
||||
#![feature(never_type)]
|
||||
#![allow(unnecessary_transmutes)]
|
||||
|
||||
use std::mem::transmute;
|
||||
use std::ptr::addr_of;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/detect-extra-ub.rs:29:20
|
||||
--> $DIR/detect-extra-ub.rs:30:20
|
||||
|
|
||||
LL | let _x: bool = transmute(3u8);
|
||||
| ^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/detect-extra-ub.rs:35:21
|
||||
--> $DIR/detect-extra-ub.rs:36:21
|
||||
|
|
||||
LL | let _x: usize = transmute(&3u8);
|
||||
| ^^^^^^^^^^^^^^^ constructing invalid value: encountered a pointer, but expected an integer
|
||||
|
|
@ -14,7 +14,7 @@ LL | let _x: usize = transmute(&3u8);
|
|||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/detect-extra-ub.rs:41:28
|
||||
--> $DIR/detect-extra-ub.rs:42:28
|
||||
|
|
||||
LL | let _x: PtrSizedEnum = transmute(&3u8);
|
||||
| ^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered a pointer, but expected an integer
|
||||
|
|
@ -23,7 +23,7 @@ LL | let _x: PtrSizedEnum = transmute(&3u8);
|
|||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/detect-extra-ub.rs:48:30
|
||||
--> $DIR/detect-extra-ub.rs:49:30
|
||||
|
|
||||
LL | let _x: (usize, usize) = transmute(x);
|
||||
| ^^^^^^^^^^^^ constructing invalid value at .0: encountered a pointer, but expected an integer
|
||||
|
|
@ -32,19 +32,19 @@ LL | let _x: (usize, usize) = transmute(x);
|
|||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/detect-extra-ub.rs:54:20
|
||||
--> $DIR/detect-extra-ub.rs:55:20
|
||||
|
|
||||
LL | let _x: &u32 = transmute(&[0u8; 4]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 4 byte alignment but found 1)
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/detect-extra-ub.rs:62:13
|
||||
--> $DIR/detect-extra-ub.rs:63:13
|
||||
|
|
||||
LL | let v = *addr_of!(data).cast::<UninhDiscriminant>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered an uninhabited enum variant
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/detect-extra-ub.rs:82:16
|
||||
--> $DIR/detect-extra-ub.rs:83:16
|
||||
|
|
||||
LL | let _val = *(&mem as *const Align as *const [*const u8; 2]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered a partial pointer or a mix of pointers
|
||||
|
|
@ -53,7 +53,7 @@ LL | let _val = *(&mem as *const Align as *const [*const u8; 2]);
|
|||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/detect-extra-ub.rs:97:16
|
||||
--> $DIR/detect-extra-ub.rs:98:16
|
||||
|
|
||||
LL | let _val = &*slice;
|
||||
| ^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
//@ run-pass
|
||||
|
||||
const fn make_nans() -> (f64, f64, f32, f32) {
|
||||
let nan1: f64 = unsafe { std::mem::transmute(0x7FF0_0001_0000_0001u64) };
|
||||
let nan2: f64 = unsafe { std::mem::transmute(0x7FF0_0000_0000_0001u64) };
|
||||
let nan1 = f64::from_bits(0x7FF0_0001_0000_0001);
|
||||
let nan2 = f64::from_bits(0x7FF0_0000_0000_0001);
|
||||
|
||||
let nan1_32 = nan1 as f32;
|
||||
let nan2_32 = nan2 as f32;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
error: path separator must be a double colon
|
||||
--> $DIR/single-colon-path-not-const-generics.rs:8:18
|
||||
|
|
||||
LL | pub struct Foo {
|
||||
| --- while parsing this struct
|
||||
LL | a: Vec<foo::bar:A>,
|
||||
| ^
|
||||
|
|
||||
help: use a double colon instead
|
||||
|
|
||||
LL | a: Vec<foo::bar::A>,
|
||||
| +
|
||||
| +
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
//@ run-pass
|
||||
#![allow(unnecessary_transmutes)]
|
||||
use std::mem::transmute;
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
20
tests/ui/linking/cdylib-no-mangle.rs
Normal file
20
tests/ui/linking/cdylib-no-mangle.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
//@ only-apple
|
||||
//@ build-fail
|
||||
//@ dont-check-compiler-stderr
|
||||
//@ dont-check-compiler-stdout
|
||||
|
||||
// Regression test for <https://github.com/rust-lang/rust/issues/139744>.
|
||||
// Functions in the dynamic library marked with no_mangle should not be GC-ed.
|
||||
|
||||
#![crate_type = "cdylib"]
|
||||
|
||||
unsafe extern "C" {
|
||||
unsafe static THIS_SYMBOL_SHOULD_BE_UNDEFINED: usize;
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe fn function_marked_with_no_mangle() {
|
||||
println!("FUNCTION_MARKED_WITH_NO_MANGLE = {}", unsafe { THIS_SYMBOL_SHOULD_BE_UNDEFINED });
|
||||
}
|
||||
|
||||
//~? ERROR linking
|
||||
27
tests/ui/linking/executable-no-mangle-strip.rs
Normal file
27
tests/ui/linking/executable-no-mangle-strip.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
//@ run-pass
|
||||
//@ ignore-windows-gnu: only statics marked with used can be GC-ed on windows-gnu
|
||||
|
||||
// Regression test for <https://github.com/rust-lang/rust/issues/139744>.
|
||||
// Functions in the binary marked with no_mangle should be GC-ed if they
|
||||
// are not indirectly referenced by main.
|
||||
|
||||
#![feature(used_with_arg)]
|
||||
|
||||
#[cfg_attr(windows, link(name = "this_lib_does_not_exist", kind = "raw-dylib"))]
|
||||
unsafe extern "C" {
|
||||
unsafe static THIS_SYMBOL_SHOULD_BE_UNDEFINED: usize;
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe fn function_marked_with_no_mangle() {
|
||||
println!("FUNCTION_MARKED_WITH_NO_MANGLE = {}", unsafe { THIS_SYMBOL_SHOULD_BE_UNDEFINED });
|
||||
}
|
||||
|
||||
#[used(compiler)]
|
||||
pub static FUNCTION_MARKED_WITH_USED: unsafe fn() = || {
|
||||
println!("FUNCTION_MARKED_WITH_USED = {}", unsafe { THIS_SYMBOL_SHOULD_BE_UNDEFINED });
|
||||
};
|
||||
|
||||
fn main() {
|
||||
println!("MAIN");
|
||||
}
|
||||
|
|
@ -1,19 +1,19 @@
|
|||
// check-fail
|
||||
// run-rustfix
|
||||
#![allow(unnecessary_transmutes)]
|
||||
|
||||
use std::ptr;
|
||||
use std::mem;
|
||||
use std::{mem, ptr};
|
||||
|
||||
unsafe fn null_ptr() {
|
||||
ptr::write(
|
||||
//~^ ERROR calling this function with a null pointer is undefined behavior
|
||||
//~^ ERROR calling this function with a null pointer is undefined behavior
|
||||
ptr::null_mut() as *mut u32,
|
||||
mem::transmute::<[u8; 4], _>([0, 0, 0, 255]),
|
||||
);
|
||||
|
||||
let null_ptr = ptr::null_mut();
|
||||
ptr::write(
|
||||
//~^ ERROR calling this function with a null pointer is undefined behavior
|
||||
//~^ ERROR calling this function with a null pointer is undefined behavior
|
||||
null_ptr as *mut u32,
|
||||
mem::transmute::<[u8; 4], _>([0, 0, 0, 255]),
|
||||
);
|
||||
|
|
@ -38,10 +38,10 @@ unsafe fn null_ptr() {
|
|||
ptr::copy_nonoverlapping::<usize>(ptr::null(), ptr::NonNull::dangling().as_ptr(), 0);
|
||||
//~^ ERROR calling this function with a null pointer is undefined behavior
|
||||
ptr::copy_nonoverlapping::<usize>(
|
||||
//~^ ERROR calling this function with a null pointer is undefined behavior
|
||||
//~^ ERROR calling this function with a null pointer is undefined behavior
|
||||
ptr::NonNull::dangling().as_ptr(),
|
||||
ptr::null_mut(),
|
||||
0
|
||||
0,
|
||||
);
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ LL | |
|
|||
LL | | ptr::NonNull::dangling().as_ptr(),
|
||||
LL | | ptr::null_mut(),
|
||||
| | --------------- null pointer originates from here
|
||||
LL | | 0
|
||||
LL | | 0,
|
||||
LL | | );
|
||||
| |_____^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
#![deny(improper_ctypes)]
|
||||
#![feature(ptr_internals)]
|
||||
#![feature(transparent_unions)]
|
||||
#![feature(repr128)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::num;
|
||||
|
||||
|
|
@ -40,6 +42,20 @@ enum Isize {
|
|||
C,
|
||||
}
|
||||
|
||||
#[repr(u128)]
|
||||
enum U128 {
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
}
|
||||
|
||||
#[repr(i128)]
|
||||
enum I128 {
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
struct TransparentStruct<T>(T, std::marker::PhantomData<Z>);
|
||||
|
||||
|
|
@ -71,6 +87,8 @@ extern "C" {
|
|||
fn repr_c(x: ReprC);
|
||||
fn repr_u8(x: U8);
|
||||
fn repr_isize(x: Isize);
|
||||
fn repr_u128(x: U128); //~ ERROR `extern` block uses type `U128`
|
||||
fn repr_i128(x: I128); //~ ERROR `extern` block uses type `I128`
|
||||
fn option_ref(x: Option<&'static u8>);
|
||||
fn option_fn(x: Option<extern "C" fn()>);
|
||||
fn option_nonnull(x: Option<std::ptr::NonNull<u8>>);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: `extern` block uses type `U`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:68:14
|
||||
--> $DIR/lint-ctypes-enum.rs:84:14
|
||||
|
|
||||
LL | fn uf(x: U);
|
||||
| ^ not FFI-safe
|
||||
|
|
@ -7,7 +7,7 @@ LL | fn uf(x: U);
|
|||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||
= note: enum has no representation hint
|
||||
note: the type is defined here
|
||||
--> $DIR/lint-ctypes-enum.rs:9:1
|
||||
--> $DIR/lint-ctypes-enum.rs:11:1
|
||||
|
|
||||
LL | enum U {
|
||||
| ^^^^^^
|
||||
|
|
@ -18,7 +18,7 @@ LL | #![deny(improper_ctypes)]
|
|||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: `extern` block uses type `B`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:69:14
|
||||
--> $DIR/lint-ctypes-enum.rs:85:14
|
||||
|
|
||||
LL | fn bf(x: B);
|
||||
| ^ not FFI-safe
|
||||
|
|
@ -26,13 +26,13 @@ LL | fn bf(x: B);
|
|||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||
= note: enum has no representation hint
|
||||
note: the type is defined here
|
||||
--> $DIR/lint-ctypes-enum.rs:12:1
|
||||
--> $DIR/lint-ctypes-enum.rs:14:1
|
||||
|
|
||||
LL | enum B {
|
||||
| ^^^^^^
|
||||
|
||||
error: `extern` block uses type `T`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:70:14
|
||||
--> $DIR/lint-ctypes-enum.rs:86:14
|
||||
|
|
||||
LL | fn tf(x: T);
|
||||
| ^ not FFI-safe
|
||||
|
|
@ -40,13 +40,39 @@ LL | fn tf(x: T);
|
|||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||
= note: enum has no representation hint
|
||||
note: the type is defined here
|
||||
--> $DIR/lint-ctypes-enum.rs:16:1
|
||||
--> $DIR/lint-ctypes-enum.rs:18:1
|
||||
|
|
||||
LL | enum T {
|
||||
| ^^^^^^
|
||||
|
||||
error: `extern` block uses type `U128`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:90:21
|
||||
|
|
||||
LL | fn repr_u128(x: U128);
|
||||
| ^^^^ not FFI-safe
|
||||
|
|
||||
= note: 128-bit integers don't currently have a known stable ABI
|
||||
note: the type is defined here
|
||||
--> $DIR/lint-ctypes-enum.rs:46:1
|
||||
|
|
||||
LL | enum U128 {
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: `extern` block uses type `I128`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:91:21
|
||||
|
|
||||
LL | fn repr_i128(x: I128);
|
||||
| ^^^^ not FFI-safe
|
||||
|
|
||||
= note: 128-bit integers don't currently have a known stable ABI
|
||||
note: the type is defined here
|
||||
--> $DIR/lint-ctypes-enum.rs:53:1
|
||||
|
|
||||
LL | enum I128 {
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: `extern` block uses type `u128`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:82:31
|
||||
--> $DIR/lint-ctypes-enum.rs:100:31
|
||||
|
|
||||
LL | fn option_nonzero_u128(x: Option<num::NonZero<u128>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -54,7 +80,7 @@ LL | fn option_nonzero_u128(x: Option<num::NonZero<u128>>);
|
|||
= note: 128-bit integers don't currently have a known stable ABI
|
||||
|
||||
error: `extern` block uses type `i128`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:89:31
|
||||
--> $DIR/lint-ctypes-enum.rs:107:31
|
||||
|
|
||||
LL | fn option_nonzero_i128(x: Option<num::NonZero<i128>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -62,7 +88,7 @@ LL | fn option_nonzero_i128(x: Option<num::NonZero<i128>>);
|
|||
= note: 128-bit integers don't currently have a known stable ABI
|
||||
|
||||
error: `extern` block uses type `Option<TransparentUnion<NonZero<u8>>>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:94:36
|
||||
--> $DIR/lint-ctypes-enum.rs:112:36
|
||||
|
|
||||
LL | fn option_transparent_union(x: Option<TransparentUnion<num::NonZero<u8>>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -71,7 +97,7 @@ LL | fn option_transparent_union(x: Option<TransparentUnion<num::NonZero<u8>
|
|||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Option<Rust<NonZero<u8>>>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:96:28
|
||||
--> $DIR/lint-ctypes-enum.rs:114:28
|
||||
|
|
||||
LL | fn option_repr_rust(x: Option<Rust<num::NonZero<u8>>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -80,7 +106,7 @@ LL | fn option_repr_rust(x: Option<Rust<num::NonZero<u8>>>);
|
|||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Option<u8>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:97:21
|
||||
--> $DIR/lint-ctypes-enum.rs:115:21
|
||||
|
|
||||
LL | fn option_u8(x: Option<u8>);
|
||||
| ^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -89,7 +115,7 @@ LL | fn option_u8(x: Option<u8>);
|
|||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `u128`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:107:33
|
||||
--> $DIR/lint-ctypes-enum.rs:125:33
|
||||
|
|
||||
LL | fn result_nonzero_u128_t(x: Result<num::NonZero<u128>, ()>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -97,7 +123,7 @@ LL | fn result_nonzero_u128_t(x: Result<num::NonZero<u128>, ()>);
|
|||
= note: 128-bit integers don't currently have a known stable ABI
|
||||
|
||||
error: `extern` block uses type `i128`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:114:33
|
||||
--> $DIR/lint-ctypes-enum.rs:132:33
|
||||
|
|
||||
LL | fn result_nonzero_i128_t(x: Result<num::NonZero<i128>, ()>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -105,7 +131,7 @@ LL | fn result_nonzero_i128_t(x: Result<num::NonZero<i128>, ()>);
|
|||
= note: 128-bit integers don't currently have a known stable ABI
|
||||
|
||||
error: `extern` block uses type `Result<TransparentUnion<NonZero<u8>>, ()>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:119:38
|
||||
--> $DIR/lint-ctypes-enum.rs:137:38
|
||||
|
|
||||
LL | fn result_transparent_union_t(x: Result<TransparentUnion<num::NonZero<u8>>, ()>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -114,7 +140,7 @@ LL | fn result_transparent_union_t(x: Result<TransparentUnion<num::NonZero<u
|
|||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<Rust<NonZero<u8>>, ()>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:121:30
|
||||
--> $DIR/lint-ctypes-enum.rs:139:30
|
||||
|
|
||||
LL | fn result_repr_rust_t(x: Result<Rust<num::NonZero<u8>>, ()>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -123,7 +149,7 @@ LL | fn result_repr_rust_t(x: Result<Rust<num::NonZero<u8>>, ()>);
|
|||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<NonZero<u8>, U>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:125:51
|
||||
--> $DIR/lint-ctypes-enum.rs:143:51
|
||||
|
|
||||
LL | fn result_1zst_exhaustive_single_variant_t(x: Result<num::NonZero<u8>, U>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -132,7 +158,7 @@ LL | fn result_1zst_exhaustive_single_variant_t(x: Result<num::NonZero<u8>,
|
|||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<NonZero<u8>, B>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:127:53
|
||||
--> $DIR/lint-ctypes-enum.rs:145:53
|
||||
|
|
||||
LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result<num::NonZero<u8>, B>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -141,7 +167,7 @@ LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result<num::NonZero<u8>
|
|||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<NonZero<u8>, NonExhaustive>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:129:51
|
||||
--> $DIR/lint-ctypes-enum.rs:147:51
|
||||
|
|
||||
LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result<num::NonZero<u8>, NonExhaustive>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -150,7 +176,7 @@ LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result<num::NonZero<u8>,
|
|||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<NonZero<u8>, Field>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:132:49
|
||||
--> $DIR/lint-ctypes-enum.rs:150:49
|
||||
|
|
||||
LL | fn result_1zst_exhaustive_single_field_t(x: Result<num::NonZero<u8>, Field>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -159,7 +185,7 @@ LL | fn result_1zst_exhaustive_single_field_t(x: Result<num::NonZero<u8>, Fi
|
|||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<Result<(), NonZero<u8>>, ()>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:134:30
|
||||
--> $DIR/lint-ctypes-enum.rs:152:30
|
||||
|
|
||||
LL | fn result_cascading_t(x: Result<Result<(), num::NonZero<u8>>, ()>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -168,7 +194,7 @@ LL | fn result_cascading_t(x: Result<Result<(), num::NonZero<u8>>, ()>);
|
|||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `u128`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:145:33
|
||||
--> $DIR/lint-ctypes-enum.rs:163:33
|
||||
|
|
||||
LL | fn result_nonzero_u128_e(x: Result<(), num::NonZero<u128>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -176,7 +202,7 @@ LL | fn result_nonzero_u128_e(x: Result<(), num::NonZero<u128>>);
|
|||
= note: 128-bit integers don't currently have a known stable ABI
|
||||
|
||||
error: `extern` block uses type `i128`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:152:33
|
||||
--> $DIR/lint-ctypes-enum.rs:170:33
|
||||
|
|
||||
LL | fn result_nonzero_i128_e(x: Result<(), num::NonZero<i128>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -184,7 +210,7 @@ LL | fn result_nonzero_i128_e(x: Result<(), num::NonZero<i128>>);
|
|||
= note: 128-bit integers don't currently have a known stable ABI
|
||||
|
||||
error: `extern` block uses type `Result<(), TransparentUnion<NonZero<u8>>>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:157:38
|
||||
--> $DIR/lint-ctypes-enum.rs:175:38
|
||||
|
|
||||
LL | fn result_transparent_union_e(x: Result<(), TransparentUnion<num::NonZero<u8>>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -193,7 +219,7 @@ LL | fn result_transparent_union_e(x: Result<(), TransparentUnion<num::NonZe
|
|||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<(), Rust<NonZero<u8>>>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:159:30
|
||||
--> $DIR/lint-ctypes-enum.rs:177:30
|
||||
|
|
||||
LL | fn result_repr_rust_e(x: Result<(), Rust<num::NonZero<u8>>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -202,7 +228,7 @@ LL | fn result_repr_rust_e(x: Result<(), Rust<num::NonZero<u8>>>);
|
|||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<U, NonZero<u8>>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:163:51
|
||||
--> $DIR/lint-ctypes-enum.rs:181:51
|
||||
|
|
||||
LL | fn result_1zst_exhaustive_single_variant_e(x: Result<U, num::NonZero<u8>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -211,7 +237,7 @@ LL | fn result_1zst_exhaustive_single_variant_e(x: Result<U, num::NonZero<u8
|
|||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<B, NonZero<u8>>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:165:53
|
||||
--> $DIR/lint-ctypes-enum.rs:183:53
|
||||
|
|
||||
LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result<B, num::NonZero<u8>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -220,7 +246,7 @@ LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result<B, num::NonZero<
|
|||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<NonExhaustive, NonZero<u8>>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:167:51
|
||||
--> $DIR/lint-ctypes-enum.rs:185:51
|
||||
|
|
||||
LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result<NonExhaustive, num::NonZero<u8>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -229,7 +255,7 @@ LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result<NonExhaustive, num
|
|||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<Field, NonZero<u8>>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:170:49
|
||||
--> $DIR/lint-ctypes-enum.rs:188:49
|
||||
|
|
||||
LL | fn result_1zst_exhaustive_single_field_e(x: Result<Field, num::NonZero<u8>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -238,7 +264,7 @@ LL | fn result_1zst_exhaustive_single_field_e(x: Result<Field, num::NonZero<
|
|||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<(), Result<(), NonZero<u8>>>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:172:30
|
||||
--> $DIR/lint-ctypes-enum.rs:190:30
|
||||
|
|
||||
LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero<u8>>>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -247,7 +273,7 @@ LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero<u8>>>);
|
|||
= note: enum has no representation hint
|
||||
|
||||
error: `extern` block uses type `Result<(), ()>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-enum.rs:174:27
|
||||
--> $DIR/lint-ctypes-enum.rs:192:27
|
||||
|
|
||||
LL | fn result_unit_t_e(x: Result<(), ()>);
|
||||
| ^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
@ -255,5 +281,5 @@ LL | fn result_unit_t_e(x: Result<(), ()>);
|
|||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||
= note: enum has no representation hint
|
||||
|
||||
error: aborting due to 27 previous errors
|
||||
error: aborting due to 29 previous errors
|
||||
|
||||
|
|
|
|||
22
tests/ui/parser/ty-path-followed-by-single-colon.rs
Normal file
22
tests/ui/parser/ty-path-followed-by-single-colon.rs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// Paths in type contexts may be followed by single colons.
|
||||
// This means we can't generally assume that the user typo'ed a double colon.
|
||||
// issue: <https://github.com/rust-lang/rust/issues/140227>
|
||||
//@ check-pass
|
||||
#![crate_type = "lib"]
|
||||
#![expect(non_camel_case_types)]
|
||||
|
||||
#[rustfmt::skip]
|
||||
mod garden {
|
||||
|
||||
fn f<path>() where path:to::somewhere {} // OK!
|
||||
|
||||
fn g(_: impl Take<path:to::somewhere>) {} // OK!
|
||||
|
||||
#[cfg(any())] fn h() where a::path:to::nowhere {} // OK!
|
||||
|
||||
fn i(_: impl Take<path::<>:to::somewhere>) {} // OK!
|
||||
|
||||
mod to { pub(super) trait somewhere {} }
|
||||
trait Take { type path; }
|
||||
|
||||
}
|
||||
19
tests/ui/pattern/byte-string-mutability-mismatch.rs
Normal file
19
tests/ui/pattern/byte-string-mutability-mismatch.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
//! Byte string literal patterns use the mutability of the literal, rather than the mutability of
|
||||
//! the pattern's scrutinee. Since byte string literals are always shared references, it's a
|
||||
//! mismatch to use a byte string literal pattern to match on a mutable array or slice reference.
|
||||
|
||||
fn main() {
|
||||
let mut val = [97u8, 10u8];
|
||||
match &mut val {
|
||||
b"a\n" => {},
|
||||
//~^ ERROR mismatched types
|
||||
//~| types differ in mutability
|
||||
_ => {},
|
||||
}
|
||||
match &mut val[..] {
|
||||
b"a\n" => {},
|
||||
//~^ ERROR mismatched types
|
||||
//~| types differ in mutability
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
25
tests/ui/pattern/byte-string-mutability-mismatch.stderr
Normal file
25
tests/ui/pattern/byte-string-mutability-mismatch.stderr
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/byte-string-mutability-mismatch.rs:8:9
|
||||
|
|
||||
LL | match &mut val {
|
||||
| -------- this expression has type `&mut [u8; 2]`
|
||||
LL | b"a\n" => {},
|
||||
| ^^^^^^ types differ in mutability
|
||||
|
|
||||
= note: expected mutable reference `&mut _`
|
||||
found reference `&'static _`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/byte-string-mutability-mismatch.rs:14:10
|
||||
|
|
||||
LL | match &mut val[..] {
|
||||
| ------------ this expression has type `&mut [u8]`
|
||||
LL | b"a\n" => {},
|
||||
| ^^^^^^ types differ in mutability
|
||||
|
|
||||
= note: expected mutable reference `&mut _`
|
||||
found reference `&'static _`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
34
tests/ui/pattern/deref-patterns/byte-string-type-errors.rs
Normal file
34
tests/ui/pattern/deref-patterns/byte-string-type-errors.rs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
//! Test type errors for byte string literal patterns. `deref_patterns` allows byte string literal
|
||||
//! patterns to have type `[u8]` or `[u8; N]` when matching on a slice or array; this can affect the
|
||||
//! "found" type reported in error messages when matching on a slice or array of the wrong type.
|
||||
|
||||
#![feature(deref_patterns)]
|
||||
#![expect(incomplete_features)]
|
||||
|
||||
fn main() {
|
||||
// Baseline 1: under normal circumstances, byte string literal patterns have type `&[u8; N]`,
|
||||
// the same as byte string literals.
|
||||
if let b"test" = () {}
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected `()`, found `&[u8; 4]`
|
||||
|
||||
// Baseline 2: there's a special case for byte string patterns in stable rust, allowing them to
|
||||
// match on slice references. This affects the error when matching on a non-`&[u8]` slice ref,
|
||||
// reporting the "found" type as `&[u8]`.
|
||||
if let b"test" = &[] as &[i8] {}
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected `&[i8]`, found `&[u8]`
|
||||
|
||||
// Test matching on a non-`[u8]` slice: the pattern has type `[u8]` if a slice is expected.
|
||||
if let b"test" = *(&[] as &[i8]) {}
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected `[i8]`, found `[u8]`
|
||||
|
||||
// Test matching on a non-`[u8;4]` array: the pattern has type `[u8;4]` if an array is expected.
|
||||
if let b"test" = [()] {}
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected `[(); 1]`, found `[u8; 4]`
|
||||
if let b"test" = *b"this array is too long" {}
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected an array with a size of 22, found one with a size of 4
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/byte-string-type-errors.rs:11:12
|
||||
|
|
||||
LL | if let b"test" = () {}
|
||||
| ^^^^^^^ -- this expression has type `()`
|
||||
| |
|
||||
| expected `()`, found `&[u8; 4]`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/byte-string-type-errors.rs:18:12
|
||||
|
|
||||
LL | if let b"test" = &[] as &[i8] {}
|
||||
| ^^^^^^^ ------------ this expression has type `&[i8]`
|
||||
| |
|
||||
| expected `&[i8]`, found `&[u8]`
|
||||
|
|
||||
= note: expected reference `&[i8]`
|
||||
found reference `&'static [u8]`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/byte-string-type-errors.rs:23:12
|
||||
|
|
||||
LL | if let b"test" = *(&[] as &[i8]) {}
|
||||
| ^^^^^^^ --------------- this expression has type `[i8]`
|
||||
| |
|
||||
| expected `[i8]`, found `[u8]`
|
||||
|
|
||||
= note: expected slice `[i8]`
|
||||
found slice `[u8]`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/byte-string-type-errors.rs:28:12
|
||||
|
|
||||
LL | if let b"test" = [()] {}
|
||||
| ^^^^^^^ ---- this expression has type `[(); 1]`
|
||||
| |
|
||||
| expected `[(); 1]`, found `[u8; 4]`
|
||||
|
|
||||
= note: expected array `[(); 1]`
|
||||
found array `[u8; 4]`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/byte-string-type-errors.rs:31:12
|
||||
|
|
||||
LL | if let b"test" = *b"this array is too long" {}
|
||||
| ^^^^^^^ -------------------------- this expression has type `[u8; 22]`
|
||||
| |
|
||||
| expected an array with a size of 22, found one with a size of 4
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
|
@ -12,4 +12,21 @@ fn main() {
|
|||
//~^ ERROR: mismatched types
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// `deref_patterns` allows string and byte string literals to have non-ref types.
|
||||
match *"test" {
|
||||
"test" => {}
|
||||
//~^ ERROR: mismatched types
|
||||
_ => {}
|
||||
}
|
||||
match *b"test" {
|
||||
b"test" => {}
|
||||
//~^ ERROR: mismatched types
|
||||
_ => {}
|
||||
}
|
||||
match *(b"test" as &[u8]) {
|
||||
b"test" => {}
|
||||
//~^ ERROR: mismatched types
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,31 @@ help: consider dereferencing to access the inner value using the Deref trait
|
|||
LL | match *Box::new(0) {
|
||||
| +
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/needs-gate.rs:18:9
|
||||
|
|
||||
LL | match *"test" {
|
||||
| ------- this expression has type `str`
|
||||
LL | "test" => {}
|
||||
| ^^^^^^ expected `str`, found `&str`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/needs-gate.rs:23:9
|
||||
|
|
||||
LL | match *b"test" {
|
||||
| -------- this expression has type `[u8; 4]`
|
||||
LL | b"test" => {}
|
||||
| ^^^^^^^ expected `[u8; 4]`, found `&[u8; 4]`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/needs-gate.rs:28:9
|
||||
|
|
||||
LL | match *(b"test" as &[u8]) {
|
||||
| ------------------- this expression has type `[u8]`
|
||||
LL | b"test" => {}
|
||||
| ^^^^^^^ expected `[u8]`, found `&[u8; 4]`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0658.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
|
|
|
|||
66
tests/ui/pattern/deref-patterns/strings.rs
Normal file
66
tests/ui/pattern/deref-patterns/strings.rs
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
//@ run-pass
|
||||
//! Test deref patterns using string and bytestring literals.
|
||||
|
||||
#![feature(deref_patterns)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
fn main() {
|
||||
for (test_in, test_expect) in [("zero", 0), ("one", 1), ("two", 2)] {
|
||||
// Test string literal patterns having type `str`.
|
||||
let test_actual = match *test_in {
|
||||
"zero" => 0,
|
||||
"one" => 1,
|
||||
_ => 2,
|
||||
};
|
||||
assert_eq!(test_actual, test_expect);
|
||||
|
||||
// Test string literals in explicit `deref!(_)` patterns.
|
||||
let test_actual = match test_in.to_string() {
|
||||
deref!("zero") => 0,
|
||||
deref!("one") => 1,
|
||||
_ => 2,
|
||||
};
|
||||
assert_eq!(test_actual, test_expect);
|
||||
}
|
||||
|
||||
// Test that we can still mutate in the match arm after using a literal to test equality:
|
||||
let mut test = "test".to_string();
|
||||
if let deref!(s @ "test") = &mut test {
|
||||
s.make_ascii_uppercase();
|
||||
}
|
||||
assert_eq!(test, "TEST");
|
||||
|
||||
for (test_in, test_expect) in [(b"0", 0), (b"1", 1), (b"2", 2)] {
|
||||
// Test byte string literal patterns having type `[u8; N]`
|
||||
let test_actual = match *test_in {
|
||||
b"0" => 0,
|
||||
b"1" => 1,
|
||||
_ => 2,
|
||||
};
|
||||
assert_eq!(test_actual, test_expect);
|
||||
|
||||
// Test byte string literal patterns having type `[u8]`
|
||||
let test_actual = match *(test_in as &[u8]) {
|
||||
b"0" => 0,
|
||||
b"1" => 1,
|
||||
_ => 2,
|
||||
};
|
||||
assert_eq!(test_actual, test_expect);
|
||||
|
||||
// Test byte string literals used as arrays in explicit `deref!(_)` patterns.
|
||||
let test_actual = match Box::new(*test_in) {
|
||||
deref!(b"0") => 0,
|
||||
deref!(b"1") => 1,
|
||||
_ => 2,
|
||||
};
|
||||
assert_eq!(test_actual, test_expect);
|
||||
|
||||
// Test byte string literals used as slices in explicit `deref!(_)` patterns.
|
||||
let test_actual = match test_in.to_vec() {
|
||||
deref!(b"0") => 0,
|
||||
deref!(b"1") => 1,
|
||||
_ => 2,
|
||||
};
|
||||
assert_eq!(test_actual, test_expect);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,18 +2,14 @@
|
|||
#![allow(incomplete_features)]
|
||||
|
||||
fn main() {
|
||||
// FIXME(deref_patterns): fails to typecheck because `"foo"` has type &str but deref creates a
|
||||
// place of type `str`.
|
||||
// FIXME(deref_patterns): fails to typecheck because string literal patterns don't peel
|
||||
// references from the scrutinee.
|
||||
match "foo".to_string() {
|
||||
deref!("foo") => {}
|
||||
//~^ ERROR: mismatched types
|
||||
"foo" => {}
|
||||
//~^ ERROR: mismatched types
|
||||
_ => {}
|
||||
}
|
||||
match &"foo".to_string() {
|
||||
deref!("foo") => {}
|
||||
//~^ ERROR: mismatched types
|
||||
"foo" => {}
|
||||
//~^ ERROR: mismatched types
|
||||
_ => {}
|
||||
|
|
|
|||
|
|
@ -1,34 +1,16 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/typeck_fail.rs:8:16
|
||||
--> $DIR/typeck_fail.rs:8:9
|
||||
|
|
||||
LL | match "foo".to_string() {
|
||||
| ----------------- this expression has type `String`
|
||||
LL | deref!("foo") => {}
|
||||
| ^^^^^ expected `str`, found `&str`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/typeck_fail.rs:10:9
|
||||
|
|
||||
LL | match "foo".to_string() {
|
||||
| ----------------- this expression has type `String`
|
||||
...
|
||||
LL | "foo" => {}
|
||||
| ^^^^^ expected `String`, found `&str`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/typeck_fail.rs:15:16
|
||||
--> $DIR/typeck_fail.rs:13:9
|
||||
|
|
||||
LL | match &"foo".to_string() {
|
||||
| ------------------ this expression has type `&String`
|
||||
LL | deref!("foo") => {}
|
||||
| ^^^^^ expected `str`, found `&str`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/typeck_fail.rs:17:9
|
||||
|
|
||||
LL | match &"foo".to_string() {
|
||||
| ------------------ this expression has type `&String`
|
||||
...
|
||||
LL | "foo" => {}
|
||||
| ^^^^^ expected `&String`, found `&str`
|
||||
|
|
||||
|
|
@ -36,7 +18,7 @@ LL | "foo" => {}
|
|||
found reference `&'static str`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/typeck_fail.rs:24:9
|
||||
--> $DIR/typeck_fail.rs:20:9
|
||||
|
|
||||
LL | match Some(0) {
|
||||
| ------- this expression has type `Option<{integer}>`
|
||||
|
|
@ -46,6 +28,6 @@ LL | Ok(0) => {}
|
|||
= note: expected enum `Option<{integer}>`
|
||||
found enum `Result<_, _>`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
//@ run-rustfix
|
||||
|
||||
use std::fmt;
|
||||
|
||||
struct Hello;
|
||||
|
||||
impl fmt::Display for Hello {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { //~ ERROR path separator must be a double colon
|
||||
write!(f, "hello")
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = Hello;
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
//@ run-rustfix
|
||||
|
||||
use std::fmt;
|
||||
|
||||
struct Hello;
|
||||
|
||||
impl fmt::Display for Hello {
|
||||
fn fmt(&self, f: &mut fmt:Formatter) -> fmt::Result { //~ ERROR path separator must be a double colon
|
||||
write!(f, "hello")
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = Hello;
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
error: path separator must be a double colon
|
||||
--> $DIR/argument-list-from-path-sep-error-129273.rs:8:30
|
||||
|
|
||||
LL | fn fmt(&self, f: &mut fmt:Formatter) -> fmt::Result {
|
||||
| ^
|
||||
|
|
||||
help: use a double colon instead
|
||||
|
|
||||
LL | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
| +
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
@ -7,14 +7,14 @@ mod foo {
|
|||
|
||||
struct Foo {
|
||||
a: foo:A,
|
||||
//~^ ERROR path separator must be a double colon
|
||||
//~| ERROR struct `A` is private
|
||||
//~^ ERROR found single colon in a struct field type path
|
||||
//~| ERROR expected `,`, or `}`, found `:`
|
||||
}
|
||||
|
||||
struct Bar {
|
||||
b: foo::bar:B,
|
||||
//~^ ERROR path separator must be a double colon
|
||||
//~| ERROR module `bar` is private
|
||||
//~^ ERROR found single colon in a struct field type path
|
||||
//~| ERROR expected `,`, or `}`, found `:`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,51 +1,40 @@
|
|||
error: path separator must be a double colon
|
||||
error: found single colon in a struct field type path
|
||||
--> $DIR/struct-field-type-including-single-colon.rs:9:11
|
||||
|
|
||||
LL | a: foo:A,
|
||||
| ^
|
||||
|
|
||||
help: use a double colon instead
|
||||
help: write a path separator here
|
||||
|
|
||||
LL | a: foo::A,
|
||||
| +
|
||||
|
||||
error: path separator must be a double colon
|
||||
error: expected `,`, or `}`, found `:`
|
||||
--> $DIR/struct-field-type-including-single-colon.rs:9:11
|
||||
|
|
||||
LL | struct Foo {
|
||||
| --- while parsing this struct
|
||||
LL | a: foo:A,
|
||||
| ^
|
||||
|
||||
error: found single colon in a struct field type path
|
||||
--> $DIR/struct-field-type-including-single-colon.rs:15:16
|
||||
|
|
||||
LL | b: foo::bar:B,
|
||||
| ^
|
||||
|
|
||||
help: use a double colon instead
|
||||
help: write a path separator here
|
||||
|
|
||||
LL | b: foo::bar::B,
|
||||
| +
|
||||
|
||||
error[E0603]: struct `A` is private
|
||||
--> $DIR/struct-field-type-including-single-colon.rs:9:12
|
||||
|
|
||||
LL | a: foo:A,
|
||||
| ^ private struct
|
||||
|
|
||||
note: the struct `A` is defined here
|
||||
--> $DIR/struct-field-type-including-single-colon.rs:2:5
|
||||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^^
|
||||
|
||||
error[E0603]: module `bar` is private
|
||||
--> $DIR/struct-field-type-including-single-colon.rs:15:13
|
||||
error: expected `,`, or `}`, found `:`
|
||||
--> $DIR/struct-field-type-including-single-colon.rs:15:16
|
||||
|
|
||||
LL | struct Bar {
|
||||
| --- while parsing this struct
|
||||
LL | b: foo::bar:B,
|
||||
| ^^^ - struct `B` is not publicly re-exported
|
||||
| |
|
||||
| private module
|
||||
|
|
||||
note: the module `bar` is defined here
|
||||
--> $DIR/struct-field-type-including-single-colon.rs:3:5
|
||||
|
|
||||
LL | mod bar {
|
||||
| ^^^^^^^
|
||||
| ^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0603`.
|
||||
|
|
|
|||
85
tests/ui/transmute/unnecessary-transmutation.fixed
Normal file
85
tests/ui/transmute/unnecessary-transmutation.fixed
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
//@ run-rustfix
|
||||
#![deny(unnecessary_transmutes)]
|
||||
#![allow(unused_unsafe, unused_imports, unused_variables, unused_parens)]
|
||||
use std::mem::transmute;
|
||||
|
||||
pub fn bytes_at_home(x: u32) -> [u8; 4] {
|
||||
unsafe { u32::to_ne_bytes(x) }
|
||||
//~^ ERROR
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let x: u16 = u16::from_ne_bytes(*b"01");
|
||||
//~^ ERROR
|
||||
let x: [u8; 2] = u16::to_ne_bytes(x);
|
||||
//~^ ERROR
|
||||
let x: u32 = u32::from_ne_bytes(*b"0123");
|
||||
//~^ ERROR
|
||||
let x: [u8; 4] = u32::to_ne_bytes(x);
|
||||
//~^ ERROR
|
||||
let x: u64 = u64::from_ne_bytes(*b"feriscat");
|
||||
//~^ ERROR
|
||||
let x: [u8; 8] = u64::to_ne_bytes(x);
|
||||
//~^ ERROR
|
||||
|
||||
let y: i16 = i16::from_ne_bytes(*b"01");
|
||||
//~^ ERROR
|
||||
let y: [u8; 2] = i16::to_ne_bytes(y);
|
||||
//~^ ERROR
|
||||
let y: i32 = i32::from_ne_bytes(*b"0123");
|
||||
//~^ ERROR
|
||||
let y: [u8; 4] = i32::to_ne_bytes(y);
|
||||
//~^ ERROR
|
||||
let y: i64 = i64::from_ne_bytes(*b"feriscat");
|
||||
//~^ ERROR
|
||||
let y: [u8; 8] = i64::to_ne_bytes(y);
|
||||
//~^ ERROR
|
||||
|
||||
let z: f32 = f32::from_ne_bytes(*b"0123");
|
||||
//~^ ERROR
|
||||
let z: [u8; 4] = f32::to_ne_bytes(z);
|
||||
//~^ ERROR
|
||||
let z: f64 = f64::from_ne_bytes(*b"feriscat");
|
||||
//~^ ERROR
|
||||
let z: [u8; 8] = f64::to_ne_bytes(z);
|
||||
//~^ ERROR
|
||||
|
||||
let y: u32 = u32::from('🦀');
|
||||
//~^ ERROR
|
||||
let y: char = char::from_u32_unchecked(y);
|
||||
//~^ ERROR
|
||||
|
||||
let x: u16 = i16::cast_unsigned(8i16);
|
||||
//~^ ERROR
|
||||
let x: i16 = u16::cast_signed(x);
|
||||
//~^ ERROR
|
||||
let x: u32 = i32::cast_unsigned(4i32);
|
||||
//~^ ERROR
|
||||
let x: i32 = u32::cast_signed(x);
|
||||
//~^ ERROR
|
||||
let x: u64 = i64::cast_unsigned(7i64);
|
||||
//~^ ERROR
|
||||
let x: i64 = u64::cast_signed(x);
|
||||
//~^ ERROR
|
||||
|
||||
let y: f32 = f32::from_bits(1u32);
|
||||
//~^ ERROR
|
||||
let y: u32 = f32::to_bits(y);
|
||||
//~^ ERROR
|
||||
let y: f64 = f64::from_bits(3u64);
|
||||
//~^ ERROR
|
||||
let y: u64 = f64::to_bits(2.0);
|
||||
//~^ ERROR
|
||||
|
||||
let z: bool = (1u8 == 1);
|
||||
//~^ ERROR
|
||||
let z: u8 = (z) as u8;
|
||||
//~^ ERROR
|
||||
|
||||
let z: bool = transmute(1i8);
|
||||
// no error!
|
||||
let z: i8 = (z) as i8;
|
||||
//~^ ERROR
|
||||
}
|
||||
}
|
||||
85
tests/ui/transmute/unnecessary-transmutation.rs
Normal file
85
tests/ui/transmute/unnecessary-transmutation.rs
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
//@ run-rustfix
|
||||
#![deny(unnecessary_transmutes)]
|
||||
#![allow(unused_unsafe, unused_imports, unused_variables, unused_parens)]
|
||||
use std::mem::transmute;
|
||||
|
||||
pub fn bytes_at_home(x: u32) -> [u8; 4] {
|
||||
unsafe { transmute(x) }
|
||||
//~^ ERROR
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let x: u16 = transmute(*b"01");
|
||||
//~^ ERROR
|
||||
let x: [u8; 2] = transmute(x);
|
||||
//~^ ERROR
|
||||
let x: u32 = transmute(*b"0123");
|
||||
//~^ ERROR
|
||||
let x: [u8; 4] = transmute(x);
|
||||
//~^ ERROR
|
||||
let x: u64 = transmute(*b"feriscat");
|
||||
//~^ ERROR
|
||||
let x: [u8; 8] = transmute(x);
|
||||
//~^ ERROR
|
||||
|
||||
let y: i16 = transmute(*b"01");
|
||||
//~^ ERROR
|
||||
let y: [u8; 2] = transmute(y);
|
||||
//~^ ERROR
|
||||
let y: i32 = transmute(*b"0123");
|
||||
//~^ ERROR
|
||||
let y: [u8; 4] = transmute(y);
|
||||
//~^ ERROR
|
||||
let y: i64 = transmute(*b"feriscat");
|
||||
//~^ ERROR
|
||||
let y: [u8; 8] = transmute(y);
|
||||
//~^ ERROR
|
||||
|
||||
let z: f32 = transmute(*b"0123");
|
||||
//~^ ERROR
|
||||
let z: [u8; 4] = transmute(z);
|
||||
//~^ ERROR
|
||||
let z: f64 = transmute(*b"feriscat");
|
||||
//~^ ERROR
|
||||
let z: [u8; 8] = transmute(z);
|
||||
//~^ ERROR
|
||||
|
||||
let y: u32 = transmute('🦀');
|
||||
//~^ ERROR
|
||||
let y: char = transmute(y);
|
||||
//~^ ERROR
|
||||
|
||||
let x: u16 = transmute(8i16);
|
||||
//~^ ERROR
|
||||
let x: i16 = transmute(x);
|
||||
//~^ ERROR
|
||||
let x: u32 = transmute(4i32);
|
||||
//~^ ERROR
|
||||
let x: i32 = transmute(x);
|
||||
//~^ ERROR
|
||||
let x: u64 = transmute(7i64);
|
||||
//~^ ERROR
|
||||
let x: i64 = transmute(x);
|
||||
//~^ ERROR
|
||||
|
||||
let y: f32 = transmute(1u32);
|
||||
//~^ ERROR
|
||||
let y: u32 = transmute(y);
|
||||
//~^ ERROR
|
||||
let y: f64 = transmute(3u64);
|
||||
//~^ ERROR
|
||||
let y: u64 = transmute(2.0);
|
||||
//~^ ERROR
|
||||
|
||||
let z: bool = transmute(1u8);
|
||||
//~^ ERROR
|
||||
let z: u8 = transmute(z);
|
||||
//~^ ERROR
|
||||
|
||||
let z: bool = transmute(1i8);
|
||||
// no error!
|
||||
let z: i8 = transmute(z);
|
||||
//~^ ERROR
|
||||
}
|
||||
}
|
||||
235
tests/ui/transmute/unnecessary-transmutation.stderr
Normal file
235
tests/ui/transmute/unnecessary-transmutation.stderr
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:7:14
|
||||
|
|
||||
LL | unsafe { transmute(x) }
|
||||
| ^^^^^^^^^^^^ help: replace this with: `u32::to_ne_bytes(x)`
|
||||
|
|
||||
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
|
||||
note: the lint level is defined here
|
||||
--> $DIR/unnecessary-transmutation.rs:2:9
|
||||
|
|
||||
LL | #![deny(unnecessary_transmutes)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:13:22
|
||||
|
|
||||
LL | let x: u16 = transmute(*b"01");
|
||||
| ^^^^^^^^^^^^^^^^^ help: replace this with: `u16::from_ne_bytes(*b"01")`
|
||||
|
|
||||
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:15:26
|
||||
|
|
||||
LL | let x: [u8; 2] = transmute(x);
|
||||
| ^^^^^^^^^^^^ help: replace this with: `u16::to_ne_bytes(x)`
|
||||
|
|
||||
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:17:22
|
||||
|
|
||||
LL | let x: u32 = transmute(*b"0123");
|
||||
| ^^^^^^^^^^^^^^^^^^^ help: replace this with: `u32::from_ne_bytes(*b"0123")`
|
||||
|
|
||||
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:19:26
|
||||
|
|
||||
LL | let x: [u8; 4] = transmute(x);
|
||||
| ^^^^^^^^^^^^ help: replace this with: `u32::to_ne_bytes(x)`
|
||||
|
|
||||
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:21:22
|
||||
|
|
||||
LL | let x: u64 = transmute(*b"feriscat");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ help: replace this with: `u64::from_ne_bytes(*b"feriscat")`
|
||||
|
|
||||
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:23:26
|
||||
|
|
||||
LL | let x: [u8; 8] = transmute(x);
|
||||
| ^^^^^^^^^^^^ help: replace this with: `u64::to_ne_bytes(x)`
|
||||
|
|
||||
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:26:22
|
||||
|
|
||||
LL | let y: i16 = transmute(*b"01");
|
||||
| ^^^^^^^^^^^^^^^^^ help: replace this with: `i16::from_ne_bytes(*b"01")`
|
||||
|
|
||||
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:28:26
|
||||
|
|
||||
LL | let y: [u8; 2] = transmute(y);
|
||||
| ^^^^^^^^^^^^ help: replace this with: `i16::to_ne_bytes(y)`
|
||||
|
|
||||
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:30:22
|
||||
|
|
||||
LL | let y: i32 = transmute(*b"0123");
|
||||
| ^^^^^^^^^^^^^^^^^^^ help: replace this with: `i32::from_ne_bytes(*b"0123")`
|
||||
|
|
||||
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:32:26
|
||||
|
|
||||
LL | let y: [u8; 4] = transmute(y);
|
||||
| ^^^^^^^^^^^^ help: replace this with: `i32::to_ne_bytes(y)`
|
||||
|
|
||||
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:34:22
|
||||
|
|
||||
LL | let y: i64 = transmute(*b"feriscat");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ help: replace this with: `i64::from_ne_bytes(*b"feriscat")`
|
||||
|
|
||||
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:36:26
|
||||
|
|
||||
LL | let y: [u8; 8] = transmute(y);
|
||||
| ^^^^^^^^^^^^ help: replace this with: `i64::to_ne_bytes(y)`
|
||||
|
|
||||
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:39:22
|
||||
|
|
||||
LL | let z: f32 = transmute(*b"0123");
|
||||
| ^^^^^^^^^^^^^^^^^^^ help: replace this with: `f32::from_ne_bytes(*b"0123")`
|
||||
|
|
||||
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:41:26
|
||||
|
|
||||
LL | let z: [u8; 4] = transmute(z);
|
||||
| ^^^^^^^^^^^^ help: replace this with: `f32::to_ne_bytes(z)`
|
||||
|
|
||||
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:43:22
|
||||
|
|
||||
LL | let z: f64 = transmute(*b"feriscat");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ help: replace this with: `f64::from_ne_bytes(*b"feriscat")`
|
||||
|
|
||||
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:45:26
|
||||
|
|
||||
LL | let z: [u8; 8] = transmute(z);
|
||||
| ^^^^^^^^^^^^ help: replace this with: `f64::to_ne_bytes(z)`
|
||||
|
|
||||
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:48:22
|
||||
|
|
||||
LL | let y: u32 = transmute('🦀');
|
||||
| ^^^^^^^^^^^^^^^ help: replace this with: `u32::from('🦀')`
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:50:23
|
||||
|
|
||||
LL | let y: char = transmute(y);
|
||||
| ^^^^^^^^^^^^ help: replace this with: `char::from_u32_unchecked(y)`
|
||||
|
|
||||
= help: consider `char::from_u32(…).unwrap()`
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:53:22
|
||||
|
|
||||
LL | let x: u16 = transmute(8i16);
|
||||
| ^^^^^^^^^^^^^^^ help: replace this with: `i16::cast_unsigned(8i16)`
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:55:22
|
||||
|
|
||||
LL | let x: i16 = transmute(x);
|
||||
| ^^^^^^^^^^^^ help: replace this with: `u16::cast_signed(x)`
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:57:22
|
||||
|
|
||||
LL | let x: u32 = transmute(4i32);
|
||||
| ^^^^^^^^^^^^^^^ help: replace this with: `i32::cast_unsigned(4i32)`
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:59:22
|
||||
|
|
||||
LL | let x: i32 = transmute(x);
|
||||
| ^^^^^^^^^^^^ help: replace this with: `u32::cast_signed(x)`
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:61:22
|
||||
|
|
||||
LL | let x: u64 = transmute(7i64);
|
||||
| ^^^^^^^^^^^^^^^ help: replace this with: `i64::cast_unsigned(7i64)`
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:63:22
|
||||
|
|
||||
LL | let x: i64 = transmute(x);
|
||||
| ^^^^^^^^^^^^ help: replace this with: `u64::cast_signed(x)`
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:66:22
|
||||
|
|
||||
LL | let y: f32 = transmute(1u32);
|
||||
| ^^^^^^^^^^^^^^^ help: replace this with: `f32::from_bits(1u32)`
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:68:22
|
||||
|
|
||||
LL | let y: u32 = transmute(y);
|
||||
| ^^^^^^^^^^^^ help: replace this with: `f32::to_bits(y)`
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:70:22
|
||||
|
|
||||
LL | let y: f64 = transmute(3u64);
|
||||
| ^^^^^^^^^^^^^^^ help: replace this with: `f64::from_bits(3u64)`
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:72:22
|
||||
|
|
||||
LL | let y: u64 = transmute(2.0);
|
||||
| ^^^^^^^^^^^^^^ help: replace this with: `f64::to_bits(2.0)`
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:75:23
|
||||
|
|
||||
LL | let z: bool = transmute(1u8);
|
||||
| ^^^^^^^^^^^^^^ help: replace this with: `(1u8 == 1)`
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:77:21
|
||||
|
|
||||
LL | let z: u8 = transmute(z);
|
||||
| ^^^^^^^^^^^^ help: replace this with: `(z) as u8`
|
||||
|
||||
error: unnecessary transmute
|
||||
--> $DIR/unnecessary-transmutation.rs:82:21
|
||||
|
|
||||
LL | let z: i8 = transmute(z);
|
||||
| ^^^^^^^^^^^^ help: replace this with: `(z) as i8`
|
||||
|
||||
error: aborting due to 32 previous errors
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue