summaryrefslogtreecommitdiff
path: root/src/hir_typeck
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2017-05-07 12:19:34 +0800
committerJohn Hodge <tpg@ucc.asn.au>2017-05-07 12:19:34 +0800
commit9a94732765756dd89c5b5a4cc89c890befea291c (patch)
tree3b3e6ac64ebac25301bf3c283895aee11d409732 /src/hir_typeck
parent916c8650efcb0224c580bb7d30b358caa67497db (diff)
downloadmrust-9a94732765756dd89c5b5a4cc89c890befea291c.tar.gz
Typecheck Expressions - Fix a few inferrence problems
Diffstat (limited to 'src/hir_typeck')
-rw-r--r--src/hir_typeck/expr_cs.cpp38
-rw-r--r--src/hir_typeck/helpers.cpp2
2 files changed, 24 insertions, 16 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 54c63ccd..acf991dd 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -4266,36 +4266,37 @@ namespace {
DEBUG("-- Deref coercions");
{
::HIR::TypeRef tmp_ty;
- const ::HIR::TypeRef* out_ty = &ty_src;
+ const ::HIR::TypeRef* out_ty_p = &ty_src;
unsigned int count = 0;
::std::vector< ::HIR::TypeRef> types;
- while( (out_ty = context.m_resolve.autoderef(sp, *out_ty, tmp_ty)) )
+ while( (out_ty_p = context.m_resolve.autoderef(sp, *out_ty_p, tmp_ty)) )
{
+ const auto& out_ty = context.m_ivars.get_type(*out_ty_p);
count += 1;
- if( out_ty->m_data.is_Infer() && out_ty->m_data.as_Infer().ty_class == ::HIR::InferClass::None ) {
+ if( out_ty.m_data.is_Infer() && out_ty.m_data.as_Infer().ty_class == ::HIR::InferClass::None ) {
// Hit a _, so can't keep going
break;
}
- types.push_back( out_ty->clone() );
+ types.push_back( out_ty.clone() );
- if( context.m_ivars.types_equal(ty_dst, *out_ty) == false ) {
+ if( context.m_ivars.types_equal(ty_dst, out_ty) == false ) {
// Check equivalence
- if( ty_dst.m_data.tag() == out_ty->m_data.tag() ) {
- TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty_dst.m_data, out_ty->m_data), (d_e, s_e),
+ if( ty_dst.m_data.tag() == out_ty.m_data.tag() ) {
+ TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty_dst.m_data, out_ty.m_data), (d_e, s_e),
(
- if( ty_dst .compare_with_placeholders(sp, *out_ty, context.m_ivars.callback_resolve_infer()) == ::HIR::Compare::Unequal ) {
+ if( ty_dst .compare_with_placeholders(sp, out_ty, context.m_ivars.callback_resolve_infer()) == ::HIR::Compare::Unequal ) {
DEBUG("Same tag, but not fuzzy match");
continue ;
}
- DEBUG("Same tag and fuzzy match - assuming " << ty_dst << " == " << *out_ty);
- context.equate_types(sp, ty_dst, *out_ty);
+ DEBUG("Same tag and fuzzy match - assuming " << ty_dst << " == " << out_ty);
+ context.equate_types(sp, ty_dst, out_ty);
),
(Slice,
// Equate!
- context.equate_types(sp, ty_dst, *out_ty);
+ context.equate_types(sp, ty_dst, out_ty);
// - Fall through
)
)
@@ -4958,10 +4959,16 @@ namespace {
// - If either is an ivar, add the other as a possibility
TU_IFLET( ::HIR::TypeRef::Data, src_ty.m_data, Infer, se,
// TODO: Update for InferClass::Diverge ?
- if( se.ty_class != ::HIR::InferClass::None ) {
- context.equate_types(sp, dst_ty, src_ty);
- }
- else {
+ switch(se.ty_class)
+ {
+ case ::HIR::InferClass::Integer:
+ case ::HIR::InferClass::Float:
+ if( dst_ty.m_data.is_Primitive() ) {
+ context.equate_types(sp, dst_ty, src_ty);
+ }
+ break;
+ case ::HIR::InferClass::None:
+ case ::HIR::InferClass::Diverge:
TU_IFLET(::HIR::TypeRef::Data, dst_ty.m_data, Infer, de,
context.possible_equate_type_unsize_to(se.index, dst_ty);
context.possible_equate_type_unsize_from(de.index, src_ty);
@@ -4984,6 +4991,7 @@ namespace {
// No equivalence added
}
// - Fall through and search for the impl
+ DEBUG("- Unsize, no ivar equivalence");
}
if( v.trait == context.m_crate.get_lang_item_path(sp, "coerce_unsized") )
{
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index 1c7fbd66..60210867 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -3285,7 +3285,7 @@ const ::HIR::TypeRef* TraitResolution::autoderef(const Span& sp, const ::HIR::Ty
const auto& ty = this->m_ivars.get_type(ty_in);
TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Borrow, e,
DEBUG("Deref " << ty << " into " << *e.inner);
- return &*e.inner;
+ return &this->m_ivars.get_type(*e.inner);
)
// TODO: Just doing `*[1,2,3]` doesn't work, but this is needed to allow `[1,2,3].iter()` to work
else TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Array, e,