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

Inherited functions attribute overridden #19316

Open
dlangBugzillaToGithub opened this issue Sep 13, 2017 · 0 comments
Open

Inherited functions attribute overridden #19316

dlangBugzillaToGithub opened this issue Sep 13, 2017 · 0 comments

Comments

@dlangBugzillaToGithub
Copy link

John Hall reported this on 2017-09-13T18:16:45Z

Transferred from https://issues.dlang.org/show_bug.cgi?id=17826

Description

When overriding a function, the derived class's version takes on the function attributes of the base class member function. This overrules any type attributes the user will include. In the example below, Bar.foo is @safe @nogc pure nothrow and Foo.bar overrides it with @system, but this is ignored and it is actually @safe @nogc pure nothrow, like Bar.bar. 

This is not an issue of type inference (i.e. that Foo.bar does not have any non-safe commands so the compiler infers it is @safe). If the @system is removed from Foo.bar and some kind of non-safe operations are included in its body, then the compiler has an error that Foo.bar is safe.

I would consider a satisfactory resolution of this issue either or both:
1) Some kind of error message that anything overriding Bar.bar must have the same function attributes
2) The fix for issue 7534 (and associated bugs) only applies to const/immutable/etc member functions. It could be extended to other function attributes. This way, one could write Foo.bar as @system without the override.
https://issues.dlang.org/show_bug.cgi?id=7534



class Bar
{
    void bar(string s) @safe @nogc pure nothrow { }
}

class Foo : Bar
{
    override void bar(string s) @system { } //function is actually @safe @nogc pure nothrow
}

void main()
{
    import std.traits : hasFunctionAttributes;
    
    alias S = typeof(Foo.bar);
    alias T = typeof(Bar.bar);

    static assert(hasFunctionAttributes!(S, "@safe"));
    static assert(hasFunctionAttributes!(T, "@safe"));
    static assert(hasFunctionAttributes!(S, "@nogc"));
    static assert(hasFunctionAttributes!(T, "@nogc"));
    static assert(hasFunctionAttributes!(S, "pure"));
    static assert(hasFunctionAttributes!(T, "pure"));
    static assert(hasFunctionAttributes!(S, "nothrow"));
    static assert(hasFunctionAttributes!(T, "nothrow"));
    
    static assert(!hasFunctionAttributes!(S, "@system"));
    static assert(!hasFunctionAttributes!(T, "@system"));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant