Skip to content

Commit 80d1f14

Browse files
committed
Implement the basic rules of RFC 599, but do not yet support custom types.
1 parent f5c6a23 commit 80d1f14

8 files changed

+275
-8
lines changed

src/librustc_typeck/astconv.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs};
5656
use middle::traits;
5757
use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty};
5858
use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope,
59-
ShiftedRscope, BindingRscope};
59+
ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope};
6060
use TypeAndSubsts;
6161
use util::common::{ErrorReported, FN_OUTPUT_NAME};
6262
use util::nodemap::DefIdMap;
@@ -1084,7 +1084,11 @@ pub fn ast_ty_to_ty<'tcx>(
10841084
ast::TyRptr(ref region, ref mt) => {
10851085
let r = opt_ast_region_to_region(this, rscope, ast_ty.span, region);
10861086
debug!("ty_rptr r={}", r.repr(this.tcx()));
1087-
let t = ast_ty_to_ty(this, rscope, &*mt.ty);
1087+
let rscope1 =
1088+
&ObjectLifetimeDefaultRscope::new(
1089+
rscope,
1090+
Some(ty::ObjectLifetimeDefault::Specific(r)));
1091+
let t = ast_ty_to_ty(this, rscope1, &*mt.ty);
10881092
ty::mk_rptr(tcx, tcx.mk_region(r), ty::mt {ty: t, mutbl: mt.mutbl})
10891093
}
10901094
ast::TyTup(ref fields) => {

src/librustc_typeck/check/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1891,6 +1891,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18911891

18921892
impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
18931893
fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
1894+
// TODO. RFC #599 specifies that object lifetime defaults take
1895+
// precedence over other defaults. *However,* within a fn
1896+
// body, we typically use inference to allow users to elide
1897+
// lifetimes whenever they like, and then just infer it to
1898+
// whatever it must be. So I interpret that as applying only
1899+
// to fn sigs.
18941900
Some(self.infcx().next_region_var(infer::MiscVariable(span)))
18951901
}
18961902

src/librustc_typeck/rscope.rs

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub struct ExplicitRscope;
4545

4646
impl RegionScope for ExplicitRscope {
4747
fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region> {
48-
None
48+
Some(ty::ReStatic)
4949
}
5050

5151
fn anon_regions(&self,
@@ -67,7 +67,7 @@ impl UnelidableRscope {
6767

6868
impl RegionScope for UnelidableRscope {
6969
fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region> {
70-
None
70+
Some(ty::ReStatic)
7171
}
7272

7373
fn anon_regions(&self,
@@ -95,7 +95,10 @@ impl ElidableRscope {
9595

9696
impl RegionScope for ElidableRscope {
9797
fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region> {
98-
Some(self.default)
98+
// Per RFC #599, object-lifetimes default to 'static unless
99+
// overridden by context, and this takes precedence over
100+
// lifetime elision.
101+
Some(ty::ReStatic)
99102
}
100103

101104
fn anon_regions(&self,
@@ -128,9 +131,11 @@ impl BindingRscope {
128131
}
129132

130133
impl RegionScope for BindingRscope {
131-
fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region>
132-
{
133-
Some(self.next_region())
134+
fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region> {
135+
// Per RFC #599, object-lifetimes default to 'static unless
136+
// overridden by context, and this takes precedence over the
137+
// binding defaults.
138+
Some(ty::ReStatic)
134139
}
135140

136141
fn anon_regions(&self,
@@ -142,6 +147,42 @@ impl RegionScope for BindingRscope {
142147
}
143148
}
144149

150+
/// A scope which overrides the default object lifetime but has no other effect.
151+
pub struct ObjectLifetimeDefaultRscope<'r> {
152+
base_scope: &'r (RegionScope+'r),
153+
default: Option<ty::ObjectLifetimeDefault>,
154+
}
155+
156+
impl<'r> ObjectLifetimeDefaultRscope<'r> {
157+
pub fn new(base_scope: &'r (RegionScope+'r),
158+
default: Option<ty::ObjectLifetimeDefault>)
159+
-> ObjectLifetimeDefaultRscope<'r>
160+
{
161+
ObjectLifetimeDefaultRscope {
162+
base_scope: base_scope,
163+
default: default,
164+
}
165+
}
166+
}
167+
168+
impl<'r> RegionScope for ObjectLifetimeDefaultRscope<'r> {
169+
fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
170+
match self.default {
171+
None => self.base_scope.object_lifetime_default(span),
172+
Some(ty::ObjectLifetimeDefault::Ambiguous) => None,
173+
Some(ty::ObjectLifetimeDefault::Specific(r)) => Some(r),
174+
}
175+
}
176+
177+
fn anon_regions(&self,
178+
span: Span,
179+
count: uint)
180+
-> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>>
181+
{
182+
self.base_scope.anon_regions(span, count)
183+
}
184+
}
185+
145186
/// A scope which simply shifts the Debruijn index of other scopes
146187
/// to account for binding levels.
147188
pub struct ShiftedRscope<'r> {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that `Box<Test>` is equivalent to `Box<Test+'static>`, both in
12+
// fields and fn arguments.
13+
14+
#![allow(dead_code)]
15+
16+
trait Test {
17+
fn foo(&self) { }
18+
}
19+
20+
struct SomeStruct {
21+
t: Box<Test>,
22+
u: Box<Test+'static>,
23+
}
24+
25+
fn a(t: Box<Test>, mut ss: SomeStruct) {
26+
ss.t = t;
27+
}
28+
29+
fn b(t: Box<Test+'static>, mut ss: SomeStruct) {
30+
ss.t = t;
31+
}
32+
33+
fn c(t: Box<Test>, mut ss: SomeStruct) {
34+
ss.u = t;
35+
}
36+
37+
fn d(t: Box<Test+'static>, mut ss: SomeStruct) {
38+
ss.u = t;
39+
}
40+
41+
fn main() {
42+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that the lifetime from the enclosing `&` is "inherited"
12+
// through the `Box` struct.
13+
14+
#![allow(dead_code)]
15+
16+
trait Test {
17+
fn foo(&self) { }
18+
}
19+
20+
struct SomeStruct<'a> {
21+
t: &'a Box<Test>,
22+
u: &'a Box<Test+'a>,
23+
}
24+
25+
fn a<'a>(t: &'a Box<Test>, mut ss: SomeStruct<'a>) {
26+
ss.t = t;
27+
}
28+
29+
fn b<'a>(t: &'a Box<Test>, mut ss: SomeStruct<'a>) {
30+
ss.u = t;
31+
}
32+
33+
fn c<'a>(t: &'a Box<Test+'a>, mut ss: SomeStruct<'a>) {
34+
ss.t = t;
35+
}
36+
37+
fn d<'a>(t: &'a Box<Test+'a>, mut ss: SomeStruct<'a>) {
38+
ss.u = t;
39+
}
40+
41+
fn main() {
42+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that the lifetime of the enclosing `&` is used for the object
12+
// lifetime bound.
13+
14+
#![allow(dead_code)]
15+
16+
trait Test {
17+
fn foo(&self) { }
18+
}
19+
20+
struct SomeStruct<'a> {
21+
t: &'a mut Test,
22+
u: &'a mut (Test+'a),
23+
}
24+
25+
fn a<'a>(t: &'a mut Test, mut ss: SomeStruct<'a>) {
26+
ss.t = t;
27+
}
28+
29+
fn b<'a>(t: &'a mut Test, mut ss: SomeStruct<'a>) {
30+
ss.u = t;
31+
}
32+
33+
fn c<'a>(t: &'a mut (Test+'a), mut ss: SomeStruct<'a>) {
34+
ss.t = t;
35+
}
36+
37+
fn d<'a>(t: &'a mut (Test+'a), mut ss: SomeStruct<'a>) {
38+
ss.u = t;
39+
}
40+
41+
42+
fn main() {
43+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that the lifetime from the enclosing `&` is "inherited"
12+
// through the `MyBox` struct.
13+
14+
#![allow(dead_code)]
15+
16+
trait Test {
17+
fn foo(&self) { }
18+
}
19+
20+
struct SomeStruct<'a> {
21+
t: &'a MyBox<Test>,
22+
u: &'a MyBox<Test+'a>,
23+
}
24+
25+
struct MyBox<T:?Sized> {
26+
b: Box<T>
27+
}
28+
29+
fn a<'a>(t: &'a MyBox<Test>, mut ss: SomeStruct<'a>) {
30+
ss.t = t;
31+
}
32+
33+
fn b<'a>(t: &'a MyBox<Test>, mut ss: SomeStruct<'a>) {
34+
ss.u = t;
35+
}
36+
37+
fn c<'a>(t: &'a MyBox<Test+'a>, mut ss: SomeStruct<'a>) {
38+
ss.t = t;
39+
}
40+
41+
fn d<'a>(t: &'a MyBox<Test+'a>, mut ss: SomeStruct<'a>) {
42+
ss.u = t;
43+
}
44+
45+
fn main() {
46+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that the lifetime of the enclosing `&` is used for the object
12+
// lifetime bound.
13+
14+
#![allow(dead_code)]
15+
16+
trait Test {
17+
fn foo(&self) { }
18+
}
19+
20+
struct SomeStruct<'a> {
21+
t: &'a Test,
22+
u: &'a (Test+'a),
23+
}
24+
25+
fn a<'a>(t: &'a Test, mut ss: SomeStruct<'a>) {
26+
ss.t = t;
27+
}
28+
29+
fn b<'a>(t: &'a Test, mut ss: SomeStruct<'a>) {
30+
ss.u = t;
31+
}
32+
33+
fn c<'a>(t: &'a (Test+'a), mut ss: SomeStruct<'a>) {
34+
ss.t = t;
35+
}
36+
37+
fn d<'a>(t: &'a (Test+'a), mut ss: SomeStruct<'a>) {
38+
ss.u = t;
39+
}
40+
41+
42+
fn main() {
43+
}

0 commit comments

Comments
 (0)