summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-06-07 23:27:22 +0800
committerJohn Hodge <tpg@mutabah.net>2016-06-07 23:27:22 +0800
commit54a3d0f37aa0c9994a4a39ab5245826119d414de (patch)
tree9cc0eef0a20121e1a055c90d4bf2fd4668a9d670
parentedb10e30f1d35c3b98a6e4683edd603a46661edf (diff)
downloadmrust-54a3d0f37aa0c9994a4a39ab5245826119d414de.tar.gz
HIR Typecheck - Rough handling of casts
-rw-r--r--src/hir/type.cpp51
-rw-r--r--src/hir_typeck/expr.cpp55
2 files changed, 103 insertions, 3 deletions
diff --git a/src/hir/type.cpp b/src/hir/type.cpp
index a3ed3597..dfaf9d1d 100644
--- a/src/hir/type.cpp
+++ b/src/hir/type.cpp
@@ -122,6 +122,19 @@ void ::HIR::TypeRef::fmt(::std::ostream& os) const
)
)
}
+
+namespace {
+ bool path_params_equal(const ::HIR::PathParams& t, const ::HIR::PathParams& x)
+ {
+ if( t.m_types.size() != x.m_types.size() )
+ return false;
+ for( unsigned int i = 0; i < t.m_types.size(); i ++ )
+ if( !(t.m_types[i] == x.m_types[i]) )
+ return false;
+ return true;
+ }
+}
+
bool ::HIR::TypeRef::operator==(const ::HIR::TypeRef& x) const
{
if( m_data.tag() != x.m_data.tag() )
@@ -130,7 +143,7 @@ bool ::HIR::TypeRef::operator==(const ::HIR::TypeRef& x) const
TU_MATCH(::HIR::TypeRef::Data, (m_data, x.m_data), (te, xe),
(Infer,
// TODO: Should comparing inferrence vars be an error?
- return true;
+ return te.index == xe.index;
),
(Diverge,
return true;
@@ -139,7 +152,41 @@ bool ::HIR::TypeRef::operator==(const ::HIR::TypeRef& x) const
return te == xe;
),
(Path,
- assert(!"TODO: Compare path types");
+ if( te.path.m_data.tag() != xe.path.m_data.tag() ) {
+ return false;
+ }
+ TU_MATCH(::HIR::Path::Data, (te.path.m_data, xe.path.m_data), (tpe, xpe),
+ (Generic,
+ if( tpe.m_path != xpe.m_path )
+ return false;
+ return path_params_equal(tpe.m_params, xpe.m_params);
+ ),
+ (UfcsInherent,
+ if( *tpe.type != *xpe.type )
+ return false;
+ if( tpe.item != xpe.item )
+ return false;
+ return path_params_equal(tpe.params, xpe.params);
+ ),
+ (UfcsKnown,
+ if( *tpe.type != *xpe.type )
+ return false;
+ if( tpe.trait.m_path != xpe.trait.m_path )
+ return false;
+ if( !path_params_equal(tpe.trait.m_params, xpe.trait.m_params) )
+ return false;
+ if( tpe.item != xpe.item )
+ return false;
+ return path_params_equal(tpe.params, xpe.params);
+ ),
+ (UfcsUnknown,
+ if( *tpe.type != *xpe.type )
+ return false;
+ if( tpe.item != xpe.item )
+ return false;
+ return path_params_equal(tpe.params, xpe.params);
+ )
+ )
),
(Generic,
return te.name == xe.name && te.binding == xe.binding;
diff --git a/src/hir_typeck/expr.cpp b/src/hir_typeck/expr.cpp
index d076ad49..19dfdda7 100644
--- a/src/hir_typeck/expr.cpp
+++ b/src/hir_typeck/expr.cpp
@@ -2040,7 +2040,60 @@ namespace {
// - Cast: Nothing needs to happen
void visit(::HIR::ExprNode_Cast& node) override
{
- // TODO: Check cast validity?
+ const auto& val_ty = this->context.get_type( node.m_value->m_res_type );
+ const auto& target_ty = this->context.get_type( node.m_res_type );
+ TU_MATCH_DEF(::HIR::TypeRef::Data, (target_ty.m_data), (e),
+ (
+ ERROR(node.span(), E0000, "Invalid cast");
+ ),
+ (Primitive,
+ switch(e)
+ {
+ case ::HIR::CoreType::Char:
+ break;
+ case ::HIR::CoreType::Str:
+ case ::HIR::CoreType::Bool:
+ ERROR(node.span(), E0000, "Invalid cast");
+ break;
+ default:
+ // TODO: Check that the source and destination are integer types.
+ break;
+ }
+ ),
+ (Borrow,
+ // TODO: Actually a coerce - check it
+ ),
+ (Infer,
+ // - wait
+ ),
+ (Pointer,
+ // Valid source:
+ // *<same> <any>
+ // *<other> <same>
+ // &<same> <same>
+ TU_MATCH_DEF(::HIR::TypeRef::Data, (val_ty.m_data), (e2),
+ (
+ ),
+ (Infer,
+ ),
+ (Borrow,
+ if( e.type != e2.type ) {
+ // ERROR
+ }
+ this->context.apply_equality(node.span(), *e2.inner, *e.inner);
+ ),
+ (Pointer,
+ if( e.type != e2.type ) {
+ this->context.apply_equality(node.span(), *e2.inner, *e.inner);
+ }
+ else {
+ // Nothing
+ }
+ )
+ )
+ )
+ )
+ // TODO: Check cast validity and do inferrence
::HIR::ExprVisitorDef::visit(node);
}
// - Index: Look for implementation of the Index trait