about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBryanskiy <ivakin.kir@gmail.com>2024-07-26 16:33:30 +0300
committerBryanskiy <ivakin.kir@gmail.com>2024-07-26 16:35:05 +0300
commitfd9d0bfbacc2d5af183ba394ca16cb2581dab02d (patch)
tree6c196115c661273f4f204f42b1708ae61be62692
parent2a73553513f393ab00e2da217ff0082403f1985b (diff)
downloadrust-fd9d0bfbacc2d5af183ba394ca16cb2581dab02d.tar.gz
rust-fd9d0bfbacc2d5af183ba394ca16cb2581dab02d.zip
Forbid `?Trait` bounds repetitions
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs26
-rw-r--r--tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs7
-rw-r--r--tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr20
-rw-r--r--tests/ui/traits/maybe-polarity-repeated.rs9
-rw-r--r--tests/ui/traits/maybe-polarity-repeated.stderr21
5 files changed, 72 insertions, 11 deletions
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index f05884f8912..9d839908559 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -75,16 +75,22 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             }
         }
 
-        if unbounds.len() > 1 && !tcx.features().more_maybe_bounds {
-            self.tcx()
-                .sess
-                .create_feature_err(
-                    errors::MultipleRelaxedDefaultBounds {
-                        spans: unbounds.iter().map(|ptr| ptr.span).collect(),
-                    },
-                    sym::more_maybe_bounds,
-                )
-                .emit();
+        let mut unique_bounds = FxIndexSet::default();
+        let mut seen_repeat = false;
+        for unbound in &unbounds {
+            if let Res::Def(DefKind::Trait, unbound_def_id) = unbound.trait_ref.path.res {
+                seen_repeat |= !unique_bounds.insert(unbound_def_id);
+            }
+        }
+        if unbounds.len() > 1 {
+            let err = errors::MultipleRelaxedDefaultBounds {
+                spans: unbounds.iter().map(|ptr| ptr.span).collect(),
+            };
+            if seen_repeat {
+                self.dcx().emit_err(err);
+            } else if !tcx.features().more_maybe_bounds {
+                self.tcx().sess.create_feature_err(err, sym::more_maybe_bounds).emit();
+            };
         }
 
         let mut seen_sized_unbound = false;
diff --git a/tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs
index 4541499b7c7..debe143b091 100644
--- a/tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs
+++ b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs
@@ -14,4 +14,11 @@ fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
 //~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
 //~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
 
+trait Trait {}
+// Do not suggest `#![feature(more_maybe_bounds)]` for repetitions
+fn baz<T: ?Trait + ?Trait>(_ : T) {}
+//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
+//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr
index 2b7a353020a..e6d65e05997 100644
--- a/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr
+++ b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr
@@ -47,7 +47,25 @@ warning: relaxing a default bound only does something for `?Sized`; all other tr
 LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
    |                     ^^^^^^^
 
-error: aborting due to 4 previous errors; 2 warnings emitted
+error[E0203]: type parameter has more than one relaxed default bound, only one is supported
+  --> $DIR/feature-gate-more-maybe-bounds.rs:19:11
+   |
+LL | fn baz<T: ?Trait + ?Trait>(_ : T) {}
+   |           ^^^^^^   ^^^^^^
+
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+  --> $DIR/feature-gate-more-maybe-bounds.rs:19:11
+   |
+LL | fn baz<T: ?Trait + ?Trait>(_ : T) {}
+   |           ^^^^^^
+
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+  --> $DIR/feature-gate-more-maybe-bounds.rs:19:20
+   |
+LL | fn baz<T: ?Trait + ?Trait>(_ : T) {}
+   |                    ^^^^^^
+
+error: aborting due to 5 previous errors; 4 warnings emitted
 
 Some errors have detailed explanations: E0203, E0658.
 For more information about an error, try `rustc --explain E0203`.
diff --git a/tests/ui/traits/maybe-polarity-repeated.rs b/tests/ui/traits/maybe-polarity-repeated.rs
new file mode 100644
index 00000000000..4b5ec83fffa
--- /dev/null
+++ b/tests/ui/traits/maybe-polarity-repeated.rs
@@ -0,0 +1,9 @@
+#![feature(more_maybe_bounds)]
+
+trait Trait {}
+fn foo<T: ?Trait + ?Trait>(_: T) {}
+//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
+//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+
+fn main() {}
diff --git a/tests/ui/traits/maybe-polarity-repeated.stderr b/tests/ui/traits/maybe-polarity-repeated.stderr
new file mode 100644
index 00000000000..610c484fbec
--- /dev/null
+++ b/tests/ui/traits/maybe-polarity-repeated.stderr
@@ -0,0 +1,21 @@
+error[E0203]: type parameter has more than one relaxed default bound, only one is supported
+  --> $DIR/maybe-polarity-repeated.rs:4:11
+   |
+LL | fn foo<T: ?Trait + ?Trait>(_: T) {}
+   |           ^^^^^^   ^^^^^^
+
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+  --> $DIR/maybe-polarity-repeated.rs:4:11
+   |
+LL | fn foo<T: ?Trait + ?Trait>(_: T) {}
+   |           ^^^^^^
+
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+  --> $DIR/maybe-polarity-repeated.rs:4:20
+   |
+LL | fn foo<T: ?Trait + ?Trait>(_: T) {}
+   |                    ^^^^^^
+
+error: aborting due to 1 previous error; 2 warnings emitted
+
+For more information about this error, try `rustc --explain E0203`.