"disallowed operator in constant expression");
ret;
}
- expr_cast(_, _) { }
expr_lit(@{node: lit_str(_), _}) {
sess.span_err(e.span,
"string constants are not supported");
}
else { ret lval_to_dps(bcx, a, dest); }
}
- ast::expr_cast(val, _) {
- alt tcx.cast_map.find(e.id) {
- some(ty::triv_cast.) { ret trans_expr(bcx, val, dest); }
- _ { ret trans_cast(bcx, val, e.id, dest); }
- }
- }
+ ast::expr_cast(val, _) { ret trans_cast(bcx, val, e.id, dest); }
ast::expr_anon_obj(anon_obj) {
ret trans_anon_obj(bcx, e.span, anon_obj, e.id, dest);
}
// that is_call_expr(ex) -- but we don't support that
// yet
// FIXME
- check (ast_util::is_tail_call_expr(ex));
+ check (ast_util::is_call_expr(ex));
ret trans_be(bcx, ex);
}
ast::expr_fail(expr) {
fn build_return(bcx: @block_ctxt) { Br(bcx, bcx_fcx(bcx).llreturn); }
// fn trans_be(cx: &@block_ctxt, e: &@ast::expr) -> result {
-fn trans_be(cx: @block_ctxt, e: @ast::expr) :
-ast_util::is_tail_call_expr(e) ->
+fn trans_be(cx: @block_ctxt, e: @ast::expr) : ast_util::is_call_expr(e) ->
@block_ctxt {
// FIXME: Turn this into a real tail call once
// calling convention issues are settled
// that does so later on?
fn trans_const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
alt e.node {
- ast::expr_cast(e1, _) {
- alt ccx_tcx(cx).cast_map.find(e.id) {
- some(ty::triv_cast.) { trans_const_expr(cx, e1) }
- _ {
- cx.sess.span_err(e.span,
- "non-trivial cast in constant expression");
- fail;
- }
- }
- }
ast::expr_lit(lit) { ret trans_crate_lit(cx, *lit); }
ast::expr_binary(b, e1, e2) {
let te1 = trans_const_expr(cx, e1);
export bind_params_in_type;
export block_ty;
export constr;
-export cast_type;
export constr_general;
export constr_table;
export count_ty_params;
export t;
export tag_variants;
export tag_variant_with_id;
-export triv_cast;
-export triv_eq_ty;
export ty_param_substs_opt_and_ty;
export ty_param_kinds_and_ty;
export ty_native_fn;
export ty_ptr;
export ty_rec;
export ty_tag;
-export ty_to_machine_ty;
export ty_tup;
export ty_type;
export ty_send_type;
type tag_var_cache =
@smallintmap::smallintmap<@mutable [variant_info]>;
-tag cast_type {
- /* cast may be ignored after substituting primitive with machine types
- since expr already has the right type */
- triv_cast;
-}
-
type ctxt =
@{ts: @type_store,
sess: session::session,
def_map: resolve::def_map,
- cast_map: hashmap<ast::node_id, cast_type>,
node_types: node_type_table,
items: ast_map::map,
freevars: freevars::freevar_map,
@{ts: ts,
sess: s,
def_map: dm,
- cast_map: ast_util::new_node_hash(),
node_types: ntt,
items: amap,
freevars: freevars,
// the types are interned.
fn eq_ty(&&a: t, &&b: t) -> bool { a == b }
-
-// Convert type to machine type
-// (i.e. replace uint, int, float with target architecture machine types)
-//
-// FIXME somewhat expensive but this should only be called rarely
-fn ty_to_machine_ty(cx: ctxt, ty: t) -> t {
- fn sub_fn(cx: ctxt, uint_ty: t, int_ty: t, float_ty: t, in: t) -> t {
- alt struct(cx, in) {
- ty_uint(ast::ty_u.) { ret uint_ty; }
- ty_int(ast::ty_i.) { ret int_ty; }
- ty_float(ast::ty_f.) { ret float_ty; }
- _ { ret in; }
- }
- }
-
- let cfg = cx.sess.get_targ_cfg();
- let uint_ty = mk_mach_uint(cx, cfg.uint_type);
- let int_ty = mk_mach_int(cx, cfg.int_type);
- let float_ty = mk_mach_float(cx, cfg.float_type);
- let fold_m = fm_general(bind sub_fn(cx, uint_ty, int_ty, float_ty, _));
-
- ret fold_ty(cx, fold_m, ty);
-}
-
-// Two types are trivially equal if they are either
-// equal or if they are equal after substituting all occurences of
-// machine independent primitive types by their machine type equivalents
-// for the current target architecture
-fn triv_eq_ty(cx: ctxt, &&a: t, &&b: t) -> bool {
- let a = alt interner::get(*cx.ts, a).struct
- { ty_named(t, _) { t } _ { a } };
- let b = alt interner::get(*cx.ts, b).struct
- { ty_named(t, _) { t } _ { b } };
- a == b || ty_to_machine_ty(cx, a) == ty_to_machine_ty(cx, b)
-}
-
// Type lookups
fn node_id_to_ty_param_substs_opt_and_ty(cx: ctxt, id: ast::node_id) ->
ty_param_substs_opt_and_ty {
}
ast::expr_be(e) {
// FIXME: prove instead of assert
- assert (ast_util::is_tail_call_expr(e));
+ assert (ast_util::is_call_expr(e));
check_expr_with(fcx, e, fcx.ret_ty);
-
- alt e.node {
- ast::expr_cast(_, _) {
- alt tcx.cast_map.find(e.id) {
- option::some(ty::triv_cast.) { }
- _ { tcx.sess.span_err(expr.span,
- "non-trivial cast of tail-call return value");
- }
- }
- }
- _ { /* regular tail call */ }
- }
-
bot = true;
write::nil_ty(tcx, id);
}
ast::expr_cast(e, t) {
bot = check_expr(fcx, e);
let t_1 = ast_ty_to_ty_crate(fcx.ccx, t);
- let t_e = expr_ty(tcx, e);
+ let t_e = ty::expr_ty(tcx, e);
if ty::type_is_nil(tcx, t_e) {
tcx.sess.span_err(expr.span,
"cast from nil: " +
- ty_to_str(tcx, expr_ty(tcx, e)) + " as " +
+ ty_to_str(tcx, t_e) + " as " +
ty_to_str(tcx, t_1));
}
if ty::type_is_nil(tcx, t_1) {
tcx.sess.span_err(expr.span,
"cast to nil: " +
- ty_to_str(tcx, expr_ty(tcx, e)) + " as " +
+ ty_to_str(tcx, t_e) + " as " +
ty_to_str(tcx, t_1));
}
&& type_is_scalar(fcx, expr.span, t_1)) {
tcx.sess.span_err(expr.span,
"non-scalar cast: " +
- ty_to_str(tcx, expr_ty(tcx, e)) + " as " +
+ ty_to_str(tcx, t_e) + " as " +
ty_to_str(tcx, t_1));
}
-
- // mark as triv_cast for later dropping in trans
- if ty::triv_eq_ty(tcx, t_1, t_e)
- { tcx.cast_map.insert(expr.id, ty::triv_cast); }
-
write::ty_only_fixup(fcx, id, t_1);
}
ast::expr_vec(args, mut) {
-import core::{str, option, int};
-import std::map;
import codemap::span;
import ast::*;
ret {node: t, span: sp};
}
-fn new_node_hash<copy V>() -> map::hashmap<node_id, V> {
- fn node_id_hash(&&i: node_id) -> uint { ret int::hash(i as int); }
- fn node_id_eq(&&a: node_id, &&b: node_id) -> bool
- { ret int::eq(a as int, b as int); }
- ret map::mk_hashmap(node_id_hash, node_id_eq);
-}
-
/* assuming that we're not in macro expansion */
fn mk_sp(lo: uint, hi: uint) -> span {
ret {lo: lo, hi: hi, expanded_from: codemap::os_none};
alt e.node { expr_call(_, _, _) { true } _ { false } }
}
-pure fn is_tail_call_expr(e: @expr) -> bool {
- alt e.node {
- expr_call(_, _, _) { true }
- expr_cast(inner_e, _) { is_call_expr(inner_e) }
- _ { false }
- }
-}
-
fn is_constraint_arg(e: @expr) -> bool {
alt e.node {
expr_lit(_) { ret true; }
let e = parse_expr(p);
// FIXME: Is this the right place for this check?
- if /*check*/ ast_util::is_tail_call_expr(e) {
+ if /*check*/ast_util::is_call_expr(e) {
hi = e.span.hi;
ex = ast::expr_be(e);
} else { p.fatal("Non-call expression in tail call"); }
Returns the arccosine of an angle (measured in rad)
*/
pure fn acos(x: float) -> float
- { be m_float::acos(x as m_float) as float }
+ { ret m_float::acos(x as m_float) as float }
/*
Function: asin
Returns the arcsine of an angle (measured in rad)
*/
pure fn asin(x: float) -> float
- { be m_float::asin(x as m_float) as float }
+ { ret m_float::asin(x as m_float) as float }
/*
Function: atan
Returns the arctangents of an angle (measured in rad)
*/
pure fn atan(x: float) -> float
- { be m_float::atan(x as m_float) as float }
+ { ret m_float::atan(x as m_float) as float }
/*
Returns the arctangent of an angle (measured in rad)
*/
pure fn atan2(y: float, x: float) -> float
- { be m_float::atan2(y as m_float, x as m_float) as float }
+ { ret m_float::atan2(y as m_float, x as m_float) as float }
/*
Function: ceil
Returns the smallest integral value less than or equal to `n`
*/
pure fn ceil(n: float) -> float
- { be m_float::ceil(n as m_float) as float }
+ { ret m_float::ceil(n as m_float) as float }
/*
Function: cos
Returns the cosine of an angle `x` (measured in rad)
*/
pure fn cos(x: float) -> float
- { be m_float::cos(x as m_float) as float }
+ { ret m_float::cos(x as m_float) as float }
/*
Function: cosh
*/
pure fn cosh(x: float) -> float
- { be m_float::cosh(x as m_float) as float }
+ { ret m_float::cosh(x as m_float) as float }
/*
Returns `consts::e` to the power of `n*
*/
pure fn exp(n: float) -> float
- { be m_float::exp(n as m_float) as float }
+ { ret m_float::exp(n as m_float) as float }
/*
Function: abs
Returns the absolute value of `n`
*/
pure fn abs(n: float) -> float
- { be m_float::abs(n as m_float) as float }
+ { ret m_float::abs(n as m_float) as float }
/*
Function: floor
Returns the largest integral value less than or equal to `n`
*/
pure fn floor(n: float) -> float
- { be m_float::floor(n as m_float) as float }
+ { ret m_float::floor(n as m_float) as float }
/*
Function: fmod
Returns the floating-point remainder of `x/y`
*/
pure fn fmod(x: float, y: float) -> float
- { be m_float::fmod(x as m_float, y as m_float) as float }
+ { ret m_float::fmod(x as m_float, y as m_float) as float }
/*
Function: ln
Returns the natural logaritm of `n`
*/
pure fn ln(n: float) -> float
- { be m_float::ln(n as m_float) as float }
+ { ret m_float::ln(n as m_float) as float }
/*
Function: ldexp
Returns `x` multiplied by 2 to the power of `n`
*/
pure fn ldexp(n: float, i: int) -> float
- { be m_float::ldexp(n as m_float, i as c_int) as float }
+ { ret m_float::ldexp(n as m_float, i as c_int) as float }
/*
Function: ln1p
even for very small values of `n`
*/
pure fn ln1p(n: float) -> float
- { be m_float::ln1p(n as m_float) as float }
+ { ret m_float::ln1p(n as m_float) as float }
/*
Function: log10
Returns the logarithm to base 10 of `n`
*/
pure fn log10(n: float) -> float
- { be m_float::log10(n as m_float) as float }
+ { ret m_float::log10(n as m_float) as float }
/*
Function: log2
Returns the logarithm to base 2 of `n`
*/
pure fn log2(n: float) -> float
- { be m_float::log2(n as m_float) as float }
+ { ret m_float::log2(n as m_float) as float }
/*
Function: modf
*/
#[no(warn_trivial_casts)] // FIXME Implement
pure fn modf(n: float, &iptr: float) -> float { unsafe {
- be m_float::modf(n as m_float, ptr::addr_of(iptr) as *m_float) as float
+ ret m_float::modf(n as m_float, ptr::addr_of(iptr) as *m_float) as float
} }
/*
The fractional part of `n`
*/
pure fn frexp(n: float, &exp: c_int) -> float
- { be m_float::frexp(n as m_float, exp) as float }
+ { ret m_float::frexp(n as m_float, exp) as float }
/*
Function: pow
*/
pure fn pow(v: float, e: float) -> float
- { be m_float::pow(v as m_float, e as m_float) as float }
+ { ret m_float::pow(v as m_float, e as m_float) as float }
/*
prevailing rounding mode) in floating-point format
*/
pure fn rint(x: float) -> float
- { be m_float::rint(x as m_float) as float }
+ { ret m_float::rint(x as m_float) as float }
/*
Function: round
cases away from zero, regardless of the current rounding direction.
*/
pure fn round(x: float) -> float
- { be m_float::round(x as m_float) as float }
+ { ret m_float::round(x as m_float) as float }
/*
Function: sin
Returns the sine of an angle `x` (measured in rad)
*/
pure fn sin(x: float) -> float
- { be m_float::sin(x as m_float) as float }
+ { ret m_float::sin(x as m_float) as float }
/*
Function: sinh
Returns the hyperbolic sine of an angle `x` (measured in rad)
*/
pure fn sinh(x: float) -> float
- { be m_float::sinh(x as m_float) as float }
+ { ret m_float::sinh(x as m_float) as float }
/*
Function: sqrt
Returns the square root of `x`
*/
pure fn sqrt(x: float) -> float
- { be m_float::sqrt(x as m_float) as float }
+ { ret m_float::sqrt(x as m_float) as float }
/*
Function: tan
*/
pure fn tan(x: float) -> float
- { be m_float::tan(x as m_float) as float }
+ { ret m_float::tan(x as m_float) as float }
/*
Function: tanh
*/
pure fn tanh(x: float) -> float
- { be m_float::tanh(x as m_float) as float }
+ { ret m_float::tanh(x as m_float) as float }
/*
Function: trunc
*/
pure fn trunc(x: float) -> float
- { be m_float::trunc(x as m_float) as float }
+ { ret m_float::trunc(x as m_float) as float }
//
// Local Variables:
+++ /dev/null
-// error-pattern: non-trivial cast of tail-call return value
-import core::mtypes::*;
-
-fn foo_float() -> m_float { ret 0.0 as m_float; }
-fn bar_float() -> bool { be foo_float() as bool; }
-
-fn foo_int() -> m_int { ret 0 as m_int; }
-fn bar_int() -> bool { be foo_int() as bool; }
-
-fn foo_uint() -> m_uint { ret 0u as m_uint; }
-fn bar_uint() -> bool { be foo_uint() as bool; }
-
-fn main() {
- assert bar_float() == 0.0;
- assert bar_int() == 0.0;
- assert bar_uint() == 0.0;
-}
\ No newline at end of file
+++ /dev/null
-import core::ctypes::*;
-
-import core::mtypes::m_float;
-import core::mtypes::m_int;
-import core::mtypes::m_uint;
-
-fn foo_float() -> m_float { ret 0.0 as m_float; }
-fn bar_float() -> float { be foo_float() as float; }
-
-fn foo_int() -> m_int { ret 0 as m_int; }
-fn bar_int() -> int { be foo_int() as int; }
-
-fn foo_uint() -> m_uint { ret 0u as m_uint; }
-fn bar_uint() -> uint { be foo_uint() as uint; }
-
-fn foo_long() -> long { ret 0 as long; }
-fn bar_long() -> int { be foo_long() as int; }
-
-fn foo_ulong() -> ulong { ret 0u as ulong; }
-fn bar_ulong() -> uint { be foo_uint() as uint; }
-
-fn main() {
- assert bar_float() == 0.0;
- assert bar_int() == 0;
- assert bar_uint() == 0u;
- assert bar_long() == 0;
- assert bar_ulong() == 0u;
-}
\ No newline at end of file
+++ /dev/null
-import core::mtypes::m_int;
-
-// This will be more interesting once there is support
-// for consts that refer to other consts, i.e. math_f64::consts::pi as m_float
-#[cfg(target_arch="x86")]
-const foo: m_int = 0i32 as m_int;
-
-#[cfg(target_arch="x86_64")]
-const foo: m_int = 0i64 as m_int;
-
-fn main() {
- assert foo == 0 as m_int;
-}
\ No newline at end of file