Skip to content

Commit d84693b

Browse files
committed
Auto merge of #43115 - petrochenkov:methlife2, r=eddyb
Store all generic arguments for method calls in AST/HIR The first part of #42492. Landed separately to start the process of merging libsyntax changes breaking rustfmt, which is not easy these days.
2 parents 8b1271f + 9ac79e4 commit d84693b

File tree

21 files changed

+137
-136
lines changed

21 files changed

+137
-136
lines changed

src/Cargo.lock

+7-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -1844,10 +1844,10 @@ impl<'a> LoweringContext<'a> {
18441844
let f = P(self.lower_expr(f));
18451845
hir::ExprCall(f, args.iter().map(|x| self.lower_expr(x)).collect())
18461846
}
1847-
ExprKind::MethodCall(i, ref tps, ref args) => {
1848-
let tps = tps.iter().map(|x| self.lower_ty(x)).collect();
1847+
ExprKind::MethodCall(ref seg, ref args) => {
1848+
let hir_seg = self.lower_path_segment(e.span, seg, ParamMode::Optional, 0);
18491849
let args = args.iter().map(|x| self.lower_expr(x)).collect();
1850-
hir::ExprMethodCall(respan(i.span, self.lower_ident(i.node)), tps, args)
1850+
hir::ExprMethodCall(hir_seg, seg.span, args)
18511851
}
18521852
ExprKind::Binary(binop, ref lhs, ref rhs) => {
18531853
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_passes/ast_validation.rs

+17
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,23 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
125125
ExprKind::Continue(Some(ident)) => {
126126
self.check_label(ident.node, ident.span);
127127
}
128+
ExprKind::MethodCall(ref segment, ..) => {
129+
if let Some(ref params) = segment.parameters {
130+
match **params {
131+
PathParameters::AngleBracketed(ref param_data) => {
132+
if !param_data.bindings.is_empty() {
133+
let binding_span = param_data.bindings[0].span;
134+
self.err_handler().span_err(binding_span,
135+
"type bindings cannot be used in method calls");
136+
}
137+
}
138+
PathParameters::Parenthesized(..) => {
139+
self.err_handler().span_err(expr.span,
140+
"parenthesized parameters cannot be used on method calls");
141+
}
142+
}
143+
}
144+
}
128145
_ => {}
129146
}
130147

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_resolve/lib.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -2467,9 +2467,9 @@ impl<'a> Resolver<'a> {
24672467
path_str, ident.node));
24682468
return err;
24692469
}
2470-
ExprKind::MethodCall(ident, ..) => {
2470+
ExprKind::MethodCall(ref segment, ..) => {
24712471
err.span_label(parent.span, format!("did you mean `{}::{}(...)`?",
2472-
path_str, ident.node));
2472+
path_str, segment.identifier));
24732473
return err;
24742474
}
24752475
_ => {}
@@ -3145,15 +3145,13 @@ impl<'a> Resolver<'a> {
31453145
ExprKind::Field(ref subexpression, _) => {
31463146
self.resolve_expr(subexpression, Some(expr));
31473147
}
3148-
ExprKind::MethodCall(_, ref types, ref arguments) => {
3148+
ExprKind::MethodCall(ref segment, ref arguments) => {
31493149
let mut arguments = arguments.iter();
31503150
self.resolve_expr(arguments.next().unwrap(), Some(expr));
31513151
for argument in arguments {
31523152
self.resolve_expr(argument, None);
31533153
}
3154-
for ty in types.iter() {
3155-
self.visit_ty(ty);
3156-
}
3154+
self.visit_path_segment(expr.span, segment);
31573155
}
31583156

31593157
ExprKind::Repeat(ref element, ref count) => {
@@ -3185,10 +3183,10 @@ impl<'a> Resolver<'a> {
31853183
let traits = self.get_traits_containing_item(name.node, ValueNS);
31863184
self.trait_map.insert(expr.id, traits);
31873185
}
3188-
ExprKind::MethodCall(name, ..) => {
3186+
ExprKind::MethodCall(ref segment, ..) => {
31893187
debug!("(recording candidate traits for expr) recording traits for {}",
31903188
expr.id);
3191-
let traits = self.get_traits_containing_item(name.node, ValueNS);
3189+
let traits = self.get_traits_containing_item(segment.identifier, ValueNS);
31923190
self.trait_map.insert(expr.id, traits);
31933191
}
31943192
_ => {

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.

0 commit comments

Comments
 (0)