fcx: &'a FnCtxt<'a, 'tcx>,
span: Span,
self_expr: &'a ast::Expr,
+ call_expr: &'a ast::Expr,
}
struct InstantiatedMethodSig<'tcx> {
pub fn confirm<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
span: Span,
self_expr: &ast::Expr,
+ call_expr: &ast::Expr,
unadjusted_self_ty: Ty<'tcx>,
pick: probe::Pick<'tcx>,
supplied_method_types: Vec<Ty<'tcx>>)
pick.repr(fcx.tcx()),
supplied_method_types.repr(fcx.tcx()));
- let mut confirm_cx = ConfirmContext::new(fcx, span, self_expr);
+ let mut confirm_cx = ConfirmContext::new(fcx, span, self_expr, call_expr);
confirm_cx.confirm(unadjusted_self_ty, pick, supplied_method_types)
}
impl<'a,'tcx> ConfirmContext<'a,'tcx> {
fn new(fcx: &'a FnCtxt<'a, 'tcx>,
span: Span,
- self_expr: &'a ast::Expr)
+ self_expr: &'a ast::Expr,
+ call_expr: &'a ast::Expr)
-> ConfirmContext<'a, 'tcx>
{
- ConfirmContext { fcx: fcx, span: span, self_expr: self_expr }
+ ConfirmContext { fcx: fcx, span: span, self_expr: self_expr, call_expr: call_expr }
}
fn confirm(&mut self,
traits::ObligationCause::misc(self.span),
method_bounds_substs,
method_bounds);
+
+ self.fcx.add_default_region_param_bounds(
+ method_bounds_substs,
+ self.call_expr);
}
///////////////////////////////////////////////////////////////////////////
method_name: ast::Name,
self_ty: Ty<'tcx>,
supplied_method_types: Vec<Ty<'tcx>>,
- call_expr_id: ast::NodeId,
+ call_expr: &ast::Expr,
self_expr: &ast::Expr)
-> Result<MethodCallee<'tcx>, MethodError>
{
* - `self_expr`: the self expression (`foo`)
*/
- debug!("lookup(method_name={}, self_ty={}, call_expr_id={}, self_expr={})",
+ debug!("lookup(method_name={}, self_ty={}, call_expr={}, self_expr={})",
method_name.repr(fcx.tcx()),
self_ty.repr(fcx.tcx()),
- call_expr_id,
+ call_expr.repr(fcx.tcx()),
self_expr.repr(fcx.tcx()));
- let pick = try!(probe::probe(fcx, span, method_name, self_ty, call_expr_id));
- Ok(confirm::confirm(fcx, span, self_expr, self_ty, pick, supplied_method_types))
+ let pick = try!(probe::probe(fcx, span, method_name, self_ty, call_expr.id));
+ Ok(confirm::confirm(fcx, span, self_expr, call_expr, self_ty, pick, supplied_method_types))
}
pub fn lookup_in_trait<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>,
}
}
+ pub fn add_default_region_param_bounds(&self,
+ substs: &Substs<'tcx>,
+ expr: &ast::Expr)
+ {
+ for &ty in substs.types.iter() {
+ let default_bound = ty::ReScope(expr.id);
+ let origin = infer::RelateDefaultParamBound(expr.span, ty);
+ self.register_region_obligation(origin, ty, default_bound);
+ }
+ }
+
pub fn add_obligations_for_parameters(&self,
cause: traits::ObligationCause<'tcx>,
substs: &Substs<'tcx>,
method_name.node.name,
expr_t,
tps,
- expr.id,
+ expr,
rcvr) {
Ok(method) => {
let method_ty = method.ty;
expr: &ast::Expr)
{
fcx.opt_node_ty_substs(expr.id, |item_substs| {
- for &ty in item_substs.substs.types.iter() {
- let default_bound = ty::ReScope(expr.id);
- let origin = infer::RelateDefaultParamBound(expr.span, ty);
- fcx.register_region_obligation(origin, ty, default_bound);
- }
+ fcx.add_default_region_param_bounds(&item_substs.substs, expr);
});
}
--- /dev/null
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test a method call where the parameter `B` would (illegally) be
+// inferred to a region bound in the method argument. If this program
+// were accepted, then the closure passed to `s.f` could escape its
+// argument.
+
+struct S;
+
+impl S {
+ fn f<B>(&self, _: |&i32| -> B) {
+ }
+}
+
+fn main() {
+ let s = S;
+ s.f(|p| p) //~ ERROR cannot infer
+}