]> git.lizzy.rs Git - rust.git/commitdiff
librustc: Don't allow use after move of implicitly coerced object. Fixes #11481.
authorLuqman Aden <laden@csclub.uwaterloo.ca>
Mon, 13 Jan 2014 00:59:47 +0000 (19:59 -0500)
committerLuqman Aden <laden@csclub.uwaterloo.ca>
Tue, 14 Jan 2014 01:51:49 +0000 (20:51 -0500)
src/librustc/middle/mem_categorization.rs
src/test/compile-fail/use-after-move-implicity-coerced-object.rs [new file with mode: 0644]

index c50d23ff592e8b0b014c69066679b03982153555..8cf39d14763b395ec07cfee1f77693cc52d02777 100644 (file)
@@ -345,9 +345,12 @@ pub fn cat_expr(&self, expr: &ast::Expr) -> cmt {
                 match **adjustment {
                     ty::AutoObject(..) => {
                         // Implicity casts a concrete object to trait object
-                        // Result is an rvalue
+                        // so just patch up the type
                         let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
-                        self.cat_rvalue_node(expr, expr_ty)
+                        @cmt_ {
+                            ty: expr_ty,
+                            ..*self.cat_expr_unadjusted(expr)
+                        }
                     }
 
                     ty::AutoAddEnv(..) => {
diff --git a/src/test/compile-fail/use-after-move-implicity-coerced-object.rs b/src/test/compile-fail/use-after-move-implicity-coerced-object.rs
new file mode 100644 (file)
index 0000000..bef6165
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright 2014 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.
+
+struct Number {
+    n: i64
+}
+
+impl ToStr for Number {
+    fn to_str(&self) -> ~str {
+        self.n.to_str()
+    }
+}
+
+struct List {
+    list: ~[~ToStr]
+}
+
+impl List {
+    fn push(&mut self, n: ~ToStr) {
+        self.list.push(n);
+    }
+}
+
+fn main() {
+    let n = ~Number { n: 42 };
+    let mut l = ~List { list: ~[] };
+    l.push(n);
+    //^~ NOTE: `n` moved here because it has type `~Number`, which is non-copyable (perhaps you meant to use clone()?)
+    let x = n.to_str(); //~ ERROR: use of moved value: `n`
+}