Skip to content

Commit dd626b4

Browse files
committed
auto merge of #16933 : nick29581/rust/dst-rvalue, r=nikomatsakis
Closes #16813 r? @nikomatsakis I feel like I should be checking more things in check_rvalues, but not sure what - I don't properly understand expr_use_visitor
2 parents aaf141d + 742f49c commit dd626b4

11 files changed

+123
-4
lines changed

src/librustc/diagnostics.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -169,5 +169,6 @@ register_diagnostics!(
169169
E0157,
170170
E0158,
171171
E0159,
172-
E0160
172+
E0160,
173+
E0161
173174
)

src/librustc/driver/driver.rs

+3
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,9 @@ pub fn phase_3_run_analysis_passes(sess: Session,
404404
time(time_passes, "borrow checking", (), |_|
405405
middle::borrowck::check_crate(&ty_cx, krate));
406406

407+
time(time_passes, "rvalue checking", (), |_|
408+
middle::check_rvalues::check_crate(&ty_cx, krate));
409+
407410
time(time_passes, "kind checking", (), |_|
408411
kind::check_crate(&ty_cx, krate));
409412

src/librustc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ pub mod middle {
8080
pub mod check_const;
8181
pub mod check_loop;
8282
pub mod check_match;
83+
pub mod check_rvalues;
8384
pub mod check_static;
8485
pub mod const_eval;
8586
pub mod dataflow;

src/librustc/middle/check_rvalues.rs

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
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+
14+
use middle::expr_use_visitor as euv;
15+
use middle::mem_categorization as mc;
16+
use middle::ty;
17+
use util::ppaux::ty_to_string;
18+
19+
use syntax::ast;
20+
use syntax::codemap::Span;
21+
use syntax::visit;
22+
23+
pub fn check_crate(tcx: &ty::ctxt,
24+
krate: &ast::Crate) {
25+
let mut rvcx = RvalueContext { tcx: tcx };
26+
visit::walk_crate(&mut rvcx, krate, ());
27+
}
28+
29+
struct RvalueContext<'a> {
30+
tcx: &'a ty::ctxt
31+
}
32+
33+
impl<'a> visit::Visitor<()> for RvalueContext<'a> {
34+
fn visit_fn(&mut self,
35+
_: &visit::FnKind,
36+
fd: &ast::FnDecl,
37+
b: &ast::Block,
38+
_: Span,
39+
_: ast::NodeId,
40+
_: ()) {
41+
let mut euv = euv::ExprUseVisitor::new(self, self.tcx);
42+
euv.walk_fn(fd, b);
43+
}
44+
}
45+
46+
impl<'a> euv::Delegate for RvalueContext<'a> {
47+
fn consume(&mut self,
48+
_: ast::NodeId,
49+
span: Span,
50+
cmt: mc::cmt,
51+
_: euv::ConsumeMode) {
52+
debug!("consume; cmt: {:?}; type: {}", *cmt, ty_to_string(self.tcx, cmt.ty));
53+
if !ty::type_is_sized(self.tcx, cmt.ty) {
54+
span_err!(self.tcx.sess, span, E0161,
55+
"cannot move a value of type {0}: the size of {0} cannot be statically determined",
56+
ty_to_string(self.tcx, cmt.ty));
57+
}
58+
}
59+
60+
fn consume_pat(&mut self,
61+
_consume_pat: &ast::Pat,
62+
_cmt: mc::cmt,
63+
_mode: euv::ConsumeMode) {
64+
}
65+
66+
fn borrow(&mut self,
67+
_borrow_id: ast::NodeId,
68+
_borrow_span: Span,
69+
_cmt: mc::cmt,
70+
_loan_region: ty::Region,
71+
_bk: ty::BorrowKind,
72+
_loan_cause: euv::LoanCause) {
73+
}
74+
75+
fn decl_without_init(&mut self,
76+
_id: ast::NodeId,
77+
_span: Span) {
78+
}
79+
80+
fn mutate(&mut self,
81+
_assignment_id: ast::NodeId,
82+
_assignment_span: Span,
83+
_assignee_cmt: mc::cmt,
84+
_mode: euv::MutateMode) {
85+
}
86+
}

src/librustc/middle/mem_categorization.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ pub enum MutabilityCategory {
150150
// like `*x`, the type of this deref node is the deref'd type (`T`),
151151
// but in a pattern like `@x`, the `@x` pattern is again a
152152
// dereference, but its type is the type *before* the dereference
153-
// (`@T`). So use `cmt.type` to find the type of the value in a consistent
153+
// (`@T`). So use `cmt.ty` to find the type of the value in a consistent
154154
// fashion. For more details, see the method `cat_pattern`
155155
#[deriving(Clone, PartialEq)]
156156
pub struct cmt_ {

src/test/compile-fail/dst-bad-assign-2.rs

+1
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,5 @@ pub fn main() {
4343
let f5: &mut Fat<ToBar> = &mut Fat { f1: 5, f2: "some str", ptr: Bar1 {f :42} };
4444
let z: Box<ToBar> = box Bar1 {f: 36};
4545
f5.ptr = *z; //~ ERROR dynamically sized type on lhs of assignment
46+
//~^ ERROR E0161
4647
}

src/test/compile-fail/dst-bad-deep.rs

+1
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ pub fn main() {
2222
let g: &Fat<[int]> = &f;
2323
let h: &Fat<Fat<[int]>> = &Fat { ptr: *g };
2424
//~^ ERROR trying to initialise a dynamically sized struct
25+
//~^^ ERROR E0161
2526
}

src/test/compile-fail/dst-rvalue.rs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
// Check that dynamically sized rvalues are forbidden
12+
13+
pub fn main() {
14+
let _x: Box<str> = box *"hello world";
15+
//~^ ERROR E0161
16+
17+
let array: &[int] = &[1, 2, 3];
18+
let _x: Box<[int]> = box *array;
19+
//~^ ERROR E0161
20+
}

src/test/compile-fail/issue-5883.rs

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ struct Struct {
1717
fn new_struct(r: A+'static) -> Struct {
1818
//~^ ERROR variable `r` has dynamically sized type
1919
Struct { r: r } //~ ERROR trying to initialise a dynamically sized struct
20+
//~^ ERROR E0161
21+
//~^^ ERROR E0161
2022
}
2123

2224
trait Curve {}

src/test/compile-fail/unsized3.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@ fn f8<Sized? X>(x1: &S<X>, x2: &S<X>) {
5151

5252
// Test some tuples.
5353
fn f9<Sized? X>(x1: Box<S<X>>, x2: Box<E<X>>) {
54-
f5(&(*x1, 34i)); //~ERROR instantiating a type parameter with an incompatible type `(S<X>,int)`,
55-
f5(&(32i, *x2)); //~ERROR instantiating a type parameter with an incompatible type `(int,E<X>)`,
54+
f5(&(*x1, 34i)); //~ERROR E0161
55+
//~^ ERROR instantiating a type parameter with an incompatible type
56+
f5(&(32i, *x2)); //~ERROR E0161
57+
//~^ ERROR instantiating a type parameter with an incompatible type
5658
}
5759

5860
// I would like these to fail eventually.

src/test/compile-fail/unsized6.rs

+2
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@ fn f3<Sized? X>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
3030
let y: X = *x1; //~ERROR variable `y` has dynamically sized type `X`
3131
let y = *x2; //~ERROR variable `y` has dynamically sized type `X`
3232
let (y, z) = (*x3, 4i); //~ERROR variable `y` has dynamically sized type `X`
33+
//~^ ERROR E0161
3334
}
3435
fn f4<Sized? X: T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
3536
let y: X = *x1; //~ERROR variable `y` has dynamically sized type `X`
3637
let y = *x2; //~ERROR variable `y` has dynamically sized type `X`
3738
let (y, z) = (*x3, 4i); //~ERROR variable `y` has dynamically sized type `X`
39+
//~^ ERROR E0161
3840
}
3941

4042
fn g1<Sized? X>(x: X) {} //~ERROR variable `x` has dynamically sized type `X`

0 commit comments

Comments
 (0)