Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5/n] rustc: record the target type of every adjustment. #37408

Merged
merged 2 commits into from
Nov 6, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/librustc/cfg/construct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,11 +311,11 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
}

hir::ExprIndex(ref l, ref r) |
hir::ExprBinary(_, ref l, ref r) if self.tcx.is_method_call(expr.id) => {
hir::ExprBinary(_, ref l, ref r) if self.tcx.tables().is_method_call(expr.id) => {
self.call(expr, pred, &l, Some(&**r).into_iter())
}

hir::ExprUnary(_, ref e) if self.tcx.is_method_call(expr.id) => {
hir::ExprUnary(_, ref e) if self.tcx.tables().is_method_call(expr.id) => {
self.call(expr, pred, &e, None::<hir::Expr>.iter())
}

Expand Down Expand Up @@ -372,9 +372,9 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
func_or_rcvr: &hir::Expr,
args: I) -> CFGIndex {
let method_call = ty::MethodCall::expr(call_expr.id);
let fn_ty = match self.tcx.tables.borrow().method_map.get(&method_call) {
let fn_ty = match self.tcx.tables().method_map.get(&method_call) {
Some(method) => method.ty,
None => self.tcx.expr_ty_adjusted(func_or_rcvr)
None => self.tcx.tables().expr_ty_adjusted(func_or_rcvr)
};

let func_or_rcvr_exit = self.expr(func_or_rcvr, pred);
Expand Down
26 changes: 3 additions & 23 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1256,26 +1256,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
self.region_vars.new_bound(debruijn)
}

/// Apply `adjustment` to the type of `expr`
pub fn adjust_expr_ty(&self,
expr: &hir::Expr,
adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
-> Ty<'tcx>
{
let raw_ty = self.expr_ty(expr);
let raw_ty = self.shallow_resolve(raw_ty);
let resolve_ty = |ty: Ty<'tcx>| self.resolve_type_vars_if_possible(&ty);
raw_ty.adjust(self.tcx,
expr.span,
expr.id,
adjustment,
|method_call| self.tables
.borrow()
.method_map
.get(&method_call)
.map(|method| resolve_ty(method.ty)))
}

/// True if errors have been reported since this infcx was
/// created. This is sometimes used as a heuristic to skip
/// reporting errors that often occur as a result of earlier
Expand Down Expand Up @@ -1612,7 +1592,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}

pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
let ty = self.adjust_expr_ty(expr, self.tables.borrow().adjustments.get(&expr.id));
let ty = self.tables.borrow().expr_ty_adjusted(expr);
self.resolve_type_vars_or_error(&ty)
}

Expand Down Expand Up @@ -1656,9 +1636,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
.map(|method| method.def_id)
}

pub fn adjustments(&self) -> Ref<NodeMap<adjustment::AutoAdjustment<'tcx>>> {
pub fn adjustments(&self) -> Ref<NodeMap<adjustment::Adjustment<'tcx>>> {
fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
-> &'a NodeMap<adjustment::AutoAdjustment<'tcx>> {
-> &'a NodeMap<adjustment::Adjustment<'tcx>> {
&tables.adjustments
}

Expand Down
12 changes: 6 additions & 6 deletions src/librustc/middle/dead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
match def {
Def::AssociatedTy(..) | Def::Method(_) | Def::AssociatedConst(_)
if self.tcx.trait_of_item(def.def_id()).is_some() => {
if let Some(substs) = self.tcx.tables.borrow().item_substs.get(&id) {
if let Some(substs) = self.tcx.tables().item_substs.get(&id) {
if let ty::TyAdt(tyid, _) = substs.substs.type_at(0).sty {
self.check_def_id(tyid.did);
}
Expand Down Expand Up @@ -123,12 +123,12 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {

fn lookup_and_handle_method(&mut self, id: ast::NodeId) {
let method_call = ty::MethodCall::expr(id);
let method = self.tcx.tables.borrow().method_map[&method_call];
let method = self.tcx.tables().method_map[&method_call];
self.check_def_id(method.def_id);
}

fn handle_field_access(&mut self, lhs: &hir::Expr, name: ast::Name) {
match self.tcx.expr_ty_adjusted(lhs).sty {
match self.tcx.tables().expr_ty_adjusted(lhs).sty {
ty::TyAdt(def, _) => {
self.insert_def_id(def.struct_variant().field_named(name).did);
}
Expand All @@ -137,7 +137,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
}

fn handle_tup_field_access(&mut self, lhs: &hir::Expr, idx: usize) {
match self.tcx.expr_ty_adjusted(lhs).sty {
match self.tcx.tables().expr_ty_adjusted(lhs).sty {
ty::TyAdt(def, _) => {
self.insert_def_id(def.struct_variant().fields[idx].did);
}
Expand All @@ -148,7 +148,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {

fn handle_field_pattern_match(&mut self, lhs: &hir::Pat,
pats: &[codemap::Spanned<hir::FieldPat>]) {
let variant = match self.tcx.node_id_to_type(lhs.id).sty {
let variant = match self.tcx.tables().node_id_to_type(lhs.id).sty {
ty::TyAdt(adt, _) => {
adt.variant_of_def(self.tcx.expect_def(lhs.id))
}
Expand Down Expand Up @@ -433,7 +433,7 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
}

fn should_warn_about_field(&mut self, field: &hir::StructField) -> bool {
let field_type = self.tcx.node_id_to_type(field.id);
let field_type = self.tcx.tables().node_id_to_type(field.id);
let is_marker_field = match field_type.ty_to_def_id() {
Some(def_id) => self.tcx.lang_items.items().iter().any(|item| *item == Some(def_id)),
_ => false
Expand Down
10 changes: 5 additions & 5 deletions src/librustc/middle/effect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
match expr.node {
hir::ExprMethodCall(..) => {
let method_call = MethodCall::expr(expr.id);
let base_type = self.tcx.tables.borrow().method_map[&method_call].ty;
let base_type = self.tcx.tables().method_map[&method_call].ty;
debug!("effect: method call case, base type is {:?}",
base_type);
if type_is_unsafe_function(base_type) {
Expand All @@ -168,15 +168,15 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
}
}
hir::ExprCall(ref base, _) => {
let base_type = self.tcx.expr_ty_adjusted(base);
let base_type = self.tcx.tables().expr_ty_adjusted(base);
debug!("effect: call case, base type is {:?}",
base_type);
if type_is_unsafe_function(base_type) {
self.require_unsafe(expr.span, "call to unsafe function")
}
}
hir::ExprUnary(hir::UnDeref, ref base) => {
let base_type = self.tcx.expr_ty_adjusted(base);
let base_type = self.tcx.tables().expr_ty_adjusted(base);
debug!("effect: unary case, base type is {:?}",
base_type);
if let ty::TyRawPtr(_) = base_type.sty {
Expand All @@ -200,7 +200,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
}
}
hir::ExprField(ref base_expr, field) => {
if let ty::TyAdt(adt, ..) = self.tcx.expr_ty_adjusted(base_expr).sty {
if let ty::TyAdt(adt, ..) = self.tcx.tables().expr_ty_adjusted(base_expr).sty {
if adt.is_union() {
self.require_unsafe(field.span, "access to union field");
}
Expand All @@ -214,7 +214,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {

fn visit_pat(&mut self, pat: &hir::Pat) {
if let PatKind::Struct(_, ref fields, _) = pat.node {
if let ty::TyAdt(adt, ..) = self.tcx.pat_ty(pat).sty {
if let ty::TyAdt(adt, ..) = self.tcx.tables().pat_ty(pat).sty {
if adt.is_union() {
for field in fields {
self.require_unsafe(field.span, "matching on union field");
Expand Down
55 changes: 23 additions & 32 deletions src/librustc/middle/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,20 +720,33 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
//NOTE(@jroesch): mixed RefCell borrow causes crash
let adj = infcx.adjustments().get(&expr.id).map(|x| x.clone());
if let Some(adjustment) = adj {
match adjustment {
adjustment::AdjustNeverToAny(..) |
adjustment::AdjustReifyFnPointer |
adjustment::AdjustUnsafeFnPointer |
adjustment::AdjustMutToConstPointer => {
match adjustment.kind {
adjustment::Adjust::NeverToAny |
adjustment::Adjust::ReifyFnPointer |
adjustment::Adjust::UnsafeFnPointer |
adjustment::Adjust::MutToConstPointer => {
// Creating a closure/fn-pointer or unsizing consumes
// the input and stores it into the resulting rvalue.
debug!("walk_adjustment: trivial adjustment");
let cmt_unadjusted =
return_if_err!(self.mc.cat_expr_unadjusted(expr));
self.delegate_consume(expr.id, expr.span, cmt_unadjusted);
}
adjustment::AdjustDerefRef(ref adj) => {
self.walk_autoderefref(expr, adj);
adjustment::Adjust::DerefRef { autoderefs, autoref, unsize } => {
debug!("walk_adjustment expr={:?} adj={:?}", expr, adjustment);

self.walk_autoderefs(expr, autoderefs);

let cmt_derefd =
return_if_err!(self.mc.cat_expr_autoderefd(expr, autoderefs));

let cmt_refd =
self.walk_autoref(expr, cmt_derefd, autoref);

if unsize {
// Unsizing consumes the thin pointer and produces a fat one.
self.delegate_consume(expr.id, expr.span, cmt_refd);
}
}
}
}
Expand Down Expand Up @@ -770,28 +783,6 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
}
}

fn walk_autoderefref(&mut self,
expr: &hir::Expr,
adj: &adjustment::AutoDerefRef<'tcx>) {
debug!("walk_autoderefref expr={:?} adj={:?}",
expr,
adj);

self.walk_autoderefs(expr, adj.autoderefs);

let cmt_derefd =
return_if_err!(self.mc.cat_expr_autoderefd(expr, adj.autoderefs));

let cmt_refd =
self.walk_autoref(expr, cmt_derefd, adj.autoref);

if adj.unsize.is_some() {
// Unsizing consumes the thin pointer and produces a fat one.
self.delegate_consume(expr.id, expr.span, cmt_refd);
}
}


/// Walks the autoref `opt_autoref` applied to the autoderef'd
/// `expr`. `cmt_derefd` is the mem-categorized form of `expr`
/// after all relevant autoderefs have occurred. Because AutoRefs
Expand All @@ -803,7 +794,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
fn walk_autoref(&mut self,
expr: &hir::Expr,
cmt_base: mc::cmt<'tcx>,
opt_autoref: Option<adjustment::AutoRef<'tcx>>)
opt_autoref: Option<adjustment::AutoBorrow<'tcx>>)
-> mc::cmt<'tcx>
{
debug!("walk_autoref(expr.id={} cmt_derefd={:?} opt_autoref={:?})",
Expand All @@ -822,7 +813,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
};

match *autoref {
adjustment::AutoPtr(r, m) => {
adjustment::AutoBorrow::Ref(r, m) => {
self.delegate.borrow(expr.id,
expr.span,
cmt_base,
Expand All @@ -831,7 +822,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
AutoRef);
}

adjustment::AutoUnsafe(m) => {
adjustment::AutoBorrow::RawPtr(m) => {
debug!("walk_autoref: expr.id={} cmt_base={:?}",
expr.id,
cmt_base);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/intrinsicck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for ExprVisitor<'a, 'gcx, 'tcx> {
if let hir::ExprPath(..) = expr.node {
match self.infcx.tcx.expect_def(expr.id) {
Def::Fn(did) if self.def_id_is_transmute(did) => {
let typ = self.infcx.tcx.node_id_to_type(expr.id);
let typ = self.infcx.tcx.tables().node_id_to_type(expr.id);
match typ.sty {
ty::TyFnDef(.., ref bare_fn_ty) if bare_fn_ty.abi == RustIntrinsic => {
let from = bare_fn_ty.sig.0.inputs[0];
Expand Down
14 changes: 7 additions & 7 deletions src/librustc/middle/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1081,7 +1081,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {

hir::ExprAssignOp(_, ref l, ref r) => {
// an overloaded assign op is like a method call
if self.ir.tcx.is_method_call(expr.id) {
if self.ir.tcx.tables().is_method_call(expr.id) {
let succ = self.propagate_through_expr(&l, succ);
self.propagate_through_expr(&r, succ)
} else {
Expand Down Expand Up @@ -1113,8 +1113,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {

hir::ExprCall(ref f, ref args) => {
// FIXME(canndrew): This is_never should really be an is_uninhabited
let diverges = !self.ir.tcx.is_method_call(expr.id) &&
self.ir.tcx.expr_ty_adjusted(&f).fn_ret().0.is_never();
let diverges = !self.ir.tcx.tables().is_method_call(expr.id) &&
self.ir.tcx.tables().expr_ty_adjusted(&f).fn_ret().0.is_never();
let succ = if diverges {
self.s.exit_ln
} else {
Expand All @@ -1126,7 +1126,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {

hir::ExprMethodCall(.., ref args) => {
let method_call = ty::MethodCall::expr(expr.id);
let method_ty = self.ir.tcx.tables.borrow().method_map[&method_call].ty;
let method_ty = self.ir.tcx.tables().method_map[&method_call].ty;
// FIXME(canndrew): This is_never should really be an is_uninhabited
let succ = if method_ty.fn_ret().0.is_never() {
self.s.exit_ln
Expand Down Expand Up @@ -1409,7 +1409,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
}

hir::ExprAssignOp(_, ref l, _) => {
if !this.ir.tcx.is_method_call(expr.id) {
if !this.ir.tcx.tables().is_method_call(expr.id) {
this.check_lvalue(&l);
}

Expand Down Expand Up @@ -1459,7 +1459,7 @@ fn check_fn(_v: &Liveness,

impl<'a, 'tcx> Liveness<'a, 'tcx> {
fn fn_ret(&self, id: NodeId) -> ty::Binder<Ty<'tcx>> {
let fn_ty = self.ir.tcx.node_id_to_type(id);
let fn_ty = self.ir.tcx.tables().node_id_to_type(id);
match fn_ty.sty {
ty::TyClosure(closure_def_id, substs) =>
self.ir.tcx.closure_type(closure_def_id, substs).sig.output(),
Expand Down Expand Up @@ -1502,7 +1502,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
None if !body.stmts.is_empty() =>
match body.stmts.last().unwrap().node {
hir::StmtSemi(ref e, _) => {
self.ir.tcx.expr_ty(&e) == fn_ret
self.ir.tcx.tables().expr_ty(&e) == fn_ret
},
_ => false
},
Expand Down
26 changes: 12 additions & 14 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,11 +354,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
}

fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
let unadjusted_ty = self.expr_ty(expr)?;
Ok(unadjusted_ty.adjust(
self.tcx(), expr.span, expr.id,
self.infcx.adjustments().get(&expr.id),
|method_call| self.infcx.node_method_ty(method_call)))
self.infcx.expr_ty_adjusted(expr)
}

fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {
Expand Down Expand Up @@ -396,19 +392,21 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
}

Some(adjustment) => {
match *adjustment {
adjustment::AdjustDerefRef(
adjustment::AutoDerefRef {
autoref: None, unsize: None, autoderefs, ..}) => {
match adjustment.kind {
adjustment::Adjust::DerefRef {
autoderefs,
autoref: None,
unsize: false
} => {
// Equivalent to *expr or something similar.
self.cat_expr_autoderefd(expr, autoderefs)
}

adjustment::AdjustNeverToAny(..) |
adjustment::AdjustReifyFnPointer |
adjustment::AdjustUnsafeFnPointer |
adjustment::AdjustMutToConstPointer |
adjustment::AdjustDerefRef(_) => {
adjustment::Adjust::NeverToAny |
adjustment::Adjust::ReifyFnPointer |
adjustment::Adjust::UnsafeFnPointer |
adjustment::Adjust::MutToConstPointer |
adjustment::Adjust::DerefRef {..} => {
debug!("cat_expr({:?}): {:?}",
adjustment,
expr);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/reachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
}
hir::ExprMethodCall(..) => {
let method_call = ty::MethodCall::expr(expr.id);
let def_id = self.tcx.tables.borrow().method_map[&method_call].def_id;
let def_id = self.tcx.tables().method_map[&method_call].def_id;

// Mark the trait item (and, possibly, its default impl) as reachable
// Or mark inherent impl item as reachable
Expand Down
Loading