summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ast/dump.cpp3
-rw-r--r--src/ast/types.cpp4
-rw-r--r--src/coretypes.hpp1
-rw-r--r--src/expand/lang_item.cpp2
-rw-r--r--src/hir/from_ast.cpp3
-rw-r--r--src/hir/hir.cpp122
-rw-r--r--src/hir/hir.hpp1
-rw-r--r--src/hir/type.cpp6
-rw-r--r--src/hir/type.hpp2
-rw-r--r--src/hir_expand/const_eval_full.cpp2
-rw-r--r--src/hir_typeck/common.cpp1
-rw-r--r--src/hir_typeck/expr_cs.cpp49
-rw-r--r--src/hir_typeck/helpers.cpp2
-rw-r--r--src/hir_typeck/impl_ref.cpp16
-rw-r--r--src/hir_typeck/impl_ref.hpp1
-rw-r--r--src/mir/check.cpp2
-rw-r--r--src/mir/cleanup.cpp2
-rw-r--r--src/mir/from_hir.cpp3
-rw-r--r--src/mir/from_hir_match.cpp10
-rw-r--r--src/parse/expr.cpp9
-rw-r--r--src/trans/codegen_c.cpp5
21 files changed, 236 insertions, 10 deletions
diff --git a/src/ast/dump.cpp b/src/ast/dump.cpp
index a875506c..d6bc0aa2 100644
--- a/src/ast/dump.cpp
+++ b/src/ast/dump.cpp
@@ -353,6 +353,7 @@ public:
case CORETYPE_U16:
case CORETYPE_U32:
case CORETYPE_U64:
+ case CORETYPE_U128:
case CORETYPE_UINT:
case CORETYPE_ANY:
m_os << "0x" << ::std::hex << n.m_value << ::std::dec;
@@ -361,9 +362,9 @@ public:
case CORETYPE_I16:
case CORETYPE_I32:
case CORETYPE_I64:
+ case CORETYPE_I128:
case CORETYPE_INT:
m_os << (int64_t)n.m_value;
- //m_os << "0x" << ::std::hex << n.m_value << ::std::dec;
break;
}
}
diff --git a/src/ast/types.cpp b/src/ast/types.cpp
index 21e47b4b..ccd169d7 100644
--- a/src/ast/types.cpp
+++ b/src/ast/types.cpp
@@ -23,6 +23,7 @@ static const struct {
{"char", CORETYPE_CHAR},
{"f32", CORETYPE_F32},
{"f64", CORETYPE_F64},
+ {"i128", CORETYPE_I128},
{"i16", CORETYPE_I16},
{"i32", CORETYPE_I32},
{"i64", CORETYPE_I64},
@@ -30,6 +31,7 @@ static const struct {
{"int", CORETYPE_INT},
{"isize", CORETYPE_INT},
{"str", CORETYPE_STR},
+ {"u128", CORETYPE_U128},
{"u16", CORETYPE_U16},
{"u32", CORETYPE_U32},
{"u64", CORETYPE_U64},
@@ -68,6 +70,8 @@ const char* coretype_name(const eCoreType ct ) {
case CORETYPE_I32: return "i32";
case CORETYPE_U64: return "u64";
case CORETYPE_I64: return "i64";
+ case CORETYPE_U128: return "u128";
+ case CORETYPE_I128: return "i128";
case CORETYPE_F32: return "f32";
case CORETYPE_F64: return "f64";
}
diff --git a/src/coretypes.hpp b/src/coretypes.hpp
index cfab82c1..67e32f79 100644
--- a/src/coretypes.hpp
+++ b/src/coretypes.hpp
@@ -12,6 +12,7 @@ enum eCoreType
CORETYPE_U16, CORETYPE_I16,
CORETYPE_U32, CORETYPE_I32,
CORETYPE_U64, CORETYPE_I64,
+ CORETYPE_U128, CORETYPE_I128,
CORETYPE_F32,
CORETYPE_F64,
};
diff --git a/src/expand/lang_item.cpp b/src/expand/lang_item.cpp
index 83637bf6..8454aceb 100644
--- a/src/expand/lang_item.cpp
+++ b/src/expand/lang_item.cpp
@@ -157,6 +157,8 @@ public:
else if( name == "u32" ) {}
else if( name == "i64" ) {}
else if( name == "u64" ) {}
+ else if( name == "i128" ) {}
+ else if( name == "u128" ) {}
else if( name == "isize" ) {}
else if( name == "usize" ) {}
else if( name == "const_ptr" ) {}
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp
index e3691f16..b80759ff 100644
--- a/src/hir/from_ast.cpp
+++ b/src/hir/from_ast.cpp
@@ -664,6 +664,9 @@
case CORETYPE_I64: return ::HIR::TypeRef( ::HIR::CoreType::I64 );
case CORETYPE_U64: return ::HIR::TypeRef( ::HIR::CoreType::U64 );
+ case CORETYPE_I128: return ::HIR::TypeRef( ::HIR::CoreType::I128 );
+ case CORETYPE_U128: return ::HIR::TypeRef( ::HIR::CoreType::U128 );
+
case CORETYPE_INT: return ::HIR::TypeRef( ::HIR::CoreType::Isize );
case CORETYPE_UINT: return ::HIR::TypeRef( ::HIR::CoreType::Usize );
case CORETYPE_ANY:
diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp
index 7f4df952..f5d75101 100644
--- a/src/hir/hir.cpp
+++ b/src/hir/hir.cpp
@@ -471,6 +471,7 @@ namespace {
}
// TODO: Add traits from `Self: Foo` bounds?
+ // TODO: Move associated types to the source trait.
}
::std::vector< ::HIR::GenericBound> flatten_bounds(const ::std::vector<::HIR::GenericBound>& bounds)
{
@@ -493,6 +494,7 @@ namespace {
)
)
}
+ ::std::sort(rv.begin(), rv.end(), [](const auto& a, const auto& b){ return ::ord(a,b) == OrdLess; });
return rv;
}
}
@@ -519,8 +521,6 @@ bool ::HIR::TraitImpl::more_specific_than(const ::HIR::TraitImpl& other) const
// TODO: Cache these lists (calculate after outer typecheck?)
auto bounds_t = flatten_bounds(m_params.m_bounds);
auto bounds_o = flatten_bounds(other.m_params.m_bounds);
- ::std::sort(bounds_t.begin(), bounds_t.end(), [](const auto& a, const auto& b){ return ::ord(a,b) == OrdLess; });
- ::std::sort(bounds_o.begin(), bounds_o.end(), [](const auto& a, const auto& b){ return ::ord(a,b) == OrdLess; });
DEBUG("bounds_t = " << bounds_t);
DEBUG("bounds_o = " << bounds_o);
@@ -589,6 +589,124 @@ bool ::HIR::TraitImpl::more_specific_than(const ::HIR::TraitImpl& other) const
}
}
+// Returns `true` if the two impls overlap in the types they will accept
+bool ::HIR::TraitImpl::overlaps_with(const ::HIR::TraitImpl& other) const
+{
+ struct H {
+ static bool types_overlap(const ::HIR::PathParams& a, const ::HIR::PathParams& b)
+ {
+ for(unsigned int i = 0; i < ::std::min(a.m_types.size(), b.m_types.size()); i ++)
+ {
+ if( ! H::types_overlap(a.m_types[i], b.m_types[i]) )
+ return false;
+ }
+ return true;
+ }
+ static bool types_overlap(const ::HIR::TypeRef& a, const ::HIR::TypeRef& b)
+ {
+ static Span sp;
+ if( a.m_data.is_Generic() || b.m_data.is_Generic() )
+ return true;
+ // TODO: Unbound/Opaque paths?
+ if( a.m_data.tag() != b.m_data.tag() )
+ return false;
+ TU_MATCHA( (a.m_data, b.m_data), (ae, be),
+ (Generic,
+ ),
+ (Infer,
+ ),
+ (Diverge,
+ ),
+ (Closure,
+ BUG(sp, "Hit closure");
+ ),
+ (Primitive,
+ if( ae != be )
+ return false;
+ ),
+ (Path,
+ if( ae.path.m_data.tag() != be.path.m_data.tag() )
+ return false;
+ TU_MATCHA( (ae.path.m_data, be.path.m_data), (ape, bpe),
+ (Generic,
+ if( ape.m_path != bpe.m_path )
+ return false;
+ return H::types_overlap(ape.m_params, bpe.m_params);
+ ),
+ (UfcsUnknown,
+ ),
+ (UfcsKnown,
+ ),
+ (UfcsInherent,
+ )
+ )
+ TODO(sp, "Path - " << ae.path << " and " << be.path);
+ ),
+ (TraitObject,
+ if( ae.m_trait.m_path != be.m_trait.m_path )
+ return false;
+ TODO(sp, "TraitObject - " << a << " and " << b);
+ ),
+ (ErasedType,
+ TODO(sp, "ErasedType - " << a);
+ ),
+ (Function,
+ if( ae.is_unsafe != be.is_unsafe )
+ return false;
+ if( ae.m_abi != be.m_abi )
+ return false;
+ if( ae.m_arg_types.size() != be.m_arg_types.size() )
+ return false;
+ for(unsigned int i = 0; i < ae.m_arg_types.size(); i ++)
+ {
+ if( ! H::types_overlap(ae.m_arg_types[i], be.m_arg_types[i]) )
+ return false;
+ }
+ ),
+ (Tuple,
+ if( ae.size() != be.size() )
+ return false;
+ for(unsigned int i = 0; i < ae.size(); i ++)
+ {
+ if( ! H::types_overlap(ae[i], be[i]) )
+ return false;
+ }
+ ),
+ (Slice,
+ return H::types_overlap( *ae.inner, *be.inner );
+ ),
+ (Array,
+ if( ae.size_val != be.size_val )
+ return false;
+ return H::types_overlap( *ae.inner, *be.inner );
+ ),
+ (Pointer,
+ if( ae.type != be.type )
+ return false;
+ return H::types_overlap( *ae.inner, *be.inner );
+ ),
+ (Borrow,
+ if( ae.type != be.type )
+ return false;
+ return H::types_overlap( *ae.inner, *be.inner );
+ )
+ )
+ return true;
+ }
+ };
+
+ // 1. Are the impl types of the same form (or is one generic)
+ if( ! H::types_overlap(this->m_type, other.m_type) )
+ return false;
+ if( ! H::types_overlap(this->m_trait_args, other.m_trait_args) )
+ return false;
+
+ return this->m_type == other.m_type && this->m_trait_args == other.m_trait_args;
+
+ // TODO: Detect `impl<T> Foo<T> for Bar<T>` vs `impl<T> Foo<&T> for Bar<T>`
+ // > Create values for impl params from the type, then check if the trait params are compatible
+ return true;
+}
const ::HIR::SimplePath& ::HIR::Crate::get_lang_item_path(const Span& sp, const char* name) const
diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp
index 76e6cf81..66f4babc 100644
--- a/src/hir/hir.hpp
+++ b/src/hir/hir.hpp
@@ -383,6 +383,7 @@ public:
}
bool more_specific_than(const TraitImpl& x) const;
+ bool overlaps_with(const TraitImpl& other) const;
};
class MarkerImpl
diff --git a/src/hir/type.cpp b/src/hir/type.cpp
index f2709a90..039af5a5 100644
--- a/src/hir/type.cpp
+++ b/src/hir/type.cpp
@@ -31,6 +31,8 @@ namespace HIR {
case CoreType::I32: return os << "i32";
case CoreType::U64: return os << "u64";
case CoreType::I64: return os << "i64";
+ case CoreType::U128: return os << "u128";
+ case CoreType::I128: return os << "i128";
case CoreType::F32: return os << "f32";
case CoreType::F64: return os << "f64";
@@ -508,6 +510,7 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x
case ::HIR::CoreType::I16: case ::HIR::CoreType::U16:
case ::HIR::CoreType::I32: case ::HIR::CoreType::U32:
case ::HIR::CoreType::I64: case ::HIR::CoreType::U64:
+ case ::HIR::CoreType::I128: case ::HIR::CoreType::U128:
case ::HIR::CoreType::Isize: case ::HIR::CoreType::Usize:
return Compare::Fuzzy;
//return true;
@@ -553,6 +556,7 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x
case ::HIR::CoreType::I16: case ::HIR::CoreType::U16:
case ::HIR::CoreType::I32: case ::HIR::CoreType::U32:
case ::HIR::CoreType::I64: case ::HIR::CoreType::U64:
+ case ::HIR::CoreType::I128: case ::HIR::CoreType::U128:
case ::HIR::CoreType::Isize: case ::HIR::CoreType::Usize:
return Compare::Fuzzy;
default:
@@ -880,6 +884,7 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x
case ::HIR::CoreType::I16: case ::HIR::CoreType::U16:
case ::HIR::CoreType::I32: case ::HIR::CoreType::U32:
case ::HIR::CoreType::I64: case ::HIR::CoreType::U64:
+ case ::HIR::CoreType::I128: case ::HIR::CoreType::U128:
case ::HIR::CoreType::Isize: case ::HIR::CoreType::Usize:
return Compare::Fuzzy;
default:
@@ -950,6 +955,7 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x
case ::HIR::CoreType::I16: case ::HIR::CoreType::U16:
case ::HIR::CoreType::I32: case ::HIR::CoreType::U32:
case ::HIR::CoreType::I64: case ::HIR::CoreType::U64:
+ case ::HIR::CoreType::I128: case ::HIR::CoreType::U128:
case ::HIR::CoreType::Isize: case ::HIR::CoreType::Usize:
return Compare::Fuzzy;
default:
diff --git a/src/hir/type.hpp b/src/hir/type.hpp
index adb4e82c..aaf79359 100644
--- a/src/hir/type.hpp
+++ b/src/hir/type.hpp
@@ -38,6 +38,7 @@ enum class CoreType
U16, I16,
U32, I32,
U64, I64,
+ U128, I128,
F32, F64,
@@ -53,6 +54,7 @@ static inline bool is_integer(const CoreType& v) {
case CoreType::U16: case CoreType::I16:
case CoreType::U32: case CoreType::I32:
case CoreType::U64: case CoreType::I64:
+ case CoreType::U128: case CoreType::I128:
return true;
default:
return false;
diff --git a/src/hir_expand/const_eval_full.cpp b/src/hir_expand/const_eval_full.cpp
index cb420b5a..6e493aea 100644
--- a/src/hir_expand/const_eval_full.cpp
+++ b/src/hir_expand/const_eval_full.cpp
@@ -537,6 +537,8 @@ namespace {
case ::HIR::CoreType::I64: val = cast_to_int(true , 64); break;
case ::HIR::CoreType::U64: val = cast_to_int(false, 64); break;
+ case ::HIR::CoreType::I128: val = cast_to_int(true , 64); break;
+ case ::HIR::CoreType::U128: val = cast_to_int(false, 64); break;
case ::HIR::CoreType::Isize: val = cast_to_int(true , 64); break;
case ::HIR::CoreType::Usize: val = cast_to_int(false, 64); break;
diff --git a/src/hir_typeck/common.cpp b/src/hir_typeck/common.cpp
index 96508345..e78ed21b 100644
--- a/src/hir_typeck/common.cpp
+++ b/src/hir_typeck/common.cpp
@@ -414,6 +414,7 @@ void check_type_class_primitive(const Span& sp, const ::HIR::TypeRef& type, ::HI
case ::HIR::CoreType::I16: case ::HIR::CoreType::U16:
case ::HIR::CoreType::I32: case ::HIR::CoreType::U32:
case ::HIR::CoreType::I64: case ::HIR::CoreType::U64:
+ case ::HIR::CoreType::I128: case ::HIR::CoreType::U128:
case ::HIR::CoreType::Isize: case ::HIR::CoreType::Usize:
break;
default:
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 65e759bb..bc82072c 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -5024,7 +5024,7 @@ namespace {
if( out_ty_o == ::HIR::TypeRef() )
{
//BUG(sp, "Getting associated type '" << v.name << "' which isn't in " << v.trait << " (" << ty << ")");
- out_ty_o = ::HIR::TypeRef( ::HIR::Path(::HIR::Path( v.impl_ty.clone(), ::HIR::GenericPath(v.trait, v.params.clone()), v.name, ::HIR::PathParams() )) );
+ out_ty_o = ::HIR::TypeRef(::HIR::Path( v.impl_ty.clone(), ::HIR::GenericPath(v.trait, v.params.clone()), v.name, ::HIR::PathParams() ));
}
out_ty_o = context.m_resolve.expand_associated_types(sp, mv$(out_ty_o));
@@ -5042,7 +5042,6 @@ namespace {
// if solid or fuzzy, leave as-is
output_type = mv$( out_ty_o );
}
- count += 1;
if( cmp == ::HIR::Compare::Equal ) {
// NOTE: Sometimes equal can be returned when it's not 100% equal (TODO)
// - Equate the types
@@ -5055,6 +5054,7 @@ namespace {
return true;
}
else {
+ count += 1;
DEBUG("- (possible) " << impl);
if( possible_impl_ty == ::HIR::TypeRef() ) {
@@ -5062,6 +5062,35 @@ namespace {
possible_params = impl.get_trait_params();
best_impl = mv$(impl);
}
+ // TODO: If there is an existing impl, determine if this is part of the same specialisation tree
+ // - If more specific, replace. If less, ignore.
+ #if 1
+ // NOTE: `overlaps_with` (should be) reflective
+ else if( impl.overlaps_with(best_impl) )
+ {
+ DEBUG("- overlaps with " << best_impl);
+ if( ! impl.more_specific_than(best_impl) )
+ {
+ possible_impl_ty = impl.get_impl_type();
+ possible_params = impl.get_trait_params();
+ best_impl = mv$(impl);
+ count -= 1;
+ }
+ else if( ! best_impl.more_specific_than(impl) )
+ {
+ // Ignore
+ count -= 1;
+ }
+ else
+ {
+ DEBUG("> Neither is more specific. Error?");
+ }
+ }
+ else
+ {
+ // Disjoint impls.
+ }
+ #endif
return false;
}
@@ -5120,6 +5149,16 @@ namespace {
// Only one possible impl
if( v.name != "" ) {
+ // If the output type is just < v.impl_ty as v.trait >::v.name, return false
+ if( output_type.m_data.is_Path() && output_type.m_data.as_Path().path.m_data.is_UfcsKnown() )
+ {
+ const auto& pe = output_type.m_data.as_Path().path.m_data.as_UfcsKnown();
+ if( *pe.type == v.impl_ty && pe.trait.m_path == v.trait && pe.trait.m_params == v.params && pe.item == v.name )
+ {
+ DEBUG("- Attempted recursion, stopping it");
+ return false;
+ }
+ }
context.equate_types(sp, v.left_ty, output_type);
}
assert( possible_impl_ty != ::HIR::TypeRef() );
@@ -5818,16 +5857,12 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR:
rule.impl_ty = context.m_resolve.expand_associated_types(rule.span, mv$(rule.impl_ty));
if( check_associated(context, rule) ) {
- DEBUG("- Consumed associated type rule - " << rule);
- #if 1
+ DEBUG("- Consumed associated type rule " << i << "/" << context.link_assoc.size() << " - " << rule);
if( i != context.link_assoc.size()-1 )
{
context.link_assoc[i] = mv$( context.link_assoc.back() );
}
context.link_assoc.pop_back();
- #else
- context.link_assoc.erase( context.link_assoc.begin() + i );
- #endif
}
else {
context.link_assoc[i] = mv$(rule);
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index 92c084b4..a6543d77 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -1792,6 +1792,8 @@ void TraitResolution::expand_associated_types_inplace__UfcsKnown(const Span& sp,
LList<const ::HIR::TypeRef*> stack(&prev_stack, &m_eat_active_stack.back());
expand_associated_types_inplace(sp, *pe.type, stack);
+ for(auto& ty : pe.trait.m_params.m_types)
+ expand_associated_types_inplace(sp, ty, stack);
// - If it's a closure, then the only trait impls are those generated by typeck
TU_IFLET(::HIR::TypeRef::Data, pe.type->m_data, Closure, te,
diff --git a/src/hir_typeck/impl_ref.cpp b/src/hir_typeck/impl_ref.cpp
index 73472c16..81f018b4 100644
--- a/src/hir_typeck/impl_ref.cpp
+++ b/src/hir_typeck/impl_ref.cpp
@@ -40,6 +40,22 @@ bool ImplRef::more_specific_than(const ImplRef& other) const
)
throw "";
}
+bool ImplRef::overlaps_with(const ImplRef& other) const
+{
+ if( this->m_data.tag() != other.m_data.tag() )
+ return false;
+ TU_MATCH(Data, (this->m_data, other.m_data), (te, oe),
+ (TraitImpl,
+ if( te.impl != nullptr && oe.impl != nullptr )
+ return te.impl->overlaps_with( *oe.impl );
+ ),
+ (BoundedPtr,
+ ),
+ (Bounded,
+ )
+ )
+ return false;
+}
bool ImplRef::type_is_specialisable(const char* name) const
{
TU_MATCH(Data, (this->m_data), (e),
diff --git a/src/hir_typeck/impl_ref.hpp b/src/hir_typeck/impl_ref.hpp
index dc5378fd..ba747346 100644
--- a/src/hir_typeck/impl_ref.hpp
+++ b/src/hir_typeck/impl_ref.hpp
@@ -51,6 +51,7 @@ struct ImplRef
}
bool more_specific_than(const ImplRef& other) const;
+ bool overlaps_with(const ImplRef& other) const;
bool has_magic_params() const {
TU_IFLET(Data, m_data, TraitImpl, e,
diff --git a/src/mir/check.cpp b/src/mir/check.cpp
index 8a350f3c..0dce004e 100644
--- a/src/mir/check.cpp
+++ b/src/mir/check.cpp
@@ -477,6 +477,7 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path
case ::HIR::CoreType::I16:
case ::HIR::CoreType::I32:
case ::HIR::CoreType::I64:
+ case ::HIR::CoreType::I128:
case ::HIR::CoreType::Isize:
good = true;
break;
@@ -496,6 +497,7 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path
case ::HIR::CoreType::U16:
case ::HIR::CoreType::U32:
case ::HIR::CoreType::U64:
+ case ::HIR::CoreType::U128:
case ::HIR::CoreType::Usize:
case ::HIR::CoreType::Char:
good = true;
diff --git a/src/mir/cleanup.cpp b/src/mir/cleanup.cpp
index aded2beb..0cfe2bda 100644
--- a/src/mir/cleanup.cpp
+++ b/src/mir/cleanup.cpp
@@ -315,12 +315,14 @@ const ::HIR::Literal* MIR_Cleanup_GetConstant(const Span& sp, const StaticTraitR
{
case ::HIR::CoreType::Char:
case ::HIR::CoreType::Usize:
+ case ::HIR::CoreType::U128:
case ::HIR::CoreType::U64:
case ::HIR::CoreType::U32:
case ::HIR::CoreType::U16:
case ::HIR::CoreType::U8:
return ::MIR::Constant::make_Uint( lit.as_Integer() );
case ::HIR::CoreType::Isize:
+ case ::HIR::CoreType::I128:
case ::HIR::CoreType::I64:
case ::HIR::CoreType::I32:
case ::HIR::CoreType::I16:
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp
index 6eb91386..6abf3508 100644
--- a/src/mir/from_hir.cpp
+++ b/src/mir/from_hir.cpp
@@ -983,6 +983,7 @@ namespace {
case ::HIR::CoreType::U16:
case ::HIR::CoreType::U32:
case ::HIR::CoreType::U64:
+ case ::HIR::CoreType::U128:
case ::HIR::CoreType::Usize:
BUG(node.span(), "`-` operator on unsigned integer - " << ty_val);
break;
@@ -1611,6 +1612,7 @@ namespace {
case ::HIR::CoreType::U16:
case ::HIR::CoreType::U32:
case ::HIR::CoreType::U64:
+ case ::HIR::CoreType::U128:
case ::HIR::CoreType::Usize:
m_builder.set_result(node.span(), ::MIR::RValue( ::MIR::Constant(e.m_value) ));
break;
@@ -1618,6 +1620,7 @@ namespace {
case ::HIR::CoreType::I16:
case ::HIR::CoreType::I32:
case ::HIR::CoreType::I64:
+ case ::HIR::CoreType::I128:
case ::HIR::CoreType::Isize:
m_builder.set_result(node.span(), ::MIR::RValue( ::MIR::Constant( static_cast<int64_t>(e.m_value) ) ));
break;
diff --git a/src/mir/from_hir_match.cpp b/src/mir/from_hir_match.cpp
index 620fd368..227c46f3 100644
--- a/src/mir/from_hir_match.cpp
+++ b/src/mir/from_hir_match.cpp
@@ -535,6 +535,7 @@ void PatternRulesetBuilder::append_from_lit(const Span& sp, const ::HIR::Literal
case ::HIR::CoreType::U16:
case ::HIR::CoreType::U32:
case ::HIR::CoreType::U64:
+ case ::HIR::CoreType::U128:
case ::HIR::CoreType::Usize: {
ASSERT_BUG(sp, lit.is_Integer(), "Matching integer type with non-integer literal - " << lit);
uint64_t val = lit.as_Integer();
@@ -544,6 +545,7 @@ void PatternRulesetBuilder::append_from_lit(const Span& sp, const ::HIR::Literal
case ::HIR::CoreType::I16:
case ::HIR::CoreType::I32:
case ::HIR::CoreType::I64:
+ case ::HIR::CoreType::I128:
case ::HIR::CoreType::Isize: {
ASSERT_BUG(sp, lit.is_Integer(), "Matching integer type with non-integer literal - " << lit);
int64_t val = static_cast<int64_t>( lit.as_Integer() );
@@ -825,6 +827,7 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa
case ::HIR::CoreType::U16:
case ::HIR::CoreType::U32:
case ::HIR::CoreType::U64:
+ case ::HIR::CoreType::U128:
case ::HIR::CoreType::Usize: {
uint64_t start = H::get_pattern_value_int(sp, pat, pe.start);
uint64_t end = H::get_pattern_value_int(sp, pat, pe.end );
@@ -834,6 +837,7 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa
case ::HIR::CoreType::I16:
case ::HIR::CoreType::I32:
case ::HIR::CoreType::I64:
+ case ::HIR::CoreType::I128:
case ::HIR::CoreType::Isize: {
int64_t start = H::get_pattern_value_int(sp, pat, pe.start);
int64_t end = H::get_pattern_value_int(sp, pat, pe.end );
@@ -865,6 +869,7 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa
case ::HIR::CoreType::U16:
case ::HIR::CoreType::U32:
case ::HIR::CoreType::U64:
+ case ::HIR::CoreType::U128:
case ::HIR::CoreType::Usize: {
uint64_t val = H::get_pattern_value_int(sp, pat, pe.val);
this->push_rule( PatternRule::make_Value( ::MIR::Constant(val) ) );
@@ -873,6 +878,7 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa
case ::HIR::CoreType::I16:
case ::HIR::CoreType::I32:
case ::HIR::CoreType::I64:
+ case ::HIR::CoreType::I128:
case ::HIR::CoreType::Isize: {
int64_t val = H::get_pattern_value_int(sp, pat, pe.val);
this->push_rule( PatternRule::make_Value( ::MIR::Constant(val) ) );
@@ -1547,6 +1553,7 @@ int MIR_LowerHIR_Match_Simple__GeneratePattern(MirBuilder& builder, const Span&
case ::HIR::CoreType::U16:
case ::HIR::CoreType::U32:
case ::HIR::CoreType::U64:
+ case ::HIR::CoreType::U128:
case ::HIR::CoreType::Usize:
TU_MATCH_DEF( PatternRule, (rule), (re),
(
@@ -1569,6 +1576,7 @@ int MIR_LowerHIR_Match_Simple__GeneratePattern(MirBuilder& builder, const Span&
case ::HIR::CoreType::I16:
case ::HIR::CoreType::I32:
case ::HIR::CoreType::I64:
+ case ::HIR::CoreType::I128:
case ::HIR::CoreType::Isize:
TU_MATCH_DEF( PatternRule, (rule), (re),
(
@@ -3160,6 +3168,7 @@ void DecisionTreeGen::generate_tree_code(
case ::HIR::CoreType::U16:
case ::HIR::CoreType::U32:
case ::HIR::CoreType::U64:
+ case ::HIR::CoreType::U128:
case ::HIR::CoreType::Usize:
ASSERT_BUG(sp, node.m_branches.is_Unsigned(), "Tree for unsigned isn't a _Unsigned - node="<<node);
this->generate_branches_Unsigned(sp, node.m_default, node.m_branches.as_Unsigned(), ty, mv$(val), mv$(and_then));
@@ -3168,6 +3177,7 @@ void DecisionTreeGen::generate_tree_code(
case ::HIR::CoreType::I16:
case ::HIR::CoreType::I32:
case ::HIR::CoreType::I64:
+ case ::HIR::CoreType::I128:
case ::HIR::CoreType::Isize:
ASSERT_BUG(sp, node.m_branches.is_Signed(), "Tree for unsigned isn't a _Signed - node="<<node);
this->generate_branches_Signed(sp, node.m_default, node.m_branches.as_Signed(), ty, mv$(val), mv$(and_then));
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp
index eb82bae7..d4edb208 100644
--- a/src/parse/expr.cpp
+++ b/src/parse/expr.cpp
@@ -110,6 +110,15 @@ ExprNodeP Parse_ExprBlockLine_WithItems(TokenStream& lex, ::std::shared_ptr<AST:
GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
}
+ // `union Ident` - contextual keyword
+ if( tok.type() == TOK_IDENT && tok.str() == "union" && lex.lookahead(0) == TOK_IDENT ) {
+ PUTBACK(tok, lex);
+ if( !local_mod ) {
+ local_mod = lex.parse_state().get_current_mod().add_anon();
+ }
+ Parse_Mod_Item(lex, *local_mod, mv$(item_attrs));
+ return ExprNodeP();
+ }
switch(tok.type())
{
// Items:
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp
index 1f54c006..82196d75 100644
--- a/src/trans/codegen_c.cpp
+++ b/src/trans/codegen_c.cpp
@@ -709,6 +709,7 @@ namespace {
m_of << ::std::hex << "0x" << (e & 0xFFFFFFFF) << ::std::dec;
break;
case ::HIR::CoreType::U64:
+ case ::HIR::CoreType::U128:
case ::HIR::CoreType::Usize:
m_of << ::std::hex << "0x" << e << ::std::dec;
break;
@@ -722,6 +723,7 @@ namespace {
m_of << static_cast<int32_t>(e);
break;
case ::HIR::CoreType::I64:
+ case ::HIR::CoreType::I128:
case ::HIR::CoreType::Isize:
m_of << static_cast<int64_t>(e);
break;
@@ -1106,6 +1108,7 @@ namespace {
m_of << ::std::hex << "0x" << (c & 0xFFFFFFFF) << ::std::dec;
break;
case ::HIR::CoreType::U64:
+ case ::HIR::CoreType::U128:
case ::HIR::CoreType::Usize:
m_of << ::std::hex << "0x" << c << ::std::dec;
break;
@@ -2448,6 +2451,8 @@ namespace {
case ::HIR::CoreType::I32: m_of << "int32_t"; break;
case ::HIR::CoreType::U64: m_of << "uint64_t"; break;
case ::HIR::CoreType::I64: m_of << "int64_t"; break;
+ case ::HIR::CoreType::U128: m_of << "uint128_t"; break;
+ case ::HIR::CoreType::I128: m_of << "int128_t"; break;
case ::HIR::CoreType::F32: m_of << "float"; break;
case ::HIR::CoreType::F64: m_of << "double"; break;