mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-04 04:39:16 +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 ret_styles(r1: ret_style, r2: ret_style) -> cres<ret_style>;
|
||||||
fn contraregions(a: ty::region, b: ty::region) -> cres<ty::region>;
|
fn contraregions(a: ty::region, b: ty::region) -> cres<ty::region>;
|
||||||
fn regions(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
|
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>(
|
fn super_fns<C:combine>(
|
||||||
self: C, a_f: ty::fn_ty, b_f: ty::fn_ty) -> cres<ty::fn_ty> {
|
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(a_mt, vs_a), ty::ty_evec(b_mt, vs_b)) {
|
||||||
ty::ty_evec(b_mt, ty::vstore_slice(b_r))) {
|
self.mts(a_mt, b_mt).chain {|mt|
|
||||||
self.contraregions(a_r, b_r).chain {|r|
|
self.vstores(ty::terr_vec, vs_a, vs_b).chain {|vs|
|
||||||
self.mts(a_mt, b_mt).chain {|mt|
|
ok(ty::mk_evec(tcx, mt, vs))
|
||||||
ok(ty::mk_evec(tcx, mt, ty::vstore_slice(r)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(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))
|
(ty::ty_res(a_id, a_t, a_tps), ty::ty_res(b_id, b_t, b_tps))
|
||||||
if a_id == b_id {
|
if a_id == b_id {
|
||||||
self.tys(a_t, b_t).chain {|t|
|
self.tys(a_t, b_t).chain {|t|
|
||||||
@ -1234,6 +1262,11 @@ impl of combine for sub {
|
|||||||
super_flds(self, a, b)
|
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> {
|
fn modes(a: ast::mode, b: ast::mode) -> cres<ast::mode> {
|
||||||
super_modes(self, a, b)
|
super_modes(self, a, b)
|
||||||
}
|
}
|
||||||
@ -1402,6 +1435,11 @@ impl of combine for lub {
|
|||||||
super_flds(self, a, b)
|
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> {
|
fn modes(a: ast::mode, b: ast::mode) -> cres<ast::mode> {
|
||||||
super_modes(self, a, b)
|
super_modes(self, a, b)
|
||||||
}
|
}
|
||||||
@ -1587,6 +1625,11 @@ impl of combine for glb {
|
|||||||
super_flds(self, a, b)
|
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> {
|
fn modes(a: ast::mode, b: ast::mode) -> cres<ast::mode> {
|
||||||
super_modes(self, a, b)
|
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);
|
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 {
|
e: @ast::expr) -> lval_result {
|
||||||
let bcx = lv.bcx;
|
let bcx = lv.bcx;
|
||||||
if !expr_is_borrowed(bcx, e) { ret lv; }
|
if !expr_is_borrowed(bcx, e) { ret lv; }
|
||||||
|
@ -11,6 +11,7 @@ import syntax::codemap::span;
|
|||||||
import metadata::csearch;
|
import metadata::csearch;
|
||||||
import util::common::*;
|
import util::common::*;
|
||||||
import util::ppaux::region_to_str;
|
import util::ppaux::region_to_str;
|
||||||
|
import util::ppaux::vstore_to_str;
|
||||||
import util::ppaux::ty_to_str;
|
import util::ppaux::ty_to_str;
|
||||||
import util::ppaux::ty_constr_to_str;
|
import util::ppaux::ty_constr_to_str;
|
||||||
import syntax::print::pprust::*;
|
import syntax::print::pprust::*;
|
||||||
@ -105,7 +106,7 @@ export ty_fn_args;
|
|||||||
export type_constr;
|
export type_constr;
|
||||||
export kind, kind_sendable, kind_copyable, kind_noncopyable;
|
export kind, kind_sendable, kind_copyable, kind_noncopyable;
|
||||||
export kind_can_be_copied, kind_can_be_sent, proto_kind, kind_lteq, type_kind;
|
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_err_to_str;
|
||||||
export type_needs_drop;
|
export type_needs_drop;
|
||||||
export type_allows_implicit_copy;
|
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 type_constr = constr_general<@path>;
|
||||||
type constr = constr_general<uint>;
|
type constr = constr_general<uint>;
|
||||||
|
|
||||||
|
enum terr_vstore_kind {
|
||||||
|
terr_vec, terr_str
|
||||||
|
}
|
||||||
|
|
||||||
// Data structures used in type unification
|
// Data structures used in type unification
|
||||||
enum type_err {
|
enum type_err {
|
||||||
terr_mismatch,
|
terr_mismatch,
|
||||||
@ -348,6 +353,7 @@ enum type_err {
|
|||||||
terr_constr_len(uint, uint),
|
terr_constr_len(uint, uint),
|
||||||
terr_constr_mismatch(@type_constr, @type_constr),
|
terr_constr_mismatch(@type_constr, @type_constr),
|
||||||
terr_regions_differ(region, region),
|
terr_regions_differ(region, region),
|
||||||
|
terr_vstores_differ(terr_vstore_kind, vstore, vstore),
|
||||||
terr_in_field(@type_err, str),
|
terr_in_field(@type_err, str),
|
||||||
terr_sorts(t, t)
|
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 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 {
|
alt err {
|
||||||
terr_mismatch { ret "types differ"; }
|
terr_mismatch { ret "types differ"; }
|
||||||
terr_ret_style_mismatch(expect, actual) {
|
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, subregion),
|
||||||
region_to_str(cx, superregion));
|
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) {
|
terr_in_field(err, fname) {
|
||||||
ret #fmt("in field `%s`, %s", fname, type_err_to_str(cx, *err));
|
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