From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- .../ui/polymorphization/closure_in_upvar/fn.rs | 29 ++++ .../ui/polymorphization/closure_in_upvar/fnmut.rs | 34 +++++ .../ui/polymorphization/closure_in_upvar/fnonce.rs | 34 +++++ .../ui/polymorphization/closure_in_upvar/other.rs | 38 +++++ .../polymorphization/const_parameters/closures.rs | 67 +++++++++ .../const_parameters/closures.stderr | 44 ++++++ .../polymorphization/const_parameters/functions.rs | 37 +++++ .../const_parameters/functions.stderr | 17 +++ src/test/ui/polymorphization/drop_shims/simple.rs | 22 +++ .../ui/polymorphization/drop_shims/transitive.rs | 27 ++++ src/test/ui/polymorphization/generators.rs | 92 ++++++++++++ src/test/ui/polymorphization/generators.stderr | 39 +++++ src/test/ui/polymorphization/issue-74614.rs | 18 +++ src/test/ui/polymorphization/issue-74636.rs | 16 ++ src/test/ui/polymorphization/lifetimes.rs | 25 ++++ src/test/ui/polymorphization/lifetimes.stderr | 17 +++ .../ui/polymorphization/normalized_sig_types.rs | 26 ++++ src/test/ui/polymorphization/predicates.rs | 95 ++++++++++++ src/test/ui/polymorphization/predicates.stderr | 51 +++++++ .../ui/polymorphization/promoted-function-1.rs | 12 ++ .../ui/polymorphization/promoted-function-1.stderr | 8 + .../ui/polymorphization/promoted-function-2.rs | 16 ++ .../ui/polymorphization/promoted-function-2.stderr | 17 +++ .../ui/polymorphization/promoted-function-3.rs | 14 ++ src/test/ui/polymorphization/promoted-function.rs | 15 ++ src/test/ui/polymorphization/symbol-ambiguity.rs | 22 +++ .../ui/polymorphization/too-many-generic-params.rs | 85 +++++++++++ .../polymorphization/type_parameters/closures.rs | 161 +++++++++++++++++++++ .../type_parameters/closures.stderr | 80 ++++++++++ .../polymorphization/type_parameters/functions.rs | 96 ++++++++++++ .../type_parameters/functions.stderr | 35 +++++ src/test/ui/polymorphization/unsized_cast.rs | 30 ++++ src/test/ui/polymorphization/unsized_cast.stderr | 38 +++++ 33 files changed, 1357 insertions(+) create mode 100644 src/test/ui/polymorphization/closure_in_upvar/fn.rs create mode 100644 src/test/ui/polymorphization/closure_in_upvar/fnmut.rs create mode 100644 src/test/ui/polymorphization/closure_in_upvar/fnonce.rs create mode 100644 src/test/ui/polymorphization/closure_in_upvar/other.rs create mode 100644 src/test/ui/polymorphization/const_parameters/closures.rs create mode 100644 src/test/ui/polymorphization/const_parameters/closures.stderr create mode 100644 src/test/ui/polymorphization/const_parameters/functions.rs create mode 100644 src/test/ui/polymorphization/const_parameters/functions.stderr create mode 100644 src/test/ui/polymorphization/drop_shims/simple.rs create mode 100644 src/test/ui/polymorphization/drop_shims/transitive.rs create mode 100644 src/test/ui/polymorphization/generators.rs create mode 100644 src/test/ui/polymorphization/generators.stderr create mode 100644 src/test/ui/polymorphization/issue-74614.rs create mode 100644 src/test/ui/polymorphization/issue-74636.rs create mode 100644 src/test/ui/polymorphization/lifetimes.rs create mode 100644 src/test/ui/polymorphization/lifetimes.stderr create mode 100644 src/test/ui/polymorphization/normalized_sig_types.rs create mode 100644 src/test/ui/polymorphization/predicates.rs create mode 100644 src/test/ui/polymorphization/predicates.stderr create mode 100644 src/test/ui/polymorphization/promoted-function-1.rs create mode 100644 src/test/ui/polymorphization/promoted-function-1.stderr create mode 100644 src/test/ui/polymorphization/promoted-function-2.rs create mode 100644 src/test/ui/polymorphization/promoted-function-2.stderr create mode 100644 src/test/ui/polymorphization/promoted-function-3.rs create mode 100644 src/test/ui/polymorphization/promoted-function.rs create mode 100644 src/test/ui/polymorphization/symbol-ambiguity.rs create mode 100644 src/test/ui/polymorphization/too-many-generic-params.rs create mode 100644 src/test/ui/polymorphization/type_parameters/closures.rs create mode 100644 src/test/ui/polymorphization/type_parameters/closures.stderr create mode 100644 src/test/ui/polymorphization/type_parameters/functions.rs create mode 100644 src/test/ui/polymorphization/type_parameters/functions.stderr create mode 100644 src/test/ui/polymorphization/unsized_cast.rs create mode 100644 src/test/ui/polymorphization/unsized_cast.stderr (limited to 'src/test/ui/polymorphization') diff --git a/src/test/ui/polymorphization/closure_in_upvar/fn.rs b/src/test/ui/polymorphization/closure_in_upvar/fn.rs new file mode 100644 index 000000000..e10308588 --- /dev/null +++ b/src/test/ui/polymorphization/closure_in_upvar/fn.rs @@ -0,0 +1,29 @@ +// build-pass +// compile-flags:-Zpolymorphize=on -Csymbol-mangling-version=v0 + +fn foo(f: impl Fn()) { + let x = |_: ()| (); + + // Don't use `f` in `y`, but refer to `x` so that the closure substs contain a reference to + // `x` that will differ for each instantiation despite polymorphisation of the varying + // argument. + let y = || x(()); + + // Consider `f` used in `foo`. + f(); + // Use `y` so that it is visited in monomorphisation collection. + y(); +} + +fn entry_a() { + foo(|| ()); +} + +fn entry_b() { + foo(|| ()); +} + +fn main() { + entry_a(); + entry_b(); +} diff --git a/src/test/ui/polymorphization/closure_in_upvar/fnmut.rs b/src/test/ui/polymorphization/closure_in_upvar/fnmut.rs new file mode 100644 index 000000000..62164ff94 --- /dev/null +++ b/src/test/ui/polymorphization/closure_in_upvar/fnmut.rs @@ -0,0 +1,34 @@ +// build-pass +// compile-flags:-Zpolymorphize=on -Csymbol-mangling-version=v0 + +fn foo(f: impl Fn()) { + // Mutate an upvar from `x` so that it implements `FnMut`. + let mut outer = 3; + let mut x = |_: ()| { + outer = 4; + () + }; + + // Don't use `f` in `y`, but refer to `x` so that the closure substs contain a reference to + // `x` that will differ for each instantiation despite polymorphisation of the varying + // argument. + let mut y = || x(()); + + // Consider `f` used in `foo`. + f(); + // Use `y` so that it is visited in monomorphisation collection. + y(); +} + +fn entry_a() { + foo(|| ()); +} + +fn entry_b() { + foo(|| ()); +} + +fn main() { + entry_a(); + entry_b(); +} diff --git a/src/test/ui/polymorphization/closure_in_upvar/fnonce.rs b/src/test/ui/polymorphization/closure_in_upvar/fnonce.rs new file mode 100644 index 000000000..7a364882f --- /dev/null +++ b/src/test/ui/polymorphization/closure_in_upvar/fnonce.rs @@ -0,0 +1,34 @@ +// build-pass +// compile-flags:-Zpolymorphize=on -Csymbol-mangling-version=v0 + +fn foo(f: impl Fn()) { + // Move a non-copy type into `x` so that it implements `FnOnce`. + let outer = Vec::::new(); + let x = move |_: ()| { + let inner = outer; + () + }; + + // Don't use `f` in `y`, but refer to `x` so that the closure substs contain a reference to + // `x` that will differ for each instantiation despite polymorphisation of the varying + // argument. + let y = || x(()); + + // Consider `f` used in `foo`. + f(); + // Use `y` so that it is visited in monomorphisation collection. + y(); +} + +fn entry_a() { + foo(|| ()); +} + +fn entry_b() { + foo(|| ()); +} + +fn main() { + entry_a(); + entry_b(); +} diff --git a/src/test/ui/polymorphization/closure_in_upvar/other.rs b/src/test/ui/polymorphization/closure_in_upvar/other.rs new file mode 100644 index 000000000..27d59ec88 --- /dev/null +++ b/src/test/ui/polymorphization/closure_in_upvar/other.rs @@ -0,0 +1,38 @@ +// build-pass +// compile-flags:-Zpolymorphize=on -Csymbol-mangling-version=v0 + +fn y_uses_f(f: impl Fn()) { + let x = |_: ()| (); + + let y = || { + f(); + x(()); + }; + + f(); + y(); +} + +fn x_uses_f(f: impl Fn()) { + let x = |_: ()| { f(); }; + + let y = || x(()); + + f(); + y(); +} + +fn entry_a() { + x_uses_f(|| ()); + y_uses_f(|| ()); +} + +fn entry_b() { + x_uses_f(|| ()); + y_uses_f(|| ()); +} + +fn main() { + entry_a(); + entry_b(); +} diff --git a/src/test/ui/polymorphization/const_parameters/closures.rs b/src/test/ui/polymorphization/const_parameters/closures.rs new file mode 100644 index 000000000..2f41beeb9 --- /dev/null +++ b/src/test/ui/polymorphization/const_parameters/closures.rs @@ -0,0 +1,67 @@ +// build-fail +// compile-flags:-Zpolymorphize=on +#![feature(generic_const_exprs, rustc_attrs)] +//~^ WARN the feature `generic_const_exprs` is incomplete + +// This test checks that the polymorphization analysis correctly detects unused const +// parameters in closures. + +// Function doesn't have any generic parameters to be unused. +#[rustc_polymorphize_error] +pub fn no_parameters() { + let _ = || {}; +} + +// Function has an unused generic parameter in parent and closure. +#[rustc_polymorphize_error] +pub fn unused() -> usize { + //~^ ERROR item has unused generic parameters + let add_one = |x: usize| x + 1; + //~^ ERROR item has unused generic parameters + add_one(3) +} + +// Function has an unused generic parameter in closure, but not in parent. +#[rustc_polymorphize_error] +pub fn used_parent() -> usize { + let x: usize = T; + let add_one = |x: usize| x + 1; + //~^ ERROR item has unused generic parameters + x + add_one(3) +} + +// Function uses generic parameter in value of a binding in closure. +#[rustc_polymorphize_error] +pub fn used_binding() -> usize { + let x = || { + let y: usize = T; + y + }; + + x() +} + +// Closure uses a value as an upvar, which used the generic parameter. +#[rustc_polymorphize_error] +pub fn unused_upvar() -> usize { + let x: usize = T; + let y = || x; + //~^ ERROR item has unused generic parameters + y() +} + +// Closure uses generic parameter in substitutions to another function. +#[rustc_polymorphize_error] +pub fn used_substs() -> usize { + let x = || unused::(); + x() +} + +fn main() { + no_parameters(); + let _ = unused::<1>(); + let _ = used_parent::<1>(); + let _ = used_binding::<1>(); + let _ = unused_upvar::<1>(); + let _ = used_substs::<1>(); +} diff --git a/src/test/ui/polymorphization/const_parameters/closures.stderr b/src/test/ui/polymorphization/const_parameters/closures.stderr new file mode 100644 index 000000000..fdf817cae --- /dev/null +++ b/src/test/ui/polymorphization/const_parameters/closures.stderr @@ -0,0 +1,44 @@ +warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/closures.rs:3:12 + | +LL | #![feature(generic_const_exprs, rustc_attrs)] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #76560 for more information + +error: item has unused generic parameters + --> $DIR/closures.rs:19:19 + | +LL | pub fn unused() -> usize { + | -------------- generic parameter `T` is unused +LL | +LL | let add_one = |x: usize| x + 1; + | ^^^^^^^^^^ + +error: item has unused generic parameters + --> $DIR/closures.rs:17:8 + | +LL | pub fn unused() -> usize { + | ^^^^^^ -------------- generic parameter `T` is unused + +error: item has unused generic parameters + --> $DIR/closures.rs:28:19 + | +LL | pub fn used_parent() -> usize { + | -------------- generic parameter `T` is unused +LL | let x: usize = T; +LL | let add_one = |x: usize| x + 1; + | ^^^^^^^^^^ + +error: item has unused generic parameters + --> $DIR/closures.rs:48:13 + | +LL | pub fn unused_upvar() -> usize { + | -------------- generic parameter `T` is unused +LL | let x: usize = T; +LL | let y = || x; + | ^^ + +error: aborting due to 4 previous errors; 1 warning emitted + diff --git a/src/test/ui/polymorphization/const_parameters/functions.rs b/src/test/ui/polymorphization/const_parameters/functions.rs new file mode 100644 index 000000000..cbc1b63fb --- /dev/null +++ b/src/test/ui/polymorphization/const_parameters/functions.rs @@ -0,0 +1,37 @@ +// build-fail +// compile-flags:-Zpolymorphize=on +#![feature(generic_const_exprs, rustc_attrs)] +//~^ WARN the feature `generic_const_exprs` is incomplete + +// This test checks that the polymorphization analysis correctly detects unused const +// parameters in functions. + +// Function doesn't have any generic parameters to be unused. +#[rustc_polymorphize_error] +pub fn no_parameters() {} + +// Function has an unused generic parameter. +#[rustc_polymorphize_error] +pub fn unused() { + //~^ ERROR item has unused generic parameters +} + +// Function uses generic parameter in value of a binding. +#[rustc_polymorphize_error] +pub fn used_binding() -> usize { + let x: usize = T; + x +} + +// Function uses generic parameter in substitutions to another function. +#[rustc_polymorphize_error] +pub fn used_substs() { + unused::() +} + +fn main() { + no_parameters(); + unused::<1>(); + used_binding::<1>(); + used_substs::<1>(); +} diff --git a/src/test/ui/polymorphization/const_parameters/functions.stderr b/src/test/ui/polymorphization/const_parameters/functions.stderr new file mode 100644 index 000000000..f2b5a7307 --- /dev/null +++ b/src/test/ui/polymorphization/const_parameters/functions.stderr @@ -0,0 +1,17 @@ +warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/functions.rs:3:12 + | +LL | #![feature(generic_const_exprs, rustc_attrs)] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #76560 for more information + +error: item has unused generic parameters + --> $DIR/functions.rs:15:8 + | +LL | pub fn unused() { + | ^^^^^^ -------------- generic parameter `T` is unused + +error: aborting due to previous error; 1 warning emitted + diff --git a/src/test/ui/polymorphization/drop_shims/simple.rs b/src/test/ui/polymorphization/drop_shims/simple.rs new file mode 100644 index 000000000..2695dc6d4 --- /dev/null +++ b/src/test/ui/polymorphization/drop_shims/simple.rs @@ -0,0 +1,22 @@ +// check-pass +// compile-flags:-Zpolymorphize=on + +pub struct OnDrop(pub F); + +impl Drop for OnDrop { + fn drop(&mut self) { } +} + +fn foo( + _: R, + _: S, +) { + let bar = || { + let _ = OnDrop(|| ()); + }; + let _ = bar(); +} + +fn main() { + foo(3u32, || {}); +} diff --git a/src/test/ui/polymorphization/drop_shims/transitive.rs b/src/test/ui/polymorphization/drop_shims/transitive.rs new file mode 100644 index 000000000..c22891171 --- /dev/null +++ b/src/test/ui/polymorphization/drop_shims/transitive.rs @@ -0,0 +1,27 @@ +// check-pass +// compile-flags:-Zpolymorphize=on + +pub struct OnDrop(pub F); + +impl Drop for OnDrop { + fn drop(&mut self) { } +} + +fn bar(f: F) { + let _ = OnDrop(|| ()); + f() +} + +fn foo( + _: R, + _: S, +) { + let bar = || { + bar(|| {}) + }; + let _ = bar(); +} + +fn main() { + foo(3u32, || {}); +} diff --git a/src/test/ui/polymorphization/generators.rs b/src/test/ui/polymorphization/generators.rs new file mode 100644 index 000000000..779bac0ac --- /dev/null +++ b/src/test/ui/polymorphization/generators.rs @@ -0,0 +1,92 @@ +// build-fail +// compile-flags:-Zpolymorphize=on -Zinline-mir=off +#![feature(generic_const_exprs, generators, generator_trait, rustc_attrs)] +//~^ WARN the feature `generic_const_exprs` is incomplete + +use std::marker::Unpin; +use std::ops::{Generator, GeneratorState}; +use std::pin::Pin; + +enum YieldOrReturn { + Yield(Y), + Return(R), +} + +fn finish(mut t: T) -> Vec> +where + T: Generator<(), Yield = Y, Return = R> + Unpin, +{ + let mut results = Vec::new(); + loop { + match Pin::new(&mut t).resume(()) { + GeneratorState::Yielded(yielded) => results.push(YieldOrReturn::Yield(yielded)), + GeneratorState::Complete(returned) => { + results.push(YieldOrReturn::Return(returned)); + return results; + } + } + } +} + +// This test checks that the polymorphization analysis functions on generators. + +#[rustc_polymorphize_error] +pub fn unused_type() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { + || { + //~^ ERROR item has unused generic parameters + yield 1; + 2 + } +} + +#[rustc_polymorphize_error] +pub fn used_type_in_yield() -> impl Generator<(), Yield = Y, Return = u32> + Unpin { + || { + yield Y::default(); + 2 + } +} + +#[rustc_polymorphize_error] +pub fn used_type_in_return() -> impl Generator<(), Yield = u32, Return = R> + Unpin { + || { + yield 3; + R::default() + } +} + +#[rustc_polymorphize_error] +pub fn unused_const() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { + || { + //~^ ERROR item has unused generic parameters + yield 1; + 2 + } +} + +#[rustc_polymorphize_error] +pub fn used_const_in_yield() -> impl Generator<(), Yield = u32, Return = u32> + Unpin +{ + || { + yield Y; + 2 + } +} + +#[rustc_polymorphize_error] +pub fn used_const_in_return() -> impl Generator<(), Yield = u32, Return = u32> + Unpin +{ + || { + yield 4; + R + } +} + +fn main() { + finish(unused_type::()); + finish(used_type_in_yield::()); + finish(used_type_in_return::()); + finish(unused_const::<1u32>()); + finish(used_const_in_yield::<1u32>()); + finish(used_const_in_return::<1u32>()); +} diff --git a/src/test/ui/polymorphization/generators.stderr b/src/test/ui/polymorphization/generators.stderr new file mode 100644 index 000000000..a24eee5fe --- /dev/null +++ b/src/test/ui/polymorphization/generators.stderr @@ -0,0 +1,39 @@ +warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/generators.rs:3:12 + | +LL | #![feature(generic_const_exprs, generators, generator_trait, rustc_attrs)] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #76560 for more information + +error: item has unused generic parameters + --> $DIR/generators.rs:35:5 + | +LL | pub fn unused_type() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { + | - generic parameter `T` is unused +LL | || { + | ^^ + +note: the above error was encountered while instantiating `fn finish::<[generator@$DIR/generators.rs:35:5: 35:7], u32, u32>` + --> $DIR/generators.rs:86:5 + | +LL | finish(unused_type::()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: item has unused generic parameters + --> $DIR/generators.rs:60:5 + | +LL | pub fn unused_const() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { + | ------------ generic parameter `T` is unused +LL | || { + | ^^ + +note: the above error was encountered while instantiating `fn finish::<[generator@$DIR/generators.rs:60:5: 60:7], u32, u32>` + --> $DIR/generators.rs:89:5 + | +LL | finish(unused_const::<1u32>()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors; 1 warning emitted + diff --git a/src/test/ui/polymorphization/issue-74614.rs b/src/test/ui/polymorphization/issue-74614.rs new file mode 100644 index 000000000..8b0c00b13 --- /dev/null +++ b/src/test/ui/polymorphization/issue-74614.rs @@ -0,0 +1,18 @@ +// compile-flags:-Zpolymorphize=on +// build-pass + +fn test() { + std::mem::size_of::(); +} + +pub fn foo(_: T) -> &'static fn() { + &(test:: as fn()) +} + +fn outer() { + foo(|| ()); +} + +fn main() { + outer::(); +} diff --git a/src/test/ui/polymorphization/issue-74636.rs b/src/test/ui/polymorphization/issue-74636.rs new file mode 100644 index 000000000..4c532f451 --- /dev/null +++ b/src/test/ui/polymorphization/issue-74636.rs @@ -0,0 +1,16 @@ +// compile-flags:-Zpolymorphize=on +// build-pass + +use std::any::TypeId; + +pub fn foo(_: T) -> TypeId { + TypeId::of::() +} + +fn outer() { + foo(|| ()); +} + +fn main() { + outer::(); +} diff --git a/src/test/ui/polymorphization/lifetimes.rs b/src/test/ui/polymorphization/lifetimes.rs new file mode 100644 index 000000000..f26df4523 --- /dev/null +++ b/src/test/ui/polymorphization/lifetimes.rs @@ -0,0 +1,25 @@ +// build-fail +// compile-flags:-Zpolymorphize=on +#![feature(rustc_attrs)] + +// This test checks that the polymorphization analysis doesn't break when the +// function/closure doesn't just have generic parameters. + +// Function has an unused generic parameter. +#[rustc_polymorphize_error] +pub fn unused<'a, T>(_: &'a u32) { + //~^ ERROR item has unused generic parameters +} + +#[rustc_polymorphize_error] +pub fn used<'a, T: Default>(_: &'a u32) -> u32 { + let _: T = Default::default(); + let add_one = |x: u32| x + 1; + //~^ ERROR item has unused generic parameters + add_one(3) +} + +fn main() { + unused::(&3); + used::(&3); +} diff --git a/src/test/ui/polymorphization/lifetimes.stderr b/src/test/ui/polymorphization/lifetimes.stderr new file mode 100644 index 000000000..4773dd4fa --- /dev/null +++ b/src/test/ui/polymorphization/lifetimes.stderr @@ -0,0 +1,17 @@ +error: item has unused generic parameters + --> $DIR/lifetimes.rs:10:8 + | +LL | pub fn unused<'a, T>(_: &'a u32) { + | ^^^^^^ - generic parameter `T` is unused + +error: item has unused generic parameters + --> $DIR/lifetimes.rs:17:19 + | +LL | pub fn used<'a, T: Default>(_: &'a u32) -> u32 { + | - generic parameter `T` is unused +LL | let _: T = Default::default(); +LL | let add_one = |x: u32| x + 1; + | ^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/polymorphization/normalized_sig_types.rs b/src/test/ui/polymorphization/normalized_sig_types.rs new file mode 100644 index 000000000..d732b1071 --- /dev/null +++ b/src/test/ui/polymorphization/normalized_sig_types.rs @@ -0,0 +1,26 @@ +// build-pass +// compile-flags:-Zpolymorphize=on + +pub trait ParallelIterator: Sized { + fn drive>(_: C) { + C::into_folder(); + } +} + +pub trait Consumer: Sized { + type Result; + fn into_folder() -> Self::Result; +} + +impl ParallelIterator for () {} + +impl Consumer for F { + type Result = (); + fn into_folder() -> Self::Result { + unimplemented!() + } +} + +fn main() { + <()>::drive(|| ()); +} diff --git a/src/test/ui/polymorphization/predicates.rs b/src/test/ui/polymorphization/predicates.rs new file mode 100644 index 000000000..6a5fc2e33 --- /dev/null +++ b/src/test/ui/polymorphization/predicates.rs @@ -0,0 +1,95 @@ +// build-fail +// compile-flags: -Copt-level=0 -Zpolymorphize=on + +#![feature(rustc_attrs)] + +// This test checks that `T` is considered used in `foo`, because it is used in a predicate for +// `I`, which is used. + +#[rustc_polymorphize_error] +fn bar() { + //~^ ERROR item has unused generic parameters +} + +#[rustc_polymorphize_error] +fn foo(_: I) +//~^ ERROR item has unused generic parameters +where + I: Iterator, +{ + bar::() +} + +#[rustc_polymorphize_error] +fn baz(_: I) +//~^ ERROR item has unused generic parameters +where + std::iter::Repeat: Iterator, +{ + bar::() +} + +// In addition, check that `I` is considered used in `next::{{closure}}`, because `T` is used and +// `T` is really just `I::Item`. `E` is used due to the fixed-point marking of predicates. + +pub(crate) struct Foo<'a, I, E>(I, &'a E); + +impl<'a, I, T: 'a, E> Iterator for Foo<'a, I, E> +where + I: Iterator, +{ + type Item = T; + + #[rustc_polymorphize_error] + fn next(&mut self) -> Option { + self.find(|_| true) + //~^ ERROR item has unused generic parameters + } +} + +// Furthermore, check that `B` is considered used because `C` is used, and that `A` is considered +// used because `B` is now used. + +trait Baz {} + +impl Baz for u8 {} +impl Baz for u16 {} + +#[rustc_polymorphize_error] +fn quux() -> usize +//~^ ERROR item has unused generic parameters +where + A: Baz, + B: Baz, +{ + std::mem::size_of::() +} + +// Finally, check that `F` is considered used because `G` is used when neither are in the self-ty +// of the predicate. + +trait Foobar {} + +impl Foobar for () {} + +#[rustc_polymorphize_error] +fn foobar() -> usize +//~^ ERROR item has unused generic parameters +where + (): Foobar, +{ + std::mem::size_of::() +} + +fn main() { + let x = &[2u32]; + foo(x.iter()); + baz(x.iter()); + + let mut a = Foo([(1u32, 1u16)].iter(), &1u16); + let _ = a.next(); + + let _ = quux::(); + + let _ = foobar::(); +} diff --git a/src/test/ui/polymorphization/predicates.stderr b/src/test/ui/polymorphization/predicates.stderr new file mode 100644 index 000000000..e5af1d751 --- /dev/null +++ b/src/test/ui/polymorphization/predicates.stderr @@ -0,0 +1,51 @@ +error: item has unused generic parameters + --> $DIR/predicates.rs:15:4 + | +LL | fn foo(_: I) + | ^^^ - generic parameter `T` is unused + +error: item has unused generic parameters + --> $DIR/predicates.rs:24:4 + | +LL | fn baz(_: I) + | ^^^ - generic parameter `T` is unused + +error: item has unused generic parameters + --> $DIR/predicates.rs:45:19 + | +LL | impl<'a, I, T: 'a, E> Iterator for Foo<'a, I, E> + | - - generic parameter `E` is unused + | | + | generic parameter `I` is unused +... +LL | self.find(|_| true) + | ^^^ + +error: item has unused generic parameters + --> $DIR/predicates.rs:59:4 + | +LL | fn quux() -> usize + | ^^^^ - - generic parameter `B` is unused + | | + | generic parameter `A` is unused + +error: item has unused generic parameters + --> $DIR/predicates.rs:76:4 + | +LL | fn foobar() -> usize + | ^^^^^^ - generic parameter `F` is unused + +error: item has unused generic parameters + --> $DIR/predicates.rs:10:4 + | +LL | fn bar() { + | ^^^ - generic parameter `I` is unused + +note: the above error was encountered while instantiating `fn foo::, T>` + --> $DIR/predicates.rs:86:5 + | +LL | foo(x.iter()); + | ^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/polymorphization/promoted-function-1.rs b/src/test/ui/polymorphization/promoted-function-1.rs new file mode 100644 index 000000000..2cd026734 --- /dev/null +++ b/src/test/ui/polymorphization/promoted-function-1.rs @@ -0,0 +1,12 @@ +// build-fail +// compile-flags: -Zpolymorphize=on +#![crate_type = "lib"] +#![feature(rustc_attrs)] + +fn foo<'a>(_: &'a ()) {} + +#[rustc_polymorphize_error] +pub fn test() { + //~^ ERROR item has unused generic parameters + foo(&()); +} diff --git a/src/test/ui/polymorphization/promoted-function-1.stderr b/src/test/ui/polymorphization/promoted-function-1.stderr new file mode 100644 index 000000000..fcbb86949 --- /dev/null +++ b/src/test/ui/polymorphization/promoted-function-1.stderr @@ -0,0 +1,8 @@ +error: item has unused generic parameters + --> $DIR/promoted-function-1.rs:9:8 + | +LL | pub fn test() { + | ^^^^ - generic parameter `T` is unused + +error: aborting due to previous error + diff --git a/src/test/ui/polymorphization/promoted-function-2.rs b/src/test/ui/polymorphization/promoted-function-2.rs new file mode 100644 index 000000000..d2d0f3368 --- /dev/null +++ b/src/test/ui/polymorphization/promoted-function-2.rs @@ -0,0 +1,16 @@ +// build-fail +// compile-flags:-Zpolymorphize=on +#![crate_type = "lib"] +#![feature(generic_const_exprs, rustc_attrs)] +//~^ WARN the feature `generic_const_exprs` is incomplete + +#[rustc_polymorphize_error] +fn test() { + //~^ ERROR item has unused generic parameters + let x = [0; 3 + 4]; +} + +pub fn caller() { + test::(); + test::>(); +} diff --git a/src/test/ui/polymorphization/promoted-function-2.stderr b/src/test/ui/polymorphization/promoted-function-2.stderr new file mode 100644 index 000000000..4d7bab6aa --- /dev/null +++ b/src/test/ui/polymorphization/promoted-function-2.stderr @@ -0,0 +1,17 @@ +warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/promoted-function-2.rs:4:12 + | +LL | #![feature(generic_const_exprs, rustc_attrs)] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #76560 for more information + +error: item has unused generic parameters + --> $DIR/promoted-function-2.rs:8:4 + | +LL | fn test() { + | ^^^^ - generic parameter `T` is unused + +error: aborting due to previous error; 1 warning emitted + diff --git a/src/test/ui/polymorphization/promoted-function-3.rs b/src/test/ui/polymorphization/promoted-function-3.rs new file mode 100644 index 000000000..bbd991e36 --- /dev/null +++ b/src/test/ui/polymorphization/promoted-function-3.rs @@ -0,0 +1,14 @@ +// run-pass +// compile-flags: -Zpolymorphize=on -Zmir-opt-level=4 + +fn caller() -> &'static usize { + callee::() +} + +fn callee() -> &'static usize { + &std::mem::size_of::() +} + +fn main() { + assert_eq!(caller::<(), ()>(), &0); +} diff --git a/src/test/ui/polymorphization/promoted-function.rs b/src/test/ui/polymorphization/promoted-function.rs new file mode 100644 index 000000000..a56a8e70e --- /dev/null +++ b/src/test/ui/polymorphization/promoted-function.rs @@ -0,0 +1,15 @@ +// run-pass +// compile-flags:-Zpolymorphize=on + +fn fop() {} + +fn bar() -> &'static fn() { + &(fop:: as fn()) +} +pub const FN: &'static fn() = &(fop:: as fn()); + +fn main() { + bar::(); + bar::(); + (FN)(); +} diff --git a/src/test/ui/polymorphization/symbol-ambiguity.rs b/src/test/ui/polymorphization/symbol-ambiguity.rs new file mode 100644 index 000000000..6277a902f --- /dev/null +++ b/src/test/ui/polymorphization/symbol-ambiguity.rs @@ -0,0 +1,22 @@ +// build-pass +// compile-flags: -Zpolymorphize=on -Csymbol-mangling-version=v0 + +pub(crate) struct Foo<'a, I, E>(I, &'a E); + +impl<'a, I, T: 'a, E> Iterator for Foo<'a, I, E> +where + I: Iterator, +{ + type Item = T; + + fn next(&mut self) -> Option { + self.find(|_| true) + } +} + +fn main() { + let mut a = Foo([(1u32, 1u16)].iter(), &1u16); + let mut b = Foo([(1u16, 1u32)].iter(), &1u32); + let _ = a.next(); + let _ = b.next(); +} diff --git a/src/test/ui/polymorphization/too-many-generic-params.rs b/src/test/ui/polymorphization/too-many-generic-params.rs new file mode 100644 index 000000000..ec6244630 --- /dev/null +++ b/src/test/ui/polymorphization/too-many-generic-params.rs @@ -0,0 +1,85 @@ +// build-pass +#![feature(rustc_attrs)] + +// This test checks that the analysis doesn't panic when there are >64 generic parameters, but +// instead considers those parameters used. + +#[rustc_polymorphize_error] +fn bar() +{ + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option

= None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; +} + +fn main() { + bar::(); +} diff --git a/src/test/ui/polymorphization/type_parameters/closures.rs b/src/test/ui/polymorphization/type_parameters/closures.rs new file mode 100644 index 000000000..07ab1355a --- /dev/null +++ b/src/test/ui/polymorphization/type_parameters/closures.rs @@ -0,0 +1,161 @@ +// build-fail +// compile-flags:-Zpolymorphize=on +#![feature(stmt_expr_attributes, rustc_attrs)] + +// This test checks that the polymorphization analysis correctly detects unused type +// parameters in closures. + +// Function doesn't have any generic parameters to be unused. +#[rustc_polymorphize_error] +pub fn no_parameters() { + let _ = || {}; +} + +// Function has an unused generic parameter in parent and closure. +#[rustc_polymorphize_error] +pub fn unused() -> u32 { + //~^ ERROR item has unused generic parameters + + let add_one = |x: u32| x + 1; + //~^ ERROR item has unused generic parameters + add_one(3) +} + +// Function has an unused generic parameter in closure, but not in parent. +#[rustc_polymorphize_error] +pub fn used_parent() -> u32 { + let _: T = Default::default(); + let add_one = |x: u32| x + 1; + //~^ ERROR item has unused generic parameters + add_one(3) +} + +// Function uses generic parameter in value of a binding in closure. +#[rustc_polymorphize_error] +pub fn used_binding_value() -> T { + let x = || { + let y: T = Default::default(); + y + }; + + x() +} + +// Function uses generic parameter in generic of a binding in closure. +#[rustc_polymorphize_error] +pub fn used_binding_generic() -> Option { + let x = || { + let y: Option = None; + y + }; + + x() +} + +// Function and closure uses generic parameter in argument. +#[rustc_polymorphize_error] +pub fn used_argument(t: T) -> u32 { + let x = |_: T| 3; + x(t) +} + +// Closure uses generic parameter in argument. +#[rustc_polymorphize_error] +pub fn used_argument_closure() -> u32 { + let t: T = Default::default(); + + let x = |_: T| 3; + x(t) +} + +// Closure uses generic parameter as upvar. +#[rustc_polymorphize_error] +pub fn used_upvar() -> T { + let x: T = Default::default(); + + let y = || x; + y() +} + +// Closure uses generic parameter in substitutions to another function. +#[rustc_polymorphize_error] +pub fn used_substs() -> u32 { + let x = || unused::(); + x() +} + +struct Foo(F); + +impl Foo { + // Function has an unused generic parameter from impl and fn. + #[rustc_polymorphize_error] + pub fn unused_all() -> u32 { + //~^ ERROR item has unused generic parameters + let add_one = |x: u32| x + 1; + //~^ ERROR item has unused generic parameters + add_one(3) + } + + // Function uses generic parameter from impl and fn in closure. + #[rustc_polymorphize_error] + pub fn used_both() -> u32 { + let add_one = |x: u32| { + let _: F = Default::default(); + let _: G = Default::default(); + x + 1 + }; + + add_one(3) + } + + // Function uses generic parameter from fn in closure. + #[rustc_polymorphize_error] + pub fn used_fn() -> u32 { + //~^ ERROR item has unused generic parameters + let add_one = |x: u32| { + //~^ ERROR item has unused generic parameters + let _: G = Default::default(); + x + 1 + }; + + add_one(3) + } + + // Function uses generic parameter from impl in closure. + #[rustc_polymorphize_error] + pub fn used_impl() -> u32 { + //~^ ERROR item has unused generic parameters + let add_one = |x: u32| { + //~^ ERROR item has unused generic parameters + let _: F = Default::default(); + x + 1 + }; + + add_one(3) + } + + // Closure uses generic parameter in substitutions to another function. + #[rustc_polymorphize_error] + pub fn used_substs() -> u32 { + let x = || unused::(); + x() + } +} + +fn main() { + no_parameters(); + let _ = unused::(); + let _ = used_parent::(); + let _ = used_binding_value::(); + let _ = used_binding_generic::(); + let _ = used_argument(3u32); + let _ = used_argument_closure::(); + let _ = used_upvar::(); + let _ = used_substs::(); + + let _ = Foo::::unused_all::(); + let _ = Foo::::used_both::(); + let _ = Foo::::used_impl::(); + let _ = Foo::::used_fn::(); + let _ = Foo::::used_substs(); +} diff --git a/src/test/ui/polymorphization/type_parameters/closures.stderr b/src/test/ui/polymorphization/type_parameters/closures.stderr new file mode 100644 index 000000000..94a4a08bd --- /dev/null +++ b/src/test/ui/polymorphization/type_parameters/closures.stderr @@ -0,0 +1,80 @@ +error: item has unused generic parameters + --> $DIR/closures.rs:19:19 + | +LL | pub fn unused() -> u32 { + | - generic parameter `T` is unused +... +LL | let add_one = |x: u32| x + 1; + | ^^^^^^^^ + +error: item has unused generic parameters + --> $DIR/closures.rs:16:8 + | +LL | pub fn unused() -> u32 { + | ^^^^^^ - generic parameter `T` is unused + +error: item has unused generic parameters + --> $DIR/closures.rs:28:19 + | +LL | pub fn used_parent() -> u32 { + | - generic parameter `T` is unused +LL | let _: T = Default::default(); +LL | let add_one = |x: u32| x + 1; + | ^^^^^^^^ + +error: item has unused generic parameters + --> $DIR/closures.rs:94:23 + | +LL | impl Foo { + | - generic parameter `F` is unused +... +LL | pub fn unused_all() -> u32 { + | - generic parameter `G` is unused +LL | +LL | let add_one = |x: u32| x + 1; + | ^^^^^^^^ + +error: item has unused generic parameters + --> $DIR/closures.rs:92:12 + | +LL | impl Foo { + | - generic parameter `F` is unused +... +LL | pub fn unused_all() -> u32 { + | ^^^^^^^^^^ - generic parameter `G` is unused + +error: item has unused generic parameters + --> $DIR/closures.rs:128:23 + | +LL | pub fn used_impl() -> u32 { + | - generic parameter `G` is unused +LL | +LL | let add_one = |x: u32| { + | ^^^^^^^^ + +error: item has unused generic parameters + --> $DIR/closures.rs:126:12 + | +LL | pub fn used_impl() -> u32 { + | ^^^^^^^^^ - generic parameter `G` is unused + +error: item has unused generic parameters + --> $DIR/closures.rs:115:23 + | +LL | impl Foo { + | - generic parameter `F` is unused +... +LL | let add_one = |x: u32| { + | ^^^^^^^^ + +error: item has unused generic parameters + --> $DIR/closures.rs:113:12 + | +LL | impl Foo { + | - generic parameter `F` is unused +... +LL | pub fn used_fn() -> u32 { + | ^^^^^^^ + +error: aborting due to 9 previous errors + diff --git a/src/test/ui/polymorphization/type_parameters/functions.rs b/src/test/ui/polymorphization/type_parameters/functions.rs new file mode 100644 index 000000000..aad957e1d --- /dev/null +++ b/src/test/ui/polymorphization/type_parameters/functions.rs @@ -0,0 +1,96 @@ +// build-fail +// compile-flags:-Zpolymorphize=on +#![feature(rustc_attrs)] + +// This test checks that the polymorphization analysis correctly detects unused type +// parameters in functions. + +// Function doesn't have any generic parameters to be unused. +#[rustc_polymorphize_error] +pub fn no_parameters() {} + +// Function has an unused generic parameter. +#[rustc_polymorphize_error] +pub fn unused() { + //~^ ERROR item has unused generic parameters +} + +// Function uses generic parameter in value of a binding. +#[rustc_polymorphize_error] +pub fn used_binding_value() { + let _: T = Default::default(); +} + +// Function uses generic parameter in generic of a binding. +#[rustc_polymorphize_error] +pub fn used_binding_generic() { + let _: Option = None; +} + +// Function uses generic parameter in argument. +#[rustc_polymorphize_error] +pub fn used_argument(_: T) {} + +// Function uses generic parameter in substitutions to another function. +#[rustc_polymorphize_error] +pub fn used_substs() { + unused::() +} + +struct Foo(F); + +impl Foo { + // Function has an unused generic parameter from impl. + #[rustc_polymorphize_error] + pub fn unused_impl() { + //~^ ERROR item has unused generic parameters + } + + // Function has an unused generic parameter from impl and fn. + #[rustc_polymorphize_error] + pub fn unused_both() { + //~^ ERROR item has unused generic parameters + } + + // Function uses generic parameter from impl. + #[rustc_polymorphize_error] + pub fn used_impl() { + let _: F = Default::default(); + } + + // Function uses generic parameter from impl. + #[rustc_polymorphize_error] + pub fn used_fn() { + //~^ ERROR item has unused generic parameters + let _: G = Default::default(); + } + + // Function uses generic parameter from impl. + #[rustc_polymorphize_error] + pub fn used_both() { + let _: F = Default::default(); + let _: G = Default::default(); + } + + // Function uses generic parameter in substitutions to another function. + #[rustc_polymorphize_error] + pub fn used_substs() { + unused::() + } +} + +fn main() { + no_parameters(); + unused::(); + used_binding_value::(); + used_binding_generic::(); + used_argument(3u32); + used_substs::(); + + Foo::::unused_impl(); + Foo::::unused_both::(); + Foo::::used_impl(); + Foo::::used_fn::(); + Foo::::used_both::(); + Foo::::used_substs(); +} diff --git a/src/test/ui/polymorphization/type_parameters/functions.stderr b/src/test/ui/polymorphization/type_parameters/functions.stderr new file mode 100644 index 000000000..d629ff7bb --- /dev/null +++ b/src/test/ui/polymorphization/type_parameters/functions.stderr @@ -0,0 +1,35 @@ +error: item has unused generic parameters + --> $DIR/functions.rs:14:8 + | +LL | pub fn unused() { + | ^^^^^^ - generic parameter `T` is unused + +error: item has unused generic parameters + --> $DIR/functions.rs:45:12 + | +LL | impl Foo { + | - generic parameter `F` is unused +... +LL | pub fn unused_impl() { + | ^^^^^^^^^^^ + +error: item has unused generic parameters + --> $DIR/functions.rs:51:12 + | +LL | impl Foo { + | - generic parameter `F` is unused +... +LL | pub fn unused_both() { + | ^^^^^^^^^^^ - generic parameter `G` is unused + +error: item has unused generic parameters + --> $DIR/functions.rs:63:12 + | +LL | impl Foo { + | - generic parameter `F` is unused +... +LL | pub fn used_fn() { + | ^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/polymorphization/unsized_cast.rs b/src/test/ui/polymorphization/unsized_cast.rs new file mode 100644 index 000000000..b803fec2c --- /dev/null +++ b/src/test/ui/polymorphization/unsized_cast.rs @@ -0,0 +1,30 @@ +// build-fail +// compile-flags:-Zpolymorphize=on +#![feature(fn_traits, rustc_attrs, unboxed_closures)] + +// This test checks that the polymorphization analysis considers a closure +// as using all generic parameters if it does an unsizing cast. + +#[rustc_polymorphize_error] +fn foo() { + let _: T = Default::default(); + (|| Box::new(|| {}) as Box)(); + //~^ ERROR item has unused generic parameters + //~^^ ERROR item has unused generic parameters +} + +#[rustc_polymorphize_error] +fn foo2() { + let _: T = Default::default(); + (|| { + //~^ ERROR item has unused generic parameters + let call: extern "rust-call" fn(_, _) = Fn::call; + call(&|| {}, ()); + //~^ ERROR item has unused generic parameters + })(); +} + +fn main() { + foo::(); + foo2::(); +} diff --git a/src/test/ui/polymorphization/unsized_cast.stderr b/src/test/ui/polymorphization/unsized_cast.stderr new file mode 100644 index 000000000..27f88d281 --- /dev/null +++ b/src/test/ui/polymorphization/unsized_cast.stderr @@ -0,0 +1,38 @@ +error: item has unused generic parameters + --> $DIR/unsized_cast.rs:11:18 + | +LL | fn foo() { + | - generic parameter `T` is unused +LL | let _: T = Default::default(); +LL | (|| Box::new(|| {}) as Box)(); + | ^^ + +error: item has unused generic parameters + --> $DIR/unsized_cast.rs:11:6 + | +LL | fn foo() { + | - generic parameter `T` is unused +LL | let _: T = Default::default(); +LL | (|| Box::new(|| {}) as Box)(); + | ^^ + +error: item has unused generic parameters + --> $DIR/unsized_cast.rs:22:15 + | +LL | fn foo2() { + | - generic parameter `T` is unused +... +LL | call(&|| {}, ()); + | ^^ + +error: item has unused generic parameters + --> $DIR/unsized_cast.rs:19:6 + | +LL | fn foo2() { + | - generic parameter `T` is unused +LL | let _: T = Default::default(); +LL | (|| { + | ^^ + +error: aborting due to 4 previous errors + -- cgit v1.2.3