]> git.proxmox.com Git - rustc.git/blame - src/librustc_typeck/check/callee.rs
New upstream version 1.15.0+dfsg1
[rustc.git] / src / librustc_typeck / check / callee.rs
CommitLineData
1a4d82fc
JJ
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
c30ab7b3 11use super::{DeferredCallResolution, Expectation, FnCtxt, TupleArgumentsFlag};
1a4d82fc 12
85aaf69f 13use CrateCtxt;
54a0048b 14use hir::def::Def;
9e0c209e 15use hir::def_id::{DefId, LOCAL_CRATE};
476ff2be 16use hir::print;
9e0c209e 17use rustc::{infer, traits};
54a0048b 18use rustc::ty::{self, LvaluePreference, Ty};
476ff2be 19use syntax::symbol::Symbol;
3157f602 20use syntax_pos::Span;
1a4d82fc 21
54a0048b 22use rustc::hir;
e9174d1e 23
1a4d82fc
JJ
24/// Check that it is legal to call methods of the trait corresponding
25/// to `trait_id` (this only cares about the trait, not the specific
26/// method that is called)
e9174d1e 27pub fn check_legal_trait_for_method_call(ccx: &CrateCtxt, span: Span, trait_id: DefId) {
5bcae85e 28 if ccx.tcx.lang_items.drop_trait() == Some(trait_id) {
c30ab7b3
SL
29 struct_span_err!(ccx.tcx.sess,
30 span,
31 E0040,
32 "explicit use of destructor method")
9e0c209e 33 .span_label(span, &format!("explicit destructor calls not allowed"))
9cc50fc6 34 .emit();
1a4d82fc
JJ
35 }
36}
37
1a4d82fc
JJ
38enum CallStep<'tcx> {
39 Builtin,
85aaf69f 40 DeferredClosure(ty::FnSig<'tcx>),
c30ab7b3 41 Overloaded(ty::MethodCallee<'tcx>),
1a4d82fc
JJ
42}
43
a7813a04
XL
44impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
45 pub fn check_call(&self,
46 call_expr: &'gcx hir::Expr,
47 callee_expr: &'gcx hir::Expr,
476ff2be 48 arg_exprs: &'gcx [hir::Expr],
c30ab7b3
SL
49 expected: Expectation<'tcx>)
50 -> Ty<'tcx> {
9e0c209e 51 let original_callee_ty = self.check_expr(callee_expr);
c30ab7b3
SL
52 let expr_ty = self.structurally_resolved_type(call_expr.span, original_callee_ty);
53
54 let mut autoderef = self.autoderef(callee_expr.span, expr_ty);
55 let result = autoderef.by_ref()
56 .flat_map(|(adj_ty, idx)| {
57 self.try_overloaded_call_step(call_expr, callee_expr, adj_ty, idx)
58 })
59 .next();
3157f602
XL
60 let callee_ty = autoderef.unambiguous_final_ty();
61 autoderef.finalize(LvaluePreference::NoPreference, Some(callee_expr));
a7813a04 62
9e0c209e 63 let output = match result {
a7813a04
XL
64 None => {
65 // this will report an error since original_callee_ty is not a fn
9e0c209e 66 self.confirm_builtin_call(call_expr, original_callee_ty, arg_exprs, expected)
a7813a04 67 }
1a4d82fc 68
a7813a04 69 Some(CallStep::Builtin) => {
9e0c209e 70 self.confirm_builtin_call(call_expr, callee_ty, arg_exprs, expected)
85aaf69f 71 }
85aaf69f 72
a7813a04 73 Some(CallStep::DeferredClosure(fn_sig)) => {
9e0c209e 74 self.confirm_deferred_closure_call(call_expr, arg_exprs, expected, fn_sig)
a7813a04 75 }
c34b1796 76
a7813a04 77 Some(CallStep::Overloaded(method_callee)) => {
c30ab7b3
SL
78 self.confirm_overloaded_call(call_expr,
79 callee_expr,
80 arg_exprs,
81 expected,
82 method_callee)
a7813a04 83 }
9e0c209e
SL
84 };
85
86 // we must check that return type of called functions is WF:
87 self.register_wf_obligation(output, call_expr.span, traits::MiscObligation);
88
89 output
1a4d82fc
JJ
90 }
91
a7813a04
XL
92 fn try_overloaded_call_step(&self,
93 call_expr: &'gcx hir::Expr,
94 callee_expr: &'gcx hir::Expr,
95 adjusted_ty: Ty<'tcx>,
96 autoderefs: usize)
c30ab7b3 97 -> Option<CallStep<'tcx>> {
a7813a04
XL
98 debug!("try_overloaded_call_step(call_expr={:?}, adjusted_ty={:?}, autoderefs={})",
99 call_expr,
100 adjusted_ty,
101 autoderefs);
102
103 // If the callee is a bare function or a closure, then we're all set.
104 match self.structurally_resolved_type(callee_expr.span, adjusted_ty).sty {
105 ty::TyFnDef(..) | ty::TyFnPtr(_) => {
c30ab7b3 106 self.write_autoderef_adjustment(callee_expr.id, autoderefs, adjusted_ty);
a7813a04
XL
107 return Some(CallStep::Builtin);
108 }
85aaf69f 109
a7813a04
XL
110 ty::TyClosure(def_id, substs) => {
111 assert_eq!(def_id.krate, LOCAL_CRATE);
112
113 // Check whether this is a call to a closure where we
114 // haven't yet decided on whether the closure is fn vs
115 // fnmut vs fnonce. If so, we have to defer further processing.
116 if self.closure_kind(def_id).is_none() {
c30ab7b3
SL
117 let closure_ty = self.closure_type(def_id, substs);
118 let fn_sig = self.replace_late_bound_regions_with_fresh_var(call_expr.span,
119 infer::FnCall,
120 &closure_ty.sig)
121 .0;
122 self.record_deferred_call_resolution(def_id,
123 Box::new(CallResolution {
124 call_expr: call_expr,
125 callee_expr: callee_expr,
126 adjusted_ty: adjusted_ty,
127 autoderefs: autoderefs,
128 fn_sig: fn_sig.clone(),
129 closure_def_id: def_id,
130 }));
a7813a04
XL
131 return Some(CallStep::DeferredClosure(fn_sig));
132 }
133 }
1a4d82fc 134
a7813a04
XL
135 // Hack: we know that there are traits implementing Fn for &F
136 // where F:Fn and so forth. In the particular case of types
137 // like `x: &mut FnMut()`, if there is a call `x()`, we would
138 // normally translate to `FnMut::call_mut(&mut x, ())`, but
139 // that winds up requiring `mut x: &mut FnMut()`. A little
140 // over the top. The simplest fix by far is to just ignore
141 // this case and deref again, so we wind up with
142 // `FnMut::call_mut(&mut *x, ())`.
143 ty::TyRef(..) if autoderefs == 0 => {
144 return None;
1a4d82fc 145 }
a7813a04
XL
146
147 _ => {}
1a4d82fc 148 }
1a4d82fc 149
a7813a04
XL
150 self.try_overloaded_call_traits(call_expr, callee_expr, adjusted_ty, autoderefs)
151 .map(|method_callee| CallStep::Overloaded(method_callee))
152 }
1a4d82fc 153
a7813a04
XL
154 fn try_overloaded_call_traits(&self,
155 call_expr: &hir::Expr,
156 callee_expr: &hir::Expr,
157 adjusted_ty: Ty<'tcx>,
158 autoderefs: usize)
c30ab7b3 159 -> Option<ty::MethodCallee<'tcx>> {
a7813a04 160 // Try the options that are least restrictive on the caller first.
c30ab7b3 161 for &(opt_trait_def_id, method_name) in
476ff2be
SL
162 &[(self.tcx.lang_items.fn_trait(), Symbol::intern("call")),
163 (self.tcx.lang_items.fn_mut_trait(), Symbol::intern("call_mut")),
164 (self.tcx.lang_items.fn_once_trait(), Symbol::intern("call_once"))] {
a7813a04
XL
165 let trait_def_id = match opt_trait_def_id {
166 Some(def_id) => def_id,
167 None => continue,
168 };
169
170 match self.lookup_method_in_trait_adjusted(call_expr.span,
171 Some(&callee_expr),
172 method_name,
173 trait_def_id,
174 autoderefs,
175 false,
176 adjusted_ty,
177 None) {
178 None => continue,
179 Some(method_callee) => {
180 return Some(method_callee);
181 }
182 }
1a4d82fc 183 }
a7813a04
XL
184
185 None
186 }
187
188 fn confirm_builtin_call(&self,
189 call_expr: &hir::Expr,
190 callee_ty: Ty<'tcx>,
476ff2be 191 arg_exprs: &'gcx [hir::Expr],
c30ab7b3
SL
192 expected: Expectation<'tcx>)
193 -> Ty<'tcx> {
a7813a04
XL
194 let error_fn_sig;
195
476ff2be
SL
196 let (fn_sig, def_span) = match callee_ty.sty {
197 ty::TyFnDef(def_id, .., &ty::BareFnTy {ref sig, ..}) => {
198 (sig, self.tcx.map.span_if_local(def_id))
199 }
200 ty::TyFnPtr(&ty::BareFnTy {ref sig, ..}) => (sig, None),
201 ref t => {
202 let mut unit_variant = None;
203 if let &ty::TyAdt(adt_def, ..) = t {
204 if adt_def.is_enum() {
205 if let hir::ExprCall(ref expr, _) = call_expr.node {
206 unit_variant = Some(print::expr_to_string(expr))
207 }
208 }
209 }
210 let mut err = if let Some(path) = unit_variant {
211 let mut err = self.type_error_struct(call_expr.span, |_| {
212 format!("`{}` is being called, but it is not a function", path)
213 }, callee_ty);
214 err.help(&format!("did you mean to write `{}`?", path));
215 err
216 } else {
217 self.type_error_struct(call_expr.span, |actual| {
218 format!("expected function, found `{}`", actual)
219 }, callee_ty)
220 };
a7813a04
XL
221
222 if let hir::ExprCall(ref expr, _) = call_expr.node {
476ff2be
SL
223 let def = if let hir::ExprPath(ref qpath) = expr.node {
224 self.tables.borrow().qpath_def(qpath, expr.id)
225 } else {
226 Def::Err
227 };
228 if def != Def::Err {
229 if let Some(span) = self.tcx.map.span_if_local(def.def_id()) {
230 err.span_note(span, "defined here");
92a42be0
SL
231 }
232 }
233 }
92a42be0 234
a7813a04 235 err.emit();
9cc50fc6 236
a7813a04
XL
237 // This is the "default" function signature, used in case of error.
238 // In that case, we check each argument against "error" in order to
239 // set up all the node type bindings.
476ff2be
SL
240 error_fn_sig = ty::Binder(self.tcx.mk_fn_sig(
241 self.err_args(arg_exprs.len()).into_iter(),
242 self.tcx.types.err,
243 false,
244 ));
1a4d82fc 245
476ff2be 246 (&error_fn_sig, None)
a7813a04
XL
247 }
248 };
1a4d82fc 249
a7813a04
XL
250 // Replace any late-bound regions that appear in the function
251 // signature with region variables. We also have to
252 // renormalize the associated types at this point, since they
253 // previously appeared within a `Binder<>` and hence would not
254 // have been normalized before.
255 let fn_sig =
c30ab7b3
SL
256 self.replace_late_bound_regions_with_fresh_var(call_expr.span, infer::FnCall, fn_sig)
257 .0;
258 let fn_sig = self.normalize_associated_types_in(call_expr.span, &fn_sig);
a7813a04
XL
259
260 // Call the generic checker.
c30ab7b3
SL
261 let expected_arg_tys =
262 self.expected_types_for_fn_args(call_expr.span,
263 expected,
476ff2be
SL
264 fn_sig.output(),
265 fn_sig.inputs());
a7813a04 266 self.check_argument_types(call_expr.span,
476ff2be 267 fn_sig.inputs(),
a7813a04
XL
268 &expected_arg_tys[..],
269 arg_exprs,
270 fn_sig.variadic,
476ff2be
SL
271 TupleArgumentsFlag::DontTupleArguments,
272 def_span);
a7813a04 273
476ff2be 274 fn_sig.output()
a7813a04 275 }
85aaf69f 276
a7813a04
XL
277 fn confirm_deferred_closure_call(&self,
278 call_expr: &hir::Expr,
476ff2be 279 arg_exprs: &'gcx [hir::Expr],
a7813a04 280 expected: Expectation<'tcx>,
c30ab7b3
SL
281 fn_sig: ty::FnSig<'tcx>)
282 -> Ty<'tcx> {
a7813a04
XL
283 // `fn_sig` is the *signature* of the cosure being called. We
284 // don't know the full details yet (`Fn` vs `FnMut` etc), but we
285 // do know the types expected for each argument and the return
286 // type.
287
c30ab7b3
SL
288 let expected_arg_tys = self.expected_types_for_fn_args(call_expr.span,
289 expected,
476ff2be
SL
290 fn_sig.output().clone(),
291 fn_sig.inputs());
a7813a04
XL
292
293 self.check_argument_types(call_expr.span,
476ff2be 294 fn_sig.inputs(),
a7813a04
XL
295 &expected_arg_tys,
296 arg_exprs,
297 fn_sig.variadic,
476ff2be
SL
298 TupleArgumentsFlag::TupleArguments,
299 None);
a7813a04 300
476ff2be 301 fn_sig.output()
a7813a04 302 }
85aaf69f 303
a7813a04
XL
304 fn confirm_overloaded_call(&self,
305 call_expr: &hir::Expr,
306 callee_expr: &'gcx hir::Expr,
476ff2be 307 arg_exprs: &'gcx [hir::Expr],
a7813a04 308 expected: Expectation<'tcx>,
c30ab7b3
SL
309 method_callee: ty::MethodCallee<'tcx>)
310 -> Ty<'tcx> {
311 let output_type = self.check_method_argument_types(call_expr.span,
312 method_callee.ty,
313 callee_expr,
314 arg_exprs,
315 TupleArgumentsFlag::TupleArguments,
316 expected);
a7813a04
XL
317
318 self.write_overloaded_call_method_map(call_expr, method_callee);
9e0c209e 319 output_type
a7813a04
XL
320 }
321
322 fn write_overloaded_call_method_map(&self,
323 call_expr: &hir::Expr,
324 method_callee: ty::MethodCallee<'tcx>) {
325 let method_call = ty::MethodCall::expr(call_expr.id);
326 self.tables.borrow_mut().method_map.insert(method_call, method_callee);
327 }
1a4d82fc
JJ
328}
329
62682a34 330#[derive(Debug)]
a7813a04
XL
331struct CallResolution<'gcx: 'tcx, 'tcx> {
332 call_expr: &'gcx hir::Expr,
333 callee_expr: &'gcx hir::Expr,
85aaf69f 334 adjusted_ty: Ty<'tcx>,
9346a6ac 335 autoderefs: usize,
85aaf69f 336 fn_sig: ty::FnSig<'tcx>,
e9174d1e 337 closure_def_id: DefId,
85aaf69f
SL
338}
339
a7813a04
XL
340impl<'gcx, 'tcx> DeferredCallResolution<'gcx, 'tcx> for CallResolution<'gcx, 'tcx> {
341 fn resolve<'a>(&mut self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) {
c30ab7b3 342 debug!("DeferredCallResolution::resolve() {:?}", self);
85aaf69f
SL
343
344 // we should not be invoked until the closure kind has been
345 // determined by upvar inference
a7813a04 346 assert!(fcx.closure_kind(self.closure_def_id).is_some());
85aaf69f
SL
347
348 // We may now know enough to figure out fn vs fnmut etc.
c30ab7b3
SL
349 match fcx.try_overloaded_call_traits(self.call_expr,
350 self.callee_expr,
351 self.adjusted_ty,
352 self.autoderefs) {
85aaf69f
SL
353 Some(method_callee) => {
354 // One problem is that when we get here, we are going
355 // to have a newly instantiated function signature
356 // from the call trait. This has to be reconciled with
357 // the older function signature we had before. In
358 // principle we *should* be able to fn_sigs(), but we
359 // can't because of the annoying need for a TypeTrace.
360 // (This always bites me, should find a way to
361 // refactor it.)
c30ab7b3
SL
362 let method_sig = fcx.tcx
363 .no_late_bound_regions(method_callee.ty.fn_sig())
364 .unwrap();
85aaf69f 365
c30ab7b3 366 debug!("attempt_resolution: method_callee={:?}", method_callee);
85aaf69f 367
476ff2be
SL
368 for (method_arg_ty, self_arg_ty) in
369 method_sig.inputs().iter().skip(1).zip(self.fn_sig.inputs()) {
370 fcx.demand_eqtype(self.call_expr.span, &self_arg_ty, &method_arg_ty);
85aaf69f
SL
371 }
372
476ff2be 373 fcx.demand_eqtype(self.call_expr.span, method_sig.output(), self.fn_sig.output());
85aaf69f 374
a7813a04 375 fcx.write_overloaded_call_method_map(self.call_expr, method_callee);
85aaf69f
SL
376 }
377 None => {
c30ab7b3
SL
378 span_bug!(self.call_expr.span,
379 "failed to find an overloaded call trait for closure call");
85aaf69f
SL
380 }
381 }
382 }
383}