diff options
| author | Bryanskiy <ivakin.kir@gmail.com> | 2024-07-26 16:33:30 +0300 |
|---|---|---|
| committer | Bryanskiy <ivakin.kir@gmail.com> | 2024-07-26 16:35:05 +0300 |
| commit | fd9d0bfbacc2d5af183ba394ca16cb2581dab02d (patch) | |
| tree | 6c196115c661273f4f204f42b1708ae61be62692 | |
| parent | 2a73553513f393ab00e2da217ff0082403f1985b (diff) | |
| download | rust-fd9d0bfbacc2d5af183ba394ca16cb2581dab02d.tar.gz rust-fd9d0bfbacc2d5af183ba394ca16cb2581dab02d.zip | |
Forbid `?Trait` bounds repetitions
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`. |
