diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index fe076b904ca..650f40a8291 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -810,8 +810,12 @@ impl<'tcx> Repr<'tcx> for ty::TraitRef<'tcx> {
         // to enumerate the `for<...>` etc because the debruijn index
         // tells you everything you need to know.
         let base = ty::item_path_str(tcx, self.def_id);
-        parameterized(tcx, &base, self.substs, self.def_id, &[],
-                      || ty::lookup_trait_def(tcx, self.def_id).generics.clone())
+        let result = parameterized(tcx, &base, self.substs, self.def_id, &[],
+                      || ty::lookup_trait_def(tcx, self.def_id).generics.clone());
+        match self.substs.self_ty() {
+            None => result,
+            Some(sty) => format!("<{} as {}>", sty.repr(tcx), result)
+        }
     }
 }
 
@@ -1504,8 +1508,7 @@ impl<'tcx> UserString<'tcx> for ty::ProjectionPredicate<'tcx> {
 
 impl<'tcx> Repr<'tcx> for ty::ProjectionTy<'tcx> {
     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
-        format!("<{} as {}>::{}",
-                self.trait_ref.substs.self_ty().repr(tcx),
+        format!("{}::{}",
                 self.trait_ref.repr(tcx),
                 self.item_name.repr(tcx))
     }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index bff8e002a0a..fa76dc167f2 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3542,34 +3542,34 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
       }
       ast::ExprIndex(ref base, ref idx) => {
           check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref);
+          check_expr(fcx, &**idx);
+
           let base_t = fcx.expr_ty(&**base);
+          let idx_t = fcx.expr_ty(&**idx);
+
           if ty::type_is_error(base_t) {
               fcx.write_ty(id, base_t);
+          } else if ty::type_is_error(idx_t) {
+              fcx.write_ty(id, idx_t);
           } else {
-              check_expr(fcx, &**idx);
-              let idx_t = fcx.expr_ty(&**idx);
-              if ty::type_is_error(idx_t) {
-                  fcx.write_ty(id, idx_t);
-              } else {
-                  let base_t = structurally_resolved_type(fcx, expr.span, base_t);
-                  match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) {
-                      Some((index_ty, element_ty)) => {
-                          let idx_expr_ty = fcx.expr_ty(idx);
-                          demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
-                          fcx.write_ty(id, element_ty);
-                      }
-                      None => {
-                          check_expr_has_type(fcx, &**idx, fcx.tcx().types.err);
-                          fcx.type_error_message(
-                              expr.span,
-                              |actual| {
-                                  format!("cannot index a value of type `{}`",
-                                          actual)
-                              },
-                              base_t,
-                              None);
-                          fcx.write_ty(id, fcx.tcx().types.err);
-                      }
+              let base_t = structurally_resolved_type(fcx, expr.span, base_t);
+              match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) {
+                  Some((index_ty, element_ty)) => {
+                      let idx_expr_ty = fcx.expr_ty(idx);
+                      demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
+                      fcx.write_ty(id, element_ty);
+                  }
+                  None => {
+                      check_expr_has_type(fcx, &**idx, fcx.tcx().types.err);
+                      fcx.type_error_message(
+                          expr.span,
+                          |actual| {
+                              format!("cannot index a value of type `{}`",
+                                      actual)
+                          },
+                          base_t,
+                          None);
+                      fcx.write_ty(id, fcx.tcx().types.err);
                   }
               }
           }
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index f778a64f949..889975f0eb2 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -85,6 +85,32 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
     fn tcx(&self) -> &'cx ty::ctxt<'tcx> {
         self.fcx.tcx()
     }
+
+    // Hacky hack: During type-checking, we treat *all* operators
+    // as potentially overloaded. But then, during writeback, if
+    // 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: &ast::Expr) {
+        if let ast::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 ty::type_is_scalar(lhs_ty) && ty::type_is_scalar(rhs_ty) {
+                self.fcx.inh.method_map.borrow_mut().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 !ast_util::is_by_value_binop(op.node) {
+                    self.fcx.inh.adjustments.borrow_mut().remove(&lhs.id);
+                }
+            }
+        }
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -114,43 +140,16 @@ impl<'cx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'tcx> {
             return;
         }
 
-        // Hacky hack: During type-checking, we treat *all* operators
-        // as potentially overloaded. But then, during writeback, if
-        // we observe that something like `a+b` is (known to be)
-        // operating on scalars, we clear the overload.
-        match e.node {
-            ast::ExprBinary(ref op, ref lhs, ref rhs) => {
-                let lhs_ty = self.fcx.expr_ty(lhs);
-                let lhs_ty = self.fcx.infcx().resolve_type_vars_if_possible(&lhs_ty);
-                let rhs_ty = self.fcx.expr_ty(rhs);
-                let rhs_ty = self.fcx.infcx().resolve_type_vars_if_possible(&rhs_ty);
-                if ty::type_is_scalar(lhs_ty) && ty::type_is_scalar(rhs_ty) {
-                    self.fcx.inh.method_map.borrow_mut().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 !ast_util::is_by_value_binop(op.node) {
-                        self.fcx.inh.adjustments.borrow_mut().remove(&lhs.id);
-                    }
-                }
-            }
-            _ => { }
-        }
+        self.fix_scalar_binary_expr(e);
 
         self.visit_node_id(ResolvingExpr(e.span), e.id);
         self.visit_method_map_entry(ResolvingExpr(e.span),
                                     MethodCall::expr(e.id));
 
-        match e.node {
-            ast::ExprClosure(_, ref decl, _) => {
-                for input in &decl.inputs {
-                    let _ = self.visit_node_id(ResolvingExpr(e.span),
-                                               input.id);
-                }
+        if let ast::ExprClosure(_, ref decl, _) = e.node {
+            for input in &decl.inputs {
+                self.visit_node_id(ResolvingExpr(e.span), input.id);
             }
-            _ => {}
         }
 
         visit::walk_expr(self, e);
diff --git a/src/test/compile-fail/issue-24363.rs b/src/test/compile-fail/issue-24363.rs
new file mode 100644
index 00000000000..590c464371c
--- /dev/null
+++ b/src/test/compile-fail/issue-24363.rs
@@ -0,0 +1,16 @@
+// Copyright 2015 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 main() {
+    1.create_a_type_error[ //~ ERROR attempted access of field
+        ()+() //~ ERROR binary operation `+` cannot be applied
+              //   ^ ensure that we typeck the inner expression ^
+    ];
+}