]> git.lizzy.rs Git - rust.git/commitdiff
[wip] fixed some error, added missing test
authorRoman Stoliar <rizakrko@rambler.ru>
Wed, 9 May 2018 07:47:09 +0000 (10:47 +0300)
committerRoman Stoliar <rizakrko@rambler.ru>
Fri, 11 May 2018 12:12:53 +0000 (15:12 +0300)
src/librustc_typeck/check/op.rs
src/test/ui/type-check/missing_trait_impl.rs
src/test/ui/type-check/missing_trait_impl.stderr

index 69b891af6632784ffd92e14d4a61710d544c9742..51a455dc25c1e0f2f447bda2e1a1c8fc3af7c6ce 100644 (file)
@@ -246,7 +246,8 @@ fn check_overloaded_binop(&self,
             Err(()) => {
                 // error types are considered "builtin"
                 if !lhs_ty.references_error() {
-                    match is_assign{
+                    let codemap = self.tcx.sess.codemap();
+                    match is_assign {
                         IsAssign::Yes => {
                             let mut err = struct_span_err!(self.tcx.sess, expr.span, E0368,
                                                 "binary assignment operation `{}=` \
@@ -256,19 +257,6 @@ fn check_overloaded_binop(&self,
                             err.span_label(lhs_expr.span,
                                     format!("cannot use `{}=` on type `{}`",
                                     op.node.as_str(), lhs_ty));
-                            let missing_trait = match op.node {
-                                hir::BiAdd    => Some("std::ops::AddAssign"),
-                                hir::BiSub    => Some("std::ops::SubAssign"),
-                                hir::BiMul    => Some("std::ops::MulAssign"),
-                                hir::BiDiv    => Some("std::ops::DivAssign"),
-                                hir::BiRem    => Some("std::ops::RemAssign"),
-                                hir::BiBitAnd => Some("std::ops::BitAndAssign"),
-                                hir::BiBitXor => Some("std::ops::BitXorAssign"),
-                                hir::BiBitOr  => Some("std::ops::BitOrAssign"),
-                                hir::BiShl    => Some("std::ops::ShlAssign"),
-                                hir::BiShr    => Some("std::ops::ShrAssign"),
-                                _             => None
-                            };
                             let mut suggested_deref = false;
                             if let TyRef(_, ref ty_mut) = lhs_ty.sty {
                                 if {
@@ -280,22 +268,31 @@ fn check_overloaded_binop(&self,
                                                                 Op::Binary(op, is_assign))
                                             .is_ok()
                                 } {
-                                    let codemap = self.tcx.sess.codemap();
-                                    match codemap.span_to_snippet(lhs_expr.span) {
-                                        Ok(lstring) =>{
-                                            let msg = &format!(
+                                    if let Ok(lstring) = codemap.span_to_snippet(lhs_expr.span) {
+                                        let msg = &format!(
                                                 "`{}=` can be used on '{}', you can \
                                                 dereference `{2}`: `*{2}`",
                                                 op.node.as_str(), ty_mut.ty, lstring);
-                                            err.help(msg);
-                                            suggested_deref = true;
-                                        },
-                                        _ => {}
-                                    };
+                                        err.help(msg);
+                                        suggested_deref = true;
+                                    }
                                 }
                             }
+                            let missing_trait = match op.node {
+                                hir::BiAdd    => Some("std::ops::AddAssign"),
+                                hir::BiSub    => Some("std::ops::SubAssign"),
+                                hir::BiMul    => Some("std::ops::MulAssign"),
+                                hir::BiDiv    => Some("std::ops::DivAssign"),
+                                hir::BiRem    => Some("std::ops::RemAssign"),
+                                hir::BiBitAnd => Some("std::ops::BitAndAssign"),
+                                hir::BiBitXor => Some("std::ops::BitXorAssign"),
+                                hir::BiBitOr  => Some("std::ops::BitOrAssign"),
+                                hir::BiShl    => Some("std::ops::ShlAssign"),
+                                hir::BiShr    => Some("std::ops::ShrAssign"),
+                                _             => None
+                            };
                             if let Some(missing_trait) = missing_trait {
-                                if missing_trait == "std::ops::AddAssign" &&
+                                if op.node == hir::BiAdd &&
                                     self.check_str_addition(expr, lhs_expr, rhs_expr, lhs_ty,
                                                             rhs_ty, &mut err) {
                                     // This has nothing here because it means we did string
@@ -306,13 +303,11 @@ fn check_overloaded_binop(&self,
                                     err.note(
                                         &format!("`{}` might need a bound for `{}`",
                                                     lhs_ty, missing_trait));
-                                } else {
-                                    if !suggested_deref{
-                                        err.note(
-                                            &format!("an implementation of `{}` might \
-                                                        be missing for `{}`",
-                                                        missing_trait, lhs_ty));
-                                    }
+                                } else if !suggested_deref {
+                                    err.note(
+                                        &format!("an implementation of `{}` might \
+                                                    be missing for `{}`",
+                                                    missing_trait, lhs_ty));
                                 }
                             }
                             err.emit();
@@ -322,22 +317,6 @@ fn check_overloaded_binop(&self,
                                             "binary operation `{}` cannot be applied to type `{}`",
                                             op.node.as_str(),
                                             lhs_ty);
-                            let missing_trait = match op.node {
-                                hir::BiAdd    => Some("std::ops::Add"),
-                                hir::BiSub    => Some("std::ops::Sub"),
-                                hir::BiMul    => Some("std::ops::Mul"),
-                                hir::BiDiv    => Some("std::ops::Div"),
-                                hir::BiRem    => Some("std::ops::Rem"),
-                                hir::BiBitAnd => Some("std::ops::BitAnd"),
-                                hir::BiBitXor => Some("std::ops::BitXor"),
-                                hir::BiBitOr  => Some("std::ops::BitOr"),
-                                hir::BiShl    => Some("std::ops::Shl"),
-                                hir::BiShr    => Some("std::ops::Shr"),
-                                hir::BiEq | hir::BiNe => Some("std::cmp::PartialEq"),
-                                hir::BiLt | hir::BiLe | hir::BiGt | hir::BiGe =>
-                                    Some("std::cmp::PartialOrd"),
-                                _             => None
-                            };
                             let mut suggested_deref = false;
                             if let TyRef(_, ref ty_mut) = lhs_ty.sty {
                                 if {
@@ -349,22 +328,34 @@ fn check_overloaded_binop(&self,
                                                                 Op::Binary(op, is_assign))
                                             .is_ok()
                                 } {
-                                    let codemap = self.tcx.sess.codemap();
-                                    match codemap.span_to_snippet(lhs_expr.span) {
-                                        Ok(lstring) =>{
-                                            let msg = &format!(
+                                    if let Ok(lstring) = codemap.span_to_snippet(lhs_expr.span) {
+                                        let msg = &format!(
                                                 "`{}` can be used on '{}', you can \
                                                 dereference `{2}`: `*{2}`",
                                                 op.node.as_str(), ty_mut.ty, lstring);
-                                            err.help(msg);
-                                            suggested_deref = true;
-                                        },
-                                        _ =>{}
+                                        err.help(msg);
+                                        suggested_deref = true;
                                     }
                                 }
                             }
+                            let missing_trait = match op.node {
+                                hir::BiAdd    => Some("std::ops::Add"),
+                                hir::BiSub    => Some("std::ops::Sub"),
+                                hir::BiMul    => Some("std::ops::Mul"),
+                                hir::BiDiv    => Some("std::ops::Div"),
+                                hir::BiRem    => Some("std::ops::Rem"),
+                                hir::BiBitAnd => Some("std::ops::BitAnd"),
+                                hir::BiBitXor => Some("std::ops::BitXor"),
+                                hir::BiBitOr  => Some("std::ops::BitOr"),
+                                hir::BiShl    => Some("std::ops::Shl"),
+                                hir::BiShr    => Some("std::ops::Shr"),
+                                hir::BiEq | hir::BiNe => Some("std::cmp::PartialEq"),
+                                hir::BiLt | hir::BiLe | hir::BiGt | hir::BiGe =>
+                                    Some("std::cmp::PartialOrd"),
+                                _             => None
+                            };
                             if let Some(missing_trait) = missing_trait {
-                                if missing_trait == "std::ops::Add" &&
+                                if op.node == hir::BiAdd &&
                                     self.check_str_addition(expr, lhs_expr, rhs_expr, lhs_ty,
                                                             rhs_ty, &mut err) {
                                     // This has nothing here because it means we did string
@@ -375,13 +366,11 @@ fn check_overloaded_binop(&self,
                                     err.note(
                                         &format!("`{}` might need a bound for `{}`",
                                                     lhs_ty, missing_trait));
-                                } else {
-                                    if !suggested_deref{
-                                        err.note(
-                                            &format!("an implementation of `{}` might \
-                                                        be missing for `{}`",
-                                                        missing_trait, lhs_ty));
-                                    }
+                                } else if !suggested_deref {
+                                    err.note(
+                                        &format!("an implementation of `{}` might \
+                                                    be missing for `{}`",
+                                                    missing_trait, lhs_ty));
                                 }
                             }
                             err.emit();
@@ -468,20 +457,18 @@ pub fn check_user_unop(&self,
                                      op.as_str(), actual);
                     err.span_label(ex.span, format!("cannot apply unary \
                                                     operator `{}`", op.as_str()));
-                    let missing_trait = match op {
-                        hir::UnNeg => "std::ops::Neg",
-                        hir::UnNot => "std::ops::Not",
-                        hir::UnDeref => "std::ops::UnDerf"
-                    };
-                    match actual.sty{
-                        TyUint(_) => {
-                            if op == hir::UnNeg{
-                                err.note(&format!("unsigned values cannot be negated"));
-                            }
+                    match actual.sty {
+                        TyUint(_) if op == hir::UnNeg => {
+                            err.note(&format!("unsigned values cannot be negated"));
                         },
                         TyStr | TyNever | TyChar | TyTuple(_) | TyArray(_,_) => {},
                         TyRef(_, ref lty) if lty.ty.sty == TyStr => {},
                         _ => {
+                            let missing_trait = match op {
+                                hir::UnNeg => "std::ops::Neg",
+                                hir::UnNot => "std::ops::Not",
+                                hir::UnDeref => "std::ops::UnDerf"
+                            };
                             err.note(&format!("an implementation of `{}` might \
                                                 be missing for `{}`",
                                              missing_trait, operand_ty));
index adf6b85b6429c57e02a8cdef8d49ef7ac03e9231..b3e79ce2447fb564838d82ea413716b8c7ec8e03 100644 (file)
@@ -14,3 +14,7 @@ fn main() {
 fn foo<T>(x: T, y: T) {
     let z = x + y; //~ ERROR binary operation `+` cannot be applied to type `T`
 }
+
+fn bar<T>(x: T) {
+    x += x; //~ ERROR binary assignment operation `+=` cannot be applied to type `T`
+}
index 777f16b12ce683a4466b607fb344a3035453ec7d..4b01a626814e555a5427e4a316b65d970ef12c8a 100644 (file)
@@ -6,6 +6,17 @@ LL |     let z = x + y; //~ ERROR binary operation `+` cannot be applied to type
    |
    = note: `T` might need a bound for `std::ops::Add`
 
-error: aborting due to previous error
+error[E0368]: binary assignment operation `+=` cannot be applied to type `T`
+  --> $DIR/missing_trait_impl.rs:19:5
+   |
+LL |     x += x; //~ ERROR binary assignment operation `+=` cannot be applied to type `T`
+   |     -^^^^^
+   |     |
+   |     cannot use `+=` on type `T`
+   |
+   = note: `T` might need a bound for `std::ops::AddAssign`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0369`.
+Some errors occurred: E0368, E0369.
+For more information about an error, try `rustc --explain E0368`.