diff options
| author | bors <bors@rust-lang.org> | 2014-10-18 04:32:16 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-10-18 04:32:16 +0000 |
| commit | 2c0f87610d8fdcb6a90cd8dd1a372fe0ccc8a418 (patch) | |
| tree | 8d4eee30cd81bc590ee5314e68727ef97b367887 /src/librustc | |
| parent | 1270f8e77a53b5be5ea3de10440c79394c0ad025 (diff) | |
| parent | f4a7d32c8b53649d20735c8a90469b08fe7cc3dc (diff) | |
| download | rust-2c0f87610d8fdcb6a90cd8dd1a372fe0ccc8a418.tar.gz rust-2c0f87610d8fdcb6a90cd8dd1a372fe0ccc8a418.zip | |
auto merge of #18022 : nikomatsakis/rust/issue-18019, r=pcwalton
Only consider impliciy unboxed closure impl if the obligation is actually for `Fn`, `FnMut`, or `FnOnce`. Fixes #18019 r? @pcwalton
Diffstat (limited to 'src/librustc')
| -rw-r--r-- | src/librustc/middle/traits/select.rs | 49 |
1 files changed, 20 insertions, 29 deletions
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 4040b452e99..2a45d536066 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -608,6 +608,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { * unified during the confirmation step. */ + let tcx = self.tcx(); + let kind = if Some(obligation.trait_ref.def_id) == tcx.lang_items.fn_trait() { + ty::FnUnboxedClosureKind + } else if Some(obligation.trait_ref.def_id) == tcx.lang_items.fn_mut_trait() { + ty::FnMutUnboxedClosureKind + } else if Some(obligation.trait_ref.def_id) == tcx.lang_items.fn_once_trait() { + ty::FnOnceUnboxedClosureKind + } else { + return Ok(()); // not a fn trait, ignore + }; + let self_ty = self.infcx.shallow_resolve(obligation.self_ty()); let closure_def_id = match ty::get(self_ty).sty { ty::ty_unboxed_closure(id, _) => id, @@ -622,37 +633,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self_ty.repr(self.tcx()), obligation.repr(self.tcx())); - let tcx = self.tcx(); - let fn_traits = [ - (ty::FnUnboxedClosureKind, tcx.lang_items.fn_trait()), - (ty::FnMutUnboxedClosureKind, tcx.lang_items.fn_mut_trait()), - (ty::FnOnceUnboxedClosureKind, tcx.lang_items.fn_once_trait()), - ]; - for tuple in fn_traits.iter() { - let kind = match tuple { - &(kind, Some(ref fn_trait)) - if *fn_trait == obligation.trait_ref.def_id => - { - kind - } - _ => continue, - }; - - // Check to see whether the argument and return types match. - let closure_kind = match self.typer.unboxed_closures().borrow().find(&closure_def_id) { - Some(closure) => closure.kind, - None => { - self.tcx().sess.span_bug( - obligation.cause.span, - format!("No entry for unboxed closure: {}", - closure_def_id.repr(self.tcx())).as_slice()); - } - }; - - if closure_kind != kind { - continue; + let closure_kind = match self.typer.unboxed_closures().borrow().find(&closure_def_id) { + Some(closure) => closure.kind, + None => { + self.tcx().sess.span_bug( + obligation.cause.span, + format!("No entry for unboxed closure: {}", + closure_def_id.repr(self.tcx())).as_slice()); } + }; + if closure_kind == kind { candidates.vec.push(UnboxedClosureCandidate(closure_def_id)); } |
