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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Conversation

liamnaddell
Copy link
Contributor

@liamnaddell liamnaddell commented Jul 22, 2024

Half of this PR is option_env! , half is adding support for compiling lang-item PathInExpression's
NOTE: Testing for lang-item paths is done by testing option_env!. I'm not sure if there's any other way to test compiler-generated paths.

    gcc/rust/ChangeLog:
            * ast/rust-collect-lang-items.cc: Allow for the collection of
            EnumItem lang-items
            * ast/rust-collect-lang-items.h: ...
            * ast/rust-path.h: Change get_segments function to create an
            empty path for Lang items, which is useful for preventing
            various AST passes from recursing into the "segments" of a
            lang item path.
            * 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
            * backend/rust-compile-struct-field-expr.cc: Refactor
            HIR::PathInExpression to allow for lang items.
            * hir/rust-ast-lower-expr.cc: ...
            * hir/rust-ast-lower.cc: ...
            * hir/tree/rust-hir-path.h: ...
            * hir/tree/rust-hir-path.cc: ...
            * typecheck/rust-hir-type-check-struct.cc: ...
            * resolve/rust-ast-resolve-path.cc: Add NR1.0 resolution support
            for lang-item paths.
            * typecheck/rust-hir-type-check-path.cc: Add type resolution
            support for lang-item paths.

    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
Copy link
Contributor Author

liamnaddell commented Jan 6, 2025

Likely depends on #3343 to be merged

@liamnaddell liamnaddell marked this pull request as ready for review January 13, 2025 19:34
@liamnaddell
Copy link
Contributor Author

Marking as "ready for review" since most of the code should be there for option_env support

@liamnaddell liamnaddell changed the title [ #1806 ] Add option_env support Add option_env support Jan 13, 2025
@liamnaddell liamnaddell force-pushed the option_env branch 3 times, most recently from b80133e to c4702ba Compare January 13, 2025 21:53
@liamnaddell
Copy link
Contributor Author

Should be ready after #3366 is integrated

@liamnaddell liamnaddell force-pushed the option_env branch 10 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

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

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

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

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 (),

Comment on lines +183 to +211
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

@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 ()

gcc/rust/ChangeLog:
	* ast/rust-collect-lang-items.cc: Allow for the collection of
	EnumItem lang-items
	* ast/rust-collect-lang-items.h: ...
	* ast/rust-path.h: Change get_segments function to create an
	empty path for Lang items, which is useful for preventing
	various AST passes from recursing into the "segments" of a
	lang item path.
	* 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
	* hir/tree/rust-hir-path.h: Refactor
	HIR::PathInExpression to allow for lang items.
	* hir/rust-ast-lower-expr.cc: ...
	* hir/tree/rust-hir-path.cc: ...
	* resolve/rust-ast-resolve-path.cc: Add NR1.0 resolution support
	for lang-item paths.
	* typecheck/rust-hir-type-check-path.cc: Add type resolution
	support for lang-item paths.
	* typecheck/rust-hir-type-check-expr.h: Add prototype
	for helper function.
	* backend/rust-compile-resolve-path.cc: Add compile support for
	  lang-item paths.
	* checks/lints/rust-lint-marklive.cc: Add if guard to prevent
	  recursion into a lang-item path's empty 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
	* rust/compile/nr2/exclude: Some issues with nr2 need to be
	resolved before allowing option_env with NR2.0.

Signed-off-by: Liam Naddell <[email protected]>
Comment on lines +47 to +57
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)

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