Skip to content

Commit

Permalink
#1759: Follow-up: Handle nested generic arguments as well.
Browse files Browse the repository at this point in the history
  • Loading branch information
siegfriedpammer committed Oct 31, 2019
1 parent fba6ab9 commit 413c9eb
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -376,5 +376,14 @@ public static Func<TCaptured> CapturedTypeParameter1<TNonCaptured, TCaptured>(TN
return captured;
};
}

public static Func<TCaptured> CapturedTypeParameter2<TNonCaptured, TCaptured>(TNonCaptured a, Func<TNonCaptured, List<TCaptured>> f)
{
List<TCaptured> captured = f(a);
return delegate {
Console.WriteLine(captured.GetType().FullName);
return captured.FirstOrDefault();
};
}
}
}
27 changes: 10 additions & 17 deletions ICSharpCode.Decompiler/IL/Transforms/TransformDisplayClassUsage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,10 @@ protected internal override void VisitStObj(StObj inst)
// Get display class info
if (!IsDisplayClassLoad(target, out var displayClassLoad) || !displayClasses.TryGetValue(displayClassLoad, out var displayClass))
return;
// We want the specialized version, so that display-class type parameters are
// substituted with the type parameters from the use-site.
var fieldType = field.Type;
// However, use the unspecialized member definition to make reference comparisons in dictionary possible.
field = (IField)field.MemberDefinition;
if (displayClass.Variables.TryGetValue(field, out DisplayClassVariable info)) {
// If the display class field was previously initialized, we use a simple assignment.
Expand All @@ -321,7 +325,7 @@ protected internal override void VisitStObj(StObj inst)
if (displayClass.IsMono && displayClass.CaptureScope == null && !IsOuterClosureReference(field)) {
displayClass.CaptureScope = BlockContainer.FindClosestContainer(inst);
}
v = displayClass.DeclaringFunction.RegisterVariable(VariableKind.Local, GetVariableTypeFromClosureField(field), field.Name);
v = displayClass.DeclaringFunction.RegisterVariable(VariableKind.Local, fieldType, field.Name);
v.HasInitialValue = true;
v.CaptureScope = displayClass.CaptureScope;
inst.ReplaceWith(new StLoc(v, inst.Value).WithILRange(inst));
Expand Down Expand Up @@ -365,12 +369,16 @@ protected internal override void VisitLdFlda(LdFlda inst)
// Get display class info
if (!IsDisplayClassLoad(inst.Target, out var displayClassLoad) || !displayClasses.TryGetValue(displayClassLoad, out var displayClass))
return;
// Use the unspecialized member definition to make reference comparisons in dictionary possible.
var field = (IField)inst.Field.MemberDefinition;
// However, we want the specialized version, so that display-class type parameters are
// substituted with the type parameters from the use-site.
var fieldType = inst.Field.Type;
if (!displayClass.Variables.TryGetValue(field, out DisplayClassVariable info)) {
context.Step($"Introduce captured variable for {field.FullName}", inst);
// Introduce a fresh variable for the display class field.
Debug.Assert(displayClass.Definition == field.DeclaringTypeDefinition);
var v = displayClass.DeclaringFunction.RegisterVariable(VariableKind.Local, GetVariableTypeFromClosureField(field), field.Name);
var v = displayClass.DeclaringFunction.RegisterVariable(VariableKind.Local, fieldType, field.Name);
v.HasInitialValue = true;
v.CaptureScope = displayClass.CaptureScope;
inst.ReplaceWith(new LdLoca(v).WithILRange(inst));
Expand All @@ -381,20 +389,5 @@ protected internal override void VisitLdFlda(LdFlda inst)
Debug.Fail("LdFlda pattern not supported!");
}
}

private IType GetVariableTypeFromClosureField(IField field)
{
if (!(field.Type is ITypeParameter typeParameter))
return field.Type;
var rootMethod = context.Function.Method;
if (typeParameter.Owner != field.DeclaringTypeDefinition)
return field.Type;
if (typeParameter.Index >= rootMethod.TypeParameters.Count) {
Debug.Assert(false, "Cannot map display-class type parameter to method type parameter");
return field.Type;
}

return rootMethod.TypeParameters[typeParameter.Index];
}
}
}

0 comments on commit 413c9eb

Please sign in to comment.