use astconv::AstConv;
use check::FnCtxt;
+use middle::def_id::DefId;
use middle::pat_util;
-use middle::ty::{self, Ty, MethodCall, MethodCallee};
-use middle::ty_fold::{TypeFolder,TypeFoldable};
+use middle::ty::{self, Ty, MethodCall, MethodCallee, HasTypeFlags};
+use middle::ty::adjustment;
+use middle::ty::fold::{TypeFolder,TypeFoldable};
use middle::infer;
use write_substs_to_tcx;
use write_ty_to_tcx;
use std::cell::Cell;
use syntax::ast;
-use syntax::ast_util;
use syntax::codemap::{DUMMY_SP, Span};
-use syntax::print::pprust::pat_to_string;
-use syntax::visit;
-use syntax::visit::Visitor;
+use rustc_front::print::pprust::pat_to_string;
+use rustc_front::visit;
+use rustc_front::visit::Visitor;
+use rustc_front::util as hir_util;
+use rustc_front::hir;
///////////////////////////////////////////////////////////////////////////
// Entry point functions
-pub fn resolve_type_vars_in_expr(fcx: &FnCtxt, e: &ast::Expr) {
+pub fn resolve_type_vars_in_expr(fcx: &FnCtxt, e: &hir::Expr) {
assert_eq!(fcx.writeback_errors.get(), false);
let mut wbcx = WritebackCx::new(fcx);
wbcx.visit_expr(e);
}
pub fn resolve_type_vars_in_fn(fcx: &FnCtxt,
- decl: &ast::FnDecl,
- blk: &ast::Block) {
+ decl: &hir::FnDecl,
+ blk: &hir::Block) {
assert_eq!(fcx.writeback_errors.get(), false);
let mut wbcx = WritebackCx::new(fcx);
wbcx.visit_block(blk);
// 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 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 !ast_util::is_by_value_binop(op.node) {
- self.fcx.inh.tables.borrow_mut().adjustments.remove(&lhs.id);
+ fn fix_scalar_binary_expr(&mut self, e: &hir::Expr) {
+ 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");
+ }
+ }
}
}
+ _ => {},
}
}
}
// traffic in node-ids or update tables in the type context etc.
impl<'cx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'tcx> {
- fn visit_item(&mut self, _: &ast::Item) {
+ fn visit_item(&mut self, _: &hir::Item) {
// Ignore items
}
- fn visit_stmt(&mut self, s: &ast::Stmt) {
+ fn visit_stmt(&mut self, s: &hir::Stmt) {
if self.fcx.writeback_errors.get() {
return;
}
- self.visit_node_id(ResolvingExpr(s.span), ast_util::stmt_id(s));
+ self.visit_node_id(ResolvingExpr(s.span), hir_util::stmt_id(s));
visit::walk_stmt(self, s);
}
- fn visit_expr(&mut self, e: &ast::Expr) {
+ fn visit_expr(&mut self, e: &hir::Expr) {
if self.fcx.writeback_errors.get() {
return;
}
self.visit_method_map_entry(ResolvingExpr(e.span),
MethodCall::expr(e.id));
- if let ast::ExprClosure(_, ref decl, _) = e.node {
+ if let hir::ExprClosure(_, ref decl, _) = e.node {
for input in &decl.inputs {
self.visit_node_id(ResolvingExpr(e.span), input.id);
}
visit::walk_expr(self, e);
}
- fn visit_block(&mut self, b: &ast::Block) {
+ fn visit_block(&mut self, b: &hir::Block) {
if self.fcx.writeback_errors.get() {
return;
}
visit::walk_block(self, b);
}
- fn visit_pat(&mut self, p: &ast::Pat) {
+ fn visit_pat(&mut self, p: &hir::Pat) {
if self.fcx.writeback_errors.get() {
return;
}
visit::walk_pat(self, p);
}
- fn visit_local(&mut self, l: &ast::Local) {
+ fn visit_local(&mut self, l: &hir::Local) {
if self.fcx.writeback_errors.get() {
return;
}
visit::walk_local(self, l);
}
- fn visit_ty(&mut self, t: &ast::Ty) {
+ fn visit_ty(&mut self, t: &hir::Ty) {
match t.node {
- ast::TyFixedLengthVec(ref ty, ref count_expr) => {
+ hir::TyFixedLengthVec(ref ty, ref count_expr) => {
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)
}
}
Some(adjustment) => {
let resolved_adjustment = match adjustment {
- ty::AdjustReifyFnPointer => ty::AdjustReifyFnPointer,
+ adjustment::AdjustReifyFnPointer => {
+ adjustment::AdjustReifyFnPointer
+ }
- ty::AdjustUnsafeFnPointer => {
- ty::AdjustUnsafeFnPointer
+ adjustment::AdjustUnsafeFnPointer => {
+ adjustment::AdjustUnsafeFnPointer
}
- ty::AdjustDerefRef(adj) => {
+ adjustment::AdjustDerefRef(adj) => {
for autoderef in 0..adj.autoderefs {
let method_call = MethodCall::autoderef(id, autoderef as u32);
self.visit_method_map_entry(reason, method_call);
}
- ty::AdjustDerefRef(ty::AutoDerefRef {
+ adjustment::AdjustDerefRef(adjustment::AutoDerefRef {
autoderefs: adj.autoderefs,
autoref: self.resolve(&adj.autoref, reason),
unsize: self.resolve(&adj.unsize, reason),
ResolvingLocal(Span),
ResolvingPattern(Span),
ResolvingUpvar(ty::UpvarId),
- ResolvingClosure(ast::DefId),
+ ResolvingClosure(DefId),
}
impl ResolveReason {
tcx.expr_span(upvar_id.closure_expr_id)
}
ResolvingClosure(did) => {
- if did.krate == ast::LOCAL_CRATE {
+ if did.is_local() {
tcx.expr_span(did.node)
} else {
DUMMY_SP