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

Fix Issue 13732 - non-member templates can use "template this" #14434

Merged
merged 7 commits into from
Oct 4, 2022

Conversation

ntrel
Copy link
Contributor

@ntrel ntrel commented Sep 14, 2022

Error if a TemplateThisParameter is declared when there's no parent aggregate type or template (it could be for a mixin).

@dlang-bot
Copy link
Contributor

Thanks for your pull request and interest in making D better, @ntrel! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the coverage diff by visiting the details link of the codecov check)
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

Bugzilla references

Auto-close Bugzilla Severity Description
13732 normal Regular templates can use "template this", and they allow any type to be passed

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "master + dmd#14434"

Note: Can't use goto to jump into scope(exit).
@dkorpel
Copy link
Contributor

dkorpel commented Sep 14, 2022

The grammar considers this a primary expression, so it should be a semantic error instead of parser error

@ntrel
Copy link
Contributor Author

ntrel commented Sep 14, 2022

The grammar says this is just a token:

TemplateThisParameter:
this TemplateTypeParameter

I'm not sure how to make it a semantic check. In templateparametersem.d there is Scope sc available, is that enough to determine if there's a parent type or template?

@dkorpel
Copy link
Contributor

dkorpel commented Sep 15, 2022

The grammar says this is just a token:

You're right. What I really meant to say was: the grammar allows it outside an aggregate, so the parser should not reject it or the grammar needs to be updated as well.

I'm not sure how to make it a semantic check. In templateparametersem.d there is Scope sc available, is that enough to determine if there's a parent type or template?

I'll take a look later.

@dkorpel
Copy link
Contributor

dkorpel commented Sep 17, 2022

In templateparametersem.d there is Scope sc available, is that enough to determine if there's a parent type or template?

I don't know what templateparametersem.d refers to, but I think you can do the check in dsymbolsem.d in either DsymbolSemanticVisitor.visit(TemplateDeclaration) or templateInstanceSemantic().

fail_compilation/templatethis.d(21): Error: cannot use `this` outside an aggregate type
---
*/

Copy link
Member

Choose a reason for hiding this comment

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

Use #line for stable line numbers.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, then the error message line numbers don't match up.

Copy link
Member

@ibuclaw ibuclaw Sep 19, 2022

Choose a reason for hiding this comment

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

That is the point, adding/removing a line doesn't affect the entire output.

Copy link
Contributor

@RazvanN7 RazvanN7 Sep 23, 2022

Choose a reason for hiding this comment

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

Using #line is also annoying since the error line that is reported does not match up the editor line and you can't just :linenumber

Comment on lines 26 to 30
TEST_OUTPUT:
---
fail_compilation/templatethis.d(34): Error: cannot use `this` outside an aggregate type
fail_compilation/templatethis.d(37): Error: mixin `templatethis.t2!()` error instantiating
---
Copy link
Member

Choose a reason for hiding this comment

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

I'm not a fan of breaking up the TEST_OUTPUT directives, if the diagnostic were to change in the future, then it can't be updated in an automated way.

Copy link
Member

Choose a reason for hiding this comment

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

(cannot be updated... yet)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note: There are 85 files in fail_compilation which already do this according to a quick grep.

Copy link
Member

Choose a reason for hiding this comment

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

And they are annoying to deal with as one must manually work out where to update them when diagnostics change.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, I agree that it's better to just group all the error messages into a single TEST_OUTPUT directive.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ibuclaw OK, I see. Fixed!

@@ -6055,6 +6055,9 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions*
continue;
Type t = isType((*tempinst.tiargs)[i]);
assert(t);
if (t.ty != TY.Tclass || t.ty != TY.Tstruct)
tempinst.error("argument for template this parameter must be a class or struct");
Copy link
Member

Choose a reason for hiding this comment

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

Possibly missing syntax highlighting for class and struct.

Suggested change
tempinst.error("argument for template this parameter must be a class or struct");
tempinst.error("argument for template this parameter must be a `class` or `struct`");

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have removed this error as I don't know why it triggers with core.sync.condition.Condition.

Copy link

Choose a reason for hiding this comment

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

Probably should be a '&&' condition
-if (t.ty != TY.Tclass || t.ty != TY.Tstruct)
+if (t.ty != TY.Tclass && t.ty != TY.Tstruct)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@apz28 Thanks, looks good. But I decided to leave that check out of this pull.

Copy link
Contributor

@RazvanN7 RazvanN7 left a comment

Choose a reason for hiding this comment

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

Looks good to me.

@RazvanN7
Copy link
Contributor

RazvanN7 commented Oct 3, 2022

@ntrel Just group the error messages in the test case and we can get this in.

@RazvanN7 RazvanN7 merged commit a9ae711 into dlang:master Oct 4, 2022
@ntrel ntrel deleted the no-this branch October 4, 2022 17:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants