Skip to content

Commit

Permalink
Auto merge of #43115 - petrochenkov:methlife2, r=eddyb
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed Jul 9, 2017
2 parents 8b1271f + 9ac79e4 commit d84693b
Show file tree
Hide file tree
Showing 21 changed files with 137 additions and 136 deletions.
14 changes: 7 additions & 7 deletions src/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions src/librustc/hir/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -944,10 +944,9 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
walk_list!(visitor, visit_expr, arguments);
visitor.visit_expr(callee_expression)
}
ExprMethodCall(ref name, ref types, ref arguments) => {
visitor.visit_name(name.span, name.node);
ExprMethodCall(ref segment, _, ref arguments) => {
visitor.visit_path_segment(expression.span, segment);
walk_list!(visitor, visit_expr, arguments);
walk_list!(visitor, visit_ty, types);
}
ExprBinary(_, ref left_expression, ref right_expression) => {
visitor.visit_expr(left_expression);
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1844,10 +1844,10 @@ impl<'a> LoweringContext<'a> {
let f = P(self.lower_expr(f));
hir::ExprCall(f, args.iter().map(|x| self.lower_expr(x)).collect())
}
ExprKind::MethodCall(i, ref tps, ref args) => {
let tps = tps.iter().map(|x| self.lower_ty(x)).collect();
ExprKind::MethodCall(ref seg, ref args) => {
let hir_seg = self.lower_path_segment(e.span, seg, ParamMode::Optional, 0);
let args = args.iter().map(|x| self.lower_expr(x)).collect();
hir::ExprMethodCall(respan(i.span, self.lower_ident(i.node)), tps, args)
hir::ExprMethodCall(hir_seg, seg.span, args)
}
ExprKind::Binary(binop, ref lhs, ref rhs) => {
let binop = self.lower_binop(binop);
Expand Down
17 changes: 7 additions & 10 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -972,19 +972,16 @@ pub enum Expr_ {
/// The first field resolves to the function itself (usually an `ExprPath`),
/// and the second field is the list of arguments
ExprCall(P<Expr>, HirVec<Expr>),
/// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
/// A method call (`x.foo::<'static, Bar, Baz>(a, b, c, d)`)
///
/// The `Spanned<Name>` is the identifier for the method name.
/// The vector of `Ty`s are the ascripted type parameters for the method
/// The `PathSegment`/`Span` represent the method name and its generic arguments
/// (within the angle brackets).
///
/// The first element of the vector of `Expr`s is the expression that
/// evaluates to the object on which the method is being called on (the
/// receiver), and the remaining elements are the rest of the arguments.
///
/// The first element of the vector of `Expr`s is the expression that evaluates
/// to the object on which the method is being called on (the receiver),
/// and the remaining elements are the rest of the arguments.
/// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
/// `ExprMethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
ExprMethodCall(Spanned<Name>, HirVec<P<Ty>>, HirVec<Expr>),
/// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`.
ExprMethodCall(PathSegment, Span, HirVec<Expr>),
/// A tuple (`(a, b, c ,d)`)
ExprTup(HirVec<Expr>),
/// A binary operation (For example: `a + b`, `a * b`)
Expand Down
17 changes: 8 additions & 9 deletions src/librustc/hir/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1188,18 +1188,17 @@ impl<'a> State<'a> {
}

fn print_expr_method_call(&mut self,
name: Spanned<ast::Name>,
tys: &[P<hir::Ty>],
segment: &hir::PathSegment,
args: &[hir::Expr])
-> io::Result<()> {
let base_args = &args[1..];
self.print_expr(&args[0])?;
word(&mut self.s, ".")?;
self.print_name(name.node)?;
if !tys.is_empty() {
word(&mut self.s, "::<")?;
self.commasep(Inconsistent, tys, |s, ty| s.print_type(&ty))?;
word(&mut self.s, ">")?;
self.print_name(segment.name)?;
if !segment.parameters.lifetimes().is_empty() ||
!segment.parameters.types().is_empty() ||
!segment.parameters.bindings().is_empty() {
self.print_path_parameters(&segment.parameters, true)?;
}
self.print_call_post(base_args)
}
Expand Down Expand Up @@ -1254,8 +1253,8 @@ impl<'a> State<'a> {
hir::ExprCall(ref func, ref args) => {
self.print_expr_call(&func, args)?;
}
hir::ExprMethodCall(name, ref tys, ref args) => {
self.print_expr_method_call(name, &tys[..], args)?;
hir::ExprMethodCall(ref segment, _, ref args) => {
self.print_expr_method_call(segment, args)?;
}
hir::ExprBinary(op, ref lhs, ref rhs) => {
self.print_expr_binary(op, &lhs, &rhs)?;
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ich/impls_hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ impl_stable_hash_for!(enum hir::Expr_ {
ExprBox(sub),
ExprArray(subs),
ExprCall(callee, args),
ExprMethodCall(name, ts, args),
ExprMethodCall(segment, span, args),
ExprTup(fields),
ExprBinary(op, lhs, rhs),
ExprUnary(op, operand),
Expand Down
17 changes: 17 additions & 0 deletions src/librustc_passes/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,23 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
ExprKind::Continue(Some(ident)) => {
self.check_label(ident.node, ident.span);
}
ExprKind::MethodCall(ref segment, ..) => {
if let Some(ref params) = segment.parameters {
match **params {
PathParameters::AngleBracketed(ref param_data) => {
if !param_data.bindings.is_empty() {
let binding_span = param_data.bindings[0].span;
self.err_handler().span_err(binding_span,
"type bindings cannot be used in method calls");
}
}
PathParameters::Parenthesized(..) => {
self.err_handler().span_err(expr.span,
"parenthesized parameters cannot be used on method calls");
}
}
}
}
_ => {}
}

Expand Down
4 changes: 2 additions & 2 deletions src/librustc_privacy/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -670,10 +670,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
return;
}
}
hir::ExprMethodCall(name, ..) => {
hir::ExprMethodCall(_, span, _) => {
// Method calls have to be checked specially.
let def_id = self.tables.type_dependent_defs[&expr.id].def_id();
self.span = name.span;
self.span = span;
if self.tcx.type_of(def_id).visit_with(self) {
return;
}
Expand Down
14 changes: 6 additions & 8 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2467,9 +2467,9 @@ impl<'a> Resolver<'a> {
path_str, ident.node));
return err;
}
ExprKind::MethodCall(ident, ..) => {
ExprKind::MethodCall(ref segment, ..) => {
err.span_label(parent.span, format!("did you mean `{}::{}(...)`?",
path_str, ident.node));
path_str, segment.identifier));
return err;
}
_ => {}
Expand Down Expand Up @@ -3145,15 +3145,13 @@ impl<'a> Resolver<'a> {
ExprKind::Field(ref subexpression, _) => {
self.resolve_expr(subexpression, Some(expr));
}
ExprKind::MethodCall(_, ref types, ref arguments) => {
ExprKind::MethodCall(ref segment, ref arguments) => {
let mut arguments = arguments.iter();
self.resolve_expr(arguments.next().unwrap(), Some(expr));
for argument in arguments {
self.resolve_expr(argument, None);
}
for ty in types.iter() {
self.visit_ty(ty);
}
self.visit_path_segment(expr.span, segment);
}

ExprKind::Repeat(ref element, ref count) => {
Expand Down Expand Up @@ -3185,10 +3183,10 @@ impl<'a> Resolver<'a> {
let traits = self.get_traits_containing_item(name.node, ValueNS);
self.trait_map.insert(expr.id, traits);
}
ExprKind::MethodCall(name, ..) => {
ExprKind::MethodCall(ref segment, ..) => {
debug!("(recording candidate traits for expr) recording traits for {}",
expr.id);
let traits = self.get_traits_containing_item(name.node, ValueNS);
let traits = self.get_traits_containing_item(segment.identifier, ValueNS);
self.trait_map.insert(expr.id, traits);
}
_ => {
Expand Down
26 changes: 15 additions & 11 deletions src/librustc_typeck/check/method/confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
call_expr: &'gcx hir::Expr,
unadjusted_self_ty: Ty<'tcx>,
pick: probe::Pick<'tcx>,
supplied_method_types: Vec<Ty<'tcx>>)
segment: &hir::PathSegment)
-> MethodCallee<'tcx> {
debug!("confirm(unadjusted_self_ty={:?}, pick={:?}, supplied_method_types={:?})",
debug!("confirm(unadjusted_self_ty={:?}, pick={:?}, generic_args={:?})",
unadjusted_self_ty,
pick,
supplied_method_types);
segment.parameters);

let mut confirm_cx = ConfirmContext::new(self, span, self_expr, call_expr);
confirm_cx.confirm(unadjusted_self_ty, pick, supplied_method_types)
confirm_cx.confirm(unadjusted_self_ty, pick, segment)
}
}

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

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

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

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

fn instantiate_method_substs(&mut self,
pick: &probe::Pick<'tcx>,
mut supplied_method_types: Vec<Ty<'tcx>>,
segment: &hir::PathSegment,
substs: &Substs<'tcx>)
-> &'tcx Substs<'tcx> {
let supplied_method_types = match segment.parameters {
hir::AngleBracketedParameters(ref data) => &data.types,
_ => bug!("unexpected generic arguments: {:?}", segment.parameters),
};

// Determine the values for the generic parameters of the method.
// If they were not explicitly supplied, just construct fresh
// variables.
Expand Down Expand Up @@ -312,7 +317,6 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
num_method_types))
.emit();
}
supplied_method_types = vec![self.tcx.types.err; num_method_types];
}

// Create subst for early-bound lifetime parameters, combining
Expand All @@ -331,10 +335,10 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
let i = def.index as usize;
if i < substs.len() {
substs.type_at(i)
} else if supplied_method_types.is_empty() {
self.type_var_for_def(self.span, def, cur_substs)
} else if let Some(ast_ty) = supplied_method_types.get(i - supplied_start) {
self.to_ty(ast_ty)
} else {
supplied_method_types[i - supplied_start]
self.type_var_for_def(self.span, def, cur_substs)
}
})
}
Expand Down
11 changes: 5 additions & 6 deletions src/librustc_typeck/check/method/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,22 +130,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
/// * `supplied_method_types`: the explicit method type parameters, if any (`T1..Tn`)
/// * `self_expr`: the self expression (`foo`)
pub fn lookup_method(&self,
span: Span,
method_name: ast::Name,
self_ty: ty::Ty<'tcx>,
supplied_method_types: Vec<ty::Ty<'tcx>>,
segment: &hir::PathSegment,
span: Span,
call_expr: &'gcx hir::Expr,
self_expr: &'gcx hir::Expr)
-> Result<MethodCallee<'tcx>, MethodError<'tcx>> {
debug!("lookup(method_name={}, self_ty={:?}, call_expr={:?}, self_expr={:?})",
method_name,
segment.name,
self_ty,
call_expr,
self_expr);

let mode = probe::Mode::MethodCall;
let self_ty = self.resolve_type_vars_if_possible(&self_ty);
let pick = self.probe_for_name(span, mode, method_name, IsSuggestion(false),
let pick = self.probe_for_name(span, mode, segment.name, IsSuggestion(false),
self_ty, call_expr.id)?;

if let Some(import_id) = pick.import_id {
Expand All @@ -161,7 +160,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
call_expr,
self_ty,
pick,
supplied_method_types))
segment))
}

/// `lookup_method_in_trait` is used for overloaded operators.
Expand Down
Loading

0 comments on commit d84693b

Please sign in to comment.