Skip to content

JSpecify: False positive error for nullable source with nullable-param non-null-return method #4086

Description

@RaniAgus

Expected behavior

When a @Nullable source property is mapped to a @NonNull constructor parameter via a reused mapping method that accepts @Nullable (explicitly handles null) and returns a non-null value, the mapping should compile successfully. The reused method's parameter and return type annotations prove the mapping is safe - null is handled and the result is guaranteed non-null.

Given:

@Mapper
public interface Issue4086Mapper {
    @Mapping(target = "payload", source = "value", qualifiedByName = "mapValue")
    Target map(Source source);

    @Named("mapValue")
    default Target.Nested mapValue(@Nullable String value) {
        return value == null ? new Target.Nested( "default" ) : new Target.Nested( value );
    }
}

public class Source {
    private String value;
    public @Nullable String getValue() { return value; }
}

public class Target {
    private final Nested payload;
    public Target(@NonNull Nested payload) { this.payload = payload; }
}

Expected: compilation succeeds with:

public Target map(Source source) {
    Target.Nested payload = mapValue( source.getValue() );
    Target target = new Target( payload );
    return target;
}

Actual behavior

Compilation fails with:

error: Can't map potentially nullable source property "value" to @NonNull
constructor parameter "payload". Consider adding a defaultValue or defaultExpression.

The current check only inspects the source getter chain nullability, which reports NULLABLE. It does not consider that the assignment was resolved through a reused method whose parameter is @Nullable (no null guard needed before the call) and whose return type is @NonNull (the result is guaranteed non-null).

Steps to reproduce the problem

A @Nullable source property mapped to a @NonNull constructor parameter
via qualifiedByName referencing a method with @Nullable parameter and non-null return. Can be reproduced in this branch: main...RaniAgus:mapstruct:issues/4086

MapStruct Version

1.7.0.Beta2

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions