Skip to content
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
60 changes: 1 addition & 59 deletions src/librustc_typeck/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
//! `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};
Expand Down Expand Up @@ -48,35 +47,6 @@ pub enum MutateMode {
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
//
Expand Down Expand Up @@ -211,7 +181,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {

hir::ExprKind::Call(ref callee, ref args) => {
// callee(args)
self.walk_callee(expr, callee);
self.consume_expr(callee);
self.consume_exprs(args);
}

Expand Down Expand Up @@ -326,34 +296,6 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
}
}

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) => {
Expand Down
12 changes: 12 additions & 0 deletions src/test/ui/closures/issue-68025.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// check-pass

fn foo<F, G>(_: G, _: Box<F>)
where
F: Fn(),
G: Fn(Box<F>),
{
}

fn main() {
foo(|f| (*f)(), Box::new(|| {}));
}