]>
Commit | Line | Data |
---|---|---|
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 | ||
11 | // Checks that all rvalues in a crate have statically known size. check_crate | |
12 | // is the public starting point. | |
13 | ||
7453a54e SL |
14 | use rustc::dep_graph::DepNode; |
15 | use rustc::middle::expr_use_visitor as euv; | |
54a0048b | 16 | use rustc::infer; |
7453a54e | 17 | use rustc::middle::mem_categorization as mc; |
54a0048b SL |
18 | use rustc::ty::{self, TyCtxt, ParameterEnvironment}; |
19 | use rustc::traits::ProjectionMode; | |
1a4d82fc | 20 | |
54a0048b SL |
21 | use rustc::hir; |
22 | use rustc::hir::intravisit; | |
9cc50fc6 SL |
23 | use syntax::ast; |
24 | use syntax::codemap::Span; | |
1a4d82fc | 25 | |
54a0048b | 26 | pub fn check_crate(tcx: &TyCtxt) { |
1a4d82fc | 27 | let mut rvcx = RvalueContext { tcx: tcx }; |
9cc50fc6 | 28 | tcx.visit_all_items_in_krate(DepNode::RvalueCheck, &mut rvcx); |
1a4d82fc JJ |
29 | } |
30 | ||
31 | struct RvalueContext<'a, 'tcx: 'a> { | |
54a0048b | 32 | tcx: &'a TyCtxt<'tcx>, |
1a4d82fc JJ |
33 | } |
34 | ||
92a42be0 | 35 | impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for RvalueContext<'a, 'tcx> { |
1a4d82fc | 36 | fn visit_fn(&mut self, |
92a42be0 | 37 | fk: intravisit::FnKind<'v>, |
e9174d1e SL |
38 | fd: &'v hir::FnDecl, |
39 | b: &'v hir::Block, | |
1a4d82fc JJ |
40 | s: Span, |
41 | fn_id: ast::NodeId) { | |
42 | { | |
c1a9b12d | 43 | // FIXME (@jroesch) change this to be an inference context |
1a4d82fc | 44 | let param_env = ParameterEnvironment::for_item(self.tcx, fn_id); |
c1a9b12d SL |
45 | let infcx = infer::new_infer_ctxt(self.tcx, |
46 | &self.tcx.tables, | |
54a0048b SL |
47 | Some(param_env.clone()), |
48 | ProjectionMode::AnyFinal); | |
1a4d82fc | 49 | let mut delegate = RvalueContextDelegate { tcx: self.tcx, param_env: ¶m_env }; |
c1a9b12d | 50 | let mut euv = euv::ExprUseVisitor::new(&mut delegate, &infcx); |
1a4d82fc JJ |
51 | euv.walk_fn(fd, b); |
52 | } | |
92a42be0 | 53 | intravisit::walk_fn(self, fk, fd, b, s) |
1a4d82fc JJ |
54 | } |
55 | } | |
56 | ||
57 | struct RvalueContextDelegate<'a, 'tcx: 'a> { | |
54a0048b | 58 | tcx: &'a TyCtxt<'tcx>, |
1a4d82fc JJ |
59 | param_env: &'a ty::ParameterEnvironment<'a,'tcx>, |
60 | } | |
61 | ||
62 | impl<'a, 'tcx> euv::Delegate<'tcx> for RvalueContextDelegate<'a, 'tcx> { | |
63 | fn consume(&mut self, | |
64 | _: ast::NodeId, | |
65 | span: Span, | |
66 | cmt: mc::cmt<'tcx>, | |
67 | _: euv::ConsumeMode) { | |
62682a34 | 68 | debug!("consume; cmt: {:?}; type: {:?}", *cmt, cmt.ty); |
c1a9b12d | 69 | if !cmt.ty.is_sized(self.param_env, span) { |
1a4d82fc JJ |
70 | span_err!(self.tcx.sess, span, E0161, |
71 | "cannot move a value of type {0}: the size of {0} cannot be statically determined", | |
62682a34 | 72 | cmt.ty); |
1a4d82fc JJ |
73 | } |
74 | } | |
75 | ||
76 | fn matched_pat(&mut self, | |
e9174d1e | 77 | _matched_pat: &hir::Pat, |
1a4d82fc JJ |
78 | _cmt: mc::cmt, |
79 | _mode: euv::MatchMode) {} | |
80 | ||
81 | fn consume_pat(&mut self, | |
e9174d1e | 82 | _consume_pat: &hir::Pat, |
1a4d82fc JJ |
83 | _cmt: mc::cmt, |
84 | _mode: euv::ConsumeMode) { | |
85 | } | |
86 | ||
87 | fn borrow(&mut self, | |
88 | _borrow_id: ast::NodeId, | |
89 | _borrow_span: Span, | |
90 | _cmt: mc::cmt, | |
91 | _loan_region: ty::Region, | |
92 | _bk: ty::BorrowKind, | |
93 | _loan_cause: euv::LoanCause) { | |
94 | } | |
95 | ||
96 | fn decl_without_init(&mut self, | |
97 | _id: ast::NodeId, | |
98 | _span: Span) { | |
99 | } | |
100 | ||
101 | fn mutate(&mut self, | |
102 | _assignment_id: ast::NodeId, | |
103 | _assignment_span: Span, | |
104 | _assignee_cmt: mc::cmt, | |
105 | _mode: euv::MutateMode) { | |
106 | } | |
107 | } |