]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_typeck/check/writeback.rs
Fill in some missing parts in the default HIR visitor
[rust.git] / src / librustc_typeck / check / writeback.rs
index 6f8e064c9d8195c3e98c83affec70b55b00a031c..68c0f130c20f18a167eb54491395b8cd605ebc95 100644 (file)
@@ -17,7 +17,7 @@
 use check::FnCtxt;
 use middle::def_id::DefId;
 use middle::pat_util;
-use middle::ty::{self, Ty, MethodCall, MethodCallee};
+use middle::ty::{self, Ty, MethodCall, MethodCallee, HasTypeFlags};
 use middle::ty::adjustment;
 use middle::ty::fold::{TypeFolder,TypeFoldable};
 use middle::infer;
@@ -91,24 +91,53 @@ fn tcx(&self) -> &'cx ty::ctxt<'tcx> {
     // we observe that something like `a+b` is (known to be)
     // operating on scalars, we clear the overload.
     fn fix_scalar_binary_expr(&mut self, e: &hir::Expr) {
-        if let hir::ExprBinary(ref op, ref lhs, ref rhs) = e.node {
-            let lhs_ty = self.fcx.node_ty(lhs.id);
-            let lhs_ty = self.fcx.infcx().resolve_type_vars_if_possible(&lhs_ty);
-
-            let rhs_ty = self.fcx.node_ty(rhs.id);
-            let rhs_ty = self.fcx.infcx().resolve_type_vars_if_possible(&rhs_ty);
-
-            if lhs_ty.is_scalar() && rhs_ty.is_scalar() {
-                self.fcx.inh.tables.borrow_mut().method_map.remove(&MethodCall::expr(e.id));
-
-                // weird but true: the by-ref binops put an
-                // adjustment on the lhs but not the rhs; the
-                // adjustment for rhs is kind of baked into the
-                // system.
-                if !hir_util::is_by_value_binop(op.node) {
-                    self.fcx.inh.tables.borrow_mut().adjustments.remove(&lhs.id);
+        match e.node {
+            hir::ExprBinary(ref op, ref lhs, ref rhs) |
+            hir::ExprAssignOp(ref op, ref lhs, ref rhs) => {
+                let lhs_ty = self.fcx.node_ty(lhs.id);
+                let lhs_ty = self.fcx.infcx().resolve_type_vars_if_possible(&lhs_ty);
+
+                let rhs_ty = self.fcx.node_ty(rhs.id);
+                let rhs_ty = self.fcx.infcx().resolve_type_vars_if_possible(&rhs_ty);
+
+                if lhs_ty.is_scalar() && rhs_ty.is_scalar() {
+                    self.fcx.inh.tables.borrow_mut().method_map.remove(&MethodCall::expr(e.id));
+
+                    // weird but true: the by-ref binops put an
+                    // adjustment on the lhs but not the rhs; the
+                    // adjustment for rhs is kind of baked into the
+                    // system.
+                    match e.node {
+                        hir::ExprBinary(..) => {
+                            if !hir_util::is_by_value_binop(op.node) {
+                                self.fcx.inh.tables.borrow_mut().adjustments.remove(&lhs.id);
+                            }
+                        },
+                        hir::ExprAssignOp(..) => {
+                            self.fcx.inh.tables.borrow_mut().adjustments.remove(&lhs.id);
+                        },
+                        _ => {},
+                    }
+                } else {
+                    let tcx = self.tcx();
+
+                    if let hir::ExprAssignOp(..) = e.node {
+                        if
+                            !tcx.sess.features.borrow().augmented_assignments &&
+                            !self.fcx.expr_ty(e).references_error()
+                        {
+                            tcx.sess.span_err(
+                                e.span,
+                                "overloaded augmented assignments are not stable");
+                            fileline_help!(
+                                tcx.sess, e.span,
+                                "add #![feature(augmented_assignments)] to the crate features \
+                                 to enable");
+                        }
+                    }
                 }
             }
+            _ => {},
         }
     }
 }
@@ -196,6 +225,10 @@ fn visit_ty(&mut self, t: &hir::Ty) {
                 self.visit_ty(&**ty);
                 write_ty_to_tcx(self.tcx(), count_expr.id, self.tcx().types.usize);
             }
+            hir::TyBareFn(ref function_declaration) => {
+                visit::walk_fn_decl_nopat(self, &function_declaration.decl);
+                walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
+            }
             _ => visit::walk_ty(self, t)
         }
     }