Skip to content

Commit 5728135

Browse files
committed
---
yaml --- r: 56686 b: refs/heads/try c: d948308 h: refs/heads/master v: v3
1 parent cc2b8a4 commit 5728135

File tree

5 files changed

+143
-79
lines changed

5 files changed

+143
-79
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: c081ffbd1e845687202a975ea2e698b623e5722f
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 79a2b2eafc3c766cecec8a5f76317693bae9ed17
5-
refs/heads/try: 1745a2cd08d1aa7437ec3d080c9ca85434b54cf5
5+
refs/heads/try: d94830830f81bde37124efd6b4c8b6c9649180e0
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

branches/try/src/librustc/middle/moves.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ pub impl VisitContext {
463463
expr_method_call(callee, _, _, ref args, _) => { // callee.m(args)
464464
// Implicit self is equivalent to & mode, but every
465465
// other kind should be + mode.
466-
self.use_receiver(expr.id, expr.span, callee, visitor);
466+
self.use_receiver(callee, visitor);
467467
self.use_fn_args(expr.callee_id, *args, visitor);
468468
}
469469

@@ -665,7 +665,7 @@ pub impl VisitContext {
665665
return false;
666666
}
667667

668-
self.use_receiver(expr.id, expr.span, receiver_expr, visitor);
668+
self.use_receiver(receiver_expr, visitor);
669669

670670
// for overloaded operatrs, we are always passing in a
671671
// borrowed pointer, so it's always read mode:
@@ -718,8 +718,6 @@ pub impl VisitContext {
718718
}
719719

720720
fn use_receiver(&self,
721-
_expr_id: node_id,
722-
_span: span,
723721
receiver_expr: @expr,
724722
visitor: vt<VisitContext>)
725723
{

branches/try/src/librustc/middle/ty.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2726,6 +2726,16 @@ fn node_id_has_type_params(cx: ctxt, id: ast::node_id) -> bool {
27262726
cx.node_type_substs.contains_key(&id)
27272727
}
27282728

2729+
pub fn ty_fn_sig(fty: t) -> FnSig {
2730+
match get(fty).sty {
2731+
ty_bare_fn(ref f) => copy f.sig,
2732+
ty_closure(ref f) => copy f.sig,
2733+
ref s => {
2734+
fail!(fmt!("ty_fn_sig() called on non-fn type: %?", s))
2735+
}
2736+
}
2737+
}
2738+
27292739
// Type accessors for substructures of types
27302740
pub fn ty_fn_args(fty: t) -> ~[arg] {
27312741
match get(fty).sty {

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

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,15 @@ use middle::typeck::check;
9292
use middle::typeck::infer;
9393
use middle::typeck::{method_map_entry, method_origin, method_param};
9494
use middle::typeck::{method_self, method_static, method_trait, method_super};
95+
use middle::typeck::check::regionmanip::replace_bound_regions_in_fn_sig;
9596
use util::common::indenter;
9697
use util::ppaux::expr_repr;
9798

9899
use core::hashmap::HashSet;
99100
use core::result;
100101
use core::uint;
101102
use core::vec;
103+
use std::list::Nil;
102104
use syntax::ast::{def_id, sty_value, sty_region, sty_box};
103105
use syntax::ast::{sty_uniq, sty_static, node_id, by_copy, by_ref};
104106
use syntax::ast::{m_const, m_mutbl, m_imm};
@@ -121,7 +123,7 @@ pub fn lookup(
121123
fcx: @mut FnCtxt,
122124

123125
// In a call `a.b::<X, Y, ...>(...)`:
124-
expr: @ast::expr, // The expression `a.b`.
126+
expr: @ast::expr, // The expression `a.b(...)`.
125127
self_expr: @ast::expr, // The expression `a`.
126128
callee_id: node_id, // Where to store `a.b`'s type
127129
m_name: ast::ident, // The ident `b`.
@@ -1092,10 +1094,16 @@ pub impl<'self> LookupContext<'self> {
10921094
fn confirm_candidate(&self,
10931095
self_ty: ty::t,
10941096
candidate: &Candidate)
1095-
-> method_map_entry {
1097+
-> method_map_entry
1098+
{
10961099
let tcx = self.tcx();
10971100
let fty = self.fn_ty_from_origin(&candidate.origin);
10981101

1102+
debug!("confirm_candidate(expr=%s, candidate=%s, fty=%s)",
1103+
expr_repr(tcx, self.expr),
1104+
self.cand_to_str(candidate),
1105+
self.ty_to_str(fty));
1106+
10991107
self.enforce_trait_instance_limitations(fty, candidate);
11001108
self.enforce_drop_trait_limitations(candidate);
11011109

@@ -1145,7 +1153,33 @@ pub impl<'self> LookupContext<'self> {
11451153
../*bad*/copy candidate.rcvr_substs
11461154
};
11471155

1148-
self.fcx.write_ty_substs(self.callee_id, fty, all_substs);
1156+
// Compute the method type with type parameters substituted
1157+
debug!("fty=%s all_substs=%s",
1158+
self.ty_to_str(fty),
1159+
ty::substs_to_str(tcx, &all_substs));
1160+
let fty = ty::subst(tcx, &all_substs, fty);
1161+
debug!("after subst, fty=%s", self.ty_to_str(fty));
1162+
1163+
// Replace any bound regions that appear in the function
1164+
// signature with region variables
1165+
let bare_fn_ty = match ty::get(fty).sty {
1166+
ty::ty_bare_fn(ref f) => copy *f,
1167+
ref s => {
1168+
tcx.sess.span_bug(
1169+
self.expr.span,
1170+
fmt!("Invoking method with non-bare-fn ty: %?", s));
1171+
}
1172+
};
1173+
let (_, _, fn_sig) =
1174+
replace_bound_regions_in_fn_sig(
1175+
tcx, @Nil, None, &bare_fn_ty.sig,
1176+
|_br| self.fcx.infcx().next_region_var(
1177+
self.expr.span, self.expr.id));
1178+
let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {sig: fn_sig, ..bare_fn_ty});
1179+
debug!("after replacing bound regions, fty=%s", self.ty_to_str(fty));
1180+
1181+
self.fcx.write_ty(self.callee_id, fty);
1182+
self.fcx.write_substs(self.callee_id, all_substs);
11491183
method_map_entry {
11501184
self_arg: arg {
11511185
mode: ast::expl(candidate.self_mode),

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

Lines changed: 93 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,15 +1122,43 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
11221122
unifier: &fn()) {
11231123
debug!(">> typechecking %s", fcx.expr_to_str(expr));
11241124

1125-
fn check_argument_types(
1125+
fn check_method_argument_types(
11261126
fcx: @mut FnCtxt,
11271127
sp: span,
1128-
call_expr_id: ast::node_id,
1129-
in_fty: ty::t,
1128+
method_fn_ty: ty::t,
11301129
callee_expr: @ast::expr,
11311130
args: &[@ast::expr],
11321131
sugar: ast::CallSugar,
11331132
deref_args: DerefArgs) -> ty::t
1133+
{
1134+
match ty::get(method_fn_ty).sty {
1135+
ty::ty_bare_fn(ref fty) => {
1136+
check_argument_types(fcx, sp, fty.sig.inputs, callee_expr,
1137+
args, sugar, deref_args);
1138+
fty.sig.output
1139+
}
1140+
ty::ty_err => {
1141+
let err_inputs = err_args(fcx.tcx(), args.len());
1142+
check_argument_types(fcx, sp, err_inputs, callee_expr,
1143+
args, sugar, deref_args);
1144+
method_fn_ty
1145+
}
1146+
_ => {
1147+
fcx.tcx().sess.span_bug(
1148+
sp,
1149+
fmt!("Method without bare fn type"));
1150+
}
1151+
}
1152+
}
1153+
1154+
fn check_argument_types(
1155+
fcx: @mut FnCtxt,
1156+
sp: span,
1157+
fn_inputs: &[ty::arg],
1158+
callee_expr: @ast::expr,
1159+
args: &[@ast::expr],
1160+
sugar: ast::CallSugar,
1161+
deref_args: DerefArgs)
11341162
{
11351163
/*!
11361164
*
@@ -1140,59 +1168,12 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
11401168

11411169
let tcx = fcx.ccx.tcx;
11421170

1143-
// Replace all region parameters in the arguments and return
1144-
// type with fresh region variables.
1145-
1146-
debug!("check_argument_types: before universal quant., in_fty=%s",
1147-
fcx.infcx().ty_to_str(in_fty));
1148-
1149-
let sty = structure_of(fcx, sp, in_fty);
1150-
1151-
// FIXME(#3678) For now, do not permit calls to C abi functions.
1152-
match sty {
1153-
ty::ty_bare_fn(ty::BareFnTy {abis, _}) => {
1154-
if !abis.is_rust() {
1155-
tcx.sess.span_err(
1156-
sp,
1157-
fmt!("Calls to C ABI functions are not (yet) \
1158-
supported; be patient, dear user"));
1159-
}
1160-
}
1161-
_ => {}
1162-
}
1163-
1164-
// Extract the function signature from `in_fty`.
1165-
let sig = match sty {
1166-
ty::ty_bare_fn(ty::BareFnTy {sig: sig, _}) |
1167-
ty::ty_closure(ty::ClosureTy {sig: sig, _}) => sig,
1168-
_ => {
1169-
fcx.type_error_message(sp, |actual| {
1170-
fmt!("expected function but \
1171-
found `%s`", actual) }, in_fty, None);
1172-
1173-
// check each arg against "error", in order to set up
1174-
// all the node type bindings
1175-
FnSig {bound_lifetime_names: opt_vec::Empty,
1176-
inputs: args.map(|_x| ty::arg {mode: ast::expl(ast::by_copy),
1177-
ty: ty::mk_err(tcx)}),
1178-
output: ty::mk_err(tcx)}
1179-
}
1180-
};
1181-
1182-
// Replace any bound regions that appear in the function
1183-
// signature with region variables
1184-
let (_, _, sig) =
1185-
replace_bound_regions_in_fn_sig(
1186-
tcx, @Nil, None, &sig,
1187-
|_br| fcx.infcx().next_region_var(
1188-
sp, call_expr_id));
1189-
11901171
// Grab the argument types, supplying fresh type variables
11911172
// if the wrong number of arguments were supplied
11921173
let supplied_arg_count = args.len();
1193-
let expected_arg_count = sig.inputs.len();
1174+
let expected_arg_count = fn_inputs.len();
11941175
let formal_tys = if expected_arg_count == supplied_arg_count {
1195-
sig.inputs.map(|a| a.ty)
1176+
fn_inputs.map(|a| a.ty)
11961177
} else {
11971178
let suffix = match sugar {
11981179
ast::NoSugar => "",
@@ -1216,10 +1197,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
12161197
vec::from_elem(supplied_arg_count, ty::mk_err(tcx))
12171198
};
12181199

1219-
debug!("check_argument_types: after universal quant., \
1220-
formal_tys=%? sig.output=%s",
1221-
formal_tys.map(|t| fcx.infcx().ty_to_str(*t)),
1222-
fcx.infcx().ty_to_str(sig.output));
1200+
debug!("check_argument_types: formal_tys=%?",
1201+
formal_tys.map(|t| fcx.infcx().ty_to_str(*t)));
12231202

12241203
// Check the arguments.
12251204
// We do this in a pretty awful way: first we typecheck any arguments
@@ -1269,8 +1248,11 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
12691248
}
12701249
}
12711250
}
1251+
}
12721252

1273-
sig.output
1253+
fn err_args(tcx: ty::ctxt, len: uint) -> ~[ty::arg] {
1254+
vec::from_fn(len, |_| ty::arg {mode: ast::expl(ast::by_copy),
1255+
ty: ty::mk_err(tcx)})
12741256
}
12751257

12761258
// A generic function for checking assignment expressions
@@ -1295,13 +1277,53 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
12951277
// that they appear in call position.
12961278
check_expr(fcx, f);
12971279

1280+
1281+
// Extract the function signature from `in_fty`.
1282+
let fn_ty = fcx.expr_ty(f);
1283+
let fn_sty = structure_of(fcx, f.span, fn_ty);
1284+
1285+
// FIXME(#3678) For now, do not permit calls to C abi functions.
1286+
match fn_sty {
1287+
ty::ty_bare_fn(ty::BareFnTy {abis, _}) => {
1288+
if !abis.is_rust() {
1289+
fcx.tcx().sess.span_err(
1290+
call_expr.span,
1291+
fmt!("Calls to C ABI functions are not (yet) \
1292+
supported; be patient, dear user"));
1293+
}
1294+
}
1295+
_ => {}
1296+
}
1297+
1298+
let fn_sig = match fn_sty {
1299+
ty::ty_bare_fn(ty::BareFnTy {sig: sig, _}) |
1300+
ty::ty_closure(ty::ClosureTy {sig: sig, _}) => sig,
1301+
_ => {
1302+
fcx.type_error_message(call_expr.span, |actual| {
1303+
fmt!("expected function but \
1304+
found `%s`", actual) }, fn_ty, None);
1305+
1306+
// check each arg against "error", in order to set up
1307+
// all the node type bindings
1308+
FnSig {bound_lifetime_names: opt_vec::Empty,
1309+
inputs: err_args(fcx.tcx(), args.len()),
1310+
output: ty::mk_err(fcx.tcx())}
1311+
}
1312+
};
1313+
1314+
// Replace any bound regions that appear in the function
1315+
// signature with region variables
1316+
let (_, _, fn_sig) =
1317+
replace_bound_regions_in_fn_sig(
1318+
fcx.tcx(), @Nil, None, &fn_sig,
1319+
|_br| fcx.infcx().next_region_var(call_expr.span, call_expr.id));
1320+
12981321
// Call the generic checker.
1299-
let ret_ty = check_argument_types(fcx, call_expr.span, call_expr.id,
1300-
fcx.expr_ty(f), f, args, sugar,
1301-
DontDerefArgs);
1322+
check_argument_types(fcx, call_expr.span, fn_sig.inputs, f,
1323+
args, sugar, DontDerefArgs);
13021324

13031325
// Pull the return type out of the type of the function.
1304-
fcx.write_ty(call_expr.id, ret_ty);
1326+
fcx.write_ty(call_expr.id, fn_sig.output);
13051327
}
13061328

13071329
// Checks a method call.
@@ -1313,6 +1335,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
13131335
tps: &[@ast::Ty],
13141336
sugar: ast::CallSugar) {
13151337
check_expr(fcx, rcvr);
1338+
13161339
// no need to check for bot/err -- callee does that
13171340
let expr_t = structurally_resolved_type(fcx,
13181341
expr.span,
@@ -1352,9 +1375,9 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
13521375

13531376
// Call the generic checker.
13541377
let fn_ty = fcx.node_ty(expr.callee_id);
1355-
let ret_ty = check_argument_types(fcx, expr.span, expr.id,
1356-
fn_ty, expr, args, sugar,
1357-
DontDerefArgs);
1378+
let ret_ty = check_method_argument_types(fcx, expr.span,
1379+
fn_ty, expr, args, sugar,
1380+
DontDerefArgs);
13581381

13591382
// Pull the return type out of the type of the function.
13601383
fcx.write_ty(expr.id, ret_ty);
@@ -1405,20 +1428,19 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
14051428
let method_ty = fcx.node_ty(op_ex.callee_id);
14061429
let method_map = fcx.inh.method_map;
14071430
method_map.insert(op_ex.id, *origin);
1408-
check_argument_types(fcx, op_ex.span,
1409-
op_ex.id, method_ty,
1410-
op_ex, args,
1411-
ast::NoSugar, deref_args)
1431+
check_method_argument_types(fcx, op_ex.span,
1432+
method_ty, op_ex, args,
1433+
ast::NoSugar, deref_args)
14121434
}
14131435
_ => {
14141436
let tcx = fcx.tcx();
14151437
unbound_method();
14161438
// Check the args anyway
14171439
// so we get all the error messages
14181440
let expected_ty = ty::mk_err(tcx);
1419-
check_argument_types(fcx, op_ex.span, op_ex.id,
1420-
expected_ty, op_ex, args,
1421-
ast::NoSugar, deref_args);
1441+
check_method_argument_types(fcx, op_ex.span,
1442+
expected_ty, op_ex, args,
1443+
ast::NoSugar, deref_args);
14221444
ty::mk_err(tcx)
14231445
}
14241446
}

0 commit comments

Comments
 (0)