Skip to content

Commit 6f1b1a6

Browse files
committed
auto merge of #16631 : pcwalton/rust/unboxed-closures-wrong-trait, r=huonw
the right trait and take the method name into account. Closes #16599. r? @huonw
2 parents 6de570f + b0931a0 commit 6f1b1a6

File tree

7 files changed

+134
-44
lines changed

7 files changed

+134
-44
lines changed

src/librustc/middle/ty.rs

Lines changed: 36 additions & 13 deletions
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,
@@ -3195,19 +3214,23 @@ impl AutoRef {
31953214
}
31963215
}
31973216

3198-
pub fn method_call_type_param_defs(tcx: &ctxt, origin: typeck::MethodOrigin)
3199-
-> VecPerParamSpace<TypeParameterDef> {
3217+
pub fn method_call_type_param_defs<T>(typer: &T,
3218+
origin: typeck::MethodOrigin)
3219+
-> VecPerParamSpace<TypeParameterDef>
3220+
where T: mc::Typer {
32003221
match origin {
32013222
typeck::MethodStatic(did) => {
3202-
ty::lookup_item_type(tcx, did).generics.types.clone()
3203-
}
3204-
typeck::MethodStaticUnboxedClosure(_) => {
3205-
match tcx.lang_items.require(FnMutTraitLangItem) {
3206-
Ok(def_id) => {
3207-
lookup_trait_def(tcx, def_id).generics.types.clone()
3208-
}
3209-
Err(s) => tcx.sess.fatal(s.as_slice()),
3210-
}
3223+
ty::lookup_item_type(typer.tcx(), did).generics.types.clone()
3224+
}
3225+
typeck::MethodStaticUnboxedClosure(did) => {
3226+
let def_id = typer.unboxed_closures()
3227+
.borrow()
3228+
.find(&did)
3229+
.expect("method_call_type_param_defs: didn't \
3230+
find unboxed closure")
3231+
.kind
3232+
.trait_did(typer.tcx());
3233+
lookup_trait_def(typer.tcx(), def_id).generics.types.clone()
32113234
}
32123235
typeck::MethodParam(typeck::MethodParam{
32133236
trait_id: trt_id,
@@ -3219,7 +3242,7 @@ pub fn method_call_type_param_defs(tcx: &ctxt, origin: typeck::MethodOrigin)
32193242
method_num: n_mth,
32203243
..
32213244
}) => {
3222-
match ty::trait_item(tcx, trt_id, n_mth) {
3245+
match ty::trait_item(typer.tcx(), trt_id, n_mth) {
32233246
ty::MethodTraitItem(method) => method.generics.types.clone(),
32243247
}
32253248
}

src/librustc/middle/typeck/check/method.rs

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,11 @@ impl<'a> LookupContext<'a> {
534534
ty::MethodTraitItem(method) => method,
535535
};
536536

537+
// Make sure it has the right name!
538+
if method.ident.name != self.m_name {
539+
return
540+
}
541+
537542
let vcx = self.fcx.vtable_context();
538543
let region_params =
539544
vec!(vcx.infcx.next_region_var(MiscVariable(self.span)));
@@ -562,38 +567,28 @@ impl<'a> LookupContext<'a> {
562567
fn push_unboxed_closure_call_candidates_if_applicable(
563568
&mut self,
564569
closure_did: DefId) {
565-
let trait_dids = [
566-
self.tcx().lang_items.fn_trait(),
567-
self.tcx().lang_items.fn_mut_trait(),
568-
self.tcx().lang_items.fn_once_trait()
569-
];
570-
for optional_trait_did in trait_dids.iter() {
571-
let trait_did = match *optional_trait_did {
572-
Some(trait_did) => trait_did,
573-
None => continue,
574-
};
575-
576-
match self.tcx().unboxed_closures.borrow().find(&closure_did) {
577-
None => {} // Fall through to try inherited.
578-
Some(closure) => {
579-
self.push_unboxed_closure_call_candidate_if_applicable(
580-
trait_did,
581-
closure_did,
582-
&closure.closure_type);
583-
return
584-
}
570+
match self.tcx().unboxed_closures.borrow().find(&closure_did) {
571+
None => {} // Fall through to try inherited.
572+
Some(closure) => {
573+
let tcx = self.tcx();
574+
self.push_unboxed_closure_call_candidate_if_applicable(
575+
closure.kind.trait_did(tcx),
576+
closure_did,
577+
&closure.closure_type);
578+
return
585579
}
580+
}
586581

587-
match self.fcx.inh.unboxed_closures.borrow().find(&closure_did) {
588-
Some(closure) => {
589-
self.push_unboxed_closure_call_candidate_if_applicable(
590-
trait_did,
591-
closure_did,
592-
&closure.closure_type);
593-
return
594-
}
595-
None => {}
582+
match self.fcx.inh.unboxed_closures.borrow().find(&closure_did) {
583+
Some(closure) => {
584+
let tcx = self.tcx();
585+
self.push_unboxed_closure_call_candidate_if_applicable(
586+
closure.kind.trait_did(tcx),
587+
closure_did,
588+
&closure.closure_type);
589+
return
596590
}
591+
None => {}
597592
}
598593

599594
self.tcx().sess.bug("didn't find unboxed closure type in tcx map or \

src/librustc/middle/typeck/check/mod.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,10 @@ type parameter).
7979

8080
use middle::const_eval;
8181
use middle::def;
82+
use middle::freevars;
8283
use middle::lang_items::IteratorItem;
84+
use middle::mem_categorization::McResult;
85+
use middle::mem_categorization;
8386
use middle::pat_util::pat_id_map;
8487
use middle::pat_util;
8588
use middle::subst;
@@ -110,6 +113,7 @@ use middle::typeck::no_params;
110113
use middle::typeck::{require_same_types, vtable_map};
111114
use middle::typeck::{MethodCall, MethodMap};
112115
use middle::typeck::{TypeAndSubsts};
116+
use middle::typeck;
113117
use middle::lang_items::TypeIdLangItem;
114118
use lint;
115119
use util::common::{block_query, indenter, loop_query};
@@ -261,6 +265,39 @@ pub struct FnCtxt<'a> {
261265
ccx: &'a CrateCtxt<'a>,
262266
}
263267

268+
impl<'a> mem_categorization::Typer for FnCtxt<'a> {
269+
fn tcx<'a>(&'a self) -> &'a ty::ctxt {
270+
self.ccx.tcx
271+
}
272+
fn node_ty(&self, id: ast::NodeId) -> McResult<ty::t> {
273+
self.ccx.tcx.node_ty(id)
274+
}
275+
fn node_method_ty(&self, method_call: typeck::MethodCall)
276+
-> Option<ty::t> {
277+
self.ccx.tcx.node_method_ty(method_call)
278+
}
279+
fn adjustments<'a>(&'a self) -> &'a RefCell<NodeMap<ty::AutoAdjustment>> {
280+
self.ccx.tcx.adjustments()
281+
}
282+
fn is_method_call(&self, id: ast::NodeId) -> bool {
283+
self.ccx.tcx.is_method_call(id)
284+
}
285+
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<ast::NodeId> {
286+
self.ccx.tcx.temporary_scope(rvalue_id)
287+
}
288+
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow {
289+
self.ccx.tcx.upvar_borrow(upvar_id)
290+
}
291+
fn capture_mode(&self, closure_expr_id: ast::NodeId)
292+
-> freevars::CaptureMode {
293+
self.ccx.tcx.capture_mode(closure_expr_id)
294+
}
295+
fn unboxed_closures<'a>(&'a self)
296+
-> &'a RefCell<DefIdMap<ty::UnboxedClosure>> {
297+
&self.inh.unboxed_closures
298+
}
299+
}
300+
264301
impl<'a> Inherited<'a> {
265302
fn new(tcx: &'a ty::ctxt,
266303
param_env: ty::ParameterEnvironment)

src/librustc/middle/typeck/check/regionck.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ impl<'a> Rcx<'a> {
263263

264264
impl<'fcx> mc::Typer for Rcx<'fcx> {
265265
fn tcx<'a>(&'a self) -> &'a ty::ctxt {
266-
self.fcx.tcx()
266+
self.fcx.ccx.tcx
267267
}
268268

269269
fn node_ty(&self, id: ast::NodeId) -> mc::McResult<ty::t> {

src/librustc/middle/typeck/check/vtable.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -774,7 +774,8 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
774774
Some(method) => {
775775
debug!("vtable resolution on parameter bounds for method call {}",
776776
ex.repr(fcx.tcx()));
777-
let type_param_defs = ty::method_call_type_param_defs(cx.tcx, method.origin);
777+
let type_param_defs =
778+
ty::method_call_type_param_defs(fcx, method.origin);
778779
let substs = fcx.method_ty_substs(ex.id);
779780
let vcx = fcx.vtable_context();
780781
let vtbls = lookup_vtables(&vcx, ex.span,
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)]
12+
13+
fn main() {
14+
let mut_ = |&mut: x| x;
15+
mut_.call_once((0i, )); //~ ERROR type `closure` does not implement
16+
}
17+
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)]
12+
13+
fn main() {
14+
let onetime = |: x| x;
15+
onetime.call_once((0i,));
16+
}
17+

0 commit comments

Comments
 (0)