about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWill Crichton <wcrichto@cs.stanford.edu>2022-04-25 19:14:09 -0700
committerWill Crichton <wcrichto@cs.stanford.edu>2022-04-25 19:14:09 -0700
commitdc41dbaf8eec1ff144f45c8a3c65b7514aa70895 (patch)
treedbdf2a7818ccba04f6237dd37ae14296c7ab8b2e
parent4d0fe27896294fd22854fdc76357bcef96e2005a (diff)
downloadrust-dc41dbaf8eec1ff144f45c8a3c65b7514aa70895.tar.gz
rust-dc41dbaf8eec1ff144f45c8a3c65b7514aa70895.zip
Update unop path, fix tests
-rw-r--r--compiler/rustc_typeck/src/check/op.rs73
-rw-r--r--src/test/ui/generic-associated-types/missing-bounds.fixed46
-rw-r--r--src/test/ui/generic-associated-types/missing-bounds.rs2
-rw-r--r--src/test/ui/generic-associated-types/missing-bounds.stderr16
-rw-r--r--src/test/ui/type/type-check/missing_trait_impl.stderr8
5 files changed, 51 insertions, 94 deletions
diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs
index 3be04ef6d21..1ae53a77adc 100644
--- a/compiler/rustc_typeck/src/check/op.rs
+++ b/compiler/rustc_typeck/src/check/op.rs
@@ -456,25 +456,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         // the resulting predicate generates a more specific
                         // suggestion for the user.
                         let errors = self
-                        .lookup_op_method(lhs_ty, &[rhs_ty], Op::Binary(op, is_assign))
-                        .unwrap_err();
-                    let predicates = errors
-                        .into_iter()
-                        .filter_map(|error| error.obligation.predicate.to_opt_poly_trait_pred())
-                        .collect::<Vec<_>>();
-                    if !predicates.is_empty() {
-                        for pred in predicates {
-                            self.infcx.suggest_restricting_param_bound(&mut err,
-                                pred,
-                                self.body_id,
-                            );
+                            .lookup_op_method(
+                                lhs_ty,
+                                Some(rhs_ty),
+                                Some(rhs_expr),
+                                Op::Binary(op, is_assign),
+                            )
+                            .unwrap_err();
+                        let predicates = errors
+                            .into_iter()
+                            .filter_map(|error| error.obligation.predicate.to_opt_poly_trait_pred())
+                            .collect::<Vec<_>>();
+                        if !predicates.is_empty() {
+                            for pred in predicates {
+                                self.infcx.suggest_restricting_param_bound(
+                                    &mut err,
+                                    pred,
+                                    self.body_id,
+                                );
+                            }
+                        } else if *ty != lhs_ty {
+                            // When we know that a missing bound is responsible, we don't show
+                            // this note as it is redundant.
+                            err.note(&format!(
+                                "the trait `{missing_trait}` is not implemented for `{lhs_ty}`"
+                            ));
                         }
-                     } else if *ty != lhs_ty {
-                        // When we know that a missing bound is responsible, we don't show
-                        // this note as it is redundant.
-                        err.note(&format!(
-                            "the trait `{missing_trait}` is not implemented for `{lhs_ty}`"
-                        ));                    
                     }
                 }
                 err.emit();
@@ -663,24 +670,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         ex.span,
                         format!("cannot apply unary operator `{}`", op.as_str()),
                     );
-                    let missing_trait = match op {
-                        hir::UnOp::Deref => unreachable!("check unary op `-` or `!` only"),
-                        hir::UnOp::Not => "std::ops::Not",
-                        hir::UnOp::Neg => "std::ops::Neg",
-                    };
+
                     let mut visitor = TypeParamVisitor(vec![]);
                     visitor.visit_ty(operand_ty);
-                    if let [ty] = &visitor.0[..] && let ty::Param(p) = *operand_ty.kind() {
-                        suggest_constraining_param(
-                            self.tcx,
-                            self.body_id,
-                            &mut err,
-                            *ty,
-                            operand_ty,
-                            missing_trait,
-                            p,
-                            true,
-                        );
+                    if let [_] = &visitor.0[..] && let ty::Param(_) = *operand_ty.kind() {
+                        let predicates = errors
+                            .iter()
+                            .filter_map(|error| {
+                                error.obligation.predicate.clone().to_opt_poly_trait_pred()
+                            });
+                        for pred in predicates {
+                            self.infcx.suggest_restricting_param_bound(
+                                &mut err,
+                                pred,
+                                self.body_id,
+                            );
+                        }
                     }
 
                     let sp = self.tcx.sess.source_map().start_point(ex.span);
diff --git a/src/test/ui/generic-associated-types/missing-bounds.fixed b/src/test/ui/generic-associated-types/missing-bounds.fixed
deleted file mode 100644
index 8eddfe21e30..00000000000
--- a/src/test/ui/generic-associated-types/missing-bounds.fixed
+++ /dev/null
@@ -1,46 +0,0 @@
-// run-rustfix
-
-use std::ops::Add;
-
-struct A<B>(B);
-
-impl<B> Add for A<B> where B: Add + Add<Output = B> {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        A(self.0 + rhs.0) //~ ERROR mismatched types
-    }
-}
-
-struct C<B>(B);
-
-impl<B: Add + Add<Output = B>> Add for C<B> {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        Self(self.0 + rhs.0) //~ ERROR mismatched types
-    }
-}
-
-struct D<B>(B);
-
-impl<B: std::ops::Add> Add for D<B> {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        Self(self.0 + rhs.0) //~ ERROR cannot add `B` to `B`
-    }
-}
-
-struct E<B>(B);
-
-impl<B: Add> Add for E<B> where B: Add<Output = B>, B: Add<Output = B> {
-    //~^ ERROR equality constraints are not yet supported in `where` clauses
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        Self(self.0 + rhs.0) //~ ERROR mismatched types
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/generic-associated-types/missing-bounds.rs b/src/test/ui/generic-associated-types/missing-bounds.rs
index ffafff5e9f5..b3661ba3744 100644
--- a/src/test/ui/generic-associated-types/missing-bounds.rs
+++ b/src/test/ui/generic-associated-types/missing-bounds.rs
@@ -1,5 +1,3 @@
-// run-rustfix
-
 use std::ops::Add;
 
 struct A<B>(B);
diff --git a/src/test/ui/generic-associated-types/missing-bounds.stderr b/src/test/ui/generic-associated-types/missing-bounds.stderr
index 25db8461098..aaeec920527 100644
--- a/src/test/ui/generic-associated-types/missing-bounds.stderr
+++ b/src/test/ui/generic-associated-types/missing-bounds.stderr
@@ -1,5 +1,5 @@
 error: equality constraints are not yet supported in `where` clauses
-  --> $DIR/missing-bounds.rs:37:33
+  --> $DIR/missing-bounds.rs:35:33
    |
 LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B {
    |                                 ^^^^^^^^^^^^^^^^^^^^^^ not supported
@@ -11,7 +11,7 @@ LL | impl<B: Add> Add for E<B> where B: Add<Output = B> {
    |                                 ~~~~~~~~~~~~~~~~~~
 
 error[E0308]: mismatched types
-  --> $DIR/missing-bounds.rs:11:11
+  --> $DIR/missing-bounds.rs:9:11
    |
 LL | impl<B> Add for A<B> where B: Add {
    |      - this type parameter
@@ -24,7 +24,7 @@ LL |         A(self.0 + rhs.0)
    = note: expected type parameter `B`
              found associated type `<B as Add>::Output`
 note: tuple struct defined here
-  --> $DIR/missing-bounds.rs:5:8
+  --> $DIR/missing-bounds.rs:3:8
    |
 LL | struct A<B>(B);
    |        ^
@@ -34,7 +34,7 @@ LL | impl<B> Add for A<B> where B: Add + Add<Output = B> {
    |                                   +++++++++++++++++
 
 error[E0308]: mismatched types
-  --> $DIR/missing-bounds.rs:21:14
+  --> $DIR/missing-bounds.rs:19:14
    |
 LL | impl<B: Add> Add for C<B> {
    |      - this type parameter
@@ -47,7 +47,7 @@ LL |         Self(self.0 + rhs.0)
    = note: expected type parameter `B`
              found associated type `<B as Add>::Output`
 note: tuple struct defined here
-  --> $DIR/missing-bounds.rs:15:8
+  --> $DIR/missing-bounds.rs:13:8
    |
 LL | struct C<B>(B);
    |        ^
@@ -57,7 +57,7 @@ LL | impl<B: Add + Add<Output = B>> Add for C<B> {
    |             +++++++++++++++++
 
 error[E0369]: cannot add `B` to `B`
-  --> $DIR/missing-bounds.rs:31:21
+  --> $DIR/missing-bounds.rs:29:21
    |
 LL |         Self(self.0 + rhs.0)
    |              ------ ^ ----- B
@@ -70,7 +70,7 @@ LL | impl<B: std::ops::Add> Add for D<B> {
    |       +++++++++++++++
 
 error[E0308]: mismatched types
-  --> $DIR/missing-bounds.rs:42:14
+  --> $DIR/missing-bounds.rs:40:14
    |
 LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B {
    |      - this type parameter
@@ -83,7 +83,7 @@ LL |         Self(self.0 + rhs.0)
    = note: expected type parameter `B`
              found associated type `<B as Add>::Output`
 note: tuple struct defined here
-  --> $DIR/missing-bounds.rs:35:8
+  --> $DIR/missing-bounds.rs:33:8
    |
 LL | struct E<B>(B);
    |        ^
diff --git a/src/test/ui/type/type-check/missing_trait_impl.stderr b/src/test/ui/type/type-check/missing_trait_impl.stderr
index fe156a88453..2b58cd4180b 100644
--- a/src/test/ui/type/type-check/missing_trait_impl.stderr
+++ b/src/test/ui/type/type-check/missing_trait_impl.stderr
@@ -32,8 +32,8 @@ LL |     let y = -x;
    |
 help: consider restricting type parameter `T`
    |
-LL | fn baz<T: std::ops::Neg<Output = T>>(x: T) {
-   |         +++++++++++++++++++++++++++
+LL | fn baz<T: std::ops::Neg>(x: T) {
+   |         +++++++++++++++
 
 error[E0600]: cannot apply unary operator `!` to type `T`
   --> $DIR/missing_trait_impl.rs:14:13
@@ -43,8 +43,8 @@ LL |     let y = !x;
    |
 help: consider restricting type parameter `T`
    |
-LL | fn baz<T: std::ops::Not<Output = T>>(x: T) {
-   |         +++++++++++++++++++++++++++
+LL | fn baz<T: std::ops::Not>(x: T) {
+   |         +++++++++++++++
 
 error[E0614]: type `T` cannot be dereferenced
   --> $DIR/missing_trait_impl.rs:15:13