}
if (hoisted == null) {
- hoisted = new HoistedLocalVariable (this, localVariable, GetVariableMangledName (localVariable));
+ hoisted = new HoistedLocalVariable (this, localVariable, GetVariableMangledName (ec, localVariable));
localVariable.HoistedVariant = hoisted;
if (hoisted_locals == null)
fexpr.EmitAssign (ec, source, false, false);
Instance = fexpr;
} else {
- var local = TemporaryVariableReference.Create (source.Type, block, Location);
+ var local = TemporaryVariableReference.Create (source.Type, block, Location, writeToSymbolFile: true);
if (source.Type.IsStruct) {
local.LocalInfo.CreateBuilder (ec);
} else {
return f_ind;
}
- protected virtual string GetVariableMangledName (LocalVariable local_info)
+ protected virtual string GetVariableMangledName (ResolveContext rc, LocalVariable local_info)
{
//
// No need to mangle anonymous method hoisted variables cause they
prev = null;
}
- var body = CompatibleMethodBody (ec, tic, null, delegate_type);
+ HashSet<LocalVariable> undeclaredVariables = null;
+ var body = CompatibleMethodBody (ec, tic, null, delegate_type, ref undeclaredVariables);
if (body != null) {
am = body.Compatible (ec, body);
} else {
if (TypeInferenceReportPrinter != null) {
ec.Report.SetPrinter (prev);
}
+
+ if (undeclaredVariables != null) {
+ body.Block.TopBlock.SetUndeclaredVariables (undeclaredVariables);
+ }
}
if (am == null)
if (compatibles.TryGetValue (type, out am))
return am;
+ if (type == InternalType.ErrorType)
+ return null;
+
TypeSpec delegate_type = CompatibleChecks (ec, type);
if (delegate_type == null)
return null;
// we satisfy the rule by setting the return type on the EmitContext
// to be the delegate type return type.
//
-
- var body = CompatibleMethodBody (ec, null, return_type, delegate_type);
+ HashSet<LocalVariable> undeclaredVariables = null;
+ var body = CompatibleMethodBody (ec, null, return_type, delegate_type, ref undeclaredVariables);
if (body == null)
return null;
throw;
} catch (Exception e) {
throw new InternalErrorException (e, loc);
+ } finally {
+ //
+ // LocalVariable is not stateless and it's not easy to clone because it's
+ // cached in toplevel block. Unsetting any initialized variables should
+ // be enough
+ //
+ if (undeclaredVariables != null) {
+ body.Block.TopBlock.SetUndeclaredVariables (undeclaredVariables);
+ }
}
if (!ec.IsInProbingMode && !etree_conversion) {
return ExprClassName;
}
- AnonymousMethodBody CompatibleMethodBody (ResolveContext ec, TypeInferenceContext tic, TypeSpec return_type, TypeSpec delegate_type)
+ AnonymousMethodBody CompatibleMethodBody (ResolveContext ec, TypeInferenceContext tic, TypeSpec return_type, TypeSpec delegate_type, ref HashSet<LocalVariable> undeclaredVariables)
{
ParametersCompiled p = ResolveParameters (ec, tic, delegate_type);
if (p == null)
return null;
- ParametersBlock b = ec.IsInProbingMode ? (ParametersBlock) Block.PerformClone () : Block;
+ ParametersBlock b = ec.IsInProbingMode ? (ParametersBlock) Block.PerformClone (ref undeclaredVariables) : Block;
if (b.IsAsync) {
var rt = return_type;