summaryrefslogtreecommitdiffstats
path: root/tests/ui/inherent-impls-overlap-check
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/inherent-impls-overlap-check')
-rw-r--r--tests/ui/inherent-impls-overlap-check/auxiliary/repeat.rs54
-rw-r--r--tests/ui/inherent-impls-overlap-check/no-overlap.rs53
-rw-r--r--tests/ui/inherent-impls-overlap-check/overlap.rs71
-rw-r--r--tests/ui/inherent-impls-overlap-check/overlap.stderr47
4 files changed, 225 insertions, 0 deletions
diff --git a/tests/ui/inherent-impls-overlap-check/auxiliary/repeat.rs b/tests/ui/inherent-impls-overlap-check/auxiliary/repeat.rs
new file mode 100644
index 000000000..42ed5d19d
--- /dev/null
+++ b/tests/ui/inherent-impls-overlap-check/auxiliary/repeat.rs
@@ -0,0 +1,54 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::{Ident, Group, TokenStream, TokenTree as Tt};
+
+// This constant has to be above the ALLOCATING_ALGO_THRESHOLD
+// constant in inherent_impls_overlap.rs
+const REPEAT_COUNT: u32 = 501;
+
+#[proc_macro]
+/// Repeats the input many times, while replacing idents
+/// named "IDENT" with "id_$v", where v is a counter.
+pub fn repeat_with_idents(input: TokenStream) -> TokenStream {
+ let mut res = Vec::new();
+ fn visit_stream(res: &mut Vec<Tt>, stream :TokenStream, v: u32) {
+ let mut stream_iter = stream.into_iter();
+ while let Some(tt) = stream_iter.next() {
+ match tt {
+ Tt::Group(group) => {
+ let tt = Tt::Group(visit_group(group, v));
+ res.push(tt);
+ },
+ Tt::Ident(id) => {
+ let id = if &id.to_string() == "IDENT" {
+ Ident::new(&format!("id_{}", v), id.span())
+ } else {
+ id
+ };
+ res.push(Tt::Ident(id));
+ },
+ Tt::Punct(p) => {
+ res.push(Tt::Punct(p));
+ },
+ Tt::Literal(lit) => {
+ res.push(Tt::Literal(lit));
+ },
+ }
+ }
+ }
+ fn visit_group(group :Group, v: u32) -> Group {
+ let mut res = Vec::new();
+ visit_stream(&mut res, group.stream(), v);
+ let stream = res.into_iter().collect();
+ let delim = group.delimiter();
+ Group::new(delim, stream)
+ }
+ for v in 0 .. REPEAT_COUNT {
+ visit_stream(&mut res, input.clone(), v)
+ }
+ res.into_iter().collect()
+}
diff --git a/tests/ui/inherent-impls-overlap-check/no-overlap.rs b/tests/ui/inherent-impls-overlap-check/no-overlap.rs
new file mode 100644
index 000000000..450e6d420
--- /dev/null
+++ b/tests/ui/inherent-impls-overlap-check/no-overlap.rs
@@ -0,0 +1,53 @@
+// run-pass
+// aux-build:repeat.rs
+
+// This tests the allocating algo branch of the
+// inherent impls overlap checker.
+// This branch was added by PR:
+// https://github.com/rust-lang/rust/pull/78317
+// In this test, we repeat many impl blocks
+// to trigger the allocating branch.
+
+#![allow(unused)]
+
+extern crate repeat;
+
+// Simple case where each impl block is distinct
+
+struct Foo {}
+
+repeat::repeat_with_idents!(impl Foo { fn IDENT() {} });
+
+// There are overlapping impl blocks but due to generics,
+// they may overlap.
+
+struct Bar<T>(T);
+
+struct A;
+struct B;
+
+repeat::repeat_with_idents!(impl Bar<A> { fn IDENT() {} });
+
+impl Bar<A> { fn foo() {} }
+impl Bar<B> { fn foo() {} }
+
+// Regression test for issue #89820:
+
+impl Bar<u8> {
+ pub fn a() {}
+ pub fn aa() {}
+}
+
+impl Bar<u16> {
+ pub fn b() {}
+ pub fn bb() {}
+}
+
+impl Bar<u32> {
+ pub fn a() {}
+ pub fn aa() {}
+ pub fn bb() {}
+ pub fn b() {}
+}
+
+fn main() {}
diff --git a/tests/ui/inherent-impls-overlap-check/overlap.rs b/tests/ui/inherent-impls-overlap-check/overlap.rs
new file mode 100644
index 000000000..6f2801197
--- /dev/null
+++ b/tests/ui/inherent-impls-overlap-check/overlap.rs
@@ -0,0 +1,71 @@
+// aux-build:repeat.rs
+
+#![allow(unused)]
+
+// This tests the allocating algo branch of the
+// inherent impls overlap checker.
+// This branch was added by PR:
+// https://github.com/rust-lang/rust/pull/78317
+// In this test, we repeat many impl blocks
+// to trigger the allocating branch.
+
+// Simple overlap
+
+extern crate repeat;
+
+struct Foo {}
+
+repeat::repeat_with_idents!(impl Foo { fn IDENT() {} });
+
+impl Foo { fn hello() {} } //~ERROR duplicate definitions with name `hello`
+impl Foo { fn hello() {} }
+
+// Transitive overlap
+
+struct Foo2 {}
+
+repeat::repeat_with_idents!(impl Foo2 { fn IDENT() {} });
+
+impl Foo2 {
+ fn bar() {}
+ fn hello2() {} //~ERROR duplicate definitions with name `hello2`
+}
+
+impl Foo2 {
+ fn baz() {}
+ fn hello2() {}
+}
+
+// Slightly stronger transitive overlap
+
+struct Foo3 {}
+
+repeat::repeat_with_idents!(impl Foo3 { fn IDENT() {} });
+
+impl Foo3 {
+ fn bar() {} //~ERROR duplicate definitions with name `bar`
+ fn hello3() {} //~ERROR duplicate definitions with name `hello3`
+}
+
+impl Foo3 {
+ fn bar() {}
+ fn hello3() {}
+}
+
+// Generic overlap
+
+struct Bar<T>(T);
+
+struct A;
+struct B;
+
+repeat::repeat_with_idents!(impl Bar<A> { fn IDENT() {} });
+
+impl Bar<A> { fn foo() {} fn bar2() {} }
+impl Bar<B> {
+ fn foo() {}
+ fn bar2() {} //~ERROR duplicate definitions with name `bar2`
+}
+impl Bar<B> { fn bar2() {} }
+
+fn main() {}
diff --git a/tests/ui/inherent-impls-overlap-check/overlap.stderr b/tests/ui/inherent-impls-overlap-check/overlap.stderr
new file mode 100644
index 000000000..3dd279371
--- /dev/null
+++ b/tests/ui/inherent-impls-overlap-check/overlap.stderr
@@ -0,0 +1,47 @@
+error[E0592]: duplicate definitions with name `hello`
+ --> $DIR/overlap.rs:20:12
+ |
+LL | impl Foo { fn hello() {} }
+ | ^^^^^^^^^^ duplicate definitions for `hello`
+LL | impl Foo { fn hello() {} }
+ | ---------- other definition for `hello`
+
+error[E0592]: duplicate definitions with name `hello2`
+ --> $DIR/overlap.rs:31:5
+ |
+LL | fn hello2() {}
+ | ^^^^^^^^^^^ duplicate definitions for `hello2`
+...
+LL | fn hello2() {}
+ | ----------- other definition for `hello2`
+
+error[E0592]: duplicate definitions with name `bar`
+ --> $DIR/overlap.rs:46:5
+ |
+LL | fn bar() {}
+ | ^^^^^^^^ duplicate definitions for `bar`
+...
+LL | fn bar() {}
+ | -------- other definition for `bar`
+
+error[E0592]: duplicate definitions with name `hello3`
+ --> $DIR/overlap.rs:47:5
+ |
+LL | fn hello3() {}
+ | ^^^^^^^^^^^ duplicate definitions for `hello3`
+...
+LL | fn hello3() {}
+ | ----------- other definition for `hello3`
+
+error[E0592]: duplicate definitions with name `bar2`
+ --> $DIR/overlap.rs:67:5
+ |
+LL | fn bar2() {}
+ | ^^^^^^^^^ duplicate definitions for `bar2`
+LL | }
+LL | impl Bar<B> { fn bar2() {} }
+ | --------- other definition for `bar2`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0592`.