提交 80d1f14e 编写于 作者: N Niko Matsakis

Implement the basic rules of RFC 599, but do not yet support custom types.

上级 f5c6a23c
......@@ -56,7 +56,7 @@
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 @@ pub fn lookup_tup_field_ty(&self,
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 @@ fn anon_regions(&self,
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 @@ pub fn new(v: Vec<(String, uint)>) -> 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 @@ pub fn new(r: ty::Region) -> 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 @@ fn next_region(&self) -> ty::Region {
}
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 @@ fn anon_regions(&self,
}
}
/// 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> {
......
// 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() {
}
// 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() {
}
// 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() {
}
// 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() {
}
// 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() {
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册