This repository was archived by the owner on Jul 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 151
This repository was archived by the owner on Jul 15, 2023. It is now read-only.
CCRewrite fails with NRE on async method with Ensures.ForAll with captured params because forwarder is null #72
Copy link
Copy link
Closed
Milestone
Description
There is another issue with CCRewrite when Contract.Ensures contains Ensures.ForAll with captured lambda. Related issue #69.
Following code lead to another NRE:
class NonGen {
public async Task<List<int>> FooAsync(int limit)
{
Contract.Ensures(Contract.ForAll(Contract.Result<List<int>>(), i => i < limit));
await Task.Delay(42);
return new List<int>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
}
}Trying to use this method lead to NRE at Rewriter.cs:3994:
public override Expression VisitLocal(Local local)
{
if (HelperMethods.IsClosureType(this.declaringType, local.Type))
{
MemberBinding mb;
if (!closureLocals.TryGetValue(local, out mb))
{
// Next line will fail, because this.forwareder is null!
var closureField = new Field(this.closureClass, null, FieldFlags.Public, local.Name, this.forwarder.VisitTypeReference(local.Type), null);
this.closureClass.Members.Add(closureField);
mb = new MemberBinding(this.checkMethod.ThisParameter, closureField);
closureLocals.Add(local, mb);
// initialize the closure field
var instantiatedField = GetMemberInstanceReference(closureField, this.closureClassInstance);
this.ClosureInitializer.Statements.Add(new AssignmentStatement(new MemberBinding(this.ClosureLocal, instantiatedField), local));
}
return mb;
}
return local;
}This issue is similar to #69 but the reason is different. This time the root cause is following code in Rewriter.cs (in `EmitAsyncClosure):
if (from.IsGeneric)
{
this.closureClass.TemplateParameters = new TypeNodeList();
var parentCount = this.declaringType.ConsolidatedTemplateParameters == null ? 0 : this.declaringType.ConsolidatedTemplateParameters.Count;
for (int i = 0; i < from.TemplateParameters.Count; i++)
{
var tp = HelperMethods.NewEqualTypeParameter(dup, (ITypeParameter)from.TemplateParameters[i], this.closureClass, parentCount + i);
this.closureClass.TemplateParameters.Add(tp);
}
this.closureClass.IsGeneric = true;
this.closureClass.EnsureMangledName();
this.forwarder = new Specializer(this.declaringType.DeclaringModule, from.TemplateParameters, this.closureClass.TemplateParameters);
this.forwarder.VisitTypeParameterList(this.closureClass.TemplateParameters);
taskType = this.forwarder.VisitTypeReference(taskType);
}
else
{
// In this case forwarder is NULL!
this.closureClassInstance = this.closureClass;
}
```c#Reactions are currently unavailable