summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-01-22 13:10:49 +0000
committerbors <bors@rust-lang.org>2020-01-22 13:10:49 +0000
commitae66171b41b1d05128afd0d666475bc4ba617469 (patch)
treee57c2ac1597da82fd5e1ceadcabb53f4c12c3918
parentAuto merge of #68194 - jonas-schievink:fix-thumb-ci, r=alexcrichton (diff)
parentReplace `walk_callee` with `consume_expr` (diff)
downloadrust-master.tar.gz
rust-master.tar.bz2
rust-master.tar.xz
Auto merge of #68069 - JohnTitor:fix-closure-ice, r=matthewjasperHEADmaster
Attempt to fix ICE #68025 Fixes #68025
-rw-r--r--src/librustc_typeck/expr_use_visitor.rs60
-rw-r--r--src/test/ui/closures/issue-68025.rs12
2 files changed, 13 insertions, 59 deletions
diff --git a/src/librustc_typeck/expr_use_visitor.rs b/src/librustc_typeck/expr_use_visitor.rs
index be00c57..1d3ace9 100644
--- a/src/librustc_typeck/expr_use_visitor.rs
+++ b/src/librustc_typeck/expr_use_visitor.rs
@@ -3,7 +3,6 @@
3//! `ExprUseVisitor` determines how expressions are being used. 3//! `ExprUseVisitor` determines how expressions are being used.
4 4
5pub use self::ConsumeMode::*; 5pub use self::ConsumeMode::*;
6use self::OverloadedCallType::*;
7 6
8// Export these here so that Clippy can use them. 7// Export these here so that Clippy can use them.
9pub use mc::{Place, PlaceBase, Projection}; 8pub use mc::{Place, PlaceBase, Projection};
@@ -48,35 +47,6 @@ pub enum MutateMode {
48 WriteAndRead, // x += y 47 WriteAndRead, // x += y
49} 48}
50 49
51#[derive(Copy, Clone)]
52enum OverloadedCallType {
53 FnOverloadedCall,
54 FnMutOverloadedCall,
55 FnOnceOverloadedCall,
56}
57
58impl OverloadedCallType {
59 fn from_trait_id(tcx: TyCtxt<'_>, trait_id: DefId) -> OverloadedCallType {
60 for &(maybe_function_trait, overloaded_call_type) in &[
61 (tcx.lang_items().fn_once_trait(), FnOnceOverloadedCall),
62 (tcx.lang_items().fn_mut_trait(), FnMutOverloadedCall),
63 (tcx.lang_items().fn_trait(), FnOverloadedCall),
64 ] {
65 match maybe_function_trait {
66 Some(function_trait) if function_trait == trait_id => return overloaded_call_type,
67 _ => continue,
68 }
69 }
70
71 bug!("overloaded call didn't map to known function trait")
72 }
73
74 fn from_method_id(tcx: TyCtxt<'_>, method_id: DefId) -> OverloadedCallType {
75 let method = tcx.associated_item(method_id);
76 OverloadedCallType::from_trait_id(tcx, method.container.id())
77 }
78}
79
80/////////////////////////////////////////////////////////////////////////// 50///////////////////////////////////////////////////////////////////////////
81// The ExprUseVisitor type 51// The ExprUseVisitor type
82// 52//
@@ -211,7 +181,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
211 181
212 hir::ExprKind::Call(ref callee, ref args) => { 182 hir::ExprKind::Call(ref callee, ref args) => {
213 // callee(args) 183 // callee(args)
214 self.walk_callee(expr, callee); 184 self.consume_expr(callee);
215 self.consume_exprs(args); 185 self.consume_exprs(args);
216 } 186 }
217 187
@@ -326,34 +296,6 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
326 } 296 }
327 } 297 }
328 298
329 fn walk_callee(&mut self, call: &hir::Expr<'_>, callee: &hir::Expr<'_>) {
330 let callee_ty = return_if_err!(self.mc.expr_ty_adjusted(callee));
331 debug!("walk_callee: callee={:?} callee_ty={:?}", callee, callee_ty);
332 match callee_ty.kind {
333 ty::FnDef(..) | ty::FnPtr(_) => {
334 self.consume_expr(callee);
335 }
336 ty::Error => {}
337 _ => {
338 if let Some(def_id) = self.mc.tables.type_dependent_def_id(call.hir_id) {
339 match OverloadedCallType::from_method_id(self.tcx(), def_id) {
340 FnMutOverloadedCall => {
341 self.borrow_expr(callee, ty::MutBorrow);
342 }
343 FnOverloadedCall => {
344 self.borrow_expr(callee, ty::ImmBorrow);
345 }
346 FnOnceOverloadedCall => self.consume_expr(callee),
347 }
348 } else {
349 self.tcx()
350 .sess
351 .delay_span_bug(call.span, "no type-dependent def for overloaded call");
352 }
353 }
354 }
355 }
356
357 fn walk_stmt(&mut self, stmt: &hir::Stmt<'_>) { 299 fn walk_stmt(&mut self, stmt: &hir::Stmt<'_>) {
358 match stmt.kind { 300 match stmt.kind {
359 hir::StmtKind::Local(ref local) => { 301 hir::StmtKind::Local(ref local) => {
diff --git a/src/test/ui/closures/issue-68025.rs b/src/test/ui/closures/issue-68025.rs
new file mode 100644
index 0000000..261bfd6
--- /dev/null
+++ b/src/test/ui/closures/issue-68025.rs
@@ -0,0 +1,12 @@
1// check-pass
2
3fn foo<F, G>(_: G, _: Box<F>)
4where
5 F: Fn(),
6 G: Fn(Box<F>),
7{
8}
9
10fn main() {
11 foo(|f| (*f)(), Box::new(|| {}));
12}