]> git.lizzy.rs Git - rust.git/commitdiff
Avoid type-checking addition and indexing twice.
authorEduard-Mihai Burtescu <edy.burt@gmail.com>
Mon, 27 Mar 2017 18:52:51 +0000 (21:52 +0300)
committerEduard-Mihai Burtescu <edy.burt@gmail.com>
Thu, 6 Apr 2017 18:42:25 +0000 (21:42 +0300)
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/op.rs
src/test/compile-fail/issue-40610.rs [new file with mode: 0644]
src/test/compile-fail/issue-40861.rs [new file with mode: 0644]

index aaa3cf0f29e74c389bc2f5a65235b505a348dbd5..c995b7e92843dd1707b5639e77144e02fa8b1c60 100644 (file)
@@ -3884,7 +3884,6 @@ fn check_expr_kind(&self,
                           element_ty
                       }
                       None => {
-                          self.check_expr_has_type(&idx, self.tcx.types.err);
                           let mut err = self.type_error_struct(
                               expr.span,
                               |actual| {
index f492ab12e3f991f5fac03104fd9195800c295b20..cc33bd8754d9ed1c59caf83c37b1a4979a02b5c4 100644 (file)
@@ -184,9 +184,14 @@ fn check_overloaded_binop(&self,
         // particularly for things like `String + &String`.
         let rhs_ty_var = self.next_ty_var(TypeVariableOrigin::MiscVariable(rhs_expr.span));
 
-        let return_ty = match self.lookup_op_method(expr, lhs_ty, vec![rhs_ty_var],
-                                                    Symbol::intern(name), trait_def_id,
-                                                    lhs_expr) {
+        let return_ty = self.lookup_op_method(expr, lhs_ty, vec![rhs_ty_var],
+                                              Symbol::intern(name), trait_def_id,
+                                              lhs_expr);
+
+        // see `NB` above
+        let rhs_ty = self.check_expr_coercable_to_type(rhs_expr, rhs_ty_var);
+
+        let return_ty = match return_ty {
             Ok(return_ty) => return_ty,
             Err(()) => {
                 // error types are considered "builtin"
@@ -209,7 +214,7 @@ fn check_overloaded_binop(&self,
 
                         if let TypeVariants::TyRef(_, ref ty_mut) = lhs_ty.sty {
                             if !self.infcx.type_moves_by_default(ty_mut.ty, lhs_expr.span) &&
-                                self.lookup_op_method(expr, ty_mut.ty, vec![rhs_ty_var],
+                                self.lookup_op_method(expr, ty_mut.ty, vec![rhs_ty],
                                     Symbol::intern(name), trait_def_id,
                                     lhs_expr).is_ok() {
                                 err.note(
@@ -240,7 +245,7 @@ fn check_overloaded_binop(&self,
                         if let Some(missing_trait) = missing_trait {
                             if missing_trait == "std::ops::Add" &&
                                 self.check_str_addition(expr, lhs_expr, lhs_ty,
-                                                         rhs_expr, rhs_ty_var, &mut err) {
+                                                         rhs_expr, rhs_ty, &mut err) {
                                 // This has nothing here because it means we did string
                                 // concatenation (e.g. "Hello " + "World!"). This means
                                 // we don't want the note in the else clause to be emitted
@@ -257,9 +262,6 @@ fn check_overloaded_binop(&self,
             }
         };
 
-        // see `NB` above
-        self.check_expr_coercable_to_type(rhs_expr, rhs_ty_var);
-
         (rhs_ty_var, return_ty)
     }
 
@@ -268,12 +270,11 @@ fn check_str_addition(&self,
                           lhs_expr: &'gcx hir::Expr,
                           lhs_ty: Ty<'tcx>,
                           rhs_expr: &'gcx hir::Expr,
-                          rhs_ty_var: Ty<'tcx>,
+                          rhs_ty: Ty<'tcx>,
                           mut err: &mut errors::DiagnosticBuilder) -> bool {
         // If this function returns true it means a note was printed, so we don't need
         // to print the normal "implementation of `std::ops::Add` might be missing" note
         let mut is_string_addition = false;
-        let rhs_ty = self.check_expr_coercable_to_type(rhs_expr, rhs_ty_var);
         if let TyRef(_, l_ty) = lhs_ty.sty {
             if let TyRef(_, r_ty) = rhs_ty.sty {
                 if l_ty.ty.sty == TyStr && r_ty.ty.sty == TyStr {
diff --git a/src/test/compile-fail/issue-40610.rs b/src/test/compile-fail/issue-40610.rs
new file mode 100644 (file)
index 0000000..aec20b4
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn f(_: &[f32]) {}
+
+fn main() {
+    () + f(&[1.0]);
+    //~^ ERROR binary operation `+` cannot be applied to type `()`
+}
diff --git a/src/test/compile-fail/issue-40861.rs b/src/test/compile-fail/issue-40861.rs
new file mode 100644 (file)
index 0000000..e525b39
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn f(_: &[f32]) {}
+
+fn main() {
+    ()[f(&[1.0])];
+    //~^ ERROR cannot index a value of type `()`
+}