set_delegate_target_destroy_notify (lambda, new CCodeConstant ("NULL"));
}
set_delegate_target (lambda, delegate_target);
- } else if (get_this_type () != null) {
+ } else if (lambda.method.binding == MemberBinding.INSTANCE && get_this_type () != null) {
CCodeExpression delegate_target = get_result_cexpression ("self");
delegate_target = convert_to_generic_pointer (delegate_target, get_this_type ());
if (expr_owned || delegate_type.is_called_once) {
chainup/class-object.vala \
chainup/class-this.vala \
chainup/class-this-foo.vala \
+ chainup/class-with-lambda.vala \
chainup/method-lambda-base.vala \
chainup/no-chainup.vala \
chainup/struct-base.vala \
--- /dev/null
+public class Foo : Object {
+ public Foo.lambda_after () {
+ this ();
+ SourceFunc f = () => this != null;
+ assert (f ());
+ }
+
+ public Foo.lambda_before () {
+ SourceFunc f = () => {
+ SourceFunc g = () => true;
+ return g ();
+ };
+ this ();
+ assert (f ());
+ }
+}
+
+void main () {
+ Foo foo;
+ foo = new Foo.lambda_after ();
+ foo = new Foo.lambda_before ();
+}
method.check (context);
+ if (in_creation_method && method.this_parameter != null) {
+ if (!method.this_parameter.used) {
+ method.scope.remove ("this");
+ method.this_parameter = null;
+ method.binding = MemberBinding.STATIC;
+ } else if (m != null && m.this_parameter != null) {
+ // track usage inside nested lambda expressions
+ m.this_parameter.used |= method.this_parameter.used;
+ }
+ }
+
value_type = new MethodType (method);
value_type.value_owned = target_type.value_owned;
if (method.closure) {
method.get_captured_variables ((Collection<LocalVariable>) collection);
}
- if (in_creation_method) {
+ if (in_creation_method && method.this_parameter != null && method.this_parameter.used) {
Symbol sym = (Block) parent_statement.parent_node;
do {
sym = sym.parent_symbol;
inner.value_type = this_parameter.variable_type.copy ();
inner.value_type.value_owned = false;
inner.symbol_reference = this_parameter;
+ inner.symbol_reference.used = true;
symbol_reference = inner.value_type.get_member (member_name);
}
local.captured = true;
block.captured = true;
}
+
+ // track usage of instance parameter for flow analysis.
+ // When accessing generic type information, instance access
+ // is needed to copy/destroy generic values.
+ var generic_type = local.variable_type as GenericType;
+ if (generic_type != null && generic_type.type_parameter.parent_symbol is TypeSymbol) {
+ var m = context.analyzer.current_method_or_property_accessor as Method;
+ if (m != null && m.binding == MemberBinding.INSTANCE) {
+ m.this_parameter.used = true;
+ }
+ }
} else if (member is Parameter) {
var param = (Parameter) member;
var m = param.parent_symbol as Method;
acc.body.captured = true;
}
}
+
+ // track usage of instance parameter for flow analysis.
+ // When accessing generic type information, instance access
+ // is needed to copy/destroy generic values.
+ var generic_type = param.variable_type as GenericType;
+ if (generic_type != null && generic_type.type_parameter.parent_symbol is TypeSymbol) {
+ m = context.analyzer.current_method_or_property_accessor as Method;
+ if (m != null && m.binding == MemberBinding.INSTANCE) {
+ m.this_parameter.used = true;
+ }
+ }
} else if (member is Field) {
var f = (Field) member;
access = f.access;
inner.value_type = this_parameter.variable_type.copy ();
inner.value_type.value_owned = false;
inner.symbol_reference = this_parameter;
+ inner.symbol_reference.used = true;
} else {
check_lvalue_access ();
}