mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
Implement the basic rules of RFC 599, but do not yet support custom types.
This commit is contained in:
parent
f5c6a23c9e
commit
80d1f14e7d
@ -56,7 +56,7 @@ use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs};
|
||||
use middle::traits;
|
||||
use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty};
|
||||
use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope,
|
||||
ShiftedRscope, BindingRscope};
|
||||
ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope};
|
||||
use TypeAndSubsts;
|
||||
use util::common::{ErrorReported, FN_OUTPUT_NAME};
|
||||
use util::nodemap::DefIdMap;
|
||||
@ -1084,7 +1084,11 @@ pub fn ast_ty_to_ty<'tcx>(
|
||||
ast::TyRptr(ref region, ref mt) => {
|
||||
let r = opt_ast_region_to_region(this, rscope, ast_ty.span, region);
|
||||
debug!("ty_rptr r={}", r.repr(this.tcx()));
|
||||
let t = ast_ty_to_ty(this, rscope, &*mt.ty);
|
||||
let rscope1 =
|
||||
&ObjectLifetimeDefaultRscope::new(
|
||||
rscope,
|
||||
Some(ty::ObjectLifetimeDefault::Specific(r)));
|
||||
let t = ast_ty_to_ty(this, rscope1, &*mt.ty);
|
||||
ty::mk_rptr(tcx, tcx.mk_region(r), ty::mt {ty: t, mutbl: mt.mutbl})
|
||||
}
|
||||
ast::TyTup(ref fields) => {
|
||||
|
@ -1891,6 +1891,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
|
||||
fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
|
||||
// TODO. RFC #599 specifies that object lifetime defaults take
|
||||
// precedence over other defaults. *However,* within a fn
|
||||
// body, we typically use inference to allow users to elide
|
||||
// lifetimes whenever they like, and then just infer it to
|
||||
// whatever it must be. So I interpret that as applying only
|
||||
// to fn sigs.
|
||||
Some(self.infcx().next_region_var(infer::MiscVariable(span)))
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ pub struct ExplicitRscope;
|
||||
|
||||
impl RegionScope for ExplicitRscope {
|
||||
fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region> {
|
||||
None
|
||||
Some(ty::ReStatic)
|
||||
}
|
||||
|
||||
fn anon_regions(&self,
|
||||
@ -67,7 +67,7 @@ impl UnelidableRscope {
|
||||
|
||||
impl RegionScope for UnelidableRscope {
|
||||
fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region> {
|
||||
None
|
||||
Some(ty::ReStatic)
|
||||
}
|
||||
|
||||
fn anon_regions(&self,
|
||||
@ -95,7 +95,10 @@ impl ElidableRscope {
|
||||
|
||||
impl RegionScope for ElidableRscope {
|
||||
fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region> {
|
||||
Some(self.default)
|
||||
// Per RFC #599, object-lifetimes default to 'static unless
|
||||
// overridden by context, and this takes precedence over
|
||||
// lifetime elision.
|
||||
Some(ty::ReStatic)
|
||||
}
|
||||
|
||||
fn anon_regions(&self,
|
||||
@ -128,9 +131,11 @@ impl BindingRscope {
|
||||
}
|
||||
|
||||
impl RegionScope for BindingRscope {
|
||||
fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region>
|
||||
{
|
||||
Some(self.next_region())
|
||||
fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region> {
|
||||
// Per RFC #599, object-lifetimes default to 'static unless
|
||||
// overridden by context, and this takes precedence over the
|
||||
// binding defaults.
|
||||
Some(ty::ReStatic)
|
||||
}
|
||||
|
||||
fn anon_regions(&self,
|
||||
@ -142,6 +147,42 @@ impl RegionScope for BindingRscope {
|
||||
}
|
||||
}
|
||||
|
||||
/// A scope which overrides the default object lifetime but has no other effect.
|
||||
pub struct ObjectLifetimeDefaultRscope<'r> {
|
||||
base_scope: &'r (RegionScope+'r),
|
||||
default: Option<ty::ObjectLifetimeDefault>,
|
||||
}
|
||||
|
||||
impl<'r> ObjectLifetimeDefaultRscope<'r> {
|
||||
pub fn new(base_scope: &'r (RegionScope+'r),
|
||||
default: Option<ty::ObjectLifetimeDefault>)
|
||||
-> ObjectLifetimeDefaultRscope<'r>
|
||||
{
|
||||
ObjectLifetimeDefaultRscope {
|
||||
base_scope: base_scope,
|
||||
default: default,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r> RegionScope for ObjectLifetimeDefaultRscope<'r> {
|
||||
fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
|
||||
match self.default {
|
||||
None => self.base_scope.object_lifetime_default(span),
|
||||
Some(ty::ObjectLifetimeDefault::Ambiguous) => None,
|
||||
Some(ty::ObjectLifetimeDefault::Specific(r)) => Some(r),
|
||||
}
|
||||
}
|
||||
|
||||
fn anon_regions(&self,
|
||||
span: Span,
|
||||
count: uint)
|
||||
-> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>>
|
||||
{
|
||||
self.base_scope.anon_regions(span, count)
|
||||
}
|
||||
}
|
||||
|
||||
/// A scope which simply shifts the Debruijn index of other scopes
|
||||
/// to account for binding levels.
|
||||
pub struct ShiftedRscope<'r> {
|
||||
|
@ -0,0 +1,42 @@
|
||||
// Copyright 2015 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 that `Box<Test>` is equivalent to `Box<Test+'static>`, both in
|
||||
// fields and fn arguments.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
trait Test {
|
||||
fn foo(&self) { }
|
||||
}
|
||||
|
||||
struct SomeStruct {
|
||||
t: Box<Test>,
|
||||
u: Box<Test+'static>,
|
||||
}
|
||||
|
||||
fn a(t: Box<Test>, mut ss: SomeStruct) {
|
||||
ss.t = t;
|
||||
}
|
||||
|
||||
fn b(t: Box<Test+'static>, mut ss: SomeStruct) {
|
||||
ss.t = t;
|
||||
}
|
||||
|
||||
fn c(t: Box<Test>, mut ss: SomeStruct) {
|
||||
ss.u = t;
|
||||
}
|
||||
|
||||
fn d(t: Box<Test+'static>, mut ss: SomeStruct) {
|
||||
ss.u = t;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
42
src/test/run-pass/object-lifetime-default-from-rptr-box.rs
Normal file
42
src/test/run-pass/object-lifetime-default-from-rptr-box.rs
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright 2015 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 that the lifetime from the enclosing `&` is "inherited"
|
||||
// through the `Box` struct.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
trait Test {
|
||||
fn foo(&self) { }
|
||||
}
|
||||
|
||||
struct SomeStruct<'a> {
|
||||
t: &'a Box<Test>,
|
||||
u: &'a Box<Test+'a>,
|
||||
}
|
||||
|
||||
fn a<'a>(t: &'a Box<Test>, mut ss: SomeStruct<'a>) {
|
||||
ss.t = t;
|
||||
}
|
||||
|
||||
fn b<'a>(t: &'a Box<Test>, mut ss: SomeStruct<'a>) {
|
||||
ss.u = t;
|
||||
}
|
||||
|
||||
fn c<'a>(t: &'a Box<Test+'a>, mut ss: SomeStruct<'a>) {
|
||||
ss.t = t;
|
||||
}
|
||||
|
||||
fn d<'a>(t: &'a Box<Test+'a>, mut ss: SomeStruct<'a>) {
|
||||
ss.u = t;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
43
src/test/run-pass/object-lifetime-default-from-rptr-mut.rs
Normal file
43
src/test/run-pass/object-lifetime-default-from-rptr-mut.rs
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2015 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 that the lifetime of the enclosing `&` is used for the object
|
||||
// lifetime bound.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
trait Test {
|
||||
fn foo(&self) { }
|
||||
}
|
||||
|
||||
struct SomeStruct<'a> {
|
||||
t: &'a mut Test,
|
||||
u: &'a mut (Test+'a),
|
||||
}
|
||||
|
||||
fn a<'a>(t: &'a mut Test, mut ss: SomeStruct<'a>) {
|
||||
ss.t = t;
|
||||
}
|
||||
|
||||
fn b<'a>(t: &'a mut Test, mut ss: SomeStruct<'a>) {
|
||||
ss.u = t;
|
||||
}
|
||||
|
||||
fn c<'a>(t: &'a mut (Test+'a), mut ss: SomeStruct<'a>) {
|
||||
ss.t = t;
|
||||
}
|
||||
|
||||
fn d<'a>(t: &'a mut (Test+'a), mut ss: SomeStruct<'a>) {
|
||||
ss.u = t;
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
// Copyright 2015 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 that the lifetime from the enclosing `&` is "inherited"
|
||||
// through the `MyBox` struct.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
trait Test {
|
||||
fn foo(&self) { }
|
||||
}
|
||||
|
||||
struct SomeStruct<'a> {
|
||||
t: &'a MyBox<Test>,
|
||||
u: &'a MyBox<Test+'a>,
|
||||
}
|
||||
|
||||
struct MyBox<T:?Sized> {
|
||||
b: Box<T>
|
||||
}
|
||||
|
||||
fn a<'a>(t: &'a MyBox<Test>, mut ss: SomeStruct<'a>) {
|
||||
ss.t = t;
|
||||
}
|
||||
|
||||
fn b<'a>(t: &'a MyBox<Test>, mut ss: SomeStruct<'a>) {
|
||||
ss.u = t;
|
||||
}
|
||||
|
||||
fn c<'a>(t: &'a MyBox<Test+'a>, mut ss: SomeStruct<'a>) {
|
||||
ss.t = t;
|
||||
}
|
||||
|
||||
fn d<'a>(t: &'a MyBox<Test+'a>, mut ss: SomeStruct<'a>) {
|
||||
ss.u = t;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
43
src/test/run-pass/object-lifetime-default-from-rptr.rs
Normal file
43
src/test/run-pass/object-lifetime-default-from-rptr.rs
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2015 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 that the lifetime of the enclosing `&` is used for the object
|
||||
// lifetime bound.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
trait Test {
|
||||
fn foo(&self) { }
|
||||
}
|
||||
|
||||
struct SomeStruct<'a> {
|
||||
t: &'a Test,
|
||||
u: &'a (Test+'a),
|
||||
}
|
||||
|
||||
fn a<'a>(t: &'a Test, mut ss: SomeStruct<'a>) {
|
||||
ss.t = t;
|
||||
}
|
||||
|
||||
fn b<'a>(t: &'a Test, mut ss: SomeStruct<'a>) {
|
||||
ss.u = t;
|
||||
}
|
||||
|
||||
fn c<'a>(t: &'a (Test+'a), mut ss: SomeStruct<'a>) {
|
||||
ss.t = t;
|
||||
}
|
||||
|
||||
fn d<'a>(t: &'a (Test+'a), mut ss: SomeStruct<'a>) {
|
||||
ss.u = t;
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
}
|
Loading…
Reference in New Issue
Block a user