Skip to content

Commit 9648191

Browse files
authored
Add .. syntax to select a member function only (#1101)
* Add `..` syntax to select a member function only With this commit, `x.f()` is still UFCS, but `x..f()` will now find only a member function. For now I like that the default is UFCS, but as we get more experience I'm open to changing the default so that `.` is member selection and `..` is UFCS (which would be a breaking change, but a mechanical one). Also: Remove the old version of `get_declaration_of` now that the new lookup seems stable. * Remove some debug code * Finish removing old g_d_o paths
1 parent 963f06f commit 9648191

File tree

6 files changed

+39
-266
lines changed

6 files changed

+39
-266
lines changed

regression-tests/pure2-ufcs-member-access-and-chaining.cpp2

+7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ main: () -> int = {
2121
42.no_return();
2222

2323
res.no_return();
24+
25+
obj: mytype = ();
26+
obj..hun(42); // explicit non-UFCS
2427
}
2528

2629
no_return: (_) = { }
@@ -41,3 +44,7 @@ get_i: (r:_) -> int = {
4144
// And a test for non-local UFCS, which shouldn't do a [&] capture
4245
f: (_)->int = 0;
4346
y: int = 0.f();
47+
48+
mytype: type = {
49+
hun: (i: int) = { }
50+
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
Microsoft (R) C/C++ Optimizing Compiler Version 19.39.33523 for x86
1+
Microsoft (R) C/C++ Optimizing Compiler Version 19.40.33811 for x64
22
Copyright (C) Microsoft Corporation. All rights reserved.
33

source/lex.h

+8-5
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ enum class lexeme : std::int8_t {
8383
Semicolon,
8484
Comma,
8585
Dot,
86+
DotDot,
8687
Ellipsis,
8788
QuestionMark,
8889
At,
@@ -180,6 +181,7 @@ auto _as(lexeme l)
180181
break;case lexeme::Semicolon: return "Semicolon";
181182
break;case lexeme::Comma: return "Comma";
182183
break;case lexeme::Dot: return "Dot";
184+
break;case lexeme::DotDot: return "DotDot";
183185
break;case lexeme::Ellipsis: return "Ellipsis";
184186
break;case lexeme::QuestionMark: return "QuestionMark";
185187
break;case lexeme::At: return "At";
@@ -845,9 +847,9 @@ auto lex_line(
845847

846848
if (
847849
i >= 3
848-
&& (tokens[i-3] != "::" && tokens[i-3] != ".")
850+
&& (tokens[i-3] != "::" && tokens[i-3].type() != lexeme::Dot && tokens[i - 3].type() != lexeme::DotDot)
849851
&& (tokens[i-2] == "unique" || tokens[i-2] == "shared")
850-
&& tokens[i-1] == "."
852+
&& tokens[i-1].type() == lexeme::Dot
851853
&& tokens[i] == "new"
852854
)
853855
{
@@ -1402,10 +1404,11 @@ auto lex_line(
14021404

14031405
//G
14041406
//G punctuator: one of
1405-
//G '...' '.'
1407+
//G '.' '..' '...'
14061408
break;case '.':
1407-
if (peek1 == '.' && peek2 == '.') { store(3, lexeme::Ellipsis); }
1408-
else { store(1, lexeme::Dot); }
1409+
if (peek1 == '.' && peek2 == '.') { store(3, lexeme::Ellipsis); }
1410+
else if (peek1 == '.') { store(2, lexeme::DotDot); }
1411+
else { store(1, lexeme::Dot); }
14091412

14101413
//G '::' ':'
14111414
break;case ':':

source/parse.h

+8-7
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@ auto violates_lifetime_safety = false;
3636
auto is_prefix_operator(token const& tok)
3737
-> bool
3838
{
39-
//if (to_passing_style(tok) != passing_style::invalid) {
40-
// return true;
41-
//}
42-
4339
switch (tok.type()) {
4440
break;case lexeme::Not:
4541
case lexeme::Minus:
@@ -1682,7 +1678,7 @@ auto postfix_expression_node::get_first_token_ignoring_this() const
16821678
expr->get_token()
16831679
&& *expr->get_token() == "this"
16841680
&& std::ssize(ops) == 1
1685-
&& ops[0].op->type() == lexeme::Dot
1681+
&& (ops[0].op->type() == lexeme::Dot || ops[0].op->type() == lexeme::DotDot)
16861682
)
16871683
{
16881684
return ops[0].id_expr->get_token();
@@ -5820,6 +5816,7 @@ class parser
58205816
//G postfix-expression '[' expression-list? ','? ']'
58215817
//G postfix-expression '(' expression-list? ','? ')'
58225818
//G postfix-expression '.' id-expression
5819+
//G postfix-expression '..' id-expression
58235820
//G
58245821
auto postfix_expression()
58255822
-> std::unique_ptr<postfix_expression_node>
@@ -5837,7 +5834,8 @@ class parser
58375834
|| curr().type() == lexeme::LeftBracket
58385835
|| curr().type() == lexeme::LeftParen
58395836
|| curr().type() == lexeme::Dot
5840-
)
5837+
|| curr().type() == lexeme::DotDot
5838+
)
58415839
)
58425840
{
58435841
// * and & can't be unary operators if followed by a (, identifier, or literal
@@ -5916,7 +5914,10 @@ class parser
59165914
break;
59175915
}
59185916
}
5919-
else if (term.op->type() == lexeme::Dot)
5917+
else if (
5918+
term.op->type() == lexeme::Dot
5919+
|| term.op->type() == lexeme::DotDot
5920+
)
59205921
{
59215922
term.id_expr = id_expression();
59225923
if (!term.id_expr) {

0 commit comments

Comments
 (0)