//! `ExprUseVisitor` determines how expressions are being used.
pub use self::ConsumeMode::*;
-use self::OverloadedCallType::*;
// Export these here so that Clippy can use them.
pub use mc::{Place, PlaceBase, Projection};
-use rustc::hir::def::Res;
-use rustc::hir::def_id::DefId;
-use rustc::hir::{self, PatKind};
use rustc::infer::InferCtxt;
use rustc::ty::{self, adjustment, TyCtxt};
+use rustc_hir as hir;
+use rustc_hir::def::Res;
+use rustc_hir::def_id::DefId;
+use rustc_hir::PatKind;
use crate::mem_categorization as mc;
use rustc_span::Span;
WriteAndRead, // x += y
}
-#[derive(Copy, Clone)]
-enum OverloadedCallType {
- FnOverloadedCall,
- FnMutOverloadedCall,
- FnOnceOverloadedCall,
-}
-
-impl OverloadedCallType {
- fn from_trait_id(tcx: TyCtxt<'_>, trait_id: DefId) -> OverloadedCallType {
- for &(maybe_function_trait, overloaded_call_type) in &[
- (tcx.lang_items().fn_once_trait(), FnOnceOverloadedCall),
- (tcx.lang_items().fn_mut_trait(), FnMutOverloadedCall),
- (tcx.lang_items().fn_trait(), FnOverloadedCall),
- ] {
- match maybe_function_trait {
- Some(function_trait) if function_trait == trait_id => return overloaded_call_type,
- _ => continue,
- }
- }
-
- bug!("overloaded call didn't map to known function trait")
- }
-
- fn from_method_id(tcx: TyCtxt<'_>, method_id: DefId) -> OverloadedCallType {
- let method = tcx.associated_item(method_id);
- OverloadedCallType::from_trait_id(tcx, method.container.id())
- }
-}
-
///////////////////////////////////////////////////////////////////////////
// The ExprUseVisitor type
//
hir::ExprKind::Type(ref subexpr, _) => self.walk_expr(subexpr),
- hir::ExprKind::Unary(hir::UnDeref, ref base) => {
+ hir::ExprKind::Unary(hir::UnOp::UnDeref, ref base) => {
// *base
self.select_from_expr(base);
}
hir::ExprKind::Call(ref callee, ref args) => {
// callee(args)
- self.walk_callee(expr, callee);
+ self.consume_expr(callee);
self.consume_exprs(args);
}
}
}
- fn walk_callee(&mut self, call: &hir::Expr<'_>, callee: &hir::Expr<'_>) {
- let callee_ty = return_if_err!(self.mc.expr_ty_adjusted(callee));
- debug!("walk_callee: callee={:?} callee_ty={:?}", callee, callee_ty);
- match callee_ty.kind {
- ty::FnDef(..) | ty::FnPtr(_) => {
- self.consume_expr(callee);
- }
- ty::Error => {}
- _ => {
- if let Some(def_id) = self.mc.tables.type_dependent_def_id(call.hir_id) {
- match OverloadedCallType::from_method_id(self.tcx(), def_id) {
- FnMutOverloadedCall => {
- self.borrow_expr(callee, ty::MutBorrow);
- }
- FnOverloadedCall => {
- self.borrow_expr(callee, ty::ImmBorrow);
- }
- FnOnceOverloadedCall => self.consume_expr(callee),
- }
- } else {
- self.tcx()
- .sess
- .delay_span_bug(call.span, "no type-dependent def for overloaded call");
- }
- }
- }
- }
-
fn walk_stmt(&mut self, stmt: &hir::Stmt<'_>) {
match stmt.kind {
hir::StmtKind::Local(ref local) => {