about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/run-make/compiler-builtins/rmake.rs142
-rw-r--r--tests/ui/generics/generic-type-less-params-with-defaults.rs16
-rw-r--r--tests/ui/generics/generic-type-less-params-with-defaults.stderr36
-rw-r--r--tests/ui/impl-not-adjacent-to-type.rs1
-rw-r--r--tests/ui/lint/dead-code/pub-field-in-priv-mod.rs11
-rw-r--r--tests/ui/lint/dead-code/pub-field-in-priv-mod.stderr16
-rw-r--r--tests/ui/privacy/suggest-making-field-public.fixed2
-rw-r--r--tests/ui/privacy/suggest-making-field-public.rs2
-rw-r--r--tests/ui/return/return-impl-trait-bad.stderr4
-rw-r--r--tests/ui/return/return-impl-trait.stderr2
-rw-r--r--tests/ui/return/return-ty-mismatch-note.rs21
-rw-r--r--tests/ui/return/return-ty-mismatch-note.stderr36
-rw-r--r--tests/ui/suggestions/clone-on-unconstrained-borrowed-type-param.stderr1
-rw-r--r--tests/ui/trait-bounds/restrict-assoc-type-of-generic-bound.stderr1
-rw-r--r--tests/ui/transmute/transmute-zst-generics.rs34
-rw-r--r--tests/ui/type/type-parameter-names.stderr1
-rw-r--r--tests/ui/type/type-params-in-different-spaces-3.stderr1
-rw-r--r--tests/ui/typeck/issue-13853.stderr1
-rw-r--r--tests/ui/union/union-macro.rs1
19 files changed, 325 insertions, 4 deletions
diff --git a/tests/run-make/compiler-builtins/rmake.rs b/tests/run-make/compiler-builtins/rmake.rs
new file mode 100644
index 00000000000..e7a5e8addbe
--- /dev/null
+++ b/tests/run-make/compiler-builtins/rmake.rs
@@ -0,0 +1,142 @@
+//! The compiler_builtins library is special. It can call functions in core, but it must not
+//! require linkage against a build of core. If it ever does, building the standard library *may*
+//! result in linker errors, depending on whether the linker in use applies optimizations first or
+//! resolves symbols first. So the portable and safe approach is to forbid such a linkage
+//! requirement entirely.
+//!
+//! In addition, whether compiler_builtins requires linkage against core can depend on optimization
+//! settings. Turning off optimizations and enabling debug assertions tends to produce the most
+//! dependence on core that is possible, so that is the configuration we test here.
+
+#![deny(warnings)]
+
+extern crate run_make_support;
+
+use run_make_support::object;
+use run_make_support::object::read::archive::ArchiveFile;
+use run_make_support::object::read::Object;
+use run_make_support::object::ObjectSection;
+use run_make_support::object::ObjectSymbol;
+use run_make_support::object::RelocationTarget;
+use run_make_support::out_dir;
+use std::collections::HashSet;
+
+const MANIFEST: &str = r#"
+[package]
+name = "scratch"
+version = "0.1.0"
+edition = "2021"
+
+[lib]
+path = "lib.rs""#;
+
+fn main() {
+    let target_dir = out_dir().join("target");
+    let target = std::env::var("TARGET").unwrap();
+    if target.starts_with("wasm") || target.starts_with("nvptx") {
+        // wasm and nvptx targets don't produce rlib files that object can parse.
+        return;
+    }
+
+    println!("Testing compiler_builtins for {}", target);
+
+    // Set up the tiniest Cargo project: An empty no_std library. Just enough to run -Zbuild-std.
+    let manifest_path = out_dir().join("Cargo.toml");
+    std::fs::write(&manifest_path, MANIFEST.as_bytes()).unwrap();
+    std::fs::write(out_dir().join("lib.rs"), b"#![no_std]").unwrap();
+
+    let path = std::env::var("PATH").unwrap();
+    let rustc = std::env::var("RUSTC").unwrap();
+    let bootstrap_cargo = std::env::var("BOOTSTRAP_CARGO").unwrap();
+    let status = std::process::Command::new(bootstrap_cargo)
+        .args([
+            "build",
+            "--manifest-path",
+            manifest_path.to_str().unwrap(),
+            "-Zbuild-std=core",
+            "--target",
+            &target,
+        ])
+        .env_clear()
+        .env("PATH", path)
+        .env("RUSTC", rustc)
+        .env("RUSTFLAGS", "-Copt-level=0 -Cdebug-assertions=yes")
+        .env("CARGO_TARGET_DIR", &target_dir)
+        .env("RUSTC_BOOTSTRAP", "1")
+        .status()
+        .unwrap();
+
+    assert!(status.success());
+
+    let rlibs_path = target_dir.join(target).join("debug").join("deps");
+    let compiler_builtins_rlib = std::fs::read_dir(rlibs_path)
+        .unwrap()
+        .find_map(|e| {
+            let path = e.unwrap().path();
+            let file_name = path.file_name().unwrap().to_str().unwrap();
+            if file_name.starts_with("libcompiler_builtins") && file_name.ends_with(".rlib") {
+                Some(path)
+            } else {
+                None
+            }
+        })
+        .unwrap();
+
+    // rlib files are archives, where the archive members each a CGU, and we also have one called
+    // lib.rmeta which is the encoded metadata. Each of the CGUs is an object file.
+    let data = std::fs::read(compiler_builtins_rlib).unwrap();
+
+    let mut defined_symbols = HashSet::new();
+    let mut undefined_relocations = HashSet::new();
+
+    let archive = ArchiveFile::parse(&*data).unwrap();
+    for member in archive.members() {
+        let member = member.unwrap();
+        if member.name() == b"lib.rmeta" {
+            continue;
+        }
+        let data = member.data(&*data).unwrap();
+        let object = object::File::parse(&*data).unwrap();
+
+        // Record all defined symbols in this CGU.
+        for symbol in object.symbols() {
+            if !symbol.is_undefined() {
+                let name = symbol.name().unwrap();
+                defined_symbols.insert(name);
+            }
+        }
+
+        // Find any relocations against undefined symbols. Calls within this CGU are relocations
+        // against a defined symbol.
+        for (_offset, relocation) in object.sections().flat_map(|section| section.relocations()) {
+            let RelocationTarget::Symbol(symbol_index) = relocation.target() else {
+                continue;
+            };
+            let symbol = object.symbol_by_index(symbol_index).unwrap();
+            if symbol.is_undefined() {
+                let name = symbol.name().unwrap();
+                undefined_relocations.insert(name);
+            }
+        }
+    }
+
+    // We can have symbols in the compiler_builtins rlib that are actually from core, if they were
+    // monomorphized in the compiler_builtins crate. This is totally fine, because though the call
+    // is to a function in core, it's resolved internally.
+    //
+    // It is normal to have relocations against symbols not defined in the rlib for things like
+    // unwinding, or math functions provided the target's platform libraries. Finding these is not
+    // a problem, we want to specifically ban relocations against core which are not resolved
+    // internally.
+    undefined_relocations
+        .retain(|symbol| !defined_symbols.contains(symbol) && symbol.contains("core"));
+
+    if !undefined_relocations.is_empty() {
+        panic!(
+            "compiler_builtins must not link against core, but it does. \n\
+            These symbols may be undefined in a debug build of compiler_builtins:\n\
+            {:?}",
+            undefined_relocations
+        );
+    }
+}
diff --git a/tests/ui/generics/generic-type-less-params-with-defaults.rs b/tests/ui/generics/generic-type-less-params-with-defaults.rs
index 6b877ab8aee..d04b1c80d34 100644
--- a/tests/ui/generics/generic-type-less-params-with-defaults.rs
+++ b/tests/ui/generics/generic-type-less-params-with-defaults.rs
@@ -5,7 +5,23 @@ struct Heap;
 struct Vec<T, A = Heap>(
     marker::PhantomData<(T,A)>);
 
+struct HashMap<K, V, S = ()>(marker::PhantomData<(K,V,S)>);
+
 fn main() {
     let _: Vec;
     //~^ ERROR missing generics for struct `Vec`
+    //~| SUGGESTION <T>
+
+    let _x = (1..10).collect::<HashMap>();
+    //~^ ERROR missing generics for struct `HashMap`
+    //~| SUGGESTION <_, _>
+
+    ().extend::<[(); 0]>({
+        fn not_the_extend() {
+            let _: Vec;
+            //~^ ERROR missing generics for struct `Vec`
+            //~| SUGGESTION <T>
+        }
+        []
+    });
 }
diff --git a/tests/ui/generics/generic-type-less-params-with-defaults.stderr b/tests/ui/generics/generic-type-less-params-with-defaults.stderr
index 6f79b09f6cd..a6771a6d5c8 100644
--- a/tests/ui/generics/generic-type-less-params-with-defaults.stderr
+++ b/tests/ui/generics/generic-type-less-params-with-defaults.stderr
@@ -1,5 +1,5 @@
 error[E0107]: missing generics for struct `Vec`
-  --> $DIR/generic-type-less-params-with-defaults.rs:9:12
+  --> $DIR/generic-type-less-params-with-defaults.rs:11:12
    |
 LL |     let _: Vec;
    |            ^^^ expected at least 1 generic argument
@@ -14,6 +14,38 @@ help: add missing generic argument
 LL |     let _: Vec<T>;
    |               +++
 
-error: aborting due to 1 previous error
+error[E0107]: missing generics for struct `HashMap`
+  --> $DIR/generic-type-less-params-with-defaults.rs:15:32
+   |
+LL |     let _x = (1..10).collect::<HashMap>();
+   |                                ^^^^^^^ expected at least 2 generic arguments
+   |
+note: struct defined here, with at least 2 generic parameters: `K`, `V`
+  --> $DIR/generic-type-less-params-with-defaults.rs:8:8
+   |
+LL | struct HashMap<K, V, S = ()>(marker::PhantomData<(K,V,S)>);
+   |        ^^^^^^^ -  -
+help: add missing generic arguments
+   |
+LL |     let _x = (1..10).collect::<HashMap<_, _>>();
+   |                                       ++++++
+
+error[E0107]: missing generics for struct `Vec`
+  --> $DIR/generic-type-less-params-with-defaults.rs:21:20
+   |
+LL |             let _: Vec;
+   |                    ^^^ expected at least 1 generic argument
+   |
+note: struct defined here, with at least 1 generic parameter: `T`
+  --> $DIR/generic-type-less-params-with-defaults.rs:5:8
+   |
+LL | struct Vec<T, A = Heap>(
+   |        ^^^ -
+help: add missing generic argument
+   |
+LL |             let _: Vec<T>;
+   |                       +++
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/impl-not-adjacent-to-type.rs b/tests/ui/impl-not-adjacent-to-type.rs
index 7fc927b1d64..ccf59ed4393 100644
--- a/tests/ui/impl-not-adjacent-to-type.rs
+++ b/tests/ui/impl-not-adjacent-to-type.rs
@@ -3,6 +3,7 @@
 mod foo {
     pub struct Point {
         pub x: i32,
+        #[allow(dead_code)]
         pub y: i32,
     }
 }
diff --git a/tests/ui/lint/dead-code/pub-field-in-priv-mod.rs b/tests/ui/lint/dead-code/pub-field-in-priv-mod.rs
new file mode 100644
index 00000000000..e49a164e940
--- /dev/null
+++ b/tests/ui/lint/dead-code/pub-field-in-priv-mod.rs
@@ -0,0 +1,11 @@
+#![deny(dead_code)]
+
+fn main() {
+    let _ = foo::S{f: false};
+}
+
+mod foo {
+    pub struct S {
+        pub f: bool, //~ ERROR field `f` is never read
+    }
+}
diff --git a/tests/ui/lint/dead-code/pub-field-in-priv-mod.stderr b/tests/ui/lint/dead-code/pub-field-in-priv-mod.stderr
new file mode 100644
index 00000000000..11dd387315f
--- /dev/null
+++ b/tests/ui/lint/dead-code/pub-field-in-priv-mod.stderr
@@ -0,0 +1,16 @@
+error: field `f` is never read
+  --> $DIR/pub-field-in-priv-mod.rs:9:13
+   |
+LL |     pub struct S {
+   |                - field in this struct
+LL |         pub f: bool,
+   |             ^
+   |
+note: the lint level is defined here
+  --> $DIR/pub-field-in-priv-mod.rs:1:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/privacy/suggest-making-field-public.fixed b/tests/ui/privacy/suggest-making-field-public.fixed
index 29dcde88ab4..8a5686aa5e1 100644
--- a/tests/ui/privacy/suggest-making-field-public.fixed
+++ b/tests/ui/privacy/suggest-making-field-public.fixed
@@ -1,5 +1,5 @@
 //@ run-rustfix
-mod a {
+pub mod a {
     pub struct A(pub String);
 }
 
diff --git a/tests/ui/privacy/suggest-making-field-public.rs b/tests/ui/privacy/suggest-making-field-public.rs
index c9f04757b2f..63fdb0bce6a 100644
--- a/tests/ui/privacy/suggest-making-field-public.rs
+++ b/tests/ui/privacy/suggest-making-field-public.rs
@@ -1,5 +1,5 @@
 //@ run-rustfix
-mod a {
+pub mod a {
     pub struct A(pub(self)String);
 }
 
diff --git a/tests/ui/return/return-impl-trait-bad.stderr b/tests/ui/return/return-impl-trait-bad.stderr
index a015b9f53af..6277c5feb20 100644
--- a/tests/ui/return/return-impl-trait-bad.stderr
+++ b/tests/ui/return/return-impl-trait-bad.stderr
@@ -10,6 +10,7 @@ LL |     "this should not suggest impl Trait"
    |
    = note: expected type parameter `T`
                    found reference `&'static str`
+   = note: the caller chooses a type for `T` which can be different from `&'static str`
 
 error[E0308]: mismatched types
   --> $DIR/return-impl-trait-bad.rs:9:5
@@ -23,6 +24,7 @@ LL |     "this will not suggest it, because that would probably be wrong"
    |
    = note: expected type parameter `T`
                    found reference `&'static str`
+   = note: the caller chooses a type for `T` which can be different from `&'static str`
 
 error[E0308]: mismatched types
   --> $DIR/return-impl-trait-bad.rs:17:5
@@ -37,6 +39,7 @@ LL |     "don't suggest this, because Option<T> places additional constraints"
    |
    = note: expected type parameter `T`
                    found reference `&'static str`
+   = note: the caller chooses a type for `T` which can be different from `&'static str`
 
 error[E0308]: mismatched types
   --> $DIR/return-impl-trait-bad.rs:28:5
@@ -53,6 +56,7 @@ LL |     "don't suggest this, because the generic param is used in the bound."
    |
    = note: expected type parameter `T`
                    found reference `&'static str`
+   = note: the caller chooses a type for `T` which can be different from `&'static str`
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/return/return-impl-trait.stderr b/tests/ui/return/return-impl-trait.stderr
index 707f014a16f..114ae0c2445 100644
--- a/tests/ui/return/return-impl-trait.stderr
+++ b/tests/ui/return/return-impl-trait.stderr
@@ -12,6 +12,7 @@ LL |     ()
    |
    = note: expected type parameter `T`
                    found unit type `()`
+   = note: the caller chooses a type for `T` which can be different from `()`
 
 error[E0308]: mismatched types
   --> $DIR/return-impl-trait.rs:23:5
@@ -28,6 +29,7 @@ LL |     ()
    |
    = note: expected type parameter `T`
                    found unit type `()`
+   = note: the caller chooses a type for `T` which can be different from `()`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/return/return-ty-mismatch-note.rs b/tests/ui/return/return-ty-mismatch-note.rs
new file mode 100644
index 00000000000..352bc2a1637
--- /dev/null
+++ b/tests/ui/return/return-ty-mismatch-note.rs
@@ -0,0 +1,21 @@
+// Checks existence of a note for "a caller chooses ty for ty param" upon return ty mismatch.
+
+fn f<T>() -> (T,) {
+    (0,) //~ ERROR mismatched types
+}
+
+fn g<U, V>() -> (U, V) {
+    (0, "foo")
+    //~^ ERROR mismatched types
+    //~| ERROR mismatched types
+}
+
+fn h() -> u8 {
+    0u8
+}
+
+fn main() {
+    f::<()>();
+    g::<(), ()>;
+    let _ = h();
+}
diff --git a/tests/ui/return/return-ty-mismatch-note.stderr b/tests/ui/return/return-ty-mismatch-note.stderr
new file mode 100644
index 00000000000..135903da5c2
--- /dev/null
+++ b/tests/ui/return/return-ty-mismatch-note.stderr
@@ -0,0 +1,36 @@
+error[E0308]: mismatched types
+  --> $DIR/return-ty-mismatch-note.rs:4:6
+   |
+LL | fn f<T>() -> (T,) {
+   |      - expected this type parameter
+LL |     (0,)
+   |      ^ expected type parameter `T`, found integer
+   |
+   = note: expected type parameter `T`
+                        found type `{integer}`
+
+error[E0308]: mismatched types
+  --> $DIR/return-ty-mismatch-note.rs:8:6
+   |
+LL | fn g<U, V>() -> (U, V) {
+   |      - expected this type parameter
+LL |     (0, "foo")
+   |      ^ expected type parameter `U`, found integer
+   |
+   = note: expected type parameter `U`
+                        found type `{integer}`
+
+error[E0308]: mismatched types
+  --> $DIR/return-ty-mismatch-note.rs:8:9
+   |
+LL | fn g<U, V>() -> (U, V) {
+   |         - expected this type parameter
+LL |     (0, "foo")
+   |         ^^^^^ expected type parameter `V`, found `&str`
+   |
+   = note: expected type parameter `V`
+                   found reference `&'static str`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/suggestions/clone-on-unconstrained-borrowed-type-param.stderr b/tests/ui/suggestions/clone-on-unconstrained-borrowed-type-param.stderr
index afbb9c32d51..2c4be26a82b 100644
--- a/tests/ui/suggestions/clone-on-unconstrained-borrowed-type-param.stderr
+++ b/tests/ui/suggestions/clone-on-unconstrained-borrowed-type-param.stderr
@@ -10,6 +10,7 @@ LL |     t.clone()
    |
    = note: expected type parameter `_`
                    found reference `&_`
+   = note: the caller chooses a type for `T` which can be different from `&T`
 note: `T` does not implement `Clone`, so `&T` was cloned instead
   --> $DIR/clone-on-unconstrained-borrowed-type-param.rs:3:5
    |
diff --git a/tests/ui/trait-bounds/restrict-assoc-type-of-generic-bound.stderr b/tests/ui/trait-bounds/restrict-assoc-type-of-generic-bound.stderr
index 5024ad21892..7aa32557af2 100644
--- a/tests/ui/trait-bounds/restrict-assoc-type-of-generic-bound.stderr
+++ b/tests/ui/trait-bounds/restrict-assoc-type-of-generic-bound.stderr
@@ -10,6 +10,7 @@ LL |     return a.bar();
    |
    = note: expected type parameter `B`
              found associated type `<A as MyTrait>::T`
+   = note: the caller chooses a type for `B` which can be different from `<A as MyTrait>::T`
 help: consider further restricting this bound
    |
 LL | pub fn foo<A: MyTrait<T = B>, B>(a: A) -> B {
diff --git a/tests/ui/transmute/transmute-zst-generics.rs b/tests/ui/transmute/transmute-zst-generics.rs
new file mode 100644
index 00000000000..9aeb21923ea
--- /dev/null
+++ b/tests/ui/transmute/transmute-zst-generics.rs
@@ -0,0 +1,34 @@
+//@ run-pass
+
+// Transmuting to/from ZSTs that contain generics.
+
+#![feature(transmute_generic_consts)]
+
+// Verify non-generic ZST -> generic ZST transmute
+unsafe fn cast_zst0<T>(from: ()) -> [T; 0] {
+    ::std::mem::transmute::<(), [T; 0]>(from)
+}
+
+// Verify generic ZST -> non-generic ZST transmute
+unsafe fn cast_zst1<T>(from: [T; 0]) -> () {
+    ::std::mem::transmute::<[T; 0], ()>(from)
+}
+
+// Verify transmute with generic compound types
+unsafe fn cast_zst2<T>(from: ()) -> [(T, T); 0] {
+    ::std::mem::transmute::<(), [(T, T); 0]>(from)
+}
+
+// Verify transmute with ZST propagation through arrays
+unsafe fn cast_zst3<T>(from: ()) -> [[T; 0]; 8] {
+    ::std::mem::transmute::<(), [[T; 0]; 8]>(from)
+}
+
+pub fn main() {
+    unsafe {
+        let _: [u32; 0] = cast_zst0(());
+        let _ = cast_zst1::<u32>([]);
+        let _: [(u32, u32); 0] = cast_zst2(());
+        let _: [[u32; 0]; 8] = cast_zst3(());
+    };
+}
diff --git a/tests/ui/type/type-parameter-names.stderr b/tests/ui/type/type-parameter-names.stderr
index 8e3e2388c6c..be9000a99e4 100644
--- a/tests/ui/type/type-parameter-names.stderr
+++ b/tests/ui/type/type-parameter-names.stderr
@@ -13,6 +13,7 @@ LL |     x
               found type parameter `Foo`
    = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
    = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
+   = note: the caller chooses a type for `Bar` which can be different from `Foo`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type/type-params-in-different-spaces-3.stderr b/tests/ui/type/type-params-in-different-spaces-3.stderr
index 58783fe1ff0..3c0c022f112 100644
--- a/tests/ui/type/type-params-in-different-spaces-3.stderr
+++ b/tests/ui/type/type-params-in-different-spaces-3.stderr
@@ -14,6 +14,7 @@ LL |         u
               found type parameter `X`
    = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
    = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
+   = note: the caller chooses a type for `Self` which can be different from `X`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/typeck/issue-13853.stderr b/tests/ui/typeck/issue-13853.stderr
index 0683c782933..45363c87d29 100644
--- a/tests/ui/typeck/issue-13853.stderr
+++ b/tests/ui/typeck/issue-13853.stderr
@@ -9,6 +9,7 @@ LL |         self.iter()
    |
    = note: expected type parameter `I`
                       found struct `std::slice::Iter<'_, N>`
+   = note: the caller chooses a type for `I` which can be different from `std::slice::Iter<'_, N>`
 
 error[E0599]: no method named `iter` found for reference `&G` in the current scope
   --> $DIR/issue-13853.rs:27:23
diff --git a/tests/ui/union/union-macro.rs b/tests/ui/union/union-macro.rs
index 01cba85deb3..729f56de7a0 100644
--- a/tests/ui/union/union-macro.rs
+++ b/tests/ui/union/union-macro.rs
@@ -15,6 +15,7 @@ macro_rules! duplicate {
 
 duplicate! {
     pub union U {
+        #[allow(dead_code)]
         pub a: u8
     }
 }