Thread overview
Inferred attributes errors in template function.
May 27, 2022
vit
May 27, 2022
user1234
May 27, 2022
user1234
May 27, 2022
Tejas
May 27, 2022
Paul Backus
May 27, 2022

Hello, I have this problem:

static int i;

void bar(T)(){
	static if(is(T == int))
        (()@system => 1)();
    static if(is(T == float))
        i = 42;

}
void foo(T)(){
	bar!T();
}

void main()@safe pure{
	foo!long();
	foo!float();	//Error: `pure` function `D main` cannot call impure function `onlineapp.foo!float.foo`
	foo!int();		//Error: `@safe` function `D main` cannot call `@system` function `onlineapp.foo!int.foo`
}

When template function foo is called and its inferred attributes are not compatible with attributes of main, errors are not really useful. Compiler print that foo!float is not pure or foo!int is not @safe but doesn't tell why. Is in dmd some flag that print errors similarly to this?:

void main()@safe pure{
	foo!long();
	foo!float();	
    	//Error: `pure` function `D main` cannot call impure function `onlineapp.foo!float.foo`
    	//Error: potentially `pure` function `onlineapp.foo!float.foo` cannot call impure function `onlineapp.bar!float.bar`
    	//Error: potentially `pure` function `onlineapp.bar!float.bar` cannot access mutable static data `i`
	foo!int();		
    	//Error: `@safe` function `D main` cannot call `@system` function `onlineapp.foo!int.foo`
    	//Error: potentially `@safe` function `onlineapp.foo!int.foo` cannot call `@system` function `onlineapp.bar!int.bar`
     	//Error: potentially `@safe` function `onlineapp.bar!int.bar` cannot call `@system` delegate `onlineapp.bar!int.bar.__lambda1`
}
May 27, 2022

On Friday, 27 May 2022 at 08:39:08 UTC, vit wrote:

>

Hello, I have this problem:

static int i;

void bar(T)(){
	static if(is(T == int))
        (()@system => 1)();
    static if(is(T == float))
        i = 42;

}
void foo(T)(){
	bar!T();
}

void main()@safe pure{
	foo!long();
	foo!float();	//Error: `pure` function `D main` cannot call impure function `onlineapp.foo!float.foo`
	foo!int();		//Error: `@safe` function `D main` cannot call `@system` function `onlineapp.foo!int.foo`
}

[...]

on a side note that's funny how dmd manages to systematically print the less interesting message in both case.

May 27, 2022

On Friday, 27 May 2022 at 08:39:08 UTC, vit wrote:

>

Hello, I have this problem:

static int i;

void bar(T)(){
	static if(is(T == int))
        (()@system => 1)();
    static if(is(T == float))
        i = 42;

}
void foo(T)(){
	bar!T();
}

void main()@safe pure{
	foo!long();
	foo!float();	//Error: `pure` function `D main` cannot call impure function `onlineapp.foo!float.foo`
	foo!int();		//Error: `@safe` function `D main` cannot call `@system` function `onlineapp.foo!int.foo`
}

When template function foo is called and its inferred attributes are not compatible with attributes of main, errors are not really useful. Compiler print that foo!float is not pure or foo!int is not @safe but doesn't tell why. Is in dmd some flag that print errors similarly to this?:

void main()@safe pure{
	foo!long();
	foo!float();	
    	//Error: `pure` function `D main` cannot call impure function `onlineapp.foo!float.foo`
    	//Error: potentially `pure` function `onlineapp.foo!float.foo` cannot call impure function `onlineapp.bar!float.bar`
    	//Error: potentially `pure` function `onlineapp.bar!float.bar` cannot access mutable static data `i`
	foo!int();		
    	//Error: `@safe` function `D main` cannot call `@system` function `onlineapp.foo!int.foo`
    	//Error: potentially `@safe` function `onlineapp.foo!int.foo` cannot call `@system` function `onlineapp.bar!int.bar`
     	//Error: potentially `@safe` function `onlineapp.bar!int.bar` cannot call `@system` delegate `onlineapp.bar!int.bar.__lambda1`
}

Use -verrors=context for dmd

static int i;

void bar(T)(){
	static if(is(T == int))
        (()@system => 1)();
    static if(is(T == float))
        i = 42;

}
void foo(T)(){
	bar!T();
}

void main()@safe pure{
	foo!long();
	foo!float();	/+ onlineapp.d(16): Error: `pure` function `D main` cannot call impure function `onlineapp.foo!float.foo`
	foo!float();	
          ^		+/

	foo!int();		/+onlineapp.d(18): Error: `@safe` function `D main` cannot call `@system` function `onlineapp.foo!int.foo`
	foo!int();		
        ^		+/
}
May 27, 2022

On Friday, 27 May 2022 at 08:39:08 UTC, vit wrote:

>

Is in dmd some flag that print errors similarly to this?:

void main()@safe pure{
	foo!long();
	foo!float();	
    	//Error: `pure` function `D main` cannot call impure function `onlineapp.foo!float.foo`
    	//Error: potentially `pure` function `onlineapp.foo!float.foo` cannot call impure function `onlineapp.bar!float.bar`
    	//Error: potentially `pure` function `onlineapp.bar!float.bar` cannot access mutable static data `i`

No, there is nothing like this, at least not yet. It's being worked on, though.

https://github.com/dlang/dmd/pull/13957
https://github.com/dlang/dmd/pull/12383

May 27, 2022

On Friday, 27 May 2022 at 09:41:32 UTC, user1234 wrote:

> >

[...]

on a side note that's funny how dmd manages to systematically print the less interesting message in both case.

They are actually correct, I dont know why at some point I thought there was a problem. For the float one it's oviously not pure and for the int one it's not safe...

OP wants better error message.