Skip to content

Commit fe7e285

Browse files
committed
auto merge of #20432 : nikomatsakis/rust/fn-inference-2, r=eddyb
Previously, the borrow mode of each upvar was inferred as part of regionck. This PR moves it into its own separate step. It also employs the `ExprUseVisitor`, further simplifying the code. The eventual goal is to support better inference of `Fn` vs `FnMut` vs `FnOnce` that is not based on the expected type, as well as supporting individual by-move upvars. r? @eddyb
2 parents fc2ba13 + cbeff8b commit fe7e285

35 files changed

+1064
-857
lines changed

src/librustc/lint/builtin.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -1612,15 +1612,11 @@ impl LintPass for MissingCopyImplementations {
16121612
}
16131613
_ => return,
16141614
};
1615-
let parameter_environment = ty::empty_parameter_environment();
1616-
if !ty::type_moves_by_default(cx.tcx,
1617-
ty,
1618-
&parameter_environment) {
1615+
let parameter_environment = ty::empty_parameter_environment(cx.tcx);
1616+
if !ty::type_moves_by_default(&parameter_environment, item.span, ty) {
16191617
return
16201618
}
1621-
if ty::can_type_implement_copy(cx.tcx,
1622-
ty,
1623-
&parameter_environment).is_ok() {
1619+
if ty::can_type_implement_copy(&parameter_environment, item.span, ty).is_ok() {
16241620
cx.span_lint(MISSING_COPY_IMPLEMENTATIONS,
16251621
item.span,
16261622
"type could implement `Copy`; consider adding `impl \

src/librustc/middle/check_match.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ impl<'a> FromIterator<Vec<&'a Pat>> for Matrix<'a> {
9999

100100
pub struct MatchCheckCtxt<'a, 'tcx: 'a> {
101101
pub tcx: &'a ty::ctxt<'tcx>,
102-
pub param_env: ParameterEnvironment<'tcx>,
102+
pub param_env: ParameterEnvironment<'a, 'tcx>,
103103
}
104104

105105
#[deriving(Clone, PartialEq)]
@@ -148,7 +148,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MatchCheckCtxt<'a, 'tcx> {
148148
pub fn check_crate(tcx: &ty::ctxt) {
149149
visit::walk_crate(&mut MatchCheckCtxt {
150150
tcx: tcx,
151-
param_env: ty::empty_parameter_environment(),
151+
param_env: ty::empty_parameter_environment(tcx),
152152
}, tcx.map.krate());
153153
tcx.sess.abort_if_errors();
154154
}
@@ -1032,9 +1032,7 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
10321032
match p.node {
10331033
ast::PatIdent(ast::BindByValue(_), _, ref sub) => {
10341034
let pat_ty = ty::node_id_to_type(tcx, p.id);
1035-
if ty::type_moves_by_default(tcx,
1036-
pat_ty,
1037-
&cx.param_env) {
1035+
if ty::type_moves_by_default(&cx.param_env, pat.span, pat_ty) {
10381036
check_move(p, sub.as_ref().map(|p| &**p));
10391037
}
10401038
}
@@ -1063,8 +1061,7 @@ fn check_for_mutation_in_guard<'a, 'tcx>(cx: &'a MatchCheckCtxt<'a, 'tcx>,
10631061
cx: cx,
10641062
};
10651063
let mut visitor = ExprUseVisitor::new(&mut checker,
1066-
checker.cx.tcx,
1067-
&cx.param_env);
1064+
&checker.cx.param_env);
10681065
visitor.walk_expr(guard);
10691066
}
10701067

src/librustc/middle/check_rvalues.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for RvalueContext<'a, 'tcx> {
4141
{
4242
let param_env = ParameterEnvironment::for_item(self.tcx, fn_id);
4343
let mut delegate = RvalueContextDelegate { tcx: self.tcx, param_env: &param_env };
44-
let mut euv = euv::ExprUseVisitor::new(&mut delegate, self.tcx, &param_env);
44+
let mut euv = euv::ExprUseVisitor::new(&mut delegate, &param_env);
4545
euv.walk_fn(fd, b);
4646
}
4747
visit::walk_fn(self, fk, fd, b, s)
@@ -50,7 +50,7 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for RvalueContext<'a, 'tcx> {
5050

5151
struct RvalueContextDelegate<'a, 'tcx: 'a> {
5252
tcx: &'a ty::ctxt<'tcx>,
53-
param_env: &'a ty::ParameterEnvironment<'tcx>,
53+
param_env: &'a ty::ParameterEnvironment<'a,'tcx>,
5454
}
5555

5656
impl<'a, 'tcx> euv::Delegate<'tcx> for RvalueContextDelegate<'a, 'tcx> {
@@ -60,7 +60,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for RvalueContextDelegate<'a, 'tcx> {
6060
cmt: mc::cmt<'tcx>,
6161
_: euv::ConsumeMode) {
6262
debug!("consume; cmt: {}; type: {}", *cmt, ty_to_string(self.tcx, cmt.ty));
63-
if !ty::type_is_sized(self.tcx, cmt.ty, self.param_env) {
63+
if !ty::type_is_sized(self.param_env, span, cmt.ty) {
6464
span_err!(self.tcx.sess, span, E0161,
6565
"cannot move a value of type {0}: the size of {0} cannot be statically determined",
6666
ty_to_string(self.tcx, cmt.ty));

src/librustc/middle/check_static.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ struct CheckStaticVisitor<'a, 'tcx: 'a> {
5454
}
5555

5656
struct GlobalVisitor<'a,'b,'tcx:'a+'b>(
57-
euv::ExprUseVisitor<'a,'b,'tcx,ty::ctxt<'tcx>>);
57+
euv::ExprUseVisitor<'a,'b,'tcx,ty::ParameterEnvironment<'b,'tcx>>);
5858
struct GlobalChecker {
5959
static_consumptions: NodeSet,
6060
const_borrows: NodeSet,
@@ -70,8 +70,8 @@ pub fn check_crate(tcx: &ty::ctxt) {
7070
static_local_borrows: NodeSet::new(),
7171
};
7272
{
73-
let param_env = ty::empty_parameter_environment();
74-
let visitor = euv::ExprUseVisitor::new(&mut checker, tcx, &param_env);
73+
let param_env = ty::empty_parameter_environment(tcx);
74+
let visitor = euv::ExprUseVisitor::new(&mut checker, &param_env);
7575
visit::walk_crate(&mut GlobalVisitor(visitor), tcx.map.krate());
7676
}
7777
visit::walk_crate(&mut CheckStaticVisitor {
@@ -121,8 +121,8 @@ impl<'a, 'tcx> CheckStaticVisitor<'a, 'tcx> {
121121
let mut fulfill_cx = traits::FulfillmentContext::new();
122122
let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic);
123123
fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);
124-
let env = ty::empty_parameter_environment();
125-
match fulfill_cx.select_all_or_error(&infcx, &env, self.tcx) {
124+
let env = ty::empty_parameter_environment(self.tcx);
125+
match fulfill_cx.select_all_or_error(&infcx, &env) {
126126
Ok(()) => { },
127127
Err(ref errors) => {
128128
traits::report_fulfillment_errors(&infcx, errors);

src/librustc/middle/def.rs

+6
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,12 @@ impl TraitItemKind {
126126
}
127127

128128
impl Def {
129+
pub fn local_node_id(&self) -> ast::NodeId {
130+
let def_id = self.def_id();
131+
assert_eq!(def_id.krate, ast::LOCAL_CRATE);
132+
def_id.node
133+
}
134+
129135
pub fn def_id(&self) -> ast::DefId {
130136
match *self {
131137
DefFn(id, _) | DefStaticMethod(id, _) | DefMod(id) |

0 commit comments

Comments
 (0)