mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-03 12:13:43 +00:00
implement evec/estr subtyping/lub/glb/etc
This commit is contained in:
parent
eb935b8fcb
commit
cc16165e40
@ -896,6 +896,8 @@ iface combine {
|
||||
fn ret_styles(r1: ret_style, r2: ret_style) -> cres<ret_style>;
|
||||
fn contraregions(a: ty::region, b: ty::region) -> cres<ty::region>;
|
||||
fn regions(a: ty::region, b: ty::region) -> cres<ty::region>;
|
||||
fn vstores(vk: ty::terr_vstore_kind,
|
||||
a: ty::vstore, b: ty::vstore) -> cres<ty::vstore>;
|
||||
}
|
||||
|
||||
enum sub = infer_ctxt; // "subtype", "subregion" etc
|
||||
@ -951,6 +953,27 @@ fn super_args<C:combine>(
|
||||
}
|
||||
}
|
||||
|
||||
fn super_vstores<C:combine>(
|
||||
self: C, vk: ty::terr_vstore_kind,
|
||||
a: ty::vstore, b: ty::vstore) -> cres<ty::vstore> {
|
||||
|
||||
alt (a, b) {
|
||||
(ty::vstore_slice(a_r), ty::vstore_slice(b_r)) {
|
||||
self.contraregions(a_r, b_r).chain {|r|
|
||||
ok(ty::vstore_slice(r))
|
||||
}
|
||||
}
|
||||
|
||||
_ if a == b {
|
||||
ok(a)
|
||||
}
|
||||
|
||||
_ {
|
||||
err(ty::terr_vstores_differ(vk, b, a))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn super_fns<C:combine>(
|
||||
self: C, a_f: ty::fn_ty, b_f: ty::fn_ty) -> cres<ty::fn_ty> {
|
||||
|
||||
@ -1070,15 +1093,20 @@ fn super_tys<C:combine>(
|
||||
}
|
||||
}
|
||||
|
||||
(ty::ty_evec(a_mt, ty::vstore_slice(a_r)),
|
||||
ty::ty_evec(b_mt, ty::vstore_slice(b_r))) {
|
||||
self.contraregions(a_r, b_r).chain {|r|
|
||||
self.mts(a_mt, b_mt).chain {|mt|
|
||||
ok(ty::mk_evec(tcx, mt, ty::vstore_slice(r)))
|
||||
(ty::ty_evec(a_mt, vs_a), ty::ty_evec(b_mt, vs_b)) {
|
||||
self.mts(a_mt, b_mt).chain {|mt|
|
||||
self.vstores(ty::terr_vec, vs_a, vs_b).chain {|vs|
|
||||
ok(ty::mk_evec(tcx, mt, vs))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(ty::ty_estr(vs_a), ty::ty_estr(vs_b)) {
|
||||
self.vstores(ty::terr_str, vs_a, vs_b).chain {|vs|
|
||||
ok(ty::mk_estr(tcx,vs))
|
||||
}
|
||||
}
|
||||
|
||||
(ty::ty_res(a_id, a_t, a_tps), ty::ty_res(b_id, b_t, b_tps))
|
||||
if a_id == b_id {
|
||||
self.tys(a_t, b_t).chain {|t|
|
||||
@ -1234,6 +1262,11 @@ impl of combine for sub {
|
||||
super_flds(self, a, b)
|
||||
}
|
||||
|
||||
fn vstores(vk: ty::terr_vstore_kind,
|
||||
a: ty::vstore, b: ty::vstore) -> cres<ty::vstore> {
|
||||
super_vstores(self, vk, a, b)
|
||||
}
|
||||
|
||||
fn modes(a: ast::mode, b: ast::mode) -> cres<ast::mode> {
|
||||
super_modes(self, a, b)
|
||||
}
|
||||
@ -1402,6 +1435,11 @@ impl of combine for lub {
|
||||
super_flds(self, a, b)
|
||||
}
|
||||
|
||||
fn vstores(vk: ty::terr_vstore_kind,
|
||||
a: ty::vstore, b: ty::vstore) -> cres<ty::vstore> {
|
||||
super_vstores(self, vk, a, b)
|
||||
}
|
||||
|
||||
fn modes(a: ast::mode, b: ast::mode) -> cres<ast::mode> {
|
||||
super_modes(self, a, b)
|
||||
}
|
||||
@ -1587,6 +1625,11 @@ impl of combine for glb {
|
||||
super_flds(self, a, b)
|
||||
}
|
||||
|
||||
fn vstores(vk: ty::terr_vstore_kind,
|
||||
a: ty::vstore, b: ty::vstore) -> cres<ty::vstore> {
|
||||
super_vstores(self, vk, a, b)
|
||||
}
|
||||
|
||||
fn modes(a: ast::mode, b: ast::mode) -> cres<ast::mode> {
|
||||
super_modes(self, a, b)
|
||||
}
|
||||
|
@ -2616,7 +2616,7 @@ fn trans_arg_expr(cx: block, arg: ty::arg, lldestty: TypeRef, e: @ast::expr,
|
||||
ret rslt(bcx, val);
|
||||
}
|
||||
|
||||
fn adapt_borrowed_value(lv: lval_result, arg: ty::arg,
|
||||
fn adapt_borrowed_value(lv: lval_result, _arg: ty::arg,
|
||||
e: @ast::expr) -> lval_result {
|
||||
let bcx = lv.bcx;
|
||||
if !expr_is_borrowed(bcx, e) { ret lv; }
|
||||
|
@ -11,6 +11,7 @@ import syntax::codemap::span;
|
||||
import metadata::csearch;
|
||||
import util::common::*;
|
||||
import util::ppaux::region_to_str;
|
||||
import util::ppaux::vstore_to_str;
|
||||
import util::ppaux::ty_to_str;
|
||||
import util::ppaux::ty_constr_to_str;
|
||||
import syntax::print::pprust::*;
|
||||
@ -105,7 +106,7 @@ export ty_fn_args;
|
||||
export type_constr;
|
||||
export kind, kind_sendable, kind_copyable, kind_noncopyable;
|
||||
export kind_can_be_copied, kind_can_be_sent, proto_kind, kind_lteq, type_kind;
|
||||
export type_err;
|
||||
export type_err, terr_vstore_kind;
|
||||
export type_err_to_str;
|
||||
export type_needs_drop;
|
||||
export type_allows_implicit_copy;
|
||||
@ -328,6 +329,10 @@ type constr_general<ARG> = spanned<constr_general_<ARG, def_id>>;
|
||||
type type_constr = constr_general<@path>;
|
||||
type constr = constr_general<uint>;
|
||||
|
||||
enum terr_vstore_kind {
|
||||
terr_vec, terr_str
|
||||
}
|
||||
|
||||
// Data structures used in type unification
|
||||
enum type_err {
|
||||
terr_mismatch,
|
||||
@ -348,6 +353,7 @@ enum type_err {
|
||||
terr_constr_len(uint, uint),
|
||||
terr_constr_mismatch(@type_constr, @type_constr),
|
||||
terr_regions_differ(region, region),
|
||||
terr_vstores_differ(terr_vstore_kind, vstore, vstore),
|
||||
terr_in_field(@type_err, str),
|
||||
terr_sorts(t, t)
|
||||
}
|
||||
@ -1976,6 +1982,10 @@ fn ty_sort_str(cx: ctxt, t: t) -> str {
|
||||
}
|
||||
|
||||
fn type_err_to_str(cx: ctxt, err: type_err) -> str {
|
||||
fn terr_vstore_kind_to_str(k: terr_vstore_kind) -> str {
|
||||
alt k { terr_vec { "[]" } terr_str { "str" } }
|
||||
}
|
||||
|
||||
alt err {
|
||||
terr_mismatch { ret "types differ"; }
|
||||
terr_ret_style_mismatch(expect, actual) {
|
||||
@ -2038,6 +2048,12 @@ fn type_err_to_str(cx: ctxt, err: type_err) -> str {
|
||||
region_to_str(cx, subregion),
|
||||
region_to_str(cx, superregion));
|
||||
}
|
||||
terr_vstores_differ(k, e_vs, a_vs) {
|
||||
ret #fmt("%s storage differs: expected %s but found %s",
|
||||
terr_vstore_kind_to_str(k),
|
||||
vstore_to_str(cx, e_vs),
|
||||
vstore_to_str(cx, a_vs));
|
||||
}
|
||||
terr_in_field(err, fname) {
|
||||
ret #fmt("in field `%s`, %s", fname, type_err_to_str(cx, *err));
|
||||
}
|
||||
|
30
src/test/compile-fail/estr-subtyping.rs
Normal file
30
src/test/compile-fail/estr-subtyping.rs
Normal file
@ -0,0 +1,30 @@
|
||||
fn wants_box(x: str/@) { }
|
||||
fn wants_uniq(x: str/~) { }
|
||||
fn wants_three(x: str/3) { }
|
||||
|
||||
fn has_box(x: str/@) {
|
||||
wants_box(x);
|
||||
wants_uniq(x); //! ERROR str storage differs: expected ~ but found @
|
||||
wants_three(x); //! ERROR str storage differs: expected 3 but found @
|
||||
}
|
||||
|
||||
fn has_uniq(x: str/~) {
|
||||
wants_box(x); //! ERROR str storage differs: expected @ but found ~
|
||||
wants_uniq(x);
|
||||
wants_three(x); //! ERROR str storage differs: expected 3 but found ~
|
||||
}
|
||||
|
||||
fn has_three(x: str/3) {
|
||||
wants_box(x); //! ERROR str storage differs: expected @ but found 3
|
||||
wants_uniq(x); //! ERROR str storage differs: expected ~ but found 3
|
||||
wants_three(x);
|
||||
}
|
||||
|
||||
fn has_four(x: str/4) {
|
||||
wants_box(x); //! ERROR str storage differs: expected @ but found 4
|
||||
wants_uniq(x); //! ERROR str storage differs: expected ~ but found 4
|
||||
wants_three(x); //! ERROR str storage differs: expected 3 but found 4
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
30
src/test/compile-fail/evec-subtyping.rs
Normal file
30
src/test/compile-fail/evec-subtyping.rs
Normal file
@ -0,0 +1,30 @@
|
||||
fn wants_box(x: [uint]/@) { }
|
||||
fn wants_uniq(x: [uint]/~) { }
|
||||
fn wants_three(x: [uint]/3) { }
|
||||
|
||||
fn has_box(x: [uint]/@) {
|
||||
wants_box(x);
|
||||
wants_uniq(x); //! ERROR [] storage differs: expected ~ but found @
|
||||
wants_three(x); //! ERROR [] storage differs: expected 3 but found @
|
||||
}
|
||||
|
||||
fn has_uniq(x: [uint]/~) {
|
||||
wants_box(x); //! ERROR [] storage differs: expected @ but found ~
|
||||
wants_uniq(x);
|
||||
wants_three(x); //! ERROR [] storage differs: expected 3 but found ~
|
||||
}
|
||||
|
||||
fn has_three(x: [uint]/3) {
|
||||
wants_box(x); //! ERROR [] storage differs: expected @ but found 3
|
||||
wants_uniq(x); //! ERROR [] storage differs: expected ~ but found 3
|
||||
wants_three(x);
|
||||
}
|
||||
|
||||
fn has_four(x: [uint]/4) {
|
||||
wants_box(x); //! ERROR [] storage differs: expected @ but found 4
|
||||
wants_uniq(x); //! ERROR [] storage differs: expected ~ but found 4
|
||||
wants_three(x); //! ERROR [] storage differs: expected 3 but found 4
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
Loading…
Reference in New Issue
Block a user