Skip to content

Commit c12c238

Browse files
committed
Add an Ivar for write-once variables
Adds an Ivar for write-once variables, and makes DatatypeDef use it. Removes some now-unused arguments.
1 parent 7a6d342 commit c12c238

File tree

7 files changed

+61
-26
lines changed

7 files changed

+61
-26
lines changed

src/librustc/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ pub mod util {
138138
pub mod nodemap;
139139
pub mod snapshot_vec;
140140
pub mod lev_distance;
141+
pub mod ivar;
141142
}
142143

143144
pub mod lib {

src/librustc/metadata/csearch.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
use metadata::common::*;
1414
use metadata::cstore;
1515
use metadata::decoder;
16-
use middle::def;
1716
use middle::lang_items;
1817
use middle::ty;
1918

src/librustc/metadata/decoder.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,7 +1044,7 @@ fn get_struct_datatype_def<'tcx>(tcx: &ty::ctxt<'tcx>, intr: &IdentInterner,
10441044
let name = item_name(intr, item);
10451045
let def_id = item_def_id(item, cdata);
10461046

1047-
let fields = get_variant_fields(tcx, intr, cdata, item);
1047+
let fields = get_variant_fields(intr, cdata, item);
10481048
let def = tcx.mk_datatype_def(ty::DatatypeDef {
10491049
def_id: def_id,
10501050
variants: vec![ty::VariantDef {
@@ -1086,7 +1086,7 @@ fn get_enum_datatype_def<'tcx>(tcx: &ty::ctxt<'tcx>, intr: &IdentInterner,
10861086
_ => {}
10871087
}
10881088

1089-
let fields = get_variant_fields(tcx, intr, cdata, item);
1089+
let fields = get_variant_fields(intr, cdata, item);
10901090

10911091
ty::VariantDef {
10921092
id: *did,
@@ -1113,7 +1113,7 @@ fn get_enum_datatype_def<'tcx>(tcx: &ty::ctxt<'tcx>, intr: &IdentInterner,
11131113
def
11141114
}
11151115

1116-
fn get_variant_fields<'tcx>(tcx: &ty::ctxt<'tcx>, intr: &IdentInterner, cdata: Cmd,
1116+
fn get_variant_fields<'tcx>(intr: &IdentInterner, cdata: Cmd,
11171117
item: rbml::Doc) -> Vec<ty::FieldTy<'tcx>> {
11181118

11191119
let mut fields = Vec::new();
@@ -1124,7 +1124,7 @@ fn get_variant_fields<'tcx>(tcx: &ty::ctxt<'tcx>, intr: &IdentInterner, cdata: C
11241124

11251125
let tagdoc = reader::get_doc(an_item, tag_item_field_origin);
11261126
let origin_id = translate_def_id(cdata, reader::with_doc_data(tagdoc, parse_def_id));
1127-
let fld = ty::FieldTy::new(tcx, did, name,
1127+
let fld = ty::FieldTy::new(did, name,
11281128
struct_field_family_to_visibility(f),
11291129
origin_id);
11301130
fields.push(fld);
@@ -1136,7 +1136,7 @@ fn get_variant_fields<'tcx>(tcx: &ty::ctxt<'tcx>, intr: &IdentInterner, cdata: C
11361136
let tagdoc = reader::get_doc(an_item, tag_item_field_origin);
11371137
let f = item_family(an_item);
11381138
let origin_id = translate_def_id(cdata, reader::with_doc_data(tagdoc, parse_def_id));
1139-
let fld = ty::FieldTy::new(tcx, did, special_idents::unnamed_field.name,
1139+
let fld = ty::FieldTy::new(did, special_idents::unnamed_field.name,
11401140
struct_field_family_to_visibility(f),
11411141
origin_id);
11421142
fields.push(fld);

src/librustc/middle/ty.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ use util::ppaux::{Repr, UserString};
6666
use util::common::{memoized, ErrorReported};
6767
use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet};
6868
use util::nodemap::{FnvHashMap};
69+
use util::ivar::Ivar;
6970

7071
use arena::TypedArena;
7172
use std::borrow::{Borrow, Cow};
@@ -2291,16 +2292,15 @@ pub struct FieldTy<'tcx> {
22912292
pub vis: ast::Visibility,
22922293
// The "parent" of the field, the DefId of the struct or enum this field comes from
22932294
pub origin: DefId,
2294-
// `Cell` is used here to to allow the construction of a DatatypeDef that contains types
2295+
// Ivar is used here to to allow the construction of a DatatypeDef that contains types
22952296
// that reference this type. For example:
22962297
//
22972298
// struct Foo(Bar);
22982299
// struct Bar(Option<Box<Foo>>);
22992300
//
23002301
// Making the `ty_struct` for `Foo` requires the type of `Bar`, but making the `type`
2301-
// of `Bar` requires the type of `Foo`. The `Cell` is initially set to `ty_err` and
2302-
// the real type is filled in later
2303-
ty: Cell<Ty<'tcx>>
2302+
// of `Bar` requires the type of `Foo`.
2303+
ty: Ivar<Ty<'tcx>>
23042304
}
23052305

23062306
impl<'tcx> DatatypeDef<'tcx> {
@@ -2349,14 +2349,13 @@ impl<'tcx> VariantDef<'tcx> {
23492349
}
23502350

23512351
impl<'tcx> FieldTy<'tcx> {
2352-
pub fn new(tcx: &ctxt<'tcx>,
2353-
id: DefId, name: Name, vis: ast::Visibility, origin: DefId) -> FieldTy<'tcx> {
2352+
pub fn new(id: DefId, name: Name, vis: ast::Visibility, origin: DefId) -> FieldTy<'tcx> {
23542353
FieldTy {
23552354
id: id,
23562355
name: name,
23572356
vis: vis,
23582357
origin: origin,
2359-
ty: Cell::new(tcx.types.err),
2358+
ty: Ivar::new(),
23602359
}
23612360
}
23622361

@@ -2365,15 +2364,11 @@ impl<'tcx> FieldTy<'tcx> {
23652364
}
23662365

23672366
pub fn set_ty(&self, ty: Ty<'tcx>) {
2368-
if let ty_err = self.ty().sty {
2369-
self.ty.set(ty);
2370-
} else {
2371-
panic!("FieldTy::set_ty: Field type already set");
2372-
}
2367+
self.ty.fulfill(ty);
23732368
}
23742369

23752370
pub fn ty(&self) -> Ty<'tcx> {
2376-
self.ty.get()
2371+
self.ty.unwrap()
23772372
}
23782373

23792374
pub fn subst_ty(&self, tcx: &ctxt<'tcx>, substs: &Substs<'tcx>) -> Ty<'tcx> {

src/librustc/middle/ty_fold.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TraitRef<'tcx> {
265265

266266
impl<'tcx> TypeFoldable<'tcx> for ty::FieldTy<'tcx> {
267267
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::FieldTy<'tcx> {
268-
let ty = ty::FieldTy::new(folder.tcx(),
269-
self.id, self.name, self.vis, self.origin);
268+
let ty = ty::FieldTy::new(self.id, self.name, self.vis, self.origin);
270269
ty.set_ty(self.ty().fold_with(folder));
271270
ty
272271
}

src/librustc/util/ivar.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2012-2014 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+
use std::cell::Cell;
12+
13+
pub struct Ivar<T:Copy> {
14+
data: Cell<Option<T>>
15+
}
16+
17+
impl<T:Copy> Ivar<T> {
18+
pub fn new() -> Ivar<T> {
19+
Ivar {
20+
data: Cell::new(None)
21+
}
22+
}
23+
24+
pub fn get(&self) -> Option<T> {
25+
self.data.get()
26+
}
27+
28+
pub fn fulfill(&self, value: T) {
29+
assert!(self.data.get().is_none(),
30+
"Value already set!");
31+
self.data.set(Some(value));
32+
}
33+
34+
pub fn fulfilled(&self) -> bool {
35+
self.data.get().is_some()
36+
}
37+
38+
pub fn unwrap(&self) -> T {
39+
self.get().unwrap()
40+
}
41+
}

src/librustc_typeck/collect.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,10 +1552,10 @@ fn get_struct_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
15521552
Err(e) => { e.insert(f.span); }
15531553
}
15541554

1555-
ty::FieldTy::new(tcx, local_def(f.node.id), ident.name, visibility, def_id)
1555+
ty::FieldTy::new(local_def(f.node.id), ident.name, visibility, def_id)
15561556
}
15571557
ast::UnnamedField(visibility) => {
1558-
ty::FieldTy::new(tcx, local_def(f.node.id),
1558+
ty::FieldTy::new(local_def(f.node.id),
15591559
special_idents::unnamed_field.name,
15601560
visibility, def_id)
15611561
}
@@ -1627,7 +1627,7 @@ fn get_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, def_id: ast::DefId,
16271627
match v.node.kind {
16281628
ast::TupleVariantKind(ref args) if args.len() > 0 => {
16291629
let fields = args.iter().map(|f| {
1630-
ty::FieldTy::new(tcx, local_def(f.id),
1630+
ty::FieldTy::new(local_def(f.id),
16311631
special_idents::unnamed_field.name,
16321632
ast::Public,
16331633
def_id)
@@ -1664,11 +1664,11 @@ fn get_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, def_id: ast::DefId,
16641664
Err(e) => { e.insert(f.span); }
16651665
}
16661666

1667-
ty::FieldTy::new(tcx, local_def(f.node.id),
1667+
ty::FieldTy::new(local_def(f.node.id),
16681668
ident.name, visibility, def_id)
16691669
}
16701670
ast::UnnamedField(visibility) => {
1671-
ty::FieldTy::new(tcx, local_def(f.node.id),
1671+
ty::FieldTy::new(local_def(f.node.id),
16721672
special_idents::unnamed_field.name,
16731673
visibility, def_id)
16741674
}

0 commit comments

Comments
 (0)