TEST(Type, SpecializedObjects) { auto const A = SystemLib::s_IteratorClass; auto const B = SystemLib::s_TraversableClass; EXPECT_TRUE(A->classof(B)); auto const obj = Type::Obj; auto const exactA = obj.specializeExact(A); auto const exactB = obj.specializeExact(B); auto const subA = obj.specialize(A); auto const subB = obj.specialize(B); EXPECT_EQ(exactA.getClass(), A); EXPECT_EQ(subA.getClass(), A); EXPECT_EQ(exactA.getExactClass(), A); EXPECT_EQ(subA.getExactClass(), nullptr); EXPECT_LE(exactA, exactA); EXPECT_LE(subA, subA); EXPECT_LT(exactA, obj); EXPECT_LT(subA, obj); EXPECT_LE(Type::Bottom, subA); EXPECT_LE(Type::Bottom, exactA); EXPECT_LT(exactA, subA); EXPECT_LT(exactA, subB); EXPECT_LT(subA, subB); EXPECT_FALSE(exactA <= exactB); EXPECT_FALSE(subA <= exactB); EXPECT_EQ(exactA & subA, exactA); EXPECT_EQ(subA & exactA, exactA); EXPECT_EQ(exactB & subB, exactB); EXPECT_EQ(subB & exactB, exactB); EXPECT_EQ(Type::Obj, Type::Obj - subA); // conservative EXPECT_EQ(subA, subA - exactA); // conservative }
Type convertToType(RepoAuthType ty) { using T = RepoAuthType::Tag; switch (ty.tag()) { case T::OptBool: return Type::Bool | Type::InitNull; case T::OptInt: return Type::Int | Type::InitNull; case T::OptSStr: return Type::StaticStr | Type::InitNull; case T::OptStr: return Type::Str | Type::InitNull; case T::OptDbl: return Type::Dbl | Type::InitNull; case T::OptRes: return Type::Res | Type::InitNull; case T::OptObj: return Type::Obj | Type::InitNull; case T::Uninit: return Type::Uninit; case T::InitNull: return Type::InitNull; case T::Null: return Type::Null; case T::Bool: return Type::Bool; case T::Int: return Type::Int; case T::Dbl: return Type::Dbl; case T::Res: return Type::Res; case T::SStr: return Type::StaticStr; case T::Str: return Type::Str; case T::Obj: return Type::Obj; case T::Cell: return Type::Cell; case T::Ref: return Type::BoxedCell; case T::InitUnc: return Type::UncountedInit; case T::Unc: return Type::Uncounted; case T::InitCell: return Type::InitCell; case T::InitGen: return Type::Init; case T::Gen: return Type::Gen; // TODO(#4205897): option specialized array types case T::OptArr: return Type::Arr | Type::InitNull; case T::OptSArr: return Type::StaticArr | Type::InitNull; case T::SArr: if (auto const ar = ty.array()) return Type::StaticArr.specialize(ar); return Type::StaticArr; case T::Arr: if (auto const ar = ty.array()) return Type::Arr.specialize(ar); return Type::Arr; case T::SubObj: case T::ExactObj: { auto const base = Type::Obj; if (auto const cls = Unit::lookupUniqueClass(ty.clsName())) { return ty.tag() == T::ExactObj ? base.specializeExact(cls) : base.specialize(cls); } return base; } case T::OptSubObj: case T::OptExactObj: { auto const base = Type::Obj | Type::InitNull; if (auto const cls = Unit::lookupUniqueClass(ty.clsName())) { return ty.tag() == T::OptExactObj ? base.specializeExact(cls) : base.specialize(cls); } return base; } } not_reached(); }