Open sandboxFocusImprove this doc

LAMA0276: A called template can't have run-time type parameters

Severity Error
Reported by Metalama.Framework
Message The called template '<Template>' has a run-time type parameter. The type parameters of a called template must be marked with [CompileTime].

Cause

When a template calls an auxiliary template, Metalama expands the auxiliary template at the call site during compilation. To do this with a generic auxiliary template, Metalama must bind each type parameter to a known type at compile time, so the type parameters of the called template must be compile-time type parameters.

Metalama reports LAMA0276 when a template directly calls a generic auxiliary template that has at least one run-time type parameter, that is, a type parameter that isn't marked with [CompileTime]. This also happens when a base template marks its type parameters with [CompileTime] but the overriding template in a derived aspect doesn't. The <Template> placeholder is the called template.

In the following example, the type parameter T of the LogResultType template isn't marked with [CompileTime].

1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0276.Error;
5
6public class LogAttribute : OverrideMethodAspect
7{
8    public override dynamic? OverrideMethod()
9    {
        Error LAMA0276: The called template 'LogAttribute.LogResultType<int>()' has a run-time type parameter. The type parameters of a called template must be marked with [CompileTime].

10        LogResultType<int>();
11
12        return meta.Proceed();
13    }
14
15    // Error: the type parameter T of this called template is run-time.
16    [Template]
17    private void LogResultType<T>()
18    {
19        Console.WriteLine( $"{meta.Target.Method.Name} returns {typeof( T ).Name}." );
20    }
21}
22
1namespace Doc.LAMA0276.Error;
2
3internal class Calculator
4{
5    [Log]
6    public int Add( int a, int b ) => a + b;
7}
8

Resolution

Mark every type parameter of the called template with [CompileTime], including in overriding templates.

In the following example, T is a compile-time type parameter.

1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0276.Fixed;
5
6public class LogAttribute : OverrideMethodAspect
7{
8    public override dynamic? OverrideMethod()
9    {
10        LogResultType<int>();
11
12        return meta.Proceed();
13    }
14
15    // Fixed: the type parameter T is marked as compile-time.
16    [Template]
17    private void LogResultType<[CompileTime] T>()
18    {
19        Console.WriteLine( $"{meta.Target.Method.Name} returns {typeof( T ).Name}." );
20    }
21}
22
Source Code
1namespace Doc.LAMA0276.Fixed;
2


3internal class Calculator
4{
5    [Log]
6    public int Add( int a, int b ) => a + b;
7}
8
Transformed Code
1using System;
2
3namespace Doc.LAMA0276.Fixed;
4
5internal class Calculator
6{
7    [Log]
8    public int Add(int a, int b)
9    {
10        Console.WriteLine("Add returns Int32.");
11        return a + b;
12    }
13}
14

See also