mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 08:44:35 +00:00
Fix soundness hole in struct with expressions.
Fixes #18567. Struct{x:foo, .. with_expr} did not walk with_expr, which allowed using moved variables in some cases. The CFG for structs also built up with with_expr happening before the fields, which is now reversed. (Fields are now before the with_expr in the CFG)
This commit is contained in:
parent
60a669a174
commit
d80a62d84b
@ -448,8 +448,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ast::ExprStruct(_, ref fields, ref base) => {
|
ast::ExprStruct(_, ref fields, ref base) => {
|
||||||
let base_exit = self.opt_expr(base, pred);
|
let field_cfg = self.straightline(expr, pred, fields.iter().map(|f| &*f.expr));
|
||||||
self.straightline(expr, base_exit, fields.iter().map(|f| &*f.expr))
|
self.opt_expr(base, field_cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::ExprRepeat(ref elem, ref count) => {
|
ast::ExprRepeat(ref elem, ref count) => {
|
||||||
|
@ -672,6 +672,10 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// walk the with expression so that complex expressions
|
||||||
|
// are properly handled.
|
||||||
|
self.walk_expr(with_expr);
|
||||||
|
|
||||||
fn contains_field_named(field: &ty::field,
|
fn contains_field_named(field: &ty::field,
|
||||||
fields: &Vec<ast::Field>)
|
fields: &Vec<ast::Field>)
|
||||||
-> bool
|
-> bool
|
||||||
|
28
src/test/compile-fail/walk-struct-literal-with.rs
Normal file
28
src/test/compile-fail/walk-struct-literal-with.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// 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 Mine{
|
||||||
|
test: String,
|
||||||
|
other_val: int
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mine{
|
||||||
|
fn make_string_bar(mut self) -> Mine{
|
||||||
|
self.test = "Bar".to_string();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main(){
|
||||||
|
let start = Mine{test:"Foo".to_string(), other_val:0};
|
||||||
|
let end = Mine{other_val:1, ..start.make_string_bar()};
|
||||||
|
println!("{}", start.test); //~ ERROR use of moved value: `start.test`
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user