| 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
1namespace Doc.LAMA0276.Fixed;
2
3internal class Calculator
4{
5 [Log]
6 public int Add( int a, int b ) => a + b;
7}
8
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