type.get_ident ().locus);
}
+void
+TyTyResolveCompile::visit (const TyTy::OpaqueType &type)
+{
+ translated = error_mark_node;
+}
+
tree
TyTyResolveCompile::create_dyn_obj_record (const TyTy::DynamicObjectType &type)
{
void visit (const TyTy::ProjectionType &) override;
void visit (const TyTy::DynamicObjectType &) override;
void visit (const TyTy::ClosureType &) override;
+ void visit (const TyTy::OpaqueType &) override;
public:
static hashval_t type_hasher (tree type);
case TyTy::PLACEHOLDER:
case TyTy::INFER:
case TyTy::PARAM:
+ case TyTy::OPAQUE:
rust_unreachable ();
}
rust_unreachable ();
case TyTy::PROJECTION: // TODO: DUNNO
case TyTy::CLOSURE: // TODO: DUNNO
case TyTy::DYNAMIC: // TODO: dunno
+ case TyTy::OPAQUE:
return false;
}
rust_unreachable ();
// We shouldn't have inference types here, ever
case TyTy::INFER:
return;
+ case TyTy::OPAQUE:
+ return;
case TyTy::ERROR:
return;
}
void
TypeCheckType::visit (HIR::ParenthesisedType &type)
{
+ // I think this really needs to be a tuple.. but will sort that out when we
+ // fix the parser issue
translated = TypeCheckType::Resolve (type.get_type_in_parens ());
}
translated = new TyTy::ReferenceType (type.get_mappings ().get_hirid (),
TyTy::TyVar (base->get_ref ()),
type.get_mut (), region.value ());
-} // namespace Resolver
+}
void
TypeCheckType::visit (HIR::RawPointerType &type)
translated = lookup->clone ();
}
+void
+TypeCheckType::visit (HIR::ImplTraitType &type)
+{
+ std::vector<TyTy::TypeBoundPredicate> specified_bounds;
+ for (auto &bound : type.get_type_param_bounds ())
+ {
+ if (bound->get_bound_type ()
+ != HIR::TypeParamBound::BoundType::TRAITBOUND)
+ continue;
+
+ HIR::TypeParamBound &b = *bound.get ();
+ HIR::TraitBound &trait_bound = static_cast<HIR::TraitBound &> (b);
+
+ auto binder_pin = context->push_lifetime_binder ();
+ for (auto &lifetime_param : trait_bound.get_for_lifetimes ())
+ {
+ context->intern_and_insert_lifetime (lifetime_param.get_lifetime ());
+ }
+
+ TyTy::TypeBoundPredicate predicate = get_predicate_from_bound (
+ trait_bound.get_path (),
+ tl::nullopt /*this will setup a PLACEHOLDER for self*/);
+
+ if (!predicate.is_error ()
+ && predicate.is_object_safe (true, type.get_locus ()))
+ specified_bounds.push_back (std::move (predicate));
+ }
+
+ translated = new TyTy::OpaqueType (type.get_locus (),
+ type.get_mappings ().get_hirid (),
+ specified_bounds);
+}
+
TyTy::ParamType *
TypeResolveGenericParam::Resolve (HIR::GenericParam ¶m, bool apply_sized)
{
void visit (HIR::NeverType &type) override;
void visit (HIR::TraitObjectType &type) override;
void visit (HIR::ParenthesisedType &type) override;
+ void visit (HIR::ImplTraitType &type) override;
- void visit (HIR::TypePathSegmentFunction &segment) override
- { /* TODO */
- }
- void visit (HIR::TraitBound &bound) override
- { /* TODO */
- }
- void visit (HIR::ImplTraitType &type) override
- { /* TODO */
- }
+ // These dont need to be implemented as they are segments or part of types
+ void visit (HIR::TypePathSegmentFunction &segment) override {}
+ void visit (HIR::TraitBound &bound) override {}
private:
TypeCheckType (HirId id)
{
resolved = type.clone ();
}
+void
+SubstMapperInternal::visit (TyTy::OpaqueType &type)
+{
+ resolved = type.handle_substitions (mappings);
+}
// SubstMapperFromExisting
void visit (TyTy::NeverType &) override { rust_unreachable (); }
void visit (TyTy::DynamicObjectType &) override { rust_unreachable (); }
void visit (TyTy::ClosureType &) override { rust_unreachable (); }
+ void visit (TyTy::OpaqueType &) override { rust_unreachable (); }
private:
SubstMapper (HirId ref, HIR::GenericArgs *generics,
void visit (TyTy::StrType &type) override;
void visit (TyTy::NeverType &type) override;
void visit (TyTy::DynamicObjectType &type) override;
+ void visit (TyTy::OpaqueType &type) override;
private:
SubstMapperInternal (HirId ref, TyTy::SubstitutionArgumentMappings &mappings);
void visit (TyTy::PlaceholderType &) override { rust_unreachable (); }
void visit (TyTy::ProjectionType &) override { rust_unreachable (); }
void visit (TyTy::DynamicObjectType &) override { rust_unreachable (); }
+ void visit (TyTy::OpaqueType &type) override { rust_unreachable (); }
private:
SubstMapperFromExisting (TyTy::BaseType *concrete, TyTy::BaseType *receiver);
void visit (const TyTy::PlaceholderType &) override {}
void visit (const TyTy::ProjectionType &) override {}
void visit (const TyTy::DynamicObjectType &) override {}
+ void visit (const TyTy::OpaqueType &type) override {}
private:
GetUsedSubstArgs ();
case TyTy::NEVER:
case TyTy::PLACEHOLDER:
case TyTy::PROJECTION:
+ case TyTy::OPAQUE:
assemble_builtin_candidate (LangItem::Kind::SIZED);
break;
void visit (ProjectionType &) override { rust_unreachable (); }
void visit (DynamicObjectType &) override { rust_unreachable (); }
void visit (ClosureType &type) override { rust_unreachable (); }
+ void visit (OpaqueType &type) override { rust_unreachable (); }
// tuple-structs
void visit (ADTType &type) override;
}
}
+ virtual void visit (const OpaqueType &type) override
+ {
+ ok = false;
+ if (emit_error_flag)
+ {
+ location_t ref_locus = mappings.lookup_location (type.get_ref ());
+ location_t base_locus
+ = mappings.lookup_location (get_base ()->get_ref ());
+ rich_location r (line_table, ref_locus);
+ r.add_range (base_locus);
+ rust_error_at (r, "expected [%s] got [%s]",
+ get_base ()->as_string ().c_str (),
+ type.as_string ().c_str ());
+ }
+ }
+
protected:
BaseCmp (const BaseType *base, bool emit_errors)
: mappings (Analysis::Mappings::get ()),
const DynamicObjectType *base;
};
+class OpaqueCmp : public BaseCmp
+{
+ using Rust::TyTy::BaseCmp::visit;
+
+public:
+ OpaqueCmp (const OpaqueType *base, bool emit_errors)
+ : BaseCmp (base, emit_errors), base (base)
+ {}
+
+ // TODO
+
+private:
+ const BaseType *get_base () const override { return base; }
+
+ const OpaqueType *base;
+};
+
} // namespace TyTy
} // namespace Rust
{
// TODO
}
+
+ void visit (OpaqueType &type) override {}
};
/** Per crate context for generic type variance analysis. */
virtual void visit (ProjectionType &type) = 0;
virtual void visit (DynamicObjectType &type) = 0;
virtual void visit (ClosureType &type) = 0;
+ virtual void visit (OpaqueType &type) = 0;
};
class TyConstVisitor
virtual void visit (const ProjectionType &type) = 0;
virtual void visit (const DynamicObjectType &type) = 0;
virtual void visit (const ClosureType &type) = 0;
+ virtual void visit (const OpaqueType &type) = 0;
};
} // namespace TyTy
case TypeKind::CLOSURE:
return "Closure";
+ case TypeKind::OPAQUE:
+ return "Opaque";
+
case TypeKind::ERROR:
return "ERROR";
}
case FLOAT:
case USIZE:
case ISIZE:
-
+ case OPAQUE:
case STR:
case DYNAMIC:
case ERROR:
{
x = p->get ();
}
+ // else if (auto p = x->try_as<const OpaqueType> ())
+ // {
+ // auto pr = p->resolve ();
+
+ // rust_debug ("XXXXXX")
+
+ // if (pr == x)
+ // return pr;
+
+ // x = pr;
+ // }
else
{
return x;
case TUPLE:
case PARAM:
case PLACEHOLDER:
+ case OPAQUE:
return false;
case PROJECTION: {
case TUPLE:
case PARAM:
case PLACEHOLDER:
+ case OPAQUE:
return false;
case PROJECTION: {
return is_trait_self;
}
+// OpaqueType
+
+OpaqueType::OpaqueType (location_t locus, HirId ref,
+ std::vector<TypeBoundPredicate> specified_bounds,
+ std::set<HirId> refs)
+ : BaseType (ref, ref, KIND,
+ {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, "impl"),
+ locus},
+ specified_bounds, refs)
+{}
+
+OpaqueType::OpaqueType (location_t locus, HirId ref, HirId ty_ref,
+ std::vector<TypeBoundPredicate> specified_bounds,
+ std::set<HirId> refs)
+ : BaseType (ref, ty_ref, KIND,
+ {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, "impl"),
+ locus},
+ specified_bounds, refs)
+{}
+
+bool
+OpaqueType::can_resolve () const
+{
+ return get_ref () != get_ty_ref ();
+}
+
+void
+OpaqueType::accept_vis (TyVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
+OpaqueType::accept_vis (TyConstVisitor &vis) const
+{
+ vis.visit (*this);
+}
+
+std::string
+OpaqueType::as_string () const
+{
+ return get_name ();
+}
+
+std::string
+OpaqueType::get_name () const
+{
+ return "impl " + raw_bounds_as_name ();
+}
+
+bool
+OpaqueType::can_eq (const BaseType *other, bool emit_errors) const
+{
+ OpaqueCmp r (this, emit_errors);
+ return r.can_eq (other);
+}
+
+BaseType *
+OpaqueType::clone () const
+{
+ return new OpaqueType (ident.locus, get_ref (), get_ty_ref (),
+ get_specified_bounds (), get_combined_refs ());
+}
+
+BaseType *
+OpaqueType::resolve () const
+{
+ TyVar var (get_ty_ref ());
+ BaseType *r = var.get_tyty ();
+
+ while (r->get_kind () == TypeKind::OPAQUE)
+ {
+ OpaqueType *rr = static_cast<OpaqueType *> (r);
+ if (!rr->can_resolve ())
+ break;
+
+ TyVar v (rr->get_ty_ref ());
+ BaseType *n = v.get_tyty ();
+
+ // fix infinite loop
+ if (r == n)
+ break;
+
+ r = n;
+ }
+
+ if (r->get_kind () == TypeKind::OPAQUE && (r->get_ref () == r->get_ty_ref ()))
+ return TyVar (r->get_ty_ref ()).get_tyty ();
+
+ return r;
+}
+
+bool
+OpaqueType::is_equal (const BaseType &other) const
+{
+ auto other2 = static_cast<const OpaqueType &> (other);
+ if (can_resolve () != other2.can_resolve ())
+ return false;
+
+ if (can_resolve ())
+ return resolve ()->can_eq (other2.resolve (), false);
+
+ return bounds_compatible (other, UNDEF_LOCATION, false);
+}
+
+OpaqueType *
+OpaqueType::handle_substitions (SubstitutionArgumentMappings &subst_mappings)
+{
+ // SubstitutionArg arg = SubstitutionArg::error ();
+ // bool ok = subst_mappings.get_argument_for_symbol (this, &arg);
+ // if (!ok || arg.is_error ())
+ // return this;
+
+ // OpaqueType *p = static_cast<OpaqueType *> (clone ());
+ // subst_mappings.on_param_subst (*p, arg);
+
+ // // there are two cases one where we substitute directly to a new PARAM and
+ // // otherwise
+ // if (arg.get_tyty ()->get_kind () == TyTy::TypeKind::PARAM)
+ // {
+ // p->set_ty_ref (arg.get_tyty ()->get_ref ());
+ // return p;
+ // }
+
+ // // this is the new subst that this needs to pass
+ // p->set_ref (mappings.get_next_hir_id ());
+ // p->set_ty_ref (arg.get_tyty ()->get_ref ());
+
+ // return p;
+
+ rust_unreachable ();
+ return nullptr;
+}
+
// StrType
StrType::StrType (HirId ref, std::set<HirId> refs)
PROJECTION,
DYNAMIC,
CLOSURE,
+ OPAQUE,
// there are more to add...
ERROR
};
HIR::GenericParam ¶m;
};
+class OpaqueType : public BaseType
+{
+public:
+ static constexpr auto KIND = TypeKind::OPAQUE;
+
+ OpaqueType (location_t locus, HirId ref,
+ std::vector<TypeBoundPredicate> specified_bounds,
+ std::set<HirId> refs = std::set<HirId> ());
+
+ OpaqueType (location_t locus, HirId ref, HirId ty_ref,
+ std::vector<TypeBoundPredicate> specified_bounds,
+ std::set<HirId> refs = std::set<HirId> ());
+
+ void accept_vis (TyVisitor &vis) override;
+ void accept_vis (TyConstVisitor &vis) const override;
+
+ std::string as_string () const override;
+
+ bool can_eq (const BaseType *other, bool emit_errors) const override final;
+
+ BaseType *clone () const final override;
+
+ bool can_resolve () const;
+
+ BaseType *resolve () const;
+
+ std::string get_name () const override final;
+
+ bool is_equal (const BaseType &other) const override;
+
+ OpaqueType *handle_substitions (SubstitutionArgumentMappings &mappings);
+};
+
class StructFieldType
{
public:
== TyTy::InferType::GENERAL;
bool expected_is_concrete
= ltype->is_concrete () && !lhs_is_general_infer_var;
- bool rneeds_infer = expected_is_concrete && rgot_param;
+ bool rneeds_infer = expected_is_concrete && (rgot_param);
bool lgot_param = ltype->get_kind () == TyTy::TypeKind::PARAM;
bool rhs_is_infer_var = rtype->get_kind () == TyTy::TypeKind::INFER;
== TyTy::InferType::GENERAL;
bool receiver_is_concrete
= rtype->is_concrete () && !rhs_is_general_infer_var;
- bool lneeds_infer = receiver_is_concrete && lgot_param;
+ bool lneeds_infer = receiver_is_concrete && (lgot_param);
if (rneeds_infer)
{
case TyTy::CLOSURE:
return expect_closure (static_cast<TyTy::ClosureType *> (ltype), rtype);
+ case TyTy::OPAQUE:
+ return expect_opaque (static_cast<TyTy::OpaqueType *> (ltype), rtype);
+
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
case TyTy::PLACEHOLDER:
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
- case TyTy::CLOSURE: {
+ case TyTy::CLOSURE:
+ case TyTy::OPAQUE: {
bool is_valid = (ltype->get_infer_kind ()
== TyTy::InferType::InferTypeKind::GENERAL);
if (is_valid)
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
case TyTy::PROJECTION:
case TyTy::DYNAMIC:
case TyTy::CLOSURE:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
case TyTy::USIZE:
case TyTy::ISIZE:
case TyTy::NEVER:
+ case TyTy::OPAQUE:
if (infer_flag)
return rtype->clone ();
gcc_fallthrough ();
case TyTy::ISIZE:
case TyTy::NEVER:
case TyTy::PLACEHOLDER:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
case TyTy::NEVER:
case TyTy::PLACEHOLDER:
case TyTy::PROJECTION:
+ case TyTy::OPAQUE:
case TyTy::ERROR:
return new TyTy::ErrorType (0);
}
}
break;
+ case TyTy::SLICE:
+ case TyTy::PARAM:
+ case TyTy::POINTER:
+ case TyTy::STR:
+ case TyTy::ADT:
+ case TyTy::REF:
+ case TyTy::ARRAY:
+ case TyTy::FNDEF:
+ case TyTy::FNPTR:
+ case TyTy::TUPLE:
+ case TyTy::BOOL:
+ case TyTy::CHAR:
+ case TyTy::INT:
+ case TyTy::UINT:
+ case TyTy::FLOAT:
+ case TyTy::USIZE:
+ case TyTy::ISIZE:
+ case TyTy::NEVER:
+ case TyTy::PLACEHOLDER:
+ case TyTy::PROJECTION:
+ case TyTy::DYNAMIC:
+ case TyTy::OPAQUE:
+ case TyTy::ERROR:
+ return new TyTy::ErrorType (0);
+ }
+ return new TyTy::ErrorType (0);
+}
+
+TyTy::BaseType *
+UnifyRules::expect_opaque (TyTy::OpaqueType *ltype, TyTy::BaseType *rtype)
+{
+ switch (rtype->get_kind ())
+ {
+ case TyTy::INFER: {
+ TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
+ bool is_valid
+ = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
+ if (is_valid)
+ return ltype->clone ();
+ }
+ break;
+
+ case TyTy::OPAQUE: {
+ auto &type = *static_cast<TyTy::OpaqueType *> (rtype);
+ if (ltype->num_specified_bounds () != type.num_specified_bounds ())
+ {
+ return new TyTy::ErrorType (0);
+ }
+
+ if (!ltype->bounds_compatible (type, locus, true))
+ {
+ return new TyTy::ErrorType (0);
+ }
+
+ return ltype->clone ();
+ }
+ break;
+
+ case TyTy::CLOSURE:
case TyTy::SLICE:
case TyTy::PARAM:
case TyTy::POINTER:
TyTy::BaseType *rtype);
TyTy::BaseType *expect_closure (TyTy::ClosureType *ltype,
TyTy::BaseType *rtype);
+ TyTy::BaseType *expect_opaque (TyTy::OpaqueType *ltype,
+ TyTy::BaseType *rtype);
private:
UnifyRules (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,