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

Issue 2789 - Functions overloads are not checked for conflicts #656

Closed
wants to merge 3 commits into from

Conversation

yebblies
Copy link
Member

Two issues here:

  • The check in overloadInsert is disabled as it can't work until semantic has been run on all overloads. This has been changed so that the check and the actual insertion can be run seperately.
  • The check is out of date. Type::covariant is no longer suitable, as it allows a much wider set of conversions and requires return type covariance, which is not needed for two overloads to conflict. The new function to perform this check is TypeFunction::overloadConflict.

http://d.puremagic.com/issues/show_bug.cgi?id=2789

if (type && f->type && // can be NULL for overloaded constructors
TypeFunction::overloadConflict((TypeFunction *)type, (TypeFunction *)f->type) &&
f->type->mod == type->mod &&
!isFuncAliasDeclaration())
Copy link
Member

Choose a reason for hiding this comment

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

You already do check for mod == mod in overloadConflict.
Also testing isFuncAliasDeclaration is much cheaper and should be done
before calling overloadConflict.

Copy link
Member Author

Choose a reason for hiding this comment

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

Will do.

@MartinNowak
Copy link
Member

I'd prefer a separate function for the check.

void FuncDeclaration::overloadCheck()
{
    for (FuncDeclaration *f = overnext; f; f = f->overnext)
    {
        // do the check
    }
}

Then you can call f->overloadCheck() before overloadInsert where you had set OVERcheck now.

This is also a good opportunity to get rid of that pointless recursion in overloadInsert where all we want
to do is appending to the end.

@yebblies
Copy link
Member Author

yebblies commented Feb 1, 2012

I'd rather keep them as one function. If I split them up, most of the code will end up duplicated for not a lot of gain. There is plenty of precedent for using flags like this.

I don't see what the issue with the recursive call is. I'd prefer to change as little code as possible with each patch, in my experience it reduces conflicts and aids reviewing.

I especially don't want to change the flow used in this function because it also involves alias and template overloads. I will have a look at them after this patch is merged, but I'd rather not do too much at once here.

@MartinNowak
Copy link
Member

Ah your right, overloadInsert is polymorph and will switch between different functions.
Doesn't that mean you'd need to make AliasDeclaration::overloadInsert and
TemplateDeclaration::overloadInsert aware of these flags too?

Some unittests that check overloading of functions, aliases and templates would be nice, not sure what works though.

int TypeFunction::overloadConflict(TypeFunction *t1, TypeFunction *t2)
{
if (!t1 || !t2)
return t1 != t2;
Copy link
Member

Choose a reason for hiding this comment

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

Why do I have a conflict if one type is NULL and the other is not?

Copy link
Member Author

Choose a reason for hiding this comment

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

Typo. And probably useless code anyway, I think I'll replace it with assert(!null)

@yebblies
Copy link
Member Author

yebblies commented Feb 1, 2012

Doesn't that mean you'd need to make AliasDeclaration::overloadInsert and TemplateDeclaration::overloadInsert aware of these flags too?

No, their behavior doesn't need to change. The only modification was to the big test which only applied to functions, the others are handled in other paths. There are problems with aliases and templates (I've got the issue numbers written down somewhere) but I'd like to handle them in a separate patch.

Some unittests that check overloading of functions, aliases and templates would be nice, not sure what works though.

Not much. Overloading with aliases is iirc completely unchecked, and overloading with templates is completely broken.

WalterBright and others added 3 commits April 11, 2012 21:23
Implement rvalue reference for struct literal and construction
Two issues here:
- The check in `overloadInsert` is disabled as it can't work until semantic has been run on all overloads.  This has been changed so that the check and the actual insertion can be run seperately.
- The check is out of date. `Type::covariant` is no longer suitable, as it allows a much wider set of conversions and requires return type covariance, which is not needed for two overloads to conflict.  The new function to perform this check is `TypeFunction::overloadConflict`.

Fixes issue 2789
@andralex
Copy link
Member

LGTM pending final review by @dawgfoto.

braddr pushed a commit to braddr/dmd that referenced this pull request Oct 22, 2012
Issue 8321 - std.range.put doesn't work with RefCounted output range
@andralex
Copy link
Member

please rebase

@MartinNowak
Copy link
Member

This has to be coordinated with #1409 and #1660.

@yebblies
Copy link
Member Author

TBH this is so old I don't remember how it works. It will likely need to be redone after @9rnsr's template overloading pulls are merged anyway, so I'm going to close it.

@yebblies yebblies closed this Jun 15, 2013
@yebblies yebblies deleted the issue2789 branch November 22, 2013 08:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants