На GitHub'е написал кратко (
https://github.com/rsdn/nemerle/issues/601) — много букв для моего английского.
Для воспроизведения нужно:
1. Сборка, имя которой в алфавитном порядке идет после "Nemerle" (это ОБЯЗАТЕЛЬНОЕ условие для воспроизведения бага). Назовем ее Server. В сборке должен быть объявлен extension-метод, который возвращает (или имеет параметром, но в этом не уверен) какой-либо из типов Немерле. В данном примере это будет Nemerle.Core.option.
2. Сборка или приложение, которое использует сборку Server.
Сборка Server имеет следующий код:
public static class S
{
public static T(this _ : string) : option[int]
{
None();
}
}
Клиентское приложение использует extension-метод из Server:
using S;
module Program
{
Main() : void
{
_ = "a".T();
}
}
При компиляции клиентского приложения возникает ICE:
C:\Program Files (x86)\Nemerle\Net-4.0\Nemerle.MSBuild.targets(289,5): error : Internal compiler error 'wanted to cache cached value Nemerle.Core.option`1[T]', please report a bug to bugs.nemerle.org. You can try modifying program near this location.
C:\Program Files (x86)\Nemerle\Net-4.0\Nemerle.MSBuild.targets(289,5): error : internal compiler error: assertion failed in file ncc\external\LibraryReferenceManager.n, line 545: wanted to cache cached value Nemerle.Core.option`1[T]
at Nemerle.Compiler.LibraryReferenceManager.CacheTypeInfo(Type t, TypeInfo tc, Node node) in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\external\LibraryReferenceManager.n:line 545
at Nemerle.Compiler.LibraryReference.ExternalTypeInfo..ctor(LibraryReference lib, Type h, Node ns_node) in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\external\ExternalTypeInfo\ExternalTypeInfo.n:line 66
at Nemerle.Compiler.LibraryReference.ExternalNemerleTypeInfo..ctor(LibraryReference lib, Type h, Node ns_node) in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\external\ExternalTypeInfo\ExternalNemerleTypeInfo.n:line 55
at Nemerle.Compiler.LibraryReference.ConstructTypeInfo(Type reflected_type, Node ns_node) in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\external\LibraryReference.n:line 260
at Nemerle.Compiler.ExternalType.ConstructTypeInfo(Node node, Boolean fix_node) in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\external\ExternalType.n:line 55
at Nemerle.Compiler.NamespaceTree.Node.LookupType(list`1 split, Int32 args_count) in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\hierarchy\NamespaceTree.n:line 389
at Nemerle.Compiler.LibraryReference.TypeInfoOfType(Type framework_type) in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\external\LibraryReference.n:line 246
at Nemerle.Compiler.LibraryReference.TypeOfType(Map`2 _tenv, Type framework_type) in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\external\LibraryReference.n:line 203
at Nemerle.Compiler.LibraryReference.ExternalMethodInfo..ctor(Map`2 tenv, LibraryReference lib, MethodBase h) in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\external\ExternalMemberInfo\ExternalMethodInfo.n:line 66
at Nemerle.Compiler.LibraryReference.ExternalTypeInfo.imember_of_memberinfo(MemberInfo m) in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\external\ExternalTypeInfo\ExternalTypeInfo.n:line 660
at Nemerle.Compiler.LibraryReference.ExternalTypeInfo.collect_members() in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\external\ExternalTypeInfo\ExternalTypeInfo.n:line 692
at Nemerle.Compiler.LibraryReference.ExternalTypeInfo.LookupMemberImpl(String name) in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\external\ExternalTypeInfo\ExternalTypeInfo.n:line 735
at Nemerle.Compiler.LibraryReference.ExternalTypeInfo.GetMembers() in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\external\ExternalTypeInfo\ExternalTypeInfo.n:line 581
at Nemerle.Compiler.LibraryReference.ExternalTypeInfo.decode_extension_methods(LibraryReferenceManager mgr) in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\external\ExternalTypeInfo\ExternalTypeInfo.n:line 771
at Nemerle.Compiler.LibraryReference.ExternalTypeInfo..ctor(LibraryReference lib, Type h, Node ns_node) in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\external\ExternalTypeInfo\ExternalTypeInfo.n:line 150
at Nemerle.Compiler.LibraryReference.ConstructTypeInfo(Type reflected_type, Node ns_node) in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\external\LibraryReference.n:line 264
at Nemerle.Compiler.ExternalType.ConstructTypeInfo(Node node, Boolean fix_node) in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\external\ExternalType.n:line 55
at Nemerle.Compiler.NamespaceTree.Node.LookupType(list`1 split, Int32 args_count) in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\hierarchy\NamespaceTree.n:line 389
at Nemerle.Compiler.NamespaceTree.Node.LookupValue() in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\hierarchy\NamespaceTree.n:line 451
at Nemerle.Compiler.LibraryReferenceManager.LoadExtensions() in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\external\LibraryReferenceManager.n:line 470
at Nemerle.Compiler.ManagerClass._N__N_lambda__28193__28358.apply_void() in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\passes.n:line 641
at Nemerle.Compiler.ManagerClass._N_tryEx_28217(_N_closureOf_LoadExternalLibraries_28199 _N_LoadExternalLibraries_cp_28216, FunctionVoid f) in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\passes.n:line 594
at Nemerle.Compiler.ManagerClass.LoadExternalLibraries() in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\passes.n:line 643
at Nemerle.Compiler.ManagerClass.Run() in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\passes.n:line 676
at Nemerle.CommandlineCompiler.MainClass.main_with_catching() in C:\Projects\GitHub\Nemerle\nemerle-master\ncc\main.n:line 158
На номера строк не смотреть, это пересобранная мной версия, в ней могут быть отличия.
Механика возникновения ошибки следующая:
1. Из-за ошибки в определении наличия ссылки на Nemerle.dll (
https://github.com/rsdn/nemerle/issues/600) перед компиляцей не происходит заполнение кеша типов типами Nemerle.
2. Из-за того, что имя сборки Server в алфавитном порядке после Nemerle, сборка Server обрабатывается перед сборкой Nemerle (потому что используется сортировка в обратном порядке)
3. Компилятор загружает extension-методы в Nemerle.Compiler.LibraryReferenceManager.LoadExtensions. Находит наш метод S.S.T и пробует получить его возвращаемый тип из кеша. Из-за пп. 1 и 2 типа Nemerle.Core.option`1 еще нет в кеше. Тогда компилятор создает объект для этого типа.
4. Через Nemerle.Compiler.ExternalType.ConstructTypeInfo цепочка вызовов доходит до Nemerle.Compiler.LibraryReference.ConstructTypeInfo, где происходит обращение к Nemerle.Compiler.SystemTypeClass.NemerleAttribute.get.
5. Nemerle.Compiler.SystemTypeClass.NemerleAttribute.get смотрит на кеш, видит, что он еще не заполнен типами Nemerle, и дергает Nemerle.Compiler.InternalTypeClass.InitNemerleTypes, где и происходит загрузка типов Nemerle, в том числе и Nemerle.Core.option. Встроенные типы благополучно помещены в кеш.
6. Происходит возврат на п. 3. Компилятор получил объект для типа Nemerle.Core.option. И так как ранее этого объекта не было в кеше, то компилятор его туда пытается поместить. Но "охранник" кеша его не пропускает и выбрасывает ICE.
По идее исправление определения наличия ссылки на Nemerle.dll (
https://github.com/rsdn/nemerle/issues/600) должно исправить ситуацию.
Также было бы полезно исправить сортировку списка сборок, чтобы всегда вначале шли System и mscorlib, потом Nemerle, а потом уже все остальные.
Поправил бы сам, но нет доступа к репозиторию на GitHub'е.
Здравствуйте, /Forester/, Вы писали:
F>По идее исправление определения наличия ссылки на Nemerle.dll (https://github.com/rsdn/nemerle/issues/600) должно исправить ситуацию.
F>Также было бы полезно исправить сортировку списка сборок, чтобы всегда вначале шли System и mscorlib, потом Nemerle, а потом уже все остальные.
F>Поправил бы сам, но нет доступа к репозиторию на GitHub'е.
Можно делать пул реквесты.
Делаем свой клон , меняем что хотим, а потом на сайте GitHub нажимаем pull request.
http://yangsu.github.io/pull-request-tutorial/
https://help.github.com/articles/creating-a-pull-request