Skip to content

Commit 8c44a9d

Browse files
committed
Store all generic arguments for method calls in HIR
1 parent 287de25 commit 8c44a9d

File tree

9 files changed

+55
-67
lines changed

9 files changed

+55
-67
lines changed

src/librustc/hir/intravisit.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -944,10 +944,9 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
944944
walk_list!(visitor, visit_expr, arguments);
945945
visitor.visit_expr(callee_expression)
946946
}
947-
ExprMethodCall(ref name, ref types, ref arguments) => {
948-
visitor.visit_name(name.span, name.node);
947+
ExprMethodCall(ref segment, _, ref arguments) => {
948+
visitor.visit_path_segment(expression.span, segment);
949949
walk_list!(visitor, visit_expr, arguments);
950-
walk_list!(visitor, visit_ty, types);
951950
}
952951
ExprBinary(_, ref left_expression, ref right_expression) => {
953952
visitor.visit_expr(left_expression);

src/librustc/hir/lowering.rs

+2-9
Original file line numberDiff line numberDiff line change
@@ -1845,16 +1845,9 @@ impl<'a> LoweringContext<'a> {
18451845
hir::ExprCall(f, args.iter().map(|x| self.lower_expr(x)).collect())
18461846
}
18471847
ExprKind::MethodCall(ref seg, ref args) => {
1848-
let tps = match seg.parameters {
1849-
Some(ref params) => match **params {
1850-
PathParameters::AngleBracketed(ref param_data) => &param_data.types[..],
1851-
_ => &[],
1852-
},
1853-
_ => &[],
1854-
};
1855-
let tps = tps.iter().map(|x| self.lower_ty(x)).collect();
1848+
let hir_seg = self.lower_path_segment(e.span, seg, ParamMode::Optional, 0);
18561849
let args = args.iter().map(|x| self.lower_expr(x)).collect();
1857-
hir::ExprMethodCall(respan(seg.span, self.lower_ident(seg.identifier)), tps, args)
1850+
hir::ExprMethodCall(hir_seg, seg.span, args)
18581851
}
18591852
ExprKind::Binary(binop, ref lhs, ref rhs) => {
18601853
let binop = self.lower_binop(binop);

src/librustc/hir/mod.rs

+7-10
Original file line numberDiff line numberDiff line change
@@ -972,19 +972,16 @@ pub enum Expr_ {
972972
/// The first field resolves to the function itself (usually an `ExprPath`),
973973
/// and the second field is the list of arguments
974974
ExprCall(P<Expr>, HirVec<Expr>),
975-
/// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
975+
/// A method call (`x.foo::<'static, Bar, Baz>(a, b, c, d)`)
976976
///
977-
/// The `Spanned<Name>` is the identifier for the method name.
978-
/// The vector of `Ty`s are the ascripted type parameters for the method
977+
/// The `PathSegment`/`Span` represent the method name and its generic arguments
979978
/// (within the angle brackets).
980-
///
981-
/// The first element of the vector of `Expr`s is the expression that
982-
/// evaluates to the object on which the method is being called on (the
983-
/// receiver), and the remaining elements are the rest of the arguments.
984-
///
979+
/// The first element of the vector of `Expr`s is the expression that evaluates
980+
/// to the object on which the method is being called on (the receiver),
981+
/// and the remaining elements are the rest of the arguments.
985982
/// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
986-
/// `ExprMethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
987-
ExprMethodCall(Spanned<Name>, HirVec<P<Ty>>, HirVec<Expr>),
983+
/// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`.
984+
ExprMethodCall(PathSegment, Span, HirVec<Expr>),
988985
/// A tuple (`(a, b, c ,d)`)
989986
ExprTup(HirVec<Expr>),
990987
/// A binary operation (For example: `a + b`, `a * b`)

src/librustc/hir/print.rs

+8-9
Original file line numberDiff line numberDiff line change
@@ -1188,18 +1188,17 @@ impl<'a> State<'a> {
11881188
}
11891189

11901190
fn print_expr_method_call(&mut self,
1191-
name: Spanned<ast::Name>,
1192-
tys: &[P<hir::Ty>],
1191+
segment: &hir::PathSegment,
11931192
args: &[hir::Expr])
11941193
-> io::Result<()> {
11951194
let base_args = &args[1..];
11961195
self.print_expr(&args[0])?;
11971196
word(&mut self.s, ".")?;
1198-
self.print_name(name.node)?;
1199-
if !tys.is_empty() {
1200-
word(&mut self.s, "::<")?;
1201-
self.commasep(Inconsistent, tys, |s, ty| s.print_type(&ty))?;
1202-
word(&mut self.s, ">")?;
1197+
self.print_name(segment.name)?;
1198+
if !segment.parameters.lifetimes().is_empty() ||
1199+
!segment.parameters.types().is_empty() ||
1200+
!segment.parameters.bindings().is_empty() {
1201+
self.print_path_parameters(&segment.parameters, true)?;
12031202
}
12041203
self.print_call_post(base_args)
12051204
}
@@ -1254,8 +1253,8 @@ impl<'a> State<'a> {
12541253
hir::ExprCall(ref func, ref args) => {
12551254
self.print_expr_call(&func, args)?;
12561255
}
1257-
hir::ExprMethodCall(name, ref tys, ref args) => {
1258-
self.print_expr_method_call(name, &tys[..], args)?;
1256+
hir::ExprMethodCall(ref segment, _, ref args) => {
1257+
self.print_expr_method_call(segment, args)?;
12591258
}
12601259
hir::ExprBinary(op, ref lhs, ref rhs) => {
12611260
self.print_expr_binary(op, &lhs, &rhs)?;

src/librustc/ich/impls_hir.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ impl_stable_hash_for!(enum hir::Expr_ {
626626
ExprBox(sub),
627627
ExprArray(subs),
628628
ExprCall(callee, args),
629-
ExprMethodCall(name, ts, args),
629+
ExprMethodCall(segment, span, args),
630630
ExprTup(fields),
631631
ExprBinary(op, lhs, rhs),
632632
ExprUnary(op, operand),

src/librustc_privacy/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -670,10 +670,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
670670
return;
671671
}
672672
}
673-
hir::ExprMethodCall(name, ..) => {
673+
hir::ExprMethodCall(_, span, _) => {
674674
// Method calls have to be checked specially.
675675
let def_id = self.tables.type_dependent_defs[&expr.id].def_id();
676-
self.span = name.span;
676+
self.span = span;
677677
if self.tcx.type_of(def_id).visit_with(self) {
678678
return;
679679
}

src/librustc_typeck/check/method/confirm.rs

+15-11
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
4444
call_expr: &'gcx hir::Expr,
4545
unadjusted_self_ty: Ty<'tcx>,
4646
pick: probe::Pick<'tcx>,
47-
supplied_method_types: Vec<Ty<'tcx>>)
47+
segment: &hir::PathSegment)
4848
-> MethodCallee<'tcx> {
49-
debug!("confirm(unadjusted_self_ty={:?}, pick={:?}, supplied_method_types={:?})",
49+
debug!("confirm(unadjusted_self_ty={:?}, pick={:?}, generic_args={:?})",
5050
unadjusted_self_ty,
5151
pick,
52-
supplied_method_types);
52+
segment.parameters);
5353

5454
let mut confirm_cx = ConfirmContext::new(self, span, self_expr, call_expr);
55-
confirm_cx.confirm(unadjusted_self_ty, pick, supplied_method_types)
55+
confirm_cx.confirm(unadjusted_self_ty, pick, segment)
5656
}
5757
}
5858

@@ -73,7 +73,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
7373
fn confirm(&mut self,
7474
unadjusted_self_ty: Ty<'tcx>,
7575
pick: probe::Pick<'tcx>,
76-
supplied_method_types: Vec<Ty<'tcx>>)
76+
segment: &hir::PathSegment)
7777
-> MethodCallee<'tcx> {
7878
// Adjust the self expression the user provided and obtain the adjusted type.
7979
let self_ty = self.adjust_self_ty(unadjusted_self_ty, &pick);
@@ -83,7 +83,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
8383

8484
// Create substitutions for the method's type parameters.
8585
let rcvr_substs = self.fresh_receiver_substs(self_ty, &pick);
86-
let all_substs = self.instantiate_method_substs(&pick, supplied_method_types, rcvr_substs);
86+
let all_substs = self.instantiate_method_substs(&pick, segment, rcvr_substs);
8787

8888
debug!("all_substs={:?}", all_substs);
8989

@@ -279,9 +279,14 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
279279

280280
fn instantiate_method_substs(&mut self,
281281
pick: &probe::Pick<'tcx>,
282-
mut supplied_method_types: Vec<Ty<'tcx>>,
282+
segment: &hir::PathSegment,
283283
substs: &Substs<'tcx>)
284284
-> &'tcx Substs<'tcx> {
285+
let supplied_method_types = match segment.parameters {
286+
hir::AngleBracketedParameters(ref data) => &data.types,
287+
_ => bug!("unexpected generic arguments: {:?}", segment.parameters),
288+
};
289+
285290
// Determine the values for the generic parameters of the method.
286291
// If they were not explicitly supplied, just construct fresh
287292
// variables.
@@ -312,7 +317,6 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
312317
num_method_types))
313318
.emit();
314319
}
315-
supplied_method_types = vec![self.tcx.types.err; num_method_types];
316320
}
317321

318322
// Create subst for early-bound lifetime parameters, combining
@@ -331,10 +335,10 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
331335
let i = def.index as usize;
332336
if i < substs.len() {
333337
substs.type_at(i)
334-
} else if supplied_method_types.is_empty() {
335-
self.type_var_for_def(self.span, def, cur_substs)
338+
} else if let Some(ast_ty) = supplied_method_types.get(i - supplied_start) {
339+
self.to_ty(ast_ty)
336340
} else {
337-
supplied_method_types[i - supplied_start]
341+
self.type_var_for_def(self.span, def, cur_substs)
338342
}
339343
})
340344
}

src/librustc_typeck/check/method/mod.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -130,22 +130,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
130130
/// * `supplied_method_types`: the explicit method type parameters, if any (`T1..Tn`)
131131
/// * `self_expr`: the self expression (`foo`)
132132
pub fn lookup_method(&self,
133-
span: Span,
134-
method_name: ast::Name,
135133
self_ty: ty::Ty<'tcx>,
136-
supplied_method_types: Vec<ty::Ty<'tcx>>,
134+
segment: &hir::PathSegment,
135+
span: Span,
137136
call_expr: &'gcx hir::Expr,
138137
self_expr: &'gcx hir::Expr)
139138
-> Result<MethodCallee<'tcx>, MethodError<'tcx>> {
140139
debug!("lookup(method_name={}, self_ty={:?}, call_expr={:?}, self_expr={:?})",
141-
method_name,
140+
segment.name,
142141
self_ty,
143142
call_expr,
144143
self_expr);
145144

146145
let mode = probe::Mode::MethodCall;
147146
let self_ty = self.resolve_type_vars_if_possible(&self_ty);
148-
let pick = self.probe_for_name(span, mode, method_name, IsSuggestion(false),
147+
let pick = self.probe_for_name(span, mode, segment.name, IsSuggestion(false),
149148
self_ty, call_expr.id)?;
150149

151150
if let Some(import_id) = pick.import_id {
@@ -161,7 +160,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
161160
call_expr,
162161
self_ty,
163162
pick,
164-
supplied_method_types))
163+
segment))
165164
}
166165

167166
/// `lookup_method_in_trait` is used for overloaded operators.

src/librustc_typeck/check/mod.rs

+13-16
Original file line numberDiff line numberDiff line change
@@ -2771,33 +2771,30 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
27712771
// Checks a method call.
27722772
fn check_method_call(&self,
27732773
expr: &'gcx hir::Expr,
2774-
method_name: Spanned<ast::Name>,
2774+
segment: &hir::PathSegment,
2775+
span: Span,
27752776
args: &'gcx [hir::Expr],
2776-
tps: &[P<hir::Ty>],
27772777
expected: Expectation<'tcx>,
27782778
lvalue_pref: LvaluePreference) -> Ty<'tcx> {
27792779
let rcvr = &args[0];
27802780
let rcvr_t = self.check_expr_with_lvalue_pref(&rcvr, lvalue_pref);
2781-
27822781
// no need to check for bot/err -- callee does that
2783-
let expr_t = self.structurally_resolved_type(expr.span, rcvr_t);
2782+
let rcvr_t = self.structurally_resolved_type(expr.span, rcvr_t);
27842783

2785-
let tps = tps.iter().map(|ast_ty| self.to_ty(&ast_ty)).collect::<Vec<_>>();
2786-
let method = match self.lookup_method(method_name.span,
2787-
method_name.node,
2788-
expr_t,
2789-
tps,
2784+
let method = match self.lookup_method(rcvr_t,
2785+
segment,
2786+
span,
27902787
expr,
27912788
rcvr) {
27922789
Ok(method) => {
27932790
self.write_method_call(expr.id, method);
27942791
Ok(method)
27952792
}
27962793
Err(error) => {
2797-
if method_name.node != keywords::Invalid.name() {
2798-
self.report_method_error(method_name.span,
2799-
expr_t,
2800-
method_name.node,
2794+
if segment.name != keywords::Invalid.name() {
2795+
self.report_method_error(span,
2796+
rcvr_t,
2797+
segment.name,
28012798
Some(rcvr),
28022799
error,
28032800
Some(args));
@@ -2807,7 +2804,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
28072804
};
28082805

28092806
// Call the generic checker.
2810-
self.check_method_argument_types(method_name.span, method,
2807+
self.check_method_argument_types(span, method,
28112808
&args[1..],
28122809
DontTupleArguments,
28132810
expected)
@@ -3735,8 +3732,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
37353732
hir::ExprCall(ref callee, ref args) => {
37363733
self.check_call(expr, &callee, args, expected)
37373734
}
3738-
hir::ExprMethodCall(name, ref tps, ref args) => {
3739-
self.check_method_call(expr, name, args, &tps[..], expected, lvalue_pref)
3735+
hir::ExprMethodCall(ref segment, span, ref args) => {
3736+
self.check_method_call(expr, segment, span, args, expected, lvalue_pref)
37403737
}
37413738
hir::ExprCast(ref e, ref t) => {
37423739
// Find the type of `e`. Supply hints based on the type we are casting to,

0 commit comments

Comments
 (0)