Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option_env support #3094

Merged
merged 1 commit into from
Jan 31, 2025
Merged

Add option_env support #3094

merged 1 commit into from
Jan 31, 2025

Conversation

liamnaddell
Copy link
Contributor

@liamnaddell liamnaddell commented Jul 22, 2024


    gcc/rust/ChangeLog:
            * expand/rust-macro-builtins-utility.cc: Add macro expansion for
            option_env with eager expansion
            * expand/rust-macro-builtins.cc: Add option_env to builtin list
            * expand/rust-macro-builtins.h: Add option_env handler to header
            file

    gcc/testsuite/ChangeLog:
            * rust/compile/macros/builtin/option_env1.rs: Add success case for option_env
            * rust/compile/macros/builtin/option_env2.rs: Add failure case for option_env
            * rust/execute/torture/builtin_macro_option_env.rs: Add
            execution case for option_env
            * rust/compile/nr2/exclude: Some issues with nr2 need to be
            resolved before allowing option_env with NR2.0.

Fixes #1806

Addresses #927, #1791

Here is a checklist to help you with your PR.


Adds compiler support for option_env, adds eager expansion for option_env, adds tests for option_env

@liamnaddell liamnaddell marked this pull request as draft July 22, 2024 00:50
@liamnaddell liamnaddell marked this pull request as ready for review July 23, 2024 00:07
@liamnaddell liamnaddell force-pushed the option_env branch 3 times, most recently from 6262158 to 62a89ef Compare July 23, 2024 02:12
Copy link
Member

@CohenArthur CohenArthur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

honestly, well done - this isn't an easy part of the codebase, and you did a really good job :) don't worry about the tokenstream stuff, we can think about fixing this later. for the path issue, you're hitting a very frustrating issue which I'm trying to fix in #3068. ideally, we should be able to create paths to lang items (such as Option::Some and Option::None) so that we don't care about the module structure, or the name, or anything - we just care about hitting the proper type from the standard library. good work!

gcc/rust/expand/rust-macro-builtins-utility.cc Outdated Show resolved Hide resolved
gcc/testsuite/rust/compile/option_env1.rs Outdated Show resolved Hide resolved
@liamnaddell
Copy link
Contributor Author

honestly, well done - this isn't an easy part of the codebase, and you did a really good job :)

Thank you :)

@liamnaddell liamnaddell force-pushed the option_env branch 6 times, most recently from 8350b2c to dd8612c Compare August 1, 2024 22:54
@liamnaddell liamnaddell force-pushed the option_env branch 2 times, most recently from 36cd2a3 to 2034102 Compare August 8, 2024 01:03
@liamnaddell liamnaddell force-pushed the option_env branch 2 times, most recently from 74ad9b9 to 1f41fa7 Compare August 15, 2024 22:01
@liamnaddell
Copy link
Contributor Author

@CohenArthur Should I update this PR to use the lang-item paths from #3068 ?

@P-E-P
Copy link
Member

P-E-P commented Sep 10, 2024

@CohenArthur Should I update this PR to use the lang-item paths from #3068 ?

I've been trying to catch up on that issue (sorry for the delay!). We should probably rely on lang item path because right now the tests make use of a core module where it should be the core library (aka technically the file itself since we're defining the builtin macro from within the crate).

@liamnaddell
Copy link
Contributor Author

@CohenArthur Should I update this PR to use the lang-item paths from #3068 ?

I've been trying to catch up on that issue (sorry for the delay!). We should probably rely on lang item path because right now the tests make use of a core module where it should be the core library (aka technically the file itself since we're defining the builtin macro from within the crate).

Ok, I can wait until the lang items path stuff is usable. If appropriate, we can also revisit some of the other macros then as well to integrate lang items.

@liamnaddell liamnaddell marked this pull request as draft September 10, 2024 15:28
@liamnaddell
Copy link
Contributor Author

Converting to a Draft PR until we have lang items integrated.

@liamnaddell liamnaddell force-pushed the option_env branch 8 times, most recently from ef93339 to 1596237 Compare January 17, 2025 14:53
Comment on lines 67 to 72
if (tl::optional<LangItem::Kind> lang_item = get_lang_item_attr (item))
{
rust_debug ("[CollectLangItems] Adding lang item %s",
LangItem::ToString (*lang_item).c_str ());
mappings.insert_lang_item_node (lang_item.value (), item.get_node_id ());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say remove this, but feel free to keep it if you think it helps

Comment on lines 628 to 631
rust_assert (kind == Kind::Regular);
// For lang-items, this returns an empty path.
return segments;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should keep the original here. Everywhere that calls .get_segments() where a lang item can also be present need to be handled differently to resolve to the proper lang item anyway, so the assertion makes sense

Copy link
Contributor Author

@liamnaddell liamnaddell Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I can change this, I think it will require adding some code like:

if (path.is_lang_item())
   return;

to various AST passes, since a lot of these passes try to recurse into a PathInExpression's segments

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment on lines 633 to 632
rust_assert (kind == Kind::Regular);
// For lang-items, this returns an empty path.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment on lines 286 to 287
std::vector<PathExprSegment> path_segments,
tl::optional<LangItem::Kind> lang_item = tl::nullopt,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to see two constructors, one with segments and one with the lang item. Is that code I wrote or is it something you added for this PR?

Copy link
Contributor Author

@liamnaddell liamnaddell Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added all lang item handling at/below HIR level for PathInExpression.

I can fix this, this was a hack I forgot to remove. I'll try to handle HIR::PathInExpression similarly to AST::PathInExpression as far as it relates to constructors

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment on lines 505 to 506
= new HIR::PathInExpression (mapping, std::move (path_segments),
expr.get_lang_item (), expr.get_locus (),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so we'd get rid of the segments here for example

Suggested change
= new HIR::PathInExpression (mapping, std::move (path_segments),
expr.get_lang_item (), expr.get_locus (),
= new HIR::PathInExpression (mappin, expr.get_lang_item (), expr.get_locus (),

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment on lines 183 to 215
void
TypeCheckExpr::handle_enum_lang_item (HIR::PathInExpression &expr)
{
// Find the lang item's definition
Analysis::Mappings &mappings = Analysis::Mappings::get ();
NodeId lang_item_node = mappings.get_lang_item_node (expr.get_lang_item ());
tl::optional<HirId> ohid = mappings.lookup_node_to_hir (lang_item_node);
rust_assert (ohid != tl::nullopt);
HirId hid1 = *ohid;
std::pair<HIR::Enum *, HIR::EnumItem *> ohi
= mappings.lookup_hir_enumitem (hid1);

HIR::Enum &enum_def = *(ohi.first);
HIR::EnumItem &variant_def = *(ohi.second);

TyTy::BaseType *bl = TypeCheckItem::Resolve (enum_def);
TyTy::VariantDef *vde
= TypeCheckEnumItem::Resolve (variant_def, INT64_MAX - 1);

context->insert_variant_definition (expr.get_mappings ().get_hirid (),
vde->get_id ());
bl = SubstMapper::InferSubst (bl, expr.get_locus ());
resolver->insert_resolved_misc (expr.get_mappings ().get_nodeid (),
expr.get_mappings ().get_nodeid ());

infered = bl;
rust_assert (bl != nullptr);
return;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@philberty how does that look? you know the typechecker better than me lol

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a note, I'm looking at this code again, and it seems like some of the assert's might want to be compile errors instead maybe. I'm thinking of the case where somebody puts #[lang = 'Some'] on something that's not an enum variant

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's fine, because having "wrong lang items" is such a corner case that we don't really need to handle it. we know that core is correct code, if someone wants to reimplement their own core then the burden falls on them rather than on the compiler. asserts are better IMO

@liamnaddell
Copy link
Contributor Author

liamnaddell commented Jan 17, 2025

Also I see the build-and-check with glibcxx assertions turned on ICE's. I'll try to figure out what's going on there. (gcc is giving me trouble with compiling :/ )

@CohenArthur
Copy link
Member

Also I see the build-and-check with glibcxx assertions turned on ICE's. I'll try to figure out what's going on there. (gcc is giving me trouble with compiling :/ )

might be because we're doing something like .get_segment().front() somewhere, which triggers the assertions (and is UB). this is also why I think we should separate lang items and segmented paths and always make get_segments() assert that we're dealing with a segmented path

@liamnaddell
Copy link
Contributor Author

Also I see the build-and-check with glibcxx assertions turned on ICE's. I'll try to figure out what's going on there. (gcc is giving me trouble with compiling :/ )

might be because we're doing something like .get_segment().front() somewhere, which triggers the assertions (and is UB). this is also why I think we should separate lang items and segmented paths and always make get_segments() assert that we're dealing with a segmented path

Because of my env, I was compiling gccrs with gccrs, which didn't work, because I think gccrs' gcc wasn't properly configured. I changed to use system gcc and it compiles perfectly.

Your guess was exactly what it was. the ICE was rust-hir-path.cc:266 segments.back ()

Comment on lines 47 to 60
TyTy::BaseType *lookup = nullptr;
bool ok
= ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
&lookup);
rust_assert (ok);

tree t = attempt_constructor_expression_lookup (lookup, ctx,
expr.get_mappings (),
expr.get_locus ());
TREE_USED (t) = 1;
resolved = t;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CohenArthur That GLIBCXX assert CI/CD job caught some undefined behavior, where I pushed a random address into the ResolvePathRef::resolve function as the "final segment". I added code here to properly handle lang-item paths.

(Still working on fixing the AST::PathInExpression, I should be able to get that done soon)

@liamnaddell liamnaddell force-pushed the option_env branch 3 times, most recently from a8b5ef0 to 455fff0 Compare January 22, 2025 04:08
@liamnaddell liamnaddell force-pushed the option_env branch 5 times, most recently from 333d52d to f50cdf6 Compare January 31, 2025 02:55
Copy link
Member

@CohenArthur CohenArthur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's great work, looks perfect to me :D thank you so much @liamnaddell !

Comment on lines +257 to +258
if (expr.is_lang_item ())
return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think resolution here should be pretty easy but we'll do this in another PR - I'm happy with that fix

gcc/rust/ChangeLog:
	* expand/rust-macro-builtins-utility.cc: Add macro expansion for
	option_env with eager expansion
	* expand/rust-macro-builtins.cc: Add option_env to builtin list
	* expand/rust-macro-builtins.h: Add option_env handler to header
	file
	* resolve/rust-late-name-resolver-2.0.cc: Prevent NR2.0 from
	recursing into lang-item segments

gcc/testsuite/ChangeLog:
	* rust/compile/macros/builtin/option_env1.rs: Add success case for option_env
	* rust/compile/macros/builtin/option_env2.rs: Add failure case for option_env
	* rust/execute/torture/builtin_macro_option_env.rs: Add
	execution case for option_env
@CohenArthur CohenArthur enabled auto-merge January 31, 2025 15:28
@CohenArthur CohenArthur added this pull request to the merge queue Jan 31, 2025
Merged via the queue into Rust-GCC:master with commit 761d424 Jan 31, 2025
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement eager expansion for option_env!()
3 participants