mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 22:12:15 +00:00
Link lifetimes in let
patterns just as we do for match
patterns
This commit is contained in:
parent
0c916c58e8
commit
56f4d1831a
@ -67,6 +67,9 @@ impl<'a> GuaranteeLifetimeContext<'a> {
|
||||
|
||||
fn check(&self, cmt: mc::cmt, discr_scope: Option<ast::NodeId>) -> R {
|
||||
//! Main routine. Walks down `cmt` until we find the "guarantor".
|
||||
debug!("guarantee_lifetime.check(cmt={}, loan_region={})",
|
||||
cmt.repr(self.bccx.tcx),
|
||||
self.loan_region.repr(self.bccx.tcx));
|
||||
|
||||
match cmt.cat {
|
||||
mc::cat_rvalue(..) |
|
||||
|
@ -213,6 +213,7 @@ fn visit_arm(rcx: &mut Rcx, arm: &ast::Arm) {
|
||||
fn visit_local(rcx: &mut Rcx, l: &ast::Local) {
|
||||
// see above
|
||||
constrain_bindings_in_pat(l.pat, rcx);
|
||||
guarantor::for_local(rcx, l);
|
||||
visit::walk_local(rcx, l, ());
|
||||
}
|
||||
|
||||
@ -828,6 +829,30 @@ pub mod guarantor {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn for_local(rcx: &mut Rcx, local: &ast::Local) {
|
||||
/*!
|
||||
* Link the lifetimes of any ref bindings in a let
|
||||
* pattern to the lifetimes in the initializer.
|
||||
*
|
||||
* For example, given something like this:
|
||||
*
|
||||
* let &Foo(ref x) = ...;
|
||||
*
|
||||
* this would ensure that the lifetime 'a of the
|
||||
* region pointer being matched must be >= the lifetime
|
||||
* of the ref binding.
|
||||
*/
|
||||
|
||||
debug!("regionck::for_match()");
|
||||
let init_expr = match local.init {
|
||||
None => { return; }
|
||||
Some(e) => e
|
||||
};
|
||||
let init_guarantor = guarantor(rcx, init_expr);
|
||||
debug!("init_guarantor={}", init_guarantor.repr(rcx.tcx()));
|
||||
link_ref_bindings_in_pat(rcx, local.pat, init_guarantor);
|
||||
}
|
||||
|
||||
pub fn for_autoref(rcx: &mut Rcx,
|
||||
expr: &ast::Expr,
|
||||
autoderefs: uint,
|
||||
|
22
src/test/compile-fail/borrowck-borrow-from-temporary.rs
Normal file
22
src/test/compile-fail/borrowck-borrow-from-temporary.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// Test lifetimes are linked properly when we take reference
|
||||
// to interior.
|
||||
|
||||
struct Foo(int);
|
||||
|
||||
fn foo() -> &int {
|
||||
let &Foo(ref x) = &Foo(3); //~ ERROR borrowed value does not live long enough
|
||||
x
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
}
|
@ -196,13 +196,13 @@ fn main() {
|
||||
let Unit(ii) = Unit(51);
|
||||
|
||||
// univariant enum with ref binding
|
||||
let Unit(ref jj) = Unit(52);
|
||||
let &Unit(ref jj) = &Unit(52);
|
||||
|
||||
// tuple struct
|
||||
let TupleStruct(kk, ll) = TupleStruct(53.0, 54);
|
||||
let &TupleStruct(kk, ll) = &TupleStruct(53.0, 54);
|
||||
|
||||
// tuple struct with ref binding
|
||||
let TupleStruct(mm, ref nn) = TupleStruct(55.0, 56);
|
||||
let &TupleStruct(mm, ref nn) = &TupleStruct(55.0, 56);
|
||||
|
||||
zzz();
|
||||
}
|
||||
|
19
src/test/run-pass/regions-dependent-let-ref.rs
Normal file
19
src/test/run-pass/regions-dependent-let-ref.rs
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// Test lifetimes are linked properly when we take reference
|
||||
// to interior.
|
||||
|
||||
struct Foo(int);
|
||||
pub fn main() {
|
||||
// Here the lifetime of the `&` should be at least the
|
||||
// block, since a ref binding is created to the interior.
|
||||
let &Foo(ref _x) = &Foo(3);
|
||||
}
|
Loading…
Reference in New Issue
Block a user