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 a5709089db6..8cc475b536d 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -168,12 +168,6 @@ pub(crate) fn lower_bounds<'hir, I: IntoIterator { let hir::TraitBoundModifiers { constness, polarity } = poly_trait_ref.modifiers; - let polarity = match polarity { - rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive, - rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative, - rustc_ast::BoundPolarity::Maybe(_) => continue, - }; - let _ = self.lower_poly_trait_ref( &poly_trait_ref.trait_ref, poly_trait_ref.span, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index 46a5cbb0af4..5e27ace4cbe 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -51,7 +51,7 @@ pub(super) fn lower_trait_object_ty( &trait_bound.trait_ref, trait_bound.span, hir::BoundConstness::Never, - ty::PredicatePolarity::Positive, + hir::BoundPolarity::Positive, dummy_self, &mut bounds, PredicateFilter::SelfOnly, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index d70e4d8345a..848813ffcb8 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -668,7 +668,7 @@ pub(crate) fn lower_poly_trait_ref( trait_ref: &hir::TraitRef<'tcx>, span: Span, constness: hir::BoundConstness, - polarity: ty::PredicatePolarity, + polarity: hir::BoundPolarity, self_ty: Ty<'tcx>, bounds: &mut Bounds<'tcx>, predicate_filter: PredicateFilter, @@ -690,15 +690,6 @@ pub(crate) fn lower_poly_trait_ref( Some(self_ty), ); - if let hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) = constness - && !self.tcx().is_const_trait(trait_def_id) - { - self.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait { - span, - modifier: constness.as_str(), - }); - } - let tcx = self.tcx(); let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id); debug!(?bound_vars); @@ -708,6 +699,36 @@ pub(crate) fn lower_poly_trait_ref( bound_vars, ); + let polarity = match polarity { + rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive, + rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative, + rustc_ast::BoundPolarity::Maybe(_) => { + // Validate associated type at least. We may want to reject these + // outright in the future... + for constraint in trait_segment.args().constraints { + let _ = self.lower_assoc_item_constraint( + trait_ref.hir_ref_id, + poly_trait_ref, + constraint, + &mut Default::default(), + &mut Default::default(), + constraint.span, + predicate_filter, + ); + } + return arg_count; + } + }; + + if let hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) = constness + && !self.tcx().is_const_trait(trait_def_id) + { + self.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait { + span, + modifier: constness.as_str(), + }); + } + match predicate_filter { PredicateFilter::All | PredicateFilter::SelfOnly @@ -763,11 +784,11 @@ pub(crate) fn lower_poly_trait_ref( // since we should have emitted an error for them earlier, and they // would not be well-formed! if polarity != ty::PredicatePolarity::Positive { - assert!( - self.dcx().has_errors().is_some(), + self.dcx().span_delayed_bug( + constraint.span, "negative trait bounds should not have assoc item constraints", ); - continue; + break; } // Specify type to assert that error was already reported in `Err` case. diff --git a/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs b/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs index 47695814668..46121308fa0 100644 --- a/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs +++ b/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs @@ -3,8 +3,6 @@ fn polarity() -> impl Sized + ?use<> {} //~^ ERROR expected identifier, found keyword `use` //~| ERROR cannot find trait `r#use` in this scope -//~| WARN relaxing a default bound only does something for `?Sized` -//~| WARN relaxing a default bound only does something for `?Sized` fn asyncness() -> impl Sized + async use<> {} //~^ ERROR expected identifier, found keyword `use` diff --git a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr index aaebfe2a86e..16e7470debf 100644 --- a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr +++ b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr @@ -5,19 +5,19 @@ LL | fn polarity() -> impl Sized + ?use<> {} | ^^^ expected identifier, found keyword error: expected identifier, found keyword `use` - --> $DIR/bound-modifiers.rs:9:38 + --> $DIR/bound-modifiers.rs:7:38 | LL | fn asyncness() -> impl Sized + async use<> {} | ^^^ expected identifier, found keyword error: expected identifier, found keyword `use` - --> $DIR/bound-modifiers.rs:14:38 + --> $DIR/bound-modifiers.rs:12:38 | LL | fn constness() -> impl Sized + const use<> {} | ^^^ expected identifier, found keyword error: expected identifier, found keyword `use` - --> $DIR/bound-modifiers.rs:19:37 + --> $DIR/bound-modifiers.rs:17:37 | LL | fn binder() -> impl Sized + for<'a> use<> {} | ^^^ expected identifier, found keyword @@ -29,25 +29,25 @@ LL | fn polarity() -> impl Sized + ?use<> {} | ^^^ not found in this scope error[E0405]: cannot find trait `r#use` in this scope - --> $DIR/bound-modifiers.rs:9:38 + --> $DIR/bound-modifiers.rs:7:38 | LL | fn asyncness() -> impl Sized + async use<> {} | ^^^ not found in this scope error[E0405]: cannot find trait `r#use` in this scope - --> $DIR/bound-modifiers.rs:14:38 + --> $DIR/bound-modifiers.rs:12:38 | LL | fn constness() -> impl Sized + const use<> {} | ^^^ not found in this scope error[E0405]: cannot find trait `r#use` in this scope - --> $DIR/bound-modifiers.rs:19:37 + --> $DIR/bound-modifiers.rs:17:37 | LL | fn binder() -> impl Sized + for<'a> use<> {} | ^^^ not found in this scope error[E0658]: async closures are unstable - --> $DIR/bound-modifiers.rs:9:32 + --> $DIR/bound-modifiers.rs:7:32 | LL | fn asyncness() -> impl Sized + async use<> {} | ^^^^^ @@ -58,7 +58,7 @@ LL | fn asyncness() -> impl Sized + async use<> {} = help: to use an async block, remove the `||`: `async {` error[E0658]: const trait impls are experimental - --> $DIR/bound-modifiers.rs:14:32 + --> $DIR/bound-modifiers.rs:12:32 | LL | fn constness() -> impl Sized + const use<> {} | ^^^^^ @@ -67,21 +67,7 @@ LL | fn constness() -> impl Sized + const use<> {} = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - --> $DIR/bound-modifiers.rs:3:31 - | -LL | fn polarity() -> impl Sized + ?use<> {} - | ^^^^^^ - -warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - --> $DIR/bound-modifiers.rs:3:31 - | -LL | fn polarity() -> impl Sized + ?use<> {} - | ^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 10 previous errors; 2 warnings emitted +error: aborting due to 10 previous errors Some errors have detailed explanations: E0405, E0658. For more information about an error, try `rustc --explain E0405`. diff --git a/tests/ui/issues/issue-37534.rs b/tests/ui/issues/issue-37534.rs index 40f7186db09..dff89d3888d 100644 --- a/tests/ui/issues/issue-37534.rs +++ b/tests/ui/issues/issue-37534.rs @@ -1,6 +1,5 @@ struct Foo {} //~^ ERROR expected trait, found derive macro `Hash` -//~^^ ERROR parameter `T` is never used -//~^^^ WARN relaxing a default bound only does something for `?Sized` +//~| WARN relaxing a default bound only does something for `?Sized` fn main() {} diff --git a/tests/ui/issues/issue-37534.stderr b/tests/ui/issues/issue-37534.stderr index a687e733d3d..8747bd5ac6f 100644 --- a/tests/ui/issues/issue-37534.stderr +++ b/tests/ui/issues/issue-37534.stderr @@ -15,15 +15,6 @@ warning: relaxing a default bound only does something for `?Sized`; all other tr LL | struct Foo {} | ^^^^^ -error[E0392]: type parameter `T` is never used - --> $DIR/issue-37534.rs:1:12 - | -LL | struct Foo {} - | ^ unused type parameter - | - = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` +error: aborting due to 1 previous error; 1 warning emitted -error: aborting due to 2 previous errors; 1 warning emitted - -Some errors have detailed explanations: E0392, E0404. -For more information about an error, try `rustc --explain E0392`. +For more information about this error, try `rustc --explain E0404`. diff --git a/tests/ui/trait-bounds/maybe-bound-generics-deny.rs b/tests/ui/trait-bounds/maybe-bound-generics-deny.rs new file mode 100644 index 00000000000..dfa8e9886b6 --- /dev/null +++ b/tests/ui/trait-bounds/maybe-bound-generics-deny.rs @@ -0,0 +1,4 @@ +fn uwu>() {} +//~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied + +fn main() {} diff --git a/tests/ui/trait-bounds/maybe-bound-generics-deny.stderr b/tests/ui/trait-bounds/maybe-bound-generics-deny.stderr new file mode 100644 index 00000000000..3297eb6279f --- /dev/null +++ b/tests/ui/trait-bounds/maybe-bound-generics-deny.stderr @@ -0,0 +1,11 @@ +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/maybe-bound-generics-deny.rs:1:12 + | +LL | fn uwu>() {} + | ^^^^^----- help: remove the unnecessary generics + | | + | expected 0 generic arguments + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/trait-bounds/maybe-bound-has-path-args.rs b/tests/ui/trait-bounds/maybe-bound-has-path-args.rs new file mode 100644 index 00000000000..2cb63f25d06 --- /dev/null +++ b/tests/ui/trait-bounds/maybe-bound-has-path-args.rs @@ -0,0 +1,7 @@ +trait Trait {} + +fn test::Trait>() {} +//~^ ERROR type arguments are not allowed on this type +//~| WARN relaxing a default bound only does something for `?Sized` + +fn main() {} diff --git a/tests/ui/trait-bounds/maybe-bound-has-path-args.stderr b/tests/ui/trait-bounds/maybe-bound-has-path-args.stderr new file mode 100644 index 00000000000..701e493f5a5 --- /dev/null +++ b/tests/ui/trait-bounds/maybe-bound-has-path-args.stderr @@ -0,0 +1,17 @@ +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/maybe-bound-has-path-args.rs:3:12 + | +LL | fn test::Trait>() {} + | ^^^^^^^^^^^^^^^^^^^ + +error[E0109]: type arguments are not allowed on this type + --> $DIR/maybe-bound-has-path-args.rs:3:20 + | +LL | fn test::Trait>() {} + | ---- ^^^ type argument not allowed + | | + | not allowed on this type + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0109`. diff --git a/tests/ui/trait-bounds/maybe-bound-with-assoc.rs b/tests/ui/trait-bounds/maybe-bound-with-assoc.rs new file mode 100644 index 00000000000..b6b2551e463 --- /dev/null +++ b/tests/ui/trait-bounds/maybe-bound-with-assoc.rs @@ -0,0 +1,12 @@ +trait HasAssoc { + type Assoc; +} +fn hasassoc>() {} +//~^ WARN relaxing a default bound + +trait NoAssoc {} +fn noassoc>() {} +//~^ WARN relaxing a default bound +//~| ERROR associated type `Missing` not found for `NoAssoc` + +fn main() {} diff --git a/tests/ui/trait-bounds/maybe-bound-with-assoc.stderr b/tests/ui/trait-bounds/maybe-bound-with-assoc.stderr new file mode 100644 index 00000000000..91d78e59cd5 --- /dev/null +++ b/tests/ui/trait-bounds/maybe-bound-with-assoc.stderr @@ -0,0 +1,21 @@ +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/maybe-bound-with-assoc.rs:4:16 + | +LL | fn hasassoc>() {} + | ^^^^^^^^^^^^^^^^^^^^^ + +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/maybe-bound-with-assoc.rs:8:15 + | +LL | fn noassoc>() {} + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0220]: associated type `Missing` not found for `NoAssoc` + --> $DIR/maybe-bound-with-assoc.rs:8:24 + | +LL | fn noassoc>() {} + | ^^^^^^^ associated type `Missing` not found + +error: aborting due to 1 previous error; 2 warnings emitted + +For more information about this error, try `rustc --explain E0220`.