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::start_tag(ebml_w, tag_items_data_item_ty_param_kinds);
ebml::write_vint(ebml_w.writer, vec::len::<ty_param>(tps)); ebml::write_vint(ebml_w.writer, vec::len::<ty_param>(tps));
for tp: ty_param in tps { for tp: ty_param in tps {
let c = let c = alt ast_util::ty_param_kind(tp) {
alt tp.kind { kind_unique. { 'u' }
kind_unique. { 'u' } kind_shared. { 's' }
kind_shared. { 's' } kind_pinned. { 'p' }
kind_pinned. { 'p' } };
};
ebml_w.writer.write([c as u8]); ebml_w.writer.write([c as u8]);
} }
ebml::end_tag(ebml_w); 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) idx_key: fn(uint) -> K)
-> std::map::hashmap<K, V> { -> std::map::hashmap<K, V> {
obj adapter<K, V>(map: smallintmap::smallintmap<V>, obj adapter<shar K, shar V>(map: smallintmap::smallintmap<V>,
key_idx: fn(K) -> uint, key_idx: fn(K) -> uint,
idx_key: fn(uint) -> K) { idx_key: fn(uint) -> K) {
fn size() -> uint { fail } 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 { 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) 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> { option::t<def> {
let i = 0u; let i = 0u;
for tp: ast::ty_param in ty_params { 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; i += 1u;
} }
ret none::<def>; 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] = []; let ty_param_substs: [ty::t] = [];
i = 0u; i = 0u;
for tp: ast::ty_param in ty_params { 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; i += 1u;
} }
let arg_tys = arg_tys_of_fn(cx.ccx, variant.node.id); 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_upvar(_, _, _) { ret false; }
ast::def_variant(_, _) { ret true; } ast::def_variant(_, _) { ret true; }
ast::def_ty(_) { ret false; } ast::def_ty(_) { ret false; }
ast::def_ty_arg(_, _) { ret false; } ast::def_ty_param(_, _) { ret false; }
ast::def_binding(_) { ret false; } ast::def_binding(_) { ret false; }
ast::def_use(_) { ret false; } ast::def_use(_) { ret false; }
ast::def_native_ty(_) { ret false; } ast::def_native_ty(_) { ret false; }

View file

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

View file

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

View file

@ -33,7 +33,7 @@ fn def_id_of_def(d: def) -> def_id {
def_local(id, _) { ret id; } def_local(id, _) { ret id; }
def_variant(_, id) { ret id; } def_variant(_, id) { ret id; }
def_ty(id) { ret id; } def_ty(id) { ret id; }
def_ty_arg(_, _) { fail; } def_ty_param(_, _) { fail; }
def_binding(id) { ret id; } def_binding(id) { ret id; }
def_use(id) { ret id; } def_use(id) { ret id; }
def_native_ty(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: // Local Variables:
// mode: rust // mode: rust
// fill-column: 78; // 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); ret spanned(lo, hi, bloc);
} }
fn parse_ty_param(p: parser) -> ast::ty_param { fn parse_ty_param(default: ast::kind, p: parser) -> ast::ty_param {
let k = if eat_word(p, "pin") { ast::kind_pinned } let k = if eat_word(p, "pin") { ast::explicit(ast::kind_pinned) }
else if eat_word(p, "uniq") { ast::kind_unique } else if eat_word(p, "uniq") { ast::explicit(ast::kind_unique) }
else if eat_word(p, "shar") { ast::kind_shared } else if eat_word(p, "shar") { ast::explicit(ast::kind_shared) }
// FIXME distinguish implied shared from explicit // FIXME distinguish implied shared from explicit
else { ast::kind_shared }; else { ast::implicit(default) };
ret {ident: parse_ident(p), kind: k}; 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] = []; let ty_params: [ast::ty_param] = [];
if p.peek() == token::LT { if p.peek() == token::LT {
p.bump(); p.bump();
ty_params = parse_seq_to_gt(some(token::COMMA), parse_ty_param, p); ty_params = parse_seq_to_gt(some(token::COMMA),
} {|p| parse_ty_param(default, p)}, p);
if p.peek() == token::LT {
ty_params =
parse_seq(token::LT, token::GT, some(token::COMMA),
parse_ty_param, p).node;
} }
ret ty_params; 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]} { fn parse_fn_header(p: parser) -> {ident: ast::ident, tps: [ast::ty_param]} {
let id = parse_value_ident(p); 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}; 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 { fn parse_item_obj(p: parser, attrs: [ast::attribute]) -> @ast::item {
let lo = p.get_last_lo_pos(); let lo = p.get_last_lo_pos();
let ident = parse_value_ident(p); 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]> = let fields: ast::spanned<[ast::obj_field]> =
parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA), parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA),
parse_obj_field, p); 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 { fn parse_item_res(p: parser, attrs: [ast::attribute]) -> @ast::item {
let lo = p.get_last_lo_pos(); let lo = p.get_last_lo_pos();
let ident = parse_value_ident(p); 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); expect(p, token::LPAREN);
let arg_ident = parse_value_ident(p); let arg_ident = parse_value_ident(p);
expect(p, token::COLON); 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 { fn parse_item_type(p: parser, attrs: [ast::attribute]) -> @ast::item {
let t = parse_type_decl(p); 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); expect(p, token::EQ);
let ty = parse_ty(p, false); let ty = parse_ty(p, false);
let hi = p.get_hi_pos(); 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 { fn parse_item_tag(p: parser, attrs: [ast::attribute]) -> @ast::item {
let lo = p.get_last_lo_pos(); let lo = p.get_last_lo_pos();
let id = parse_ident(p); 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] = []; let variants: [ast::variant] = [];
// Newtype syntax // Newtype syntax
if p.peek() == token::EQ { 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 { alt kind {
ast::kind_unique. { word_nbsp(s, "uniq"); } ast::implicit(_) {}
ast::kind_pinned. { word_nbsp(s, "pin"); } ast::explicit(ast::kind_unique.) { word_nbsp(s, "uniq"); }
_ {/* fallthrough */ } 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 * Grow is only called on full elts, so nelts is also len(elts), unlike
* elsewhere. * elsewhere.
*/ */
fn grow<T>(nelts: uint, lo: uint, elts: [mutable cell<T>]) -> fn grow<T>(nelts: uint, lo: uint, elts: [mutable cell<T>]) ->
[mutable cell<T>] { [mutable cell<T>] {
assert (nelts == vec::len(elts)); assert (nelts == vec::len(elts));
@ -66,10 +60,10 @@ fn create<T>() -> t<T> {
fn get<T>(elts: [mutable cell<T>], i: uint) -> T { fn get<T>(elts: [mutable cell<T>], i: uint) -> T {
ret alt elts[i] { option::some(t) { t } _ { fail } }; ret alt elts[i] { option::some(t) { t } _ { fail } };
} }
obj deque<T>(mutable nelts: uint, obj deque<shar T>(mutable nelts: uint,
mutable lo: uint, mutable lo: uint,
mutable hi: uint, mutable hi: uint,
mutable elts: [mutable cell<T>]) { mutable elts: [mutable cell<T>]) {
fn size() -> uint { ret nelts; } fn size() -> uint { ret nelts; }
fn add_front(t: T) { fn add_front(t: T) {
let oldlo: uint = lo; 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>, obj hashmap<shar K, shar V>(hasher: hashfn<K>,
eqer: eqfn<K>, eqer: eqfn<K>,
mutable bkts: [mutable bucket<K, V>], mutable bkts: [mutable bucket<K, V>],
mutable nbkts: uint, mutable nbkts: uint,
mutable nelts: uint, mutable nelts: uint,
lf: util::rational) { lf: util::rational) {
fn size() -> uint { ret nelts; } fn size() -> uint { ret nelts; }
fn insert(key: K, val: V) -> bool { fn insert(key: K, val: V) -> bool {
let load: util::rational = 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}); } 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; } 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 { fn get(i: int) -> T {
if i == 0 { if i == 0 {
ret data._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); } fn getclam<T>() -> clam<T> { ret signed::<T>(42); }
obj impatience<T>() { obj impatience<shar T>() {
fn moreclam() -> clam<T> { be getclam::<T>(); } fn moreclam() -> clam<T> { be getclam::<T>(); }
} }