mapperly
mapperly copied to clipboard
UseDeepCloning generate Dictionary<string?, xxx> when mapping from nullable disable class file
- [x] I have read the documentation, including the FAQ
- [x] I can reproduce the bug using the latest prerelease version
- [x] I have searched existing discussion and issue to avoid duplicates
Describe the bug
The source generator does not respect generic type parameter constraint notnull on Dictionary TKey when mapping a class with #nullable disable
Instead of Dictionary<string?, xxx>, it should generate Dictionary<string, int>
Declaration code
#nullable enable
using Riok.Mapperly.Abstractions;
DataMapper.MapData(new Data());
[Mapper(UseDeepCloning = true)]
public static partial class DataMapper
{
public static partial Data MapData(Data data);
}
#nullable disable
public class Data
{
public int Id { get; set; }
public Dictionary<string, int> Attributes { get; set; }
}
Actual relevant generated code
// <auto-generated />
#nullable enable
public static partial class DataMapper
{
//...
[global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "4.1.1.0")]
private static global::System.Collections.Generic.Dictionary<string?, int> MapToDictionaryOfStringAndInt32(global::System.Collections.Generic.IReadOnlyDictionary<string?, int> source)
{
var target = new global::System.Collections.Generic.Dictionary<string?, int>(source.Count);
foreach (var item in source)
{
target[item.Key == null ? default : item.Key] = item.Value;
}
return target;
}
}
Expected relevant generated code
// <auto-generated />
#nullable enable
public static partial class DataMapper
{
// ...
[global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "4.1.1.0")]
private static global::System.Collections.Generic.Dictionary<string, int> MapToDictionaryOfStringAndInt32(global::System.Collections.Generic.IReadOnlyDictionary<string, int> source)
{
var target = new global::System.Collections.Generic.Dictionary<string, int>(source.Count);
foreach (var item in source)
{
target[item.Key == null ? default : item.Key] = item.Value;
}
return target;
}
}
Reported relevant diagnostics
-
Argument of type 'Dictionary<string, int>' cannot be used for parameter 'source' of type 'IReadOnlyDictionary<string?, int>' in 'Dictionary<string?, int> DataMapper.MapToDictionaryOfStringAndInt32(IReadOnlyDictionary<string?, int> source)' due to differences in the nullability of reference types. -
The type 'string?' cannot be used as type parameter 'TKey' in the generic type or method 'Dictionary<TKey, TValue>'. Nullability of type argument 'string?' doesn't match 'notnull' constraint.
Environment (please complete the following information):
- Mapperly Version: 4.1.1
- Nullable reference types:
enable - .NET Version: .NET 8.0
- Target Framework: net8.0
- Compiler Version: Compiler version: '4.12.0-3.24558.5 (21192bfc)'. Language version: 12.0.
- C# Language Version: 13
- IDE: console
- OS: windows 24H2