rewrite region resolution so it takes place in typeck
This commit is contained in:
parent
a532ad2828
commit
35a93e61d4
@ -1270,7 +1270,7 @@ are written after the name of the implementation, or if that is not
|
||||
specified, after the `impl` keyword.
|
||||
|
||||
~~~~
|
||||
# iface seq { }
|
||||
# iface seq<T> { }
|
||||
|
||||
impl <T> of seq<T> for [T] {
|
||||
/* ... */
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
$ident = 0;
|
||||
$indent = 0;
|
||||
while (<>) {
|
||||
if (/^rust: ">>/) {
|
||||
$indent += 1;
|
||||
|
@ -101,6 +101,15 @@ impl extensions<T:copy> for option<T> {
|
||||
#[doc = "Performs an operation on the contained value or does nothing"]
|
||||
fn iter(f: fn(T)) { iter(self, f) }
|
||||
|
||||
#[doc = "Converts `none` to a zero-element list and `some` to a \
|
||||
one-element list."]
|
||||
fn to_vec() -> [T] {
|
||||
alt self {
|
||||
some(t) { [t] }
|
||||
none { [] }
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "Performs an operation on the contained value or does nothing"]
|
||||
fn each(f: fn(T) -> bool) {
|
||||
alt self {
|
||||
|
@ -451,9 +451,8 @@ type region = {id: node_id, node: region_};
|
||||
|
||||
#[auto_serialize]
|
||||
enum region_ {
|
||||
re_inferred,
|
||||
re_anon,
|
||||
re_named(ident),
|
||||
re_self,
|
||||
re_static
|
||||
}
|
||||
|
||||
|
@ -451,15 +451,13 @@ fn parse_ret_ty(p: parser) -> (ast::ret_style, @ast::ty) {
|
||||
fn region_from_name(p: parser, s: option<str>) -> ast::region {
|
||||
let r = alt s {
|
||||
some (string) {
|
||||
if string == "self" {
|
||||
ast::re_self
|
||||
} else if string == "static" {
|
||||
if string == "static" {
|
||||
ast::re_static
|
||||
} else {
|
||||
ast::re_named(string)
|
||||
}
|
||||
}
|
||||
none { ast::re_inferred }
|
||||
none { ast::re_anon }
|
||||
};
|
||||
|
||||
{id: p.get_id(), node: r}
|
||||
|
@ -320,9 +320,8 @@ fn print_native_mod(s: ps, nmod: ast::native_mod, attrs: [ast::attribute]) {
|
||||
|
||||
fn print_region(s: ps, region: ast::region) {
|
||||
alt region.node {
|
||||
ast::re_inferred { /* no-op */ }
|
||||
ast::re_anon { /* no-op */ }
|
||||
ast::re_named(name) { word(s.s, name); word(s.s, "."); }
|
||||
ast::re_self { word(s.s, "self"); word(s.s, "."); }
|
||||
ast::re_static { word(s.s, "static"); word(s.s, "."); }
|
||||
}
|
||||
}
|
||||
@ -826,8 +825,7 @@ fn print_vstore(s: ps, t: ast::vstore) {
|
||||
ast::vstore_box { word_space(s, "/@"); }
|
||||
ast::vstore_slice(r) {
|
||||
alt r.node {
|
||||
ast::re_inferred { word_space(s, "/&"); }
|
||||
ast::re_self { word_space(s, "/&self"); }
|
||||
ast::re_anon { word_space(s, "/&"); }
|
||||
ast::re_static { word_space(s, "/&static"); }
|
||||
ast::re_named(name) {
|
||||
word(s.s, "/&");
|
||||
|
@ -104,10 +104,8 @@ fn enc_bound_region(w: io::writer, br: ty::bound_region) {
|
||||
alt br {
|
||||
ty::br_self { w.write_char('s') }
|
||||
ty::br_anon { w.write_char('a') }
|
||||
ty::br_param(id, s) {
|
||||
ty::br_named(s) {
|
||||
w.write_char('[');
|
||||
w.write_uint(id);
|
||||
w.write_char('|');
|
||||
w.write_str(s);
|
||||
w.write_char(']')
|
||||
}
|
||||
@ -132,9 +130,6 @@ fn enc_region(w: io::writer, r: ty::region) {
|
||||
w.write_int(nid);
|
||||
w.write_char('|');
|
||||
}
|
||||
ty::re_default {
|
||||
w.write_char('i');
|
||||
}
|
||||
ty::re_var(id) {
|
||||
w.write_char('v');
|
||||
w.write_uint(id.to_uint());
|
||||
|
@ -592,7 +592,7 @@ impl resolve_methods for infer_ctxt {
|
||||
self.rb,
|
||||
{|_t| false },
|
||||
rid,
|
||||
{|| err(unresolved_region(rid)) });
|
||||
{|| ok(ty::re_static) });
|
||||
}
|
||||
|
||||
fn resolve_ty(typ: ty::t) -> fres<ty::t> {
|
||||
@ -1169,7 +1169,10 @@ impl of combine for sub {
|
||||
}
|
||||
|
||||
fn regions(a: ty::region, b: ty::region) -> cres<ty::region> {
|
||||
#debug["regions(%s <= %s)", a.to_str(*self), b.to_str(*self)];
|
||||
#debug["%s.regions(%s, %s)",
|
||||
self.tag(),
|
||||
a.to_str(self.infcx()),
|
||||
b.to_str(self.infcx())];
|
||||
indent {||
|
||||
alt (a, b) {
|
||||
(ty::re_var(a_id), ty::re_var(b_id)) {
|
||||
@ -1376,8 +1379,7 @@ impl of combine for lub {
|
||||
{|x, y| self.regions(x, y) })
|
||||
}
|
||||
|
||||
(ty::re_var(v_id), r) |
|
||||
(r, ty::re_var(v_id)) {
|
||||
(ty::re_var(v_id), r) | (r, ty::re_var(v_id)) {
|
||||
lattice_var_t(self, self.infcx().rb,
|
||||
v_id, r,
|
||||
{|x, y| self.regions(x, y) })
|
||||
@ -1415,12 +1417,6 @@ impl of combine for lub {
|
||||
err(ty::terr_regions_differ(b, a))
|
||||
}
|
||||
}
|
||||
|
||||
(ty::re_default, _) |
|
||||
(_, ty::re_default) {
|
||||
// actually a compiler bug, I think.
|
||||
err(ty::terr_regions_differ(b, a))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1561,10 +1557,10 @@ impl of combine for glb {
|
||||
{|x, y| self.regions(x, y) })
|
||||
}
|
||||
|
||||
(ty::re_var(v_id), _) | (_, ty::re_var(v_id)) {
|
||||
lattice_var_t(self, self.infcx().rb,
|
||||
v_id, b,
|
||||
{|x, y| self.regions(x, y) })
|
||||
(ty::re_var(v_id), r) | (r, ty::re_var(v_id)) {
|
||||
lattice_var_t(self, self.infcx().rb,
|
||||
v_id, r,
|
||||
{|x, y| self.regions(x, y) })
|
||||
}
|
||||
|
||||
(f @ ty::re_free(f_id, f_br), ty::re_scope(s_id)) |
|
||||
@ -1601,12 +1597,6 @@ impl of combine for glb {
|
||||
err(ty::terr_regions_differ(b, a))
|
||||
}
|
||||
}
|
||||
|
||||
(ty::re_default, _) |
|
||||
(_, ty::re_default) {
|
||||
// actually a compiler bug, I think.
|
||||
err(ty::terr_regions_differ(b, a))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1727,7 +1717,7 @@ fn lattice_vars<V:copy vid, T:copy to_str st, L:lattice_ops combine>(
|
||||
let {root: a_vid, bounds: a_bounds} = self.infcx().get(vb, a_vid);
|
||||
let {root: b_vid, bounds: b_bounds} = self.infcx().get(vb, b_vid);
|
||||
|
||||
#debug["%s.vars(%s=%s <: %s=%s)",
|
||||
#debug["%s.lattice_vars(%s=%s <: %s=%s)",
|
||||
self.tag(),
|
||||
a_vid.to_str(), a_bounds.to_str(self.infcx()),
|
||||
b_vid.to_str(), b_bounds.to_str(self.infcx())];
|
||||
@ -1758,15 +1748,15 @@ fn lattice_vars<V:copy vid, T:copy to_str st, L:lattice_ops combine>(
|
||||
|
||||
fn lattice_var_t<V:copy vid, T:copy to_str st, L:lattice_ops combine>(
|
||||
self: L, vb: vals_and_bindings<V, T>,
|
||||
a_vid: V, b: T,
|
||||
a_id: V, b: T,
|
||||
c_ts: fn(T, T) -> cres<T>) -> cres<T> {
|
||||
|
||||
let {root: a_id, bounds: a_bounds} = self.infcx().get(vb, a_vid);
|
||||
let {root: a_id, bounds: a_bounds} = self.infcx().get(vb, a_id);
|
||||
|
||||
// The comments in this function are written for LUB, but they
|
||||
// apply equally well to GLB if you inverse upper/lower/sub/super/etc.
|
||||
|
||||
#debug["%s.var_ty(%s=%s <: %s)",
|
||||
#debug["%s.lattice_vart(%s=%s <: %s)",
|
||||
self.tag(),
|
||||
a_id.to_str(), a_bounds.to_str(self.infcx()),
|
||||
b.to_str(self.infcx())];
|
||||
|
@ -162,12 +162,9 @@ type binding = {node_id: ast::node_id,
|
||||
type region_map = {
|
||||
/* Mapping from a block/function expression to its parent. */
|
||||
parents: hashmap<ast::node_id,ast::node_id>,
|
||||
/* Mapping from a region type in the AST to its resolved region. */
|
||||
ast_type_to_region: hashmap<ast::node_id,ty::region>,
|
||||
|
||||
/* Mapping from a local variable to its containing block. */
|
||||
local_blocks: hashmap<ast::node_id,ast::node_id>,
|
||||
/* Mapping from an AST type node to the region that `&` resolves to. */
|
||||
ast_type_to_inferred_region: hashmap<ast::node_id,ty::region>,
|
||||
local_blocks: hashmap<ast::node_id,ast::node_id>
|
||||
};
|
||||
|
||||
type region_scope = @{
|
||||
@ -198,69 +195,6 @@ impl methods for region_scope {
|
||||
fn self_subscope(node_id: ast::node_id) -> region_scope {
|
||||
@{node_id: node_id, kind: rsk_self(self)}
|
||||
}
|
||||
|
||||
fn find(nm: str) -> option<binding> {
|
||||
alt self.kind {
|
||||
rsk_root { none }
|
||||
rsk_body(parent) { parent.find(nm) }
|
||||
rsk_self(parent) { parent.find(nm) }
|
||||
rsk_binding(parent, bs) {
|
||||
alt (*bs).find({|b| b.name == nm }) {
|
||||
none { parent.find(nm) }
|
||||
some(b) { some(b) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fn resolve_anon() -> option<ty::region> {
|
||||
// alt self.kind {
|
||||
// rsk_root { none }
|
||||
// rsk_body(_) { none }
|
||||
// rsk_self(_) { none }
|
||||
// rsk_binding(_, _) { ty::re_bound(ty::br_anon) }
|
||||
// }
|
||||
// }
|
||||
|
||||
fn resolve_self_helper(bound: bool) -> option<ty::region> {
|
||||
alt self.kind {
|
||||
rsk_root { none }
|
||||
rsk_self(_) if bound { some(ty::re_bound(ty::br_self)) }
|
||||
rsk_self(_) { some(ty::re_free(self.node_id, ty::br_self)) }
|
||||
rsk_binding(p, _) { p.resolve_self_helper(bound) }
|
||||
rsk_body(p) { p.resolve_self_helper(false) }
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_self() -> option<ty::region> {
|
||||
self.resolve_self_helper(true)
|
||||
}
|
||||
|
||||
fn resolve_ident(nm: str) -> option<ty::region> {
|
||||
alt self.find(nm) {
|
||||
some(b) if b.node_id == self.node_id {
|
||||
some(ty::re_bound(b.br))
|
||||
}
|
||||
|
||||
some(b) {
|
||||
some(ty::re_free(b.node_id, b.br))
|
||||
}
|
||||
|
||||
none {
|
||||
alt self.kind {
|
||||
rsk_self(_) | rsk_root | rsk_body(_) { none }
|
||||
rsk_binding(_, bs) {
|
||||
let idx = (*bs).len();
|
||||
let br = ty::br_param(idx, nm);
|
||||
vec::push(*bs, {node_id: self.node_id,
|
||||
name: nm,
|
||||
br: br});
|
||||
some(ty::re_bound(br))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type ctxt = {
|
||||
@ -351,50 +285,6 @@ fn get_inferred_region(cx: ctxt, sp: syntax::codemap::span) -> ty::region {
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_region_binding(cx: ctxt, span: span,
|
||||
region: ast::region) -> ty::region {
|
||||
alt region.node {
|
||||
ast::re_inferred { ty::re_default }
|
||||
ast::re_static { ty::re_static }
|
||||
ast::re_named(ident) {
|
||||
alt cx.scope.resolve_ident(ident) {
|
||||
some(r) { r }
|
||||
none {
|
||||
cx.sess.span_fatal(
|
||||
span,
|
||||
#fmt["the region `%s` is not declared", ident]);
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::re_self {
|
||||
alt cx.scope.resolve_self() {
|
||||
some(r) { r }
|
||||
none {
|
||||
cx.sess.span_fatal(
|
||||
span,
|
||||
"the `self` region is not allowed here");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_ty(ty: @ast::ty, cx: ctxt, visitor: visit::vt<ctxt>) {
|
||||
let inferred_region = get_inferred_region(cx, ty.span);
|
||||
cx.region_map.ast_type_to_inferred_region.insert(ty.id, inferred_region);
|
||||
|
||||
alt ty.node {
|
||||
ast::ty_vstore(_, ast::vstore_slice(r)) |
|
||||
ast::ty_rptr(r, _) {
|
||||
let region = resolve_region_binding(cx, ty.span, r);
|
||||
cx.region_map.ast_type_to_region.insert(ty.id, region);
|
||||
}
|
||||
_ { /* nothing to do */ }
|
||||
}
|
||||
|
||||
visit::visit_ty(ty, cx, visitor);
|
||||
}
|
||||
|
||||
fn opt_parent_id(cx: ctxt) -> option<ast::node_id> {
|
||||
alt cx.parent {
|
||||
pa_fn_item(parent_id) |
|
||||
@ -531,16 +421,12 @@ fn resolve_crate(sess: session, def_map: resolve::def_map, crate: @ast::crate)
|
||||
let cx: ctxt = {sess: sess,
|
||||
def_map: def_map,
|
||||
region_map: @{parents: map::int_hash(),
|
||||
ast_type_to_region: map::int_hash(),
|
||||
local_blocks: map::int_hash(),
|
||||
ast_type_to_inferred_region:
|
||||
map::int_hash()},
|
||||
local_blocks: map::int_hash()},
|
||||
scope: root_scope(0),
|
||||
parent: pa_crate};
|
||||
let visitor = visit::mk_vt(@{
|
||||
visit_block: resolve_block,
|
||||
visit_item: resolve_item,
|
||||
visit_ty: resolve_ty,
|
||||
visit_arm: resolve_arm,
|
||||
visit_pat: resolve_pat,
|
||||
visit_expr: resolve_expr,
|
||||
|
@ -15,12 +15,13 @@ fn check_expr(expr: @ast::expr,
|
||||
visit::visit_expr(expr, tcx, visitor);
|
||||
|
||||
let t = ty::expr_ty(tcx, expr);
|
||||
if !ty::type_has_rptrs(t) { ret; }
|
||||
if !ty::type_has_regions(t) { ret; }
|
||||
ty::walk_ty(t) { |t|
|
||||
alt ty::get(t).struct {
|
||||
ty::ty_rptr(region, _) {
|
||||
alt region {
|
||||
ty::re_bound(_) | ty::re_free(_, _) | ty::re_static {
|
||||
ty::re_bound(_) | ty::re_free(_, _) | ty::re_static |
|
||||
ty::re_var(_) {
|
||||
/* ok */
|
||||
}
|
||||
ty::re_scope(id) {
|
||||
@ -31,9 +32,6 @@ fn check_expr(expr: @ast::expr,
|
||||
ppaux::re_scope_id_to_str(tcx, id)]);
|
||||
}
|
||||
}
|
||||
ty::re_default | ty::re_var(_) {
|
||||
tcx.sess.span_bug(expr.span, "unresolved region");
|
||||
}
|
||||
}
|
||||
}
|
||||
_ { /* no-op */ }
|
||||
|
@ -36,7 +36,7 @@ export expr_ty;
|
||||
export expr_ty_params_and_ty;
|
||||
export expr_is_lval;
|
||||
export field_ty;
|
||||
export fold_ty, fold_sty_to_ty, fold_region, fold_ty_var;
|
||||
export fold_ty, fold_sty_to_ty, fold_region, fold_regions, fold_ty_var;
|
||||
export field;
|
||||
export field_idx;
|
||||
export get_field;
|
||||
@ -99,7 +99,7 @@ export ty_uniq, mk_uniq, mk_imm_uniq, type_is_unique_box;
|
||||
export ty_var, mk_var;
|
||||
export ty_self, mk_self;
|
||||
export region, bound_region;
|
||||
export get, type_has_params, type_has_vars, type_has_rptrs, type_id;
|
||||
export get, type_has_params, type_has_vars, type_has_regions, type_id;
|
||||
export ty_var_id;
|
||||
export ty_to_def_id;
|
||||
export ty_fn_args;
|
||||
@ -230,7 +230,7 @@ type t_box = @{struct: sty,
|
||||
id: uint,
|
||||
has_params: bool,
|
||||
has_vars: bool,
|
||||
has_rptrs: bool,
|
||||
has_regions: bool,
|
||||
o_def_id: option<ast::def_id>};
|
||||
|
||||
// To reduce refcounting cost, we're representing types as unsafe pointers
|
||||
@ -250,7 +250,7 @@ pure fn get(t: t) -> t_box unsafe {
|
||||
|
||||
fn type_has_params(t: t) -> bool { get(t).has_params }
|
||||
fn type_has_vars(t: t) -> bool { get(t).has_vars }
|
||||
fn type_has_rptrs(t: t) -> bool { get(t).has_rptrs }
|
||||
fn type_has_regions(t: t) -> bool { get(t).has_regions }
|
||||
fn type_def_id(t: t) -> option<ast::def_id> { get(t).o_def_id }
|
||||
fn type_id(t: t) -> uint { get(t).id }
|
||||
|
||||
@ -272,20 +272,13 @@ enum region {
|
||||
re_free(node_id, bound_region),
|
||||
re_scope(node_id),
|
||||
re_var(region_vid),
|
||||
re_static, // effectively `top` in the region lattice
|
||||
re_default
|
||||
re_static // effectively `top` in the region lattice
|
||||
}
|
||||
|
||||
enum bound_region {
|
||||
// The `self` region for a given class/impl/iface. The defining item may
|
||||
// appear in another crate.
|
||||
br_self,
|
||||
|
||||
// The anonymous region parameter for a given function.
|
||||
br_anon,
|
||||
|
||||
// A named region parameter.
|
||||
br_param(uint, str)
|
||||
br_self, // The self region for classes, impls
|
||||
br_anon, // The anonymous region parameter for a given function.
|
||||
br_named(str) // A named region parameter.
|
||||
}
|
||||
|
||||
// NB: If you change this, you'll probably want to change the corresponding
|
||||
@ -461,21 +454,21 @@ fn mk_t_with_id(cx: ctxt, st: sty, o_def_id: option<ast::def_id>) -> t {
|
||||
some(t) { unsafe { ret unsafe::reinterpret_cast(t); } }
|
||||
_ {}
|
||||
}
|
||||
let mut has_params = false, has_vars = false, has_rptrs = false;
|
||||
fn derive_flags(&has_params: bool, &has_vars: bool, &has_rptrs: bool,
|
||||
let mut has_params = false, has_vars = false, has_regions = false;
|
||||
fn derive_flags(&has_params: bool, &has_vars: bool, &has_regions: bool,
|
||||
tt: t) {
|
||||
let t = get(tt);
|
||||
has_params |= t.has_params;
|
||||
has_vars |= t.has_vars;
|
||||
has_rptrs |= t.has_rptrs;
|
||||
has_regions |= t.has_regions;
|
||||
}
|
||||
alt st {
|
||||
ty_estr(vstore_slice(_)) {
|
||||
has_rptrs = true;
|
||||
has_regions = true;
|
||||
}
|
||||
ty_evec(mt, vstore_slice(_)) {
|
||||
has_rptrs = true;
|
||||
derive_flags(has_params, has_vars, has_rptrs, mt.ty);
|
||||
has_regions = true;
|
||||
derive_flags(has_params, has_vars, has_regions, mt.ty);
|
||||
}
|
||||
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_float(_) | ty_uint(_) |
|
||||
ty_str | ty_estr(_) | ty_type | ty_opaque_closure_ptr(_) |
|
||||
@ -484,49 +477,50 @@ fn mk_t_with_id(cx: ctxt, st: sty, o_def_id: option<ast::def_id>) -> t {
|
||||
ty_var(_) | ty_self(_) { has_vars = true; }
|
||||
ty_enum(_, tys) | ty_iface(_, tys) | ty_class(_, tys) {
|
||||
for tys.each {|tt|
|
||||
derive_flags(has_params, has_vars, has_rptrs, tt);
|
||||
derive_flags(has_params, has_vars, has_regions, tt);
|
||||
}
|
||||
}
|
||||
ty_box(m) | ty_uniq(m) | ty_vec(m) | ty_evec(m, _) | ty_ptr(m) {
|
||||
derive_flags(has_params, has_vars, has_rptrs, m.ty);
|
||||
derive_flags(has_params, has_vars, has_regions, m.ty);
|
||||
}
|
||||
ty_rptr(r, m) {
|
||||
alt r {
|
||||
ty::re_var(_) { has_vars = true; }
|
||||
_ { }
|
||||
}
|
||||
has_rptrs = true;
|
||||
derive_flags(has_params, has_vars, has_rptrs, m.ty);
|
||||
has_regions = true;
|
||||
derive_flags(has_params, has_vars, has_regions, m.ty);
|
||||
}
|
||||
ty_rec(flds) {
|
||||
for flds.each {|f|
|
||||
derive_flags(has_params, has_vars, has_rptrs, f.mt.ty);
|
||||
derive_flags(has_params, has_vars, has_regions, f.mt.ty);
|
||||
}
|
||||
}
|
||||
ty_tup(ts) {
|
||||
for ts.each {|tt| derive_flags(has_params, has_vars, has_rptrs, tt); }
|
||||
for ts.each {|tt| derive_flags(has_params, has_vars,
|
||||
has_regions, tt); }
|
||||
}
|
||||
ty_fn(f) {
|
||||
for f.inputs.each {|a|
|
||||
derive_flags(has_params, has_vars, has_rptrs, a.ty);
|
||||
derive_flags(has_params, has_vars, has_regions, a.ty);
|
||||
}
|
||||
derive_flags(has_params, has_vars, has_rptrs, f.output);
|
||||
derive_flags(has_params, has_vars, has_regions, f.output);
|
||||
}
|
||||
ty_res(_, tt, tps) {
|
||||
derive_flags(has_params, has_vars, has_rptrs, tt);
|
||||
derive_flags(has_params, has_vars, has_regions, tt);
|
||||
for tps.each {|tt|
|
||||
derive_flags(has_params, has_vars, has_rptrs, tt);
|
||||
derive_flags(has_params, has_vars, has_regions, tt);
|
||||
}
|
||||
}
|
||||
ty_constr(tt, _) {
|
||||
derive_flags(has_params, has_vars, has_rptrs, tt);
|
||||
derive_flags(has_params, has_vars, has_regions, tt);
|
||||
}
|
||||
}
|
||||
let t = @{struct: st,
|
||||
id: cx.next_id,
|
||||
has_params: has_params,
|
||||
has_vars: has_vars,
|
||||
has_rptrs: has_rptrs,
|
||||
has_regions: has_regions,
|
||||
o_def_id: o_def_id};
|
||||
cx.interner.insert(key, t);
|
||||
cx.next_id += 1u;
|
||||
@ -771,11 +765,53 @@ fn fold_ty_var(cx: ctxt, t0: t, fldop: fn(ty_vid) -> t) -> t {
|
||||
}
|
||||
}
|
||||
|
||||
// n.b. this function is intended to eventually replace fold_region() below,
|
||||
// that is why its name is so similar.
|
||||
fn fold_regions(
|
||||
cx: ctxt,
|
||||
ty: t,
|
||||
fldr: fn(r: region, in_fn: bool) -> region) -> t {
|
||||
|
||||
fn do_fold(cx: ctxt, ty: t, in_fn: bool,
|
||||
fldr: fn(region, bool) -> region) -> t {
|
||||
let tb = ty::get(ty);
|
||||
if !tb.has_regions { ret ty; }
|
||||
alt tb.struct {
|
||||
ty::ty_rptr(r, mt) {
|
||||
let m_r = fldr(r, in_fn);
|
||||
let m_t = do_fold(cx, mt.ty, in_fn, fldr);
|
||||
ty::mk_rptr(cx, m_r, {ty: m_t, mutbl: mt.mutbl})
|
||||
}
|
||||
ty_estr(vstore_slice(r)) {
|
||||
let m_r = fldr(r, in_fn);
|
||||
ty::mk_estr(cx, vstore_slice(m_r))
|
||||
}
|
||||
ty_evec(mt, vstore_slice(r)) {
|
||||
let m_r = fldr(r, in_fn);
|
||||
let m_t = do_fold(cx, mt.ty, in_fn, fldr);
|
||||
ty::mk_evec(cx, {ty: m_t, mutbl: mt.mutbl}, vstore_slice(m_r))
|
||||
}
|
||||
sty @ ty_fn(_) {
|
||||
fold_sty_to_ty(cx, sty) {|t|
|
||||
do_fold(cx, t, true, fldr)
|
||||
}
|
||||
}
|
||||
sty {
|
||||
fold_sty_to_ty(cx, sty) {|t|
|
||||
do_fold(cx, t, in_fn, fldr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do_fold(cx, ty, false, fldr)
|
||||
}
|
||||
|
||||
fn fold_region(cx: ctxt, t0: t, fldop: fn(region, bool) -> region) -> t {
|
||||
fn do_fold(cx: ctxt, t0: t, under_r: bool,
|
||||
fldop: fn(region, bool) -> region) -> t {
|
||||
let tb = get(t0);
|
||||
if !tb.has_rptrs { ret t0; }
|
||||
if !tb.has_regions { ret t0; }
|
||||
alt tb.struct {
|
||||
ty_rptr(r, {ty: t1, mutbl: m}) {
|
||||
let m_r = fldop(r, under_r);
|
||||
@ -1544,9 +1580,9 @@ fn type_autoderef(cx: ctxt, t: t) -> t {
|
||||
|
||||
fn hash_bound_region(br: bound_region) -> uint {
|
||||
alt br { // no idea if this is any good
|
||||
br_self { 0u }
|
||||
br_anon { 1u }
|
||||
br_param(id, _) { id }
|
||||
ty::br_self { 0u }
|
||||
ty::br_anon { 1u }
|
||||
ty::br_named(str) { str::hash(str) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -1588,8 +1624,7 @@ fn hash_type_structure(st: sty) -> uint {
|
||||
(hash_bound_region(br)) << 2u | 1u }
|
||||
re_scope(id) { ((id as uint) << 2u) | 2u }
|
||||
re_var(id) { (id.to_uint() << 2u) | 3u }
|
||||
re_default { 4u }
|
||||
re_bot { 5u }
|
||||
re_bot { 4u }
|
||||
}
|
||||
}
|
||||
alt st {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -13,7 +13,7 @@ import driver::session::session;
|
||||
fn bound_region_to_str(_cx: ctxt, br: bound_region) -> str {
|
||||
alt br {
|
||||
br_anon { "&" }
|
||||
br_param(_, str) { #fmt["&%s", str] }
|
||||
br_named(str) { #fmt["&%s", str] }
|
||||
br_self { "&self" }
|
||||
}
|
||||
}
|
||||
@ -53,7 +53,6 @@ fn region_to_str(cx: ctxt, region: region) -> str {
|
||||
|
||||
// These two should not be seen by end-users (very often, anyhow):
|
||||
re_var(id) { #fmt("&%s", id.to_str()) }
|
||||
re_default { "&(default)" }
|
||||
re_static { "&static" }
|
||||
}
|
||||
}
|
||||
|
13
src/test/compile-fail/seq-args.rs
Normal file
13
src/test/compile-fail/seq-args.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use std;
|
||||
fn main() {
|
||||
iface seq { }
|
||||
|
||||
impl <T> of seq<T> for [T] {
|
||||
//!^ ERROR wrong number of type arguments for a polymorphic type
|
||||
/* ... */
|
||||
}
|
||||
impl of seq<bool> for u32 {
|
||||
/* Treat the integer as a sequence of bits */
|
||||
}
|
||||
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
// xfail-test
|
||||
|
||||
enum int_wrapper {
|
||||
int_wrapper_ctor(&int)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user