Skip to content

Commit

Permalink
Typecheck Expr - Hacky tweak to TAIT handling, see UpgradeQuirks
Browse files Browse the repository at this point in the history
  • Loading branch information
thepowersgang committed Apr 28, 2024
1 parent 343702e commit 9a6ea45
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 10 deletions.
9 changes: 9 additions & 0 deletions Notes/UpgradeQuirks.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@
- WHY? WHY is Box::new so funky. INTRINSICS EXIST FOR A REASON!
- `Drop for Box` is FINALLY a normal impl!
- `type Foo = impl Trait`
- Not easy, as it has complexities and poor documentation
- `::std::backtrace::lazy_resolve` returns a named erased type, but other parts of that module use that type as an opaque
- The usage sites don't contribute any type information.
- `::rustc_middle::query::erase::{erase,restore}` return/take a named erased type, wrapping/unwrapping it
- Both usages here contribute type information.
- Solution 1: As committed here - do tricky things in type inference
- Solution 2:
- Tag all TAITs with the source function in "Resolve Type Aliases"
- Ensure typecheck of that function is completed during consteval (or even during typecheck)
- `libstd` has a reference to `thread_local!` (well, `thread_local_inner!`) that is used before the `mod sys` that defines `thread_local_inner!`)
- To solve this, need to loop on expand until nothing expands
- That took ages to code.
Expand Down
13 changes: 13 additions & 0 deletions src/hir/type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,19 @@ ::HIR::TypeData_ErasedType_AliasInner::TypeData_ErasedType_AliasInner(const HIR:
, type()
{
}
bool ::HIR::TypeData_ErasedType_AliasInner::is_public_to(const HIR::SimplePath& p) const
{
if( p.m_crate_name != this->path.m_crate_name )
return false;
if( p.m_components.size() < this->path.m_components.size() - 1)
return false;
for(size_t i = 0; i < this->path.m_components.size() - 1; i++) {
if( p.m_components[i] != this->path.m_components[i] ) {
return false;
}
}
return true;
}

void ::HIR::TypeRef::fmt(::std::ostream& os) const
{
Expand Down
2 changes: 2 additions & 0 deletions src/hir/type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class ExternType;
class Struct;
class Union;
class Enum;
class Function;
class ItemPath;
struct ExprNode_Closure;
struct ExprNode_Generator;
Expand Down Expand Up @@ -150,6 +151,7 @@ struct TypeData_ErasedType_AliasInner
HIR::TypeRef type;

TypeData_ErasedType_AliasInner(const HIR::ItemPath& p);
bool is_public_to(const HIR::SimplePath& p) const;
};
TAGGED_UNION(TypeData_ErasedType_Inner, Alias,
(Fcn, struct {
Expand Down
28 changes: 18 additions & 10 deletions src/hir_typeck/expr_cs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1947,14 +1947,20 @@ void Context::equate_types_inner(const Span& sp, const ::HIR::TypeRef& li, const
}
}

#if 0
// If the RHS is an erased type, then expand it
#if 1
if( const auto* et = r_t.data().opt_ErasedType() )
{
if( const auto* ee = et->m_inner.opt_Alias() )
{
if( this->m_erased_type_aliases.count(ee->get()) > 0 ) {
equate_types_inner(sp, l_t, this->m_erased_type_aliases[ee->get()]);
// HACK: Only propagate type information backwards if this isn't an ivar
// - This logic seems to work, but isn't strictly speaking the right logic
if( !l_t.data().is_Infer() && (*ee)->is_public_to(m_resolve.m_vis_path) ) {
if( this->m_erased_type_aliases.count(ee->get()) == 0 ) {
this->m_erased_type_aliases.insert(std::make_pair( ee->get(), l_t.clone() ));
}
else {
equate_types_inner(sp, this->m_erased_type_aliases[ee->get()], l_t);
}
return ;
}
}
Expand All @@ -1964,13 +1970,15 @@ void Context::equate_types_inner(const Span& sp, const ::HIR::TypeRef& li, const
{
if( const auto* ee = et->m_inner.opt_Alias() )
{
if( this->m_erased_type_aliases.count(ee->get()) == 0 ) {
this->m_erased_type_aliases.insert(std::make_pair( ee->get(), r_t.clone() ));
}
else {
equate_types_inner(sp, this->m_erased_type_aliases[ee->get()], r_t);
if( (*ee)->is_public_to(m_resolve.m_vis_path) ) {
if( this->m_erased_type_aliases.count(ee->get()) == 0 ) {
this->m_erased_type_aliases.insert(std::make_pair( ee->get(), r_t.clone() ));
}
else {
equate_types_inner(sp, this->m_erased_type_aliases[ee->get()], r_t);
}
return ;
}
return ;
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/hir_typeck/helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,9 @@ class TraitResolution:
const HIR::SimplePath& m_lang_Deref;
const HMTypeInferrence& m_ivars;

public:
const ::HIR::SimplePath& m_vis_path;
private:
const ::HIR::GenericPath* m_current_trait_path;
const ::HIR::Trait* m_current_trait_ptr;

Expand Down

0 comments on commit 9a6ea45

Please sign in to comment.