/* * MRustC - Rust Compiler * - By John Hodge (Mutabah/thePowersGang) * * hir_typeck/static.cpp * - Non-inferred type checking */ #pragma once #include #include "common.hpp" #include "impl_ref.hpp" class StaticTraitResolve { public: const ::HIR::Crate& m_crate; ::HIR::GenericParams* m_impl_generics; ::HIR::GenericParams* m_item_generics; ::std::map< ::HIR::TypeRef, ::HIR::TypeRef> m_type_equalities; ::HIR::SimplePath m_lang_Copy; ::HIR::SimplePath m_lang_Drop; ::HIR::SimplePath m_lang_Sized; ::HIR::SimplePath m_lang_Unsize; ::HIR::SimplePath m_lang_Fn; ::HIR::SimplePath m_lang_FnMut; ::HIR::SimplePath m_lang_FnOnce; ::HIR::SimplePath m_lang_Box; ::HIR::SimplePath m_lang_PhantomData; private: mutable ::std::map< ::HIR::TypeRef, bool > m_copy_cache; public: StaticTraitResolve(const ::HIR::Crate& crate): m_crate(crate), m_impl_generics(nullptr), m_item_generics(nullptr) { m_lang_Copy = m_crate.get_lang_item_path_opt("copy"); m_lang_Drop = m_crate.get_lang_item_path_opt("drop"); m_lang_Sized = m_crate.get_lang_item_path_opt("sized"); m_lang_Unsize = m_crate.get_lang_item_path_opt("unsize"); m_lang_Fn = m_crate.get_lang_item_path_opt("fn"); m_lang_FnMut = m_crate.get_lang_item_path_opt("fn_mut"); m_lang_FnOnce = m_crate.get_lang_item_path_opt("fn_once"); m_lang_Box = m_crate.get_lang_item_path_opt("owned_box"); m_lang_PhantomData = m_crate.get_lang_item_path_opt("phantom_data"); prep_indexes(); } private: void prep_indexes(); public: bool has_self() const { return m_impl_generics ? true : false; } const ::HIR::GenericParams& impl_generics() const { static ::HIR::GenericParams empty; return m_impl_generics ? *m_impl_generics : empty; } const ::HIR::GenericParams& item_generics() const { static ::HIR::GenericParams empty; return m_item_generics ? *m_item_generics : empty; } /// \brief State manipulation /// \{ template class NullOnDrop { T*& ptr; public: NullOnDrop(T*& ptr): ptr(ptr) {} ~NullOnDrop() { ptr = nullptr; } }; NullOnDrop< ::HIR::GenericParams> set_impl_generics(::HIR::GenericParams& gps) { assert( !m_impl_generics ); m_impl_generics = &gps; m_type_equalities.clear(); prep_indexes(); return NullOnDrop< ::HIR::GenericParams>(m_impl_generics); } NullOnDrop< ::HIR::GenericParams> set_item_generics(::HIR::GenericParams& gps) { assert( !m_item_generics ); m_item_generics = &gps; m_type_equalities.clear(); prep_indexes(); return NullOnDrop< ::HIR::GenericParams>(m_item_generics); } /// \} /// \brief Lookups /// \{ typedef ::std::function t_cb_find_impl; bool find_impl( const Span& sp, const ::HIR::SimplePath& trait_path, const ::HIR::PathParams& trait_params, const ::HIR::TypeRef& type, t_cb_find_impl found_cb ) const { return this->find_impl(sp, trait_path, &trait_params, type, found_cb); } bool find_impl( const Span& sp, const ::HIR::SimplePath& trait_path, const ::HIR::PathParams* trait_params, const ::HIR::TypeRef& type, t_cb_find_impl found_cb, bool dont_handoff_to_specialised = false ) const; private: bool find_impl__check_bound( const Span& sp, const ::HIR::SimplePath& trait_path, const ::HIR::PathParams* trait_params, const ::HIR::TypeRef& type, t_cb_find_impl found_cb, const ::HIR::GenericBound& bound ) const; bool find_impl__check_crate( const Span& sp, const ::HIR::SimplePath& trait_path, const ::HIR::PathParams* trait_params, const ::HIR::TypeRef& type, t_cb_find_impl found_cb, const ::HIR::TraitImpl& impl ) const; bool find_impl__check_crate_raw( const Span& sp, const ::HIR::SimplePath& des_trait_path, const ::HIR::PathParams* des_trait_params, const ::HIR::TypeRef& des_type, const ::HIR::GenericParams& impl_params_def, const ::HIR::PathParams& impl_trait_params, const ::HIR::TypeRef& impl_type, ::std::function, ::std::vector<::HIR::TypeRef>, ::HIR::Compare)> ) const; ::HIR::Compare check_auto_trait_impl_destructure( const Span& sp, const ::HIR::SimplePath& trait, const ::HIR::PathParams* params_ptr, const ::HIR::TypeRef& type ) const; public: void expand_associated_types(const Span& sp, ::HIR::TypeRef& input) const; bool expand_associated_types_single(const Span& sp, ::HIR::TypeRef& input) const; private: void expand_associated_types_inner(const Span& sp, ::HIR::TypeRef& input) const; bool expand_associated_types__UfcsKnown(const Span& sp, ::HIR::TypeRef& input, bool recurse=true) const; bool replace_equalities(::HIR::TypeRef& input) const; public: /// \} /// Iterate over in-scope bounds (function then top) bool iterate_bounds( ::std::function cb) const; /// Locate a named trait in the provied trait (either itself or as a parent trait) bool find_named_trait_in_trait(const Span& sp, const ::HIR::SimplePath& des, const ::HIR::PathParams& params, const ::HIR::Trait& trait_ptr, const ::HIR::SimplePath& trait_path, const ::HIR::PathParams& pp, const ::HIR::TypeRef& self_type, ::std::function)> callback ) const; /// bool trait_contains_type(const Span& sp, const ::HIR::GenericPath& trait_path, const ::HIR::Trait& trait_ptr, const ::std::string& name, ::HIR::GenericPath& out_path) const; bool iterate_aty_bounds(const Span& sp, const ::HIR::Path::Data::Data_UfcsKnown& pe, ::std::function cb) const; // -------------- // Common bounds // ------------- bool type_is_copy(const Span& sp, const ::HIR::TypeRef& ty) const; bool type_is_sized(const Span& sp, const ::HIR::TypeRef& ty) const; bool can_unsize(const Span& sp, const ::HIR::TypeRef& dst, const ::HIR::TypeRef& src) const; /// Returns `true` if the passed type either implements Drop, or contains a type that implements Drop bool type_needs_drop_glue(const Span& sp, const ::HIR::TypeRef& ty) const; const ::HIR::TypeRef* is_type_owned_box(const ::HIR::TypeRef& ty) const; const ::HIR::TypeRef* is_type_phantom_data(const ::HIR::TypeRef& ty) const; TAGGED_UNION(ValuePtr, NotFound, (NotFound, struct{}), (Constant, const ::HIR::Constant*), (Static, const ::HIR::Static*), (Function, const ::HIR::Function*) ); /// `signature_only` - Returns a pointer to an item with the correct signature, not the actual implementation (faster) ValuePtr get_value(const Span& sp, const ::HIR::Path& p, MonomorphState& out_params, bool signature_only=false) const; };