diff --git a/cpp/src/semal.cpp b/cpp/src/semal.cpp index e2cd877..d297c90 100644 --- a/cpp/src/semal.cpp +++ b/cpp/src/semal.cpp @@ -548,6 +548,7 @@ namespace semal d.assert_that(std::holds_alternative(payload.rhs_expr->expr), std::format("in a cast, rhs of the cast token \"{}\" must be an identifier, not an expression or anything else.", payload.op.lexeme)); std::string type_name = std::get(payload.rhs_expr->expr).iden; rhs = d.state.get_type_from_name(type_name); + d.assert_that(lhs.is_explicitly_convertible_to(rhs), std::format("cast from \"{}\" to \"{}\" is impossible", lhs.name(), rhs.name())); d.assert_that(!rhs.is_undefined(), std::format("unknown cast destination type \"{}\"", type_name)); // todo: confirm that lhs can actually be casted to rhs. } diff --git a/cpp/src/type.cpp b/cpp/src/type.cpp index 7e41d05..8b1c09d 100644 --- a/cpp/src/type.cpp +++ b/cpp/src/type.cpp @@ -172,6 +172,12 @@ bool type::is_implicitly_convertible_to(const type& rhs) const if(this->is_weak() || rhs.is_weak()) { // weak types are implicitly convertible to a bunch of things. + auto plain_this = this->without_qualifiers(); + if(plain_this == type::from_primitive(primitive_type::i64) && rhs.is_pointer()) + { + // i64 -> any pointer (i.e uintptr_t) + return true; + } if(this->is_integer_type() && rhs.is_integer_type()) { // integer promotion. diff --git a/samples/scratchpad.psy b/samples/scratchpad.psy index 381a635..dc3176b 100644 --- a/samples/scratchpad.psy +++ b/samples/scratchpad.psy @@ -29,7 +29,7 @@ putchar :: (ch : i8) -> u0 := extern; dub :: (val : i64) -> i64 { vvptr : i64&& const; - deref vvptr = (55@i64&); + deref vvptr = (55@u64& weak); vv : f64 weak := 5; vv = 50;