// InferType
-InferType::InferType (HirId ref, InferTypeKind infer_kind, Location locus,
- std::set<HirId> refs)
+InferType::InferType (HirId ref, InferTypeKind infer_kind, TypeHint hint,
+ Location locus, std::set<HirId> refs)
: BaseType (ref, ref, TypeKind::INFER,
{Resolver::CanonicalPath::create_empty (), locus}, refs),
- infer_kind (infer_kind)
+ infer_kind (infer_kind), default_hint (hint)
{}
InferType::InferType (HirId ref, HirId ty_ref, InferTypeKind infer_kind,
- Location locus, std::set<HirId> refs)
+ TypeHint hint, Location locus, std::set<HirId> refs)
: BaseType (ref, ty_ref, TypeKind::INFER,
{Resolver::CanonicalPath::create_empty (), locus}, refs),
- infer_kind (infer_kind)
+ infer_kind (infer_kind), default_hint (hint)
{}
InferType::InferTypeKind
InferType *clone
= new InferType (mappings->get_next_hir_id (), get_infer_kind (),
- get_ident ().locus, get_combined_refs ());
+ default_hint, get_ident ().locus, get_combined_refs ());
context->insert_type (Analysis::NodeMapping (mappings->get_current_crate (),
UNKNOWN_NODEID,
{
auto context = Resolver::TypeCheckContext::get ();
bool ok = false;
- switch (infer_kind)
+
+ if (default_hint.kind == TypeKind::ERROR)
{
- case GENERAL:
+ switch (infer_kind)
+ {
+ case GENERAL:
+ return false;
+
+ case INTEGRAL: {
+ ok = context->lookup_builtin ("i32", type);
+ rust_assert (ok);
+ return ok;
+ }
+
+ case FLOAT: {
+ ok = context->lookup_builtin ("f64", type);
+ rust_assert (ok);
+ return ok;
+ }
+ }
+ return false;
+ }
+
+ switch (default_hint.kind)
+ {
+ case ISIZE:
+ ok = context->lookup_builtin ("isize", type);
+ rust_assert (ok);
+ return ok;
+
+ case USIZE:
+ ok = context->lookup_builtin ("usize", type);
+ rust_assert (ok);
+ return ok;
+
+ case INT:
+ switch (default_hint.szhint)
+ {
+ case TypeHint::SizeHint::S8:
+ ok = context->lookup_builtin ("i8", type);
+ rust_assert (ok);
+ return ok;
+
+ case TypeHint::SizeHint::S16:
+ ok = context->lookup_builtin ("i16", type);
+ rust_assert (ok);
+ return ok;
+
+ case TypeHint::SizeHint::S32:
+ ok = context->lookup_builtin ("i32", type);
+ rust_assert (ok);
+ return ok;
+
+ case TypeHint::SizeHint::S64:
+ ok = context->lookup_builtin ("i64", type);
+ rust_assert (ok);
+ return ok;
+
+ case TypeHint::SizeHint::S128:
+ ok = context->lookup_builtin ("i128", type);
+ rust_assert (ok);
+ return ok;
+
+ default:
+ return false;
+ }
+ break;
+
+ case UINT:
+ switch (default_hint.szhint)
+ {
+ case TypeHint::SizeHint::S8:
+ ok = context->lookup_builtin ("u8", type);
+ rust_assert (ok);
+ return ok;
+
+ case TypeHint::SizeHint::S16:
+ ok = context->lookup_builtin ("u16", type);
+ rust_assert (ok);
+ return ok;
+
+ case TypeHint::SizeHint::S32:
+ ok = context->lookup_builtin ("u32", type);
+ rust_assert (ok);
+ return ok;
+
+ case TypeHint::SizeHint::S64:
+ ok = context->lookup_builtin ("u64", type);
+ rust_assert (ok);
+ return ok;
+
+ case TypeHint::SizeHint::S128:
+ ok = context->lookup_builtin ("u128", type);
+ rust_assert (ok);
+ return ok;
+
+ default:
+ return false;
+ }
+ break;
+
+ case TypeKind::FLOAT:
+ switch (default_hint.szhint)
+ {
+ case TypeHint::SizeHint::S32:
+ ok = context->lookup_builtin ("f32", type);
+ rust_assert (ok);
+ return ok;
+
+ case TypeHint::SizeHint::S64:
+ ok = context->lookup_builtin ("f64", type);
+ rust_assert (ok);
+ return ok;
+
+ default:
+ return false;
+ }
+ break;
+
+ default:
return false;
+ }
- case INTEGRAL: {
- ok = context->lookup_builtin ("i32", type);
- rust_assert (ok);
- return ok;
+ return false;
+}
+
+void
+InferType::apply_primitive_type_hint (const BaseType &hint)
+{
+ switch (hint.get_kind ())
+ {
+ case ISIZE:
+ case USIZE:
+ infer_kind = INTEGRAL;
+ default_hint.kind = hint.get_kind ();
+ break;
+
+ case INT: {
+ infer_kind = INTEGRAL;
+ const IntType &i = static_cast<const IntType &> (hint);
+ default_hint.kind = hint.get_kind ();
+ default_hint.shint = TypeHint::SignedHint::SIGNED;
+ switch (i.get_int_kind ())
+ {
+ case IntType::I8:
+ default_hint.szhint = TypeHint::SizeHint::S8;
+ break;
+ case IntType::I16:
+ default_hint.szhint = TypeHint::SizeHint::S16;
+ break;
+ case IntType::I32:
+ default_hint.szhint = TypeHint::SizeHint::S32;
+ break;
+ case IntType::I64:
+ default_hint.szhint = TypeHint::SizeHint::S64;
+ break;
+ case IntType::I128:
+ default_hint.szhint = TypeHint::SizeHint::S128;
+ break;
+ }
+ }
+ break;
+
+ case UINT: {
+ infer_kind = INTEGRAL;
+ const UintType &i = static_cast<const UintType &> (hint);
+ default_hint.kind = hint.get_kind ();
+ default_hint.shint = TypeHint::SignedHint::UNSIGNED;
+ switch (i.get_uint_kind ())
+ {
+ case UintType::U8:
+ default_hint.szhint = TypeHint::SizeHint::S8;
+ break;
+ case UintType::U16:
+ default_hint.szhint = TypeHint::SizeHint::S16;
+ break;
+ case UintType::U32:
+ default_hint.szhint = TypeHint::SizeHint::S32;
+ break;
+ case UintType::U64:
+ default_hint.szhint = TypeHint::SizeHint::S64;
+ break;
+ case UintType::U128:
+ default_hint.szhint = TypeHint::SizeHint::S128;
+ break;
+ }
}
+ break;
+
+ case TypeKind::FLOAT: {
+ infer_kind = FLOAT;
+ default_hint.shint = TypeHint::SignedHint::SIGNED;
+ default_hint.kind = hint.get_kind ();
+ const FloatType &i = static_cast<const FloatType &> (hint);
+ switch (i.get_float_kind ())
+ {
+ case FloatType::F32:
+ default_hint.szhint = TypeHint::SizeHint::S32;
+ break;
- case FLOAT: {
- ok = context->lookup_builtin ("f64", type);
- rust_assert (ok);
- return ok;
+ case FloatType::F64:
+ default_hint.szhint = TypeHint::SizeHint::S64;
+ break;
+ }
}
+ break;
+
+ default:
+ // TODO bool, char, never??
+ break;
}
- return false;
}
// ErrorType
FLOAT
};
- InferType (HirId ref, InferTypeKind infer_kind, Location locus,
- std::set<HirId> refs = std::set<HirId> ());
+ struct TypeHint
+ {
+ enum SignedHint
+ {
+ SIGNED,
+ UNSIGNED,
+
+ UNKNOWN
+ };
+ enum SizeHint
+ {
+ S8,
+ S16,
+ S32,
+ S64,
+ S128,
+ SUNKNOWN
+ };
+
+ TyTy::TypeKind kind;
+ SignedHint shint;
+ SizeHint szhint;
+
+ static TypeHint Default ()
+ {
+ return TypeHint{TypeKind::ERROR, UNKNOWN, SUNKNOWN};
+ }
+ };
- InferType (HirId ref, HirId ty_ref, InferTypeKind infer_kind, Location locus,
+ InferType (HirId ref, InferTypeKind infer_kind, TypeHint hint, Location locus,
std::set<HirId> refs = std::set<HirId> ());
+ InferType (HirId ref, HirId ty_ref, InferTypeKind infer_kind, TypeHint hint,
+ Location locus, std::set<HirId> refs = std::set<HirId> ());
+
void accept_vis (TyVisitor &vis) override;
void accept_vis (TyConstVisitor &vis) const override;
bool default_type (BaseType **type) const;
+ void apply_primitive_type_hint (const TyTy::BaseType &hint);
+
private:
InferTypeKind infer_kind;
+ TypeHint default_hint;
};
class ErrorType : public BaseType
|| (ltype->get_infer_kind ()
== TyTy::InferType::InferTypeKind::INTEGRAL);
if (is_valid)
- return rtype->clone ();
+ {
+ ltype->apply_primitive_type_hint (*rtype);
+ return rtype->clone ();
+ }
}
break;
|| (ltype->get_infer_kind ()
== TyTy::InferType::InferTypeKind::FLOAT);
if (is_valid)
- return rtype->clone ();
+ {
+ ltype->apply_primitive_type_hint (*rtype);
+ return rtype->clone ();
+ }
}
break;
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
if (is_valid)
- return ltype->clone ();
+ {
+ r->apply_primitive_type_hint (*ltype);
+ return ltype->clone ();
+ }
}
break;
bool is_valid
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
if (is_valid)
- return ltype->clone ();
+ {
+ r->apply_primitive_type_hint (*ltype);
+ return ltype->clone ();
+ }
}
break;
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
|| r->get_infer_kind () == TyTy::InferType::InferTypeKind::INTEGRAL;
if (is_valid)
- return ltype->clone ();
+ {
+ r->apply_primitive_type_hint (*ltype);
+ return ltype->clone ();
+ }
}
break;
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
|| r->get_infer_kind () == TyTy::InferType::InferTypeKind::INTEGRAL;
if (is_valid)
- return ltype->clone ();
+ {
+ r->apply_primitive_type_hint (*ltype);
+ return ltype->clone ();
+ }
}
break;
= r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
|| r->get_infer_kind () == TyTy::InferType::InferTypeKind::FLOAT;
if (is_valid)
- return ltype->clone ();
+ {
+ r->apply_primitive_type_hint (*ltype);
+ return ltype->clone ();
+ }
}
break;
bool is_valid
= r->get_infer_kind () != TyTy::InferType::InferTypeKind::FLOAT;
if (is_valid)
- return ltype->clone ();
+ {
+ r->apply_primitive_type_hint (*ltype);
+ return ltype->clone ();
+ }
}
break;
bool is_valid
= r->get_infer_kind () != TyTy::InferType::InferTypeKind::FLOAT;
if (is_valid)
- return ltype->clone ();
+ {
+ r->apply_primitive_type_hint (*ltype);
+ return ltype->clone ();
+ }
}
break;