Skip to content

Commit 24b0897

Browse files
committed
librustc: Fix bogus logic for static calls to unboxed closures in the
expression use visitor. Closes #16166.
1 parent 3f5d0b5 commit 24b0897

File tree

3 files changed

+56
-12
lines changed

3 files changed

+56
-12
lines changed

src/librustc/middle/expr_use_visitor.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -130,16 +130,11 @@ impl OverloadedCallType {
130130

131131
fn from_method_id(tcx: &ty::ctxt, method_id: ast::DefId)
132132
-> OverloadedCallType {
133-
let method_descriptor =
134-
match tcx.impl_or_trait_items.borrow_mut().find(&method_id) {
135-
Some(&ty::MethodTraitItem(ref method_descriptor)) => {
136-
(*method_descriptor).clone()
137-
}
138-
None => {
139-
tcx.sess.bug("overloaded call method wasn't in method \
140-
map")
141-
}
142-
};
133+
let method_descriptor = match ty::impl_or_trait_item(tcx, method_id) {
134+
ty::MethodTraitItem(ref method_descriptor) => {
135+
(*method_descriptor).clone()
136+
}
137+
};
143138
let impl_id = match method_descriptor.container {
144139
ty::TraitContainer(_) => {
145140
tcx.sess.bug("statically resolved overloaded call method \
@@ -157,14 +152,27 @@ impl OverloadedCallType {
157152
OverloadedCallType::from_trait_id(tcx, trait_ref.def_id)
158153
}
159154

155+
fn from_unboxed_closure(tcx: &ty::ctxt, closure_did: ast::DefId)
156+
-> OverloadedCallType {
157+
let trait_did =
158+
tcx.unboxed_closures
159+
.borrow()
160+
.find(&closure_did)
161+
.expect("OverloadedCallType::from_unboxed_closure: didn't \
162+
find closure id")
163+
.kind
164+
.trait_did(tcx);
165+
OverloadedCallType::from_trait_id(tcx, trait_did)
166+
}
167+
160168
fn from_method_origin(tcx: &ty::ctxt, origin: &MethodOrigin)
161169
-> OverloadedCallType {
162170
match *origin {
163171
MethodStatic(def_id) => {
164172
OverloadedCallType::from_method_id(tcx, def_id)
165173
}
166174
MethodStaticUnboxedClosure(def_id) => {
167-
OverloadedCallType::from_method_id(tcx, def_id)
175+
OverloadedCallType::from_unboxed_closure(tcx, def_id)
168176
}
169177
MethodParam(ref method_param) => {
170178
OverloadedCallType::from_trait_id(tcx, method_param.trait_id)

src/librustc/middle/ty.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ use middle::def;
1919
use middle::dependency_format;
2020
use middle::freevars::CaptureModeMap;
2121
use middle::freevars;
22-
use middle::lang_items::{FnMutTraitLangItem, OpaqueStructLangItem};
22+
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem};
23+
use middle::lang_items::{FnOnceTraitLangItem, OpaqueStructLangItem};
2324
use middle::lang_items::{TyDescStructLangItem, TyVisitorTraitLangItem};
2425
use middle::mem_categorization as mc;
2526
use middle::resolve;
@@ -1205,6 +1206,24 @@ pub enum UnboxedClosureKind {
12051206
FnOnceUnboxedClosureKind,
12061207
}
12071208

1209+
impl UnboxedClosureKind {
1210+
pub fn trait_did(&self, cx: &ctxt) -> ast::DefId {
1211+
let result = match *self {
1212+
FnUnboxedClosureKind => cx.lang_items.require(FnTraitLangItem),
1213+
FnMutUnboxedClosureKind => {
1214+
cx.lang_items.require(FnMutTraitLangItem)
1215+
}
1216+
FnOnceUnboxedClosureKind => {
1217+
cx.lang_items.require(FnOnceTraitLangItem)
1218+
}
1219+
};
1220+
match result {
1221+
Ok(trait_did) => trait_did,
1222+
Err(err) => cx.sess.fatal(err.as_slice()),
1223+
}
1224+
}
1225+
}
1226+
12081227
pub fn mk_ctxt(s: Session,
12091228
dm: resolve::DefMap,
12101229
named_region_map: resolve_lifetime::NamedRegionMap,
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(unboxed_closures, overloaded_calls)]
12+
13+
fn main() {
14+
let mut unboxed = |&mut:| {};
15+
unboxed();
16+
}
17+

0 commit comments

Comments
 (0)