Make shared kind the default only for generic functions

You almost never want a function with pinned type params. For
types, objects, resources, and tags, pinned types are actually often
more sane. For most of these, shared rarely makes sense. Only tricky
case is objs -- you'll have to think about the kinds you want there.

Issue #1076
This commit is contained in:
Marijn Haverbeke 2011-10-28 17:00:14 +02:00
parent 6fe7aa4aff
commit 7dacccde94
16 changed files with 63 additions and 71 deletions

View File

@ -170,12 +170,11 @@ fn encode_type_param_kinds(ebml_w: ebml::writer, tps: [ty_param]) {
ebml::start_tag(ebml_w, tag_items_data_item_ty_param_kinds);
ebml::write_vint(ebml_w.writer, vec::len::<ty_param>(tps));
for tp: ty_param in tps {
let c =
alt tp.kind {
kind_unique. { 'u' }
kind_shared. { 's' }
kind_pinned. { 'p' }
};
let c = alt ast_util::ty_param_kind(tp) {
kind_unique. { 'u' }
kind_shared. { 's' }
kind_pinned. { 'p' }
};
ebml_w.writer.write([c as u8]);
}
ebml::end_tag(ebml_w);

View File

@ -90,9 +90,9 @@ fn new_smallintmap_adapter<K, V>(key_idx: fn(K) -> uint,
idx_key: fn(uint) -> K)
-> std::map::hashmap<K, V> {
obj adapter<K, V>(map: smallintmap::smallintmap<V>,
key_idx: fn(K) -> uint,
idx_key: fn(uint) -> K) {
obj adapter<shar K, shar V>(map: smallintmap::smallintmap<V>,
key_idx: fn(K) -> uint,
idx_key: fn(uint) -> K) {
fn size() -> uint { fail }

View File

@ -619,7 +619,7 @@ fn def_is_obj_field(d: def) -> bool {
}
fn def_is_ty_arg(d: def) -> bool {
ret alt d { ast::def_ty_arg(_, _) { true } _ { false } };
ret alt d { ast::def_ty_param(_, _) { true } _ { false } };
}
fn lookup_in_scope(e: env, sc: scopes, sp: span, name: ident, ns: namespace)
@ -734,7 +734,9 @@ fn lookup_in_ty_params(name: ident, ty_params: [ast::ty_param]) ->
option::t<def> {
let i = 0u;
for tp: ast::ty_param in ty_params {
if str::eq(tp.ident, name) { ret some(ast::def_ty_arg(i, tp.kind)); }
if str::eq(tp.ident, name) {
ret some(ast::def_ty_param(i, ast_util::ty_param_kind(tp)));
}
i += 1u;
}
ret none::<def>;

View File

@ -5227,7 +5227,8 @@ fn trans_tag_variant(cx: @local_ctxt, tag_id: ast::node_id,
let ty_param_substs: [ty::t] = [];
i = 0u;
for tp: ast::ty_param in ty_params {
ty_param_substs += [ty::mk_param(cx.ccx.tcx, i, tp.kind)];
ty_param_substs += [ty::mk_param(cx.ccx.tcx, i,
ast_util::ty_param_kind(tp))];
i += 1u;
}
let arg_tys = arg_tys_of_fn(cx.ccx, variant.node.id);

View File

@ -2752,7 +2752,7 @@ fn def_has_ty_params(def: ast::def) -> bool {
ast::def_upvar(_, _, _) { ret false; }
ast::def_variant(_, _) { ret true; }
ast::def_ty(_) { ret false; }
ast::def_ty_arg(_, _) { ret false; }
ast::def_ty_param(_, _) { ret false; }
ast::def_binding(_) { ret false; }
ast::def_use(_) { ret false; }
ast::def_native_ty(_) { ret false; }

View File

@ -1,6 +1,6 @@
import syntax::{ast, ast_util};
import ast::{mutability, spanned};
import syntax::ast_util::{local_def, respan};
import syntax::ast_util::{local_def, respan, ty_param_kind};
import syntax::visit;
import metadata::csearch;
import driver::session;
@ -342,7 +342,7 @@ fn ast_ty_to_ty(tcx: ty::ctxt, getter: ty_getter, &&ast_ty: @ast::ty)
typ = instantiate(tcx, ast_ty.span, getter, id, path.node.types);
}
some(ast::def_native_ty(id)) { typ = getter(id).ty; }
some(ast::def_ty_arg(id, k)) { typ = ty::mk_param(tcx, id, k); }
some(ast::def_ty_param(id, k)) { typ = ty::mk_param(tcx, id, k); }
some(_) {
tcx.sess.span_fatal(ast_ty.span,
"found type name used as a variable");
@ -495,7 +495,7 @@ mod collect {
let tps = [];
let i = 0u;
for atp: ast::ty_param in atps {
tps += [ty::mk_param(cx.tcx, i, atp.kind)];
tps += [ty::mk_param(cx.tcx, i, ty_param_kind(atp))];
i += 1u;
}
ret tps;
@ -503,7 +503,7 @@ mod collect {
fn ty_param_kinds(tps: [ast::ty_param]) -> [ast::kind] {
let k: [ast::kind] = [];
for p: ast::ty_param in tps { k += [p.kind]; }
for p: ast::ty_param in tps { k += [ty_param_kind(p)]; }
ret k;
}

View File

@ -23,7 +23,7 @@ type def_id = {crate: crate_num, node: node_id};
const local_crate: crate_num = 0;
type ty_param = {ident: ident, kind: kind};
type ty_param = {ident: ident, kind: plicit<kind>};
tag def {
def_fn(def_id, purity);
@ -37,7 +37,7 @@ tag def {
/* variant */
def_ty(def_id);
def_ty_arg(uint, kind);
def_ty_param(uint, kind);
def_binding(def_id);
def_use(def_id);
def_native_ty(def_id);
@ -99,7 +99,8 @@ tag pat_ {
tag mutability { mut; imm; maybe_mut; }
tag kind { kind_pinned; kind_shared; kind_unique; }
tag plicit<T> { explicit(T); implicit(T); }
tag kind { kind_pinned; kind_shared; kind_unique; kind_auto; }
tag _auth { auth_unsafe; }
@ -489,16 +490,10 @@ tag item_ {
item_ty(@ty, [ty_param]);
item_tag([variant], [ty_param]);
item_obj(_obj, [ty_param], /* constructor id */node_id);
item_res(_fn,
/* dtor */
node_id,
/* dtor id */
item_res(_fn /* dtor */,
node_id /* dtor id */,
[ty_param],
/* ctor id */
node_id);
node_id /* ctor id */);
}
type native_item =

View File

@ -33,7 +33,7 @@ fn def_id_of_def(d: def) -> def_id {
def_local(id, _) { ret id; }
def_variant(_, id) { ret id; }
def_ty(id) { ret id; }
def_ty_arg(_, _) { fail; }
def_ty_param(_, _) { fail; }
def_binding(id) { ret id; }
def_use(id) { ret id; }
def_native_ty(id) { ret id; }
@ -228,6 +228,10 @@ fn ret_by_ref(style: ret_style) -> bool {
}
}
fn ty_param_kind(tp: ty_param) -> kind {
alt tp.kind { explicit(x) | implicit(x) { x } }
}
// Local Variables:
// mode: rust
// fill-column: 78;

View File

@ -1735,25 +1735,21 @@ fn parse_block_tail(p: parser, lo: uint, s: ast::blk_check_mode) -> ast::blk {
ret spanned(lo, hi, bloc);
}
fn parse_ty_param(p: parser) -> ast::ty_param {
let k = if eat_word(p, "pin") { ast::kind_pinned }
else if eat_word(p, "uniq") { ast::kind_unique }
else if eat_word(p, "shar") { ast::kind_shared }
fn parse_ty_param(default: ast::kind, p: parser) -> ast::ty_param {
let k = if eat_word(p, "pin") { ast::explicit(ast::kind_pinned) }
else if eat_word(p, "uniq") { ast::explicit(ast::kind_unique) }
else if eat_word(p, "shar") { ast::explicit(ast::kind_shared) }
// FIXME distinguish implied shared from explicit
else { ast::kind_shared };
else { ast::implicit(default) };
ret {ident: parse_ident(p), kind: k};
}
fn parse_ty_params(p: parser) -> [ast::ty_param] {
fn parse_ty_params(p: parser, default: ast::kind) -> [ast::ty_param] {
let ty_params: [ast::ty_param] = [];
if p.peek() == token::LT {
p.bump();
ty_params = parse_seq_to_gt(some(token::COMMA), parse_ty_param, p);
}
if p.peek() == token::LT {
ty_params =
parse_seq(token::LT, token::GT, some(token::COMMA),
parse_ty_param, p).node;
ty_params = parse_seq_to_gt(some(token::COMMA),
{|p| parse_ty_param(default, p)}, p);
}
ret ty_params;
}
@ -1806,7 +1802,7 @@ fn parse_fn(p: parser, proto: ast::proto, purity: ast::purity,
fn parse_fn_header(p: parser) -> {ident: ast::ident, tps: [ast::ty_param]} {
let id = parse_value_ident(p);
let ty_params = parse_ty_params(p);
let ty_params = parse_ty_params(p, ast::kind_shared);
ret {ident: id, tps: ty_params};
}
@ -1859,7 +1855,7 @@ fn parse_method(p: parser) -> @ast::method {
fn parse_item_obj(p: parser, attrs: [ast::attribute]) -> @ast::item {
let lo = p.get_last_lo_pos();
let ident = parse_value_ident(p);
let ty_params = parse_ty_params(p);
let ty_params = parse_ty_params(p, ast::kind_pinned);
let fields: ast::spanned<[ast::obj_field]> =
parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA),
parse_obj_field, p);
@ -1876,7 +1872,7 @@ fn parse_item_obj(p: parser, attrs: [ast::attribute]) -> @ast::item {
fn parse_item_res(p: parser, attrs: [ast::attribute]) -> @ast::item {
let lo = p.get_last_lo_pos();
let ident = parse_value_ident(p);
let ty_params = parse_ty_params(p);
let ty_params = parse_ty_params(p, ast::kind_pinned);
expect(p, token::LPAREN);
let arg_ident = parse_value_ident(p);
expect(p, token::COLON);
@ -2052,7 +2048,7 @@ fn parse_type_decl(p: parser) -> {lo: uint, ident: ast::ident} {
fn parse_item_type(p: parser, attrs: [ast::attribute]) -> @ast::item {
let t = parse_type_decl(p);
let tps = parse_ty_params(p);
let tps = parse_ty_params(p, ast::kind_pinned);
expect(p, token::EQ);
let ty = parse_ty(p, false);
let hi = p.get_hi_pos();
@ -2063,7 +2059,7 @@ fn parse_item_type(p: parser, attrs: [ast::attribute]) -> @ast::item {
fn parse_item_tag(p: parser, attrs: [ast::attribute]) -> @ast::item {
let lo = p.get_last_lo_pos();
let id = parse_ident(p);
let ty_params = parse_ty_params(p);
let ty_params = parse_ty_params(p, ast::kind_pinned);
let variants: [ast::variant] = [];
// Newtype syntax
if p.peek() == token::EQ {

View File

@ -1191,11 +1191,12 @@ fn print_arg_mode(s: ps, m: ast::mode) {
}
}
fn print_kind(s: ps, kind: ast::kind) {
fn print_kind(s: ps, kind: ast::plicit<ast::kind>) {
alt kind {
ast::kind_unique. { word_nbsp(s, "uniq"); }
ast::kind_pinned. { word_nbsp(s, "pin"); }
_ {/* fallthrough */ }
ast::implicit(_) {}
ast::explicit(ast::kind_unique.) { word_nbsp(s, "uniq"); }
ast::explicit(ast::kind_pinned.) { word_nbsp(s, "pin"); }
ast::explicit(ast::kind_shared.) { word_nbsp(s, "shar"); }
}
}

View File

@ -41,12 +41,6 @@ fn create<T>() -> t<T> {
* Grow is only called on full elts, so nelts is also len(elts), unlike
* elsewhere.
*/
fn grow<T>(nelts: uint, lo: uint, elts: [mutable cell<T>]) ->
[mutable cell<T>] {
assert (nelts == vec::len(elts));
@ -66,10 +60,10 @@ fn create<T>() -> t<T> {
fn get<T>(elts: [mutable cell<T>], i: uint) -> T {
ret alt elts[i] { option::some(t) { t } _ { fail } };
}
obj deque<T>(mutable nelts: uint,
mutable lo: uint,
mutable hi: uint,
mutable elts: [mutable cell<T>]) {
obj deque<shar T>(mutable nelts: uint,
mutable lo: uint,
mutable hi: uint,
mutable elts: [mutable cell<T>]) {
fn size() -> uint { ret nelts; }
fn add_front(t: T) {
let oldlo: uint = lo;

View File

@ -201,12 +201,12 @@ fn mk_hashmap<K, V>(hasher: hashfn<K>, eqer: eqfn<K>) -> hashmap<K, V> {
}
}
}
obj hashmap<K, V>(hasher: hashfn<K>,
eqer: eqfn<K>,
mutable bkts: [mutable bucket<K, V>],
mutable nbkts: uint,
mutable nelts: uint,
lf: util::rational) {
obj hashmap<shar K, shar V>(hasher: hashfn<K>,
eqer: eqfn<K>,
mutable bkts: [mutable bucket<K, V>],
mutable nbkts: uint,
mutable nelts: uint,
lf: util::rational) {
fn size() -> uint { ret nelts; }
fn insert(key: K, val: V) -> bool {
let load: util::rational =

View File

@ -1,5 +1,5 @@
obj ob<K>(k: K) {
obj ob<shar K>(k: K) {
fn foo(it: block(~{a: K})) { it(~{a: k}); }
}

View File

@ -1,6 +1,6 @@
obj handle<T>(data: T) {
obj handle<shar T>(data: T) {
fn get() -> T { ret data; }
}

View File

@ -1,6 +1,6 @@
obj buf<T>(data: {_0: T, _1: T, _2: T}) {
obj buf<shar T>(data: {_0: T, _1: T, _2: T}) {
fn get(i: int) -> T {
if i == 0 {
ret data._0;

View File

@ -6,7 +6,7 @@ tag clam<T> { signed(int); unsigned(uint); }
fn getclam<T>() -> clam<T> { ret signed::<T>(42); }
obj impatience<T>() {
obj impatience<shar T>() {
fn moreclam() -> clam<T> { be getclam::<T>(); }
}