Skip to content

Commit

Permalink
Expand - Refactor to run in two (or more) passes to handle macro defi…
Browse files Browse the repository at this point in the history
…nition quirks

No idea if this is the correct way (could have been that libstd wanted `macro_use` to cause a sorting change, or early expansion), but it works
  • Loading branch information
thepowersgang committed Jan 28, 2024
1 parent 9608639 commit a9f50a0
Show file tree
Hide file tree
Showing 8 changed files with 499 additions and 311 deletions.
18 changes: 18 additions & 0 deletions Notes/UpgradeQuirks.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,21 @@
- Generic values raised to statics
- U128 literals required
- An annoying-to-debug excessive memset caused by a bad float to u64 cast



=== 1.74 ===
- if-let chains
- `if let` in match guards
- Closure captures
- `FnPtr` trait
- unsized locals
- `const` blocks
- `macro_rules` "operators"
- `Box::new` now recurses with a `#[rustc_box]`-annotated expression.
- WHY? WHY is Box::new so funky. INTRINSICS EXIST FOR A REASON!
- `Drop for Box` is FINALLY a normal impl!
- `type Foo = impl Trait`
- `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.
2 changes: 1 addition & 1 deletion src/ast/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const Attribute* AttributeList::get(const char *name) const
return &i;
}
}
return 0;
return nullptr;
}

::std::ostream& operator<<(::std::ostream& os, const AttributeList& x) {
Expand Down
4 changes: 4 additions & 0 deletions src/ast/macro.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class MacroInvocation
AST::Path m_macro_path;
RcString m_ident;
TokenTree m_input;
bool m_is_expanded = false;
public:
MacroInvocation(MacroInvocation&&) = default;
MacroInvocation& operator=(MacroInvocation&&) = default;
Expand Down Expand Up @@ -51,6 +52,9 @@ class MacroInvocation
const Span& span() const { return m_span; }
const AST::Path& path() const { return m_macro_path; }

bool is_expanded() const { return m_is_expanded; }
void set_expanded() { m_is_expanded = true; }

const RcString& input_ident() const { return m_ident; }
const TokenTree& input_tt() const { return m_input; }
TokenTree& input_tt() { return m_input; }
Expand Down
2 changes: 1 addition & 1 deletion src/expand/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class CHandler_Cold:
void handle(const AST::Attribute& mi, AST::Function& fcn) const override {
TTStream lex(mi.span(), ParseState(), mi.data());
lex.getTokenCheck(TOK_EOF);
ASSERT_BUG(mi.span(), !fcn.m_markings.is_cold, "Duplicate #[cold] attributes");
//ASSERT_BUG(mi.span(), !fcn.m_markings.is_cold, "Duplicate #[cold] attributes");
fcn.m_markings.is_cold = true;
}
};
Expand Down
76 changes: 55 additions & 21 deletions src/expand/macro_rules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class CMacroUseHandler:
public ExpandDecorator
{
AttrStage stage() const override { return AttrStage::Post; }
bool run_during_iter() const override { return true; }

void handle(const Span& sp, const AST::Attribute& mi, ::AST::Crate& crate, const AST::AbsolutePath& path, AST::Module& mod, slice<const AST::Attribute> attrs, AST::Item& i) const override
{
Expand Down Expand Up @@ -70,6 +71,26 @@ class CMacroUseHandler:
}
};

auto exists = [&mod](const RcString& name, const MacroRef& mr)->bool {
for( const auto& imp : mod.macro_imports_res() ) {
if( imp.name != name )
continue;
if( imp.data.tag() != mr.tag() )
continue ;
bool rv;
TU_MATCH_HDRA( (imp.data, mr), {)
TU_ARMA(None, a,b) { rv = true; }
TU_ARMA(MacroRules, a,b) { rv = (a == b); }
TU_ARMA(BuiltinProcMacro, a,b) { rv = (a == b); }
TU_ARMA(ExternalProcMacro, a,b) { rv = (a == b); }
}
if(rv) {
return true;
}
}
return false;
};

if(i.is_None()) {
// Just ignore
}
Expand Down Expand Up @@ -117,24 +138,33 @@ class CMacroUseHandler:
}
}

MacroRef mr;
TU_MATCH_HDRA( (e->ent), { )
TU_ARMA(Import, imp) {
assert(false);
}
TU_ARMA(MacroRules, mac_ptr) {
DEBUG("Imported " << name << "!");
TU_ARMA(Import, imp) { throw "Unexpected"; }
TU_ARMA(MacroRules, mac_ptr) { mr = &*mac_ptr; }
TU_ARMA(ProcMacro, p) { mr = &p; }
}
if(!exists(name, mr))
{
mod.add_macro_import( sp, name, std::move(mr) );

TU_MATCH_HDRA( (e->ent), { )
TU_ARMA(Import, imp) {
throw "Unexpected";
}
TU_ARMA(MacroRules, mac_ptr) {
DEBUG("Imported " << name << "!");

auto mi = AST::Module::MacroImport{ false, name, make_vec2(ec_item->name, name), &*mac_ptr };
mod.m_macro_imports.push_back(mv$(mi));
auto mi = AST::Module::MacroImport{ false, name, make_vec2(ec_item->name, name), &*mac_ptr };
mod.m_macro_imports.push_back(mv$(mi));
}
TU_ARMA(ProcMacro, p) {
DEBUG("Imported " << name << "! (proc macro)");

mod.add_macro_import( sp, name, &*mac_ptr );
}
TU_ARMA(ProcMacro, p) {
DEBUG("Imported " << name << "! (proc macro)");
auto mi = AST::Module::MacroImport{ false, p.path.m_components.back(), p.path.m_components, nullptr };
mi.path.insert(mi.path.begin(), p.path.m_crate_name);
mod.m_macro_imports.push_back(mv$(mi));
mod.add_macro_import( sp, name, &p );
auto mi = AST::Module::MacroImport{ false, p.path.m_components.back(), p.path.m_components, nullptr };
mi.path.insert(mi.path.begin(), p.path.m_crate_name);
mod.m_macro_imports.push_back(mv$(mi));
}
}
}
}
Expand All @@ -144,21 +174,25 @@ class CMacroUseHandler:
const auto& submod = *submod_p;
for( const auto& mr : submod.macros() )
{
if( !filter_valid(mr.name) )
{
if( !filter_valid(mr.name) ) {
continue;
}
DEBUG("Imported " << mr.name);
mod.add_macro_import( sp, mr.name, &*mr.data );
if( !exists(mr.name, &*mr.data) )
{
mod.add_macro_import( sp, mr.name, &*mr.data );
}
}
for( const auto& mri : submod.macro_imports_res() )
{
if( !filter_valid(mri.name) )
{
if( !filter_valid(mri.name) ) {
continue;
}
DEBUG("Imported " << mri.name << " (propagate)");
mod.add_macro_import( sp, mri.name, mri.data.clone() );
if( !exists(mri.name, mri.data) )
{
mod.add_macro_import( sp, mri.name, mri.data.clone() );
}
}
}
else {
Expand Down
Loading

0 comments on commit a9f50a0

Please sign in to comment.