Skip to content

compiler: allow unnamed -> named tuples conversions on name match#2642

Merged
borisbat merged 2 commits into
masterfrom
aleksisch/unnamed-named-tuple-conv
May 14, 2026
Merged

compiler: allow unnamed -> named tuples conversions on name match#2642
borisbat merged 2 commits into
masterfrom
aleksisch/unnamed-named-tuple-conv

Conversation

@aleksisch
Copy link
Copy Markdown
Collaborator

@aleksisch aleksisch commented May 13, 2026

It's useful to be able to not repeat yourself. If tuple names exactly match variable names we want to assign we should allow to write unnamed tuple. See tests for more details.

Closes #2641

@aleksisch aleksisch force-pushed the aleksisch/unnamed-named-tuple-conv branch 3 times, most recently from bf57c04 to 1d835df Compare May 13, 2026 12:54
@aleksisch aleksisch requested a review from borisbat May 13, 2026 18:48
Copy link
Copy Markdown
Collaborator

@borisbat borisbat left a comment

Choose a reason for hiding this comment

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

  1. documentation. update tuple.rst (or whatever its called) - when it would match, and what it would and would-not match
  2. language tutorial on tuples should expand on this
  3. update serializer version

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds compiler support for treating bare-variable tuple literals as named tuples when their variable names match the target tuple field names, addressing #2641.

Changes:

  • Tracks shorthand tuple field names during parsing.
  • Seeds tuple record types during inference for typed variable initialization and function-call matching.
  • Adds language tests for successful shorthand tuple use and mismatch failure.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
utils/dasFormatter/ds_parser.ypp Mirrors tuple shorthand metadata collection in formatter parser.
tests/language/tuple.das Adds successful shorthand tuple language tests.
tests/language/failed_tuple_shorthand_mismatch.das Adds expected-failure test for mismatched shorthand names.
src/parser/parser_impl.h Declares shorthand tuple name collection helper.
src/parser/parser_impl.cpp Implements shorthand tuple name collection from bare variables.
src/parser/ds2_parser.ypp Adds shorthand metadata collection to gen2 parser grammar.
src/parser/ds2_parser.cpp Regenerated gen2 parser output.
src/parser/ds_parser.ypp Adds shorthand metadata collection to parser grammar.
src/parser/ds_parser.cpp Regenerated parser output.
src/builtin/module_builtin_ast_serialize.cpp Serializes new tuple shorthand metadata.
src/ast/ast.cpp Preserves shorthand metadata when cloning tuple expressions.
src/ast/ast_infer_type.cpp Seeds shorthand tuple record types from typed let/global initializers.
src/ast/ast_infer_type_make.cpp Promotes matching shorthand names into tuple record names.
src/ast/ast_infer_type_function.cpp Attempts shorthand-based function-call rematching.
include/daScript/ast/ast_infer_type.h Declares new inference hooks/helpers.
include/daScript/ast/ast_expressions.h Adds tuple shorthand metadata storage.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/parser/ds_parser.ypp
Comment thread src/parser/ds2_parser.ypp
Comment on lines +1099 to +1118
vector<TypeDeclPtr> hypTypes;
hypTypes.reserve(expr->arguments.size());
for (auto arg : expr->arguments) hypTypes.push_back(arg ? arg->type : nullptr);
for (size_t idx : shorthandIndices) {
auto mkt = static_cast<ExprMakeTuple*>(expr->arguments[idx]);
auto hyp = new TypeDecl(*mkt->type);
hyp->argNames = mkt->shorthandRecordNames;
hypTypes[idx] = hyp;
}
MatchingFunctions hypFns, hypGens;
findMatchingFunctionsAndGenerics(hypFns, hypGens, expr->name, hypTypes);
if (hypFns.size() + hypGens.size() != 1) return false;
for (size_t idx : shorthandIndices) {
auto mkt = static_cast<ExprMakeTuple*>(expr->arguments[idx]);
mkt->recordType = new TypeDecl(*mkt->type);
mkt->recordType->argNames = mkt->shorthandRecordNames;
mkt->recordType->ref = false;
mkt->recordType->constant = false;
}
return true;
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I don't see how to resolve it cleanly.

What we do now: promote everything to named.

What you suggest: promote to named one by one, attempting to match function.

Your scenario misses the case:
foo((x,y), (a,b)) -> foo(tuple<x:int;y:float>, tuple<a:int;b:float>)
My scenario misses case:
foo((x,y), (a,b)) -> foo(tuple<x:int;y:float>, tuple<int;float>)

Comment thread src/ast/ast_infer_type_function.cpp Outdated
Comment thread utils/dasFormatter/ds_parser.ypp
Comment thread tests/language/tuple.das
var arr : array<tuple<eid : int; distSq : float>>
let eid = 7
let distSq = 2.5
arr |> push((eid, distSq))
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

how do i tell it to explicitly be nameless. say there are TWO push functions
push ( a : tuple<int,float> )
push ( a : tuple<edi:int, distSq:float> )
and i write push((eid,distSq)) - which one would it pick?

Copy link
Copy Markdown
Collaborator Author

@aleksisch aleksisch May 14, 2026

Choose a reason for hiding this comment

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

We give priority to unnamed tuples:

if (functions.empty() && generics.empty() && trySeedTupleShorthand(expr)) {

So we will try this feature only if nothing matched earlier.

This code works fine and prints 1. I will add it to tests anyway.

def foo(x : tuple<int; float>) {
    print("1")
}

def foo(x : tuple<x: int; y: float>) {
    print("2");
} 

[export]
def main{
    var x = 123
    var y = 321.
    foo((x, y))
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

document? test?

@aleksisch aleksisch force-pushed the aleksisch/unnamed-named-tuple-conv branch 2 times, most recently from 0b57c1f to f2981e6 Compare May 14, 2026 11:38
It's useful to be able to not repeat yourself. If tuple names
exactly match variable names we want to assign we should allow
to write unnamed tuple. See tests for more details.
@aleksisch aleksisch force-pushed the aleksisch/unnamed-named-tuple-conv branch from f2981e6 to 6d29e57 Compare May 14, 2026 14:39
Support unnamed -> named promotion for return tuples as well.
@borisbat borisbat merged commit d43f0c6 into master May 14, 2026
28 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.

Allow named unnamed tuples creation

3 participants