From 52c06493c68deb692065e13718f8c658dba43a8c Mon Sep 17 00:00:00 2001 From: Vlad Zarytovskii Date: Tue, 8 Oct 2024 14:46:53 +0200 Subject: [PATCH 1/6] Update azure-pipelines.yml --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index a8155022e68..b4f235359af 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -35,7 +35,7 @@ variables: # (since for all *new* release branches we insert into VS main and for all *previous* releases we insert into corresponding VS release), # i.e. 'rel/d17.9' *or* 'main' in dotnet/fsharp/refs/heads/main and 'main' in F# dotnet/fsharp/refs/heads/release/dev17.10 (latest release branch) - name: VSInsertionTargetBranchName - value: rel/d17.12 + value: main - name: _TeamName value: FSharp - name: TeamName From 1827c9be74391abec506d37fb659f28fde47641b Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Wed, 9 Oct 2024 04:47:49 -0700 Subject: [PATCH 2/6] Localized file check-in by OneLocBuild Task: Build definition ID 499: Build ID 2555417 (#17854) --- .../FSharp.Editor/xlf/FSharp.Editor.cs.xlf | 21 +++++++++---------- .../FSharp.Editor/xlf/FSharp.Editor.de.xlf | 21 +++++++++---------- .../FSharp.Editor/xlf/FSharp.Editor.es.xlf | 19 ++++++++--------- .../FSharp.Editor/xlf/FSharp.Editor.fr.xlf | 19 ++++++++--------- .../FSharp.Editor/xlf/FSharp.Editor.it.xlf | 21 +++++++++---------- .../FSharp.Editor/xlf/FSharp.Editor.ja.xlf | 19 ++++++++--------- .../FSharp.Editor/xlf/FSharp.Editor.ko.xlf | 19 ++++++++--------- .../FSharp.Editor/xlf/FSharp.Editor.pl.xlf | 21 +++++++++---------- .../FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf | 21 +++++++++---------- .../FSharp.Editor/xlf/FSharp.Editor.ru.xlf | 21 +++++++++---------- .../FSharp.Editor/xlf/FSharp.Editor.tr.xlf | 21 +++++++++---------- .../xlf/FSharp.Editor.zh-Hans.xlf | 19 ++++++++--------- .../xlf/FSharp.Editor.zh-Hant.xlf | 21 +++++++++---------- 13 files changed, 125 insertions(+), 138 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.cs.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.cs.xlf index 421cc037111..ab212d44291 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.cs.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.cs.xlf @@ -175,17 +175,16 @@ Parallelization (requires restart); Enable parallel type checking with signature files; Enable parallel reference resolution; Enable fast find references & rename (restart required) - Možnosti výkonu pro ukládání do mezipaměti a projekt F#; -Povolit odkazy mezi projekty v paměti; -Povolit_částečnou_kontrolu_typu; -Možnosti výkonu pro IntelliSense; -Povolit zastaralá data pro funkce IntelliSense; -Doba, do kdy se budou používat zastaralé výsledky (v milisekundách); -Paralelizace (vyžaduje restartování); -Povolit paralelní kontrolu typů pomocí souborů podpisu; -Povolit paralelní referenční rozlišení; -Povolit odkazy rychlého hledání a přejmenování (vyžaduje se restartování); -Výsledky analýzy mezipaměti (experimentální) + F# Project and Caching Performance Options; +Enable in-memory cross project references; +Enable_partial_type_checking; +IntelliSense Performance Options; +Enable stale data for IntelliSense features; +Time until stale results are used (in milliseconds); +Parallelization (requires restart); +Enable parallel type checking with signature files; +Enable parallel reference resolution; +Enable fast find references & rename (restart required) diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.de.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.de.xlf index ff2a415b3a0..631ae04fdba 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.de.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.de.xlf @@ -175,17 +175,16 @@ Parallelization (requires restart); Enable parallel type checking with signature files; Enable parallel reference resolution; Enable fast find references & rename (restart required) - Optionen zur F#-Projekt- und Cacheleistung; -Proj_ektübergreifende Verweise im Arbeitsspeicher aktivieren; -Aktivieren der partiellen Typüberprüfung; -Optionen zur IntelliSense-Leistung; -Veraltete Daten für IntelliSense-Features aktivieren; -Zeit bis zur Verwendung veralteter Ergebnisse (in Millisekunden); -Parallelisierung (Neustart erforderlich); -Parallele Typüberprüfung mit Signaturdateien aktivieren; -Parallele Verweisauflösung aktivieren; -Schnellsuche und Umbenennen von Verweisen aktivieren (Neustart erforderlich); -Cacheanalyseergebnisse (experimentell) + F# Project and Caching Performance Options; +Enable in-memory cross project references; +Enable_partial_type_checking; +IntelliSense Performance Options; +Enable stale data for IntelliSense features; +Time until stale results are used (in milliseconds); +Parallelization (requires restart); +Enable parallel type checking with signature files; +Enable parallel reference resolution; +Enable fast find references & rename (restart required) diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.es.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.es.xlf index 5df84b54acc..f992a8c96c1 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.es.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.es.xlf @@ -175,17 +175,16 @@ Parallelization (requires restart); Enable parallel type checking with signature files; Enable parallel reference resolution; Enable fast find references & rename (restart required) - Opciones de rendimiento de almacenamiento en caché y proyectos de F#; -Habilitar referencias entre proyectos en memoria; + F# Project and Caching Performance Options; +Enable in-memory cross project references; Enable_partial_type_checking; -Opciones de rendimiento de IntelliSense; -Habilitar datos obsoletos para características de IntelliSense; -Tiempo hasta que se utilizan los resultados obsoletos (en milisegundos); -Paralelización (requiere reiniciar); -Habilitar la comprobación de tipos paralelos con archivos de firma; -Habilitar resolución de referencias paralelas; -Habilitar referencias de búsqueda rápida y cambio de nombre (es necesario reiniciar); -Resultados del análisis de la caché (experimental) +IntelliSense Performance Options; +Enable stale data for IntelliSense features; +Time until stale results are used (in milliseconds); +Parallelization (requires restart); +Enable parallel type checking with signature files; +Enable parallel reference resolution; +Enable fast find references & rename (restart required) diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.fr.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.fr.xlf index efe15d65037..d9d1bc001e9 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.fr.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.fr.xlf @@ -175,17 +175,16 @@ Parallelization (requires restart); Enable parallel type checking with signature files; Enable parallel reference resolution; Enable fast find references & rename (restart required) - Options relatives aux performances de la mise en cache et des projets F#; -Activer les références de projet croisé en mémoire; + F# Project and Caching Performance Options; +Enable in-memory cross project references; Enable_partial_type_checking; -Options relatives aux performances d’IntelliSense; -Activer les données périmées pour les fonctionnalités IntelliSense; -Délai avant l’utilisation des résultats périmés (en millisecondes); -Parallélisation (Nécessite un redémarrage); -Activer la vérification de type parallèle avec les fichiers de signature; -Activer la résolution de référence parallèle; -Activer la recherche rapide de références et le renommage (redémarrage requis); -Résultats de l’analyse du cache (expérimental) +IntelliSense Performance Options; +Enable stale data for IntelliSense features; +Time until stale results are used (in milliseconds); +Parallelization (requires restart); +Enable parallel type checking with signature files; +Enable parallel reference resolution; +Enable fast find references & rename (restart required) diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.it.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.it.xlf index ca32c029946..cc9ed2b2272 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.it.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.it.xlf @@ -175,17 +175,16 @@ Parallelization (requires restart); Enable parallel type checking with signature files; Enable parallel reference resolution; Enable fast find references & rename (restart required) - Opzioni per le prestazioni di memorizzazione nella cache e progetti F#; -_Abilita i riferimenti tra progetti in memoria; -Abilita il controllo parziale dei tipi; -Opzioni per le prestazioni IntelliSense; -Abilita dati non aggiornati per le funzionalità IntelliSense; -Intervallo di utilizzo dei risultati non aggiornati (in millisecondi); -Parallelizzazione (richiede il riavvio); -Abilitare il controllo dei tipi paralleli con i file di firma; -Abilitare risoluzione riferimenti paralleli; -Abilitare i riferimenti di ricerca rapida > ridenominazione (riavvio necessario); -Risultati dell'analisi della cache (sperimentale) + F# Project and Caching Performance Options; +Enable in-memory cross project references; +Enable_partial_type_checking; +IntelliSense Performance Options; +Enable stale data for IntelliSense features; +Time until stale results are used (in milliseconds); +Parallelization (requires restart); +Enable parallel type checking with signature files; +Enable parallel reference resolution; +Enable fast find references & rename (restart required) diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ja.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ja.xlf index 44ca609e1cd..0adc031ebe8 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ja.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ja.xlf @@ -175,17 +175,16 @@ Parallelization (requires restart); Enable parallel type checking with signature files; Enable parallel reference resolution; Enable fast find references & rename (restart required) - F# プロジェクトとキャッシュのパフォーマンス オプション; -メモリ内のプロジェクト間参照を有効にする; + F# Project and Caching Performance Options; +Enable in-memory cross project references; Enable_partial_type_checking; -IntelliSense のパフォーマンス オプション; -IntelliSense 機能に対して古いデータを有効にする; -古い結果が使用されるまでの時間 (ミリ秒); -並列化 (再起動が必要); -署名ファイルを使用して並列型チェックを有効にする; -並列参照解決を有効にする; -高速検索参照と名前の変更を有効にする (再起動が必要); -キャッシュ解析の結果 (試験段階) +IntelliSense Performance Options; +Enable stale data for IntelliSense features; +Time until stale results are used (in milliseconds); +Parallelization (requires restart); +Enable parallel type checking with signature files; +Enable parallel reference resolution; +Enable fast find references & rename (restart required) diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ko.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ko.xlf index 66cfbeed575..652fddc41ce 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ko.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ko.xlf @@ -175,17 +175,16 @@ Parallelization (requires restart); Enable parallel type checking with signature files; Enable parallel reference resolution; Enable fast find references & rename (restart required) - F# 프로젝트 및 캐싱 성능 옵션; -메모리 내 크로스 프로젝트 참조 사용; + F# Project and Caching Performance Options; +Enable in-memory cross project references; Enable_partial_type_checking; -IntelliSense 성능 옵션; -IntelliSense 기능에 대해 부실 데이터 사용; -부실 결과가 사용될 때까지의 시간(밀리초); -병렬화(다시 시작 필요); -서명 파일로 병렬 유형 검사 사용; -병렬 참조 해상도 사용; -빠른 찾기 참조 및 이름 바꾸기 사용(다시 시작 필요); -캐시 구문 분석 결과(실험적) +IntelliSense Performance Options; +Enable stale data for IntelliSense features; +Time until stale results are used (in milliseconds); +Parallelization (requires restart); +Enable parallel type checking with signature files; +Enable parallel reference resolution; +Enable fast find references & rename (restart required) diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pl.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pl.xlf index 1675887bd6d..eeac9d3b2bb 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pl.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pl.xlf @@ -175,17 +175,16 @@ Parallelization (requires restart); Enable parallel type checking with signature files; Enable parallel reference resolution; Enable fast find references & rename (restart required) - Opcje wydajności projektu i buforowania języka F#; -Włącz odwołania między projektami w pamięci; -Włącz_częściową_kontrolę_typu; -Opcje wydajności funkcji IntelliSense; -Włącz nieaktualne dane na potrzeby funkcji IntelliSense; -Czas do użycia nieaktualnych wyników (w milisekundach); -Równoległość (wymaga ponownego uruchomienia); -Włącz równoległą kontrolę typu za pomocą plików sygnatury; -Włącz równoległe rozpoznawanie odwołań; -Włącz szybkie znajdowanie odwołań i zmień nazwę (wymagane ponowne uruchomienie); -Wyniki analizy pamięci podręcznej (eksperymentalne) + F# Project and Caching Performance Options; +Enable in-memory cross project references; +Enable_partial_type_checking; +IntelliSense Performance Options; +Enable stale data for IntelliSense features; +Time until stale results are used (in milliseconds); +Parallelization (requires restart); +Enable parallel type checking with signature files; +Enable parallel reference resolution; +Enable fast find references & rename (restart required) diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf index f6770d970de..9683ea413cf 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf @@ -175,17 +175,16 @@ Parallelization (requires restart); Enable parallel type checking with signature files; Enable parallel reference resolution; Enable fast find references & rename (restart required) - Projeto em F# e opções de desempenho em cache; -_Habilitar referências de projeto cruzado na memória; -Habilitar verificação parcial de tipo; -Opções de desempenho do IntelliSense; -Habilitar dados obsoletos para os recursos do IntelliSense; -Tempo até que os resultados obsoletos sejam utilizados (em milissegundos); -Paralelização (requer reinicialização); -Habilitar a verificação de tipo paralelo com arquivos de assinatura; -Habilitar a resolução de referência paralela; -Habilitar referências de localização rápida e renomear (reinicialização necessária); -Resultados da análise de cache (experimental) + F# Project and Caching Performance Options; +Enable in-memory cross project references; +Enable_partial_type_checking; +IntelliSense Performance Options; +Enable stale data for IntelliSense features; +Time until stale results are used (in milliseconds); +Parallelization (requires restart); +Enable parallel type checking with signature files; +Enable parallel reference resolution; +Enable fast find references & rename (restart required) diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ru.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ru.xlf index bc8554237a8..3bebb1c9b5d 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ru.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ru.xlf @@ -175,17 +175,16 @@ Parallelization (requires restart); Enable parallel type checking with signature files; Enable parallel reference resolution; Enable fast find references & rename (restart required) - Параметры производительности проекта и кэширования F#; -Включить перекрестные ссылки проектов в памяти; -Enable_partial_type_checking; -Параметры производительности IntelliSense; -Включите устаревшие данные для функций IntelliSense; -Время до использования устаревших результатов (в миллисекундах); -Распараллеливание (требуется перезагрузка); -Включить параллельную проверку типов с файлами сигнатур; -Включить параллельное разрешение ссылок; -Включить быстрый поиск ссылок и переименование (требуется перезагрузка); -Результаты анализа кэша (экспериментальная функция) + F# Project and Caching Performance Options; +Enable in-memory cross project references; +Enable_partial_type_checking; +IntelliSense Performance Options; +Enable stale data for IntelliSense features; +Time until stale results are used (in milliseconds); +Parallelization (requires restart); +Enable parallel type checking with signature files; +Enable parallel reference resolution; +Enable fast find references & rename (restart required) diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.tr.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.tr.xlf index cf2198ba7d3..eb1b210d3b9 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.tr.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.tr.xlf @@ -175,17 +175,16 @@ Parallelization (requires restart); Enable parallel type checking with signature files; Enable parallel reference resolution; Enable fast find references & rename (restart required) - F# Proje ve Önbelleğe Alma Performansı Seçenekleri; -Bellek içi çapraz proje başvurularını etkinleştir; -Kısmi_tür_denetlemeyi_etkinleştir; -IntelliSense Performans Seçenekleri; -IntelliSense özellikleri için eski verileri etkinleştir; -Eski sonuçların kullanılması için geçecek süre (milisaniye cinsinden); -Paralelleştirme (yeniden başlatma gerektirir); -İmza dosyalarıyla paralel tür denetlemeyi etkinleştir; -Paralel başvuru çözümlemeyi etkinleştir; -Başvuruları hızlı bulmayı ve yeniden adlandırmayı etkinleştir (yeniden başlatma gerektirir); -Ayrıştırma sonuçlarını önbelleğe al (deneysel) + F# Project and Caching Performance Options; +Enable in-memory cross project references; +Enable_partial_type_checking; +IntelliSense Performance Options; +Enable stale data for IntelliSense features; +Time until stale results are used (in milliseconds); +Parallelization (requires restart); +Enable parallel type checking with signature files; +Enable parallel reference resolution; +Enable fast find references & rename (restart required) diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hans.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hans.xlf index 16a89acc021..ea215c62094 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hans.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hans.xlf @@ -175,17 +175,16 @@ Parallelization (requires restart); Enable parallel type checking with signature files; Enable parallel reference resolution; Enable fast find references & rename (restart required) - F# 项目和缓存性能选项; -启用内存中跨项目引用; + F# Project and Caching Performance Options; +Enable in-memory cross project references; Enable_partial_type_checking; -IntelliSense 性能选项; -为 IntelliSense 功能启用过时数据; -使用过时结果前等待的时间(以毫秒计); -并行化(需要重启); -使用签名文件启用并行类型检查; -启用并行引用解析; -启用快速查找引用和重命名(需要重新启动); -缓存分析结果(实验性) +IntelliSense Performance Options; +Enable stale data for IntelliSense features; +Time until stale results are used (in milliseconds); +Parallelization (requires restart); +Enable parallel type checking with signature files; +Enable parallel reference resolution; +Enable fast find references & rename (restart required) diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hant.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hant.xlf index 932d4de3e61..de00bd4aaf3 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hant.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hant.xlf @@ -175,17 +175,16 @@ Parallelization (requires restart); Enable parallel type checking with signature files; Enable parallel reference resolution; Enable fast find references & rename (restart required) - F# 專案與快取效能選項; -允許記憶體內跨專案參考; -啟用部分型別檢查; -IntelliSense 效能選項; -為 IntelliSense 功能啟用過時資料; -使用過時結果前等待的時間 (毫秒); -平行處理 (需要重新啟動); -啟用簽章檔案的平行類型檢查; -啟用平行參考解析; -啟用快速尋找參考和重新命名 (需要重新啟動); -快取剖析結果 (實驗性) + F# Project and Caching Performance Options; +Enable in-memory cross project references; +Enable_partial_type_checking; +IntelliSense Performance Options; +Enable stale data for IntelliSense features; +Time until stale results are used (in milliseconds); +Parallelization (requires restart); +Enable parallel type checking with signature files; +Enable parallel reference resolution; +Enable fast find references & rename (restart required) From 4c6860a2c10259dd462e6a7fc5968fdc2cea5b83 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Wed, 23 Oct 2024 08:17:45 -0700 Subject: [PATCH 3/6] Localized file check-in by OneLocBuild Task: Build definition ID 499: Build ID 2567162 (#17912) * Localized file check-in by OneLocBuild Task: Build definition ID 499: Build ID 2567162 * Localized file check-in by OneLocBuild Task: Build definition ID 499: Build ID 2567162 --- src/Compiler/xlf/FSComp.txt.cs.xlf | 2 +- src/Compiler/xlf/FSComp.txt.de.xlf | 2 +- src/Compiler/xlf/FSComp.txt.es.xlf | 2 +- src/Compiler/xlf/FSComp.txt.fr.xlf | 2 +- src/Compiler/xlf/FSComp.txt.it.xlf | 2 +- src/Compiler/xlf/FSComp.txt.ja.xlf | 2 +- src/Compiler/xlf/FSComp.txt.ko.xlf | 2 +- src/Compiler/xlf/FSComp.txt.pl.xlf | 2 +- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 2 +- src/Compiler/xlf/FSComp.txt.ru.xlf | 2 +- src/Compiler/xlf/FSComp.txt.tr.xlf | 2 +- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 2 +- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 4a6bbf58d2f..9b2ffab9f29 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -4534,7 +4534,7 @@ Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq {{ ... }}' - Neplatný výraz záznamu, pořadí nebo výpočtu. Výrazy pořadí by měly mít notaci seq {{ ... }}. + Neplatný výraz záznamu, pořadí nebo výpočtu. Výrazy pořadí by měly mít notaci seq {{ ... }}. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 1546541aee7..5f13e448790 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -4534,7 +4534,7 @@ Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq {{ ... }}' - Ungültiger Datensatz-, Sequenz- oder Berechnungsausdruck. Sequenzausdrücke müssen das Format "seq {{ ... }}" besitzen. + Ungültiger Datensatz-, Sequenz- oder Berechnungsausdruck. Sequenzausdrücke müssen das Format "seq {{ ... }}" besitzen. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index db357235565..b0dad7f5a49 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -4534,7 +4534,7 @@ Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq {{ ... }}' - Expresión de registro, secuencia o cómputo no válida. Las expresiones de secuencia deben tener el formato 'seq {{ ... }}'. + Expresión de registro, secuencia o cómputo no válida. Las expresiones de secuencia deben tener el formato 'seq {{ ... }}'. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index dca6fe2b78d..27dcef8fed2 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -4534,7 +4534,7 @@ Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq {{ ... }}' - Expression d'enregistrement, de séquence ou de calcul non valide. Les expressions de séquence doivent avoir le format 'seq {{ ... }}' + Expression d'enregistrement, de séquence ou de calcul non valide. Les expressions de séquence doivent avoir le format 'seq {{ ... }}' diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 0d2815aa9b2..a33315b7e24 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -4534,7 +4534,7 @@ Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq {{ ... }}' - Espressione di calcolo, sequenza o record non valida. Il formato delle espressioni sequenza deve essere 'seq {{ ... }}' + Espressione di calcolo, sequenza o record non valida. Il formato delle espressioni sequenza deve essere 'seq {{ ... }}' diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index d660cf6768b..a237ca44974 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -4534,7 +4534,7 @@ Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq {{ ... }}' - 無効なレコード、シーケンス式、またはコンピュテーション式です。シーケンス式は 'seq {{ ... }}' という形式にしてください。 + 無効なレコード、シーケンス式、またはコンピュテーション式です。シーケンス式は 'seq {{ ... }}' という形式にしてください。 diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index a0f3d1411b4..91cbc9d876d 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -4534,7 +4534,7 @@ Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq {{ ... }}' - 레코드, 시퀀스 또는 계산 식이 잘못되었습니다. 시퀀스 식의 형식은 'seq {{ ... }}'여야 합니다. + 레코드, 시퀀스 또는 계산 식이 잘못되었습니다. 시퀀스 식의 형식은 'seq {{ ... }}'여야 합니다. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index fcb2638d5a2..f68b13a24f0 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -4534,7 +4534,7 @@ Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq {{ ... }}' - Nieprawidłowe wyrażenie rekordu, sekwencji lub obliczenia. Wyrażenia sekwencji powinny mieć postać „seq {{ ... }}” + Nieprawidłowe wyrażenie rekordu, sekwencji lub obliczenia. Wyrażenia sekwencji powinny mieć postać „seq {{ ... }}” diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index a27487e1c20..464bcbdd957 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -4534,7 +4534,7 @@ Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq {{ ... }}' - Expressão de registro, sequência ou computação inválida. Expressões de sequência devem estar na forma 'seq {{ ... }}' + Expressão de registro, sequência ou computação inválida. Expressões de sequência devem estar na forma 'seq {{ ... }}' diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 18c6c501759..2879f5abd34 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -4534,7 +4534,7 @@ Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq {{ ... }}' - Недопустимая запись, выражение последовательности или вычислительное выражение. Выражения последовательностей должны иметь форму "seq {{ ... }}' + Недопустимая запись, выражение последовательности или вычислительное выражение. Выражения последовательностей должны иметь форму "seq {{ ... }}' diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 94a7a284470..ebf62e5469e 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -4534,7 +4534,7 @@ Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq {{ ... }}' - Geçersiz kayıt, dizi veya hesaplama ifadesi. Dizi ifadeleri 'seq {{ ... }}' biçiminde olmalıdır + Geçersiz kayıt, dizi veya hesaplama ifadesi. Dizi ifadeleri 'seq {{ ... }}' biçiminde olmalıdır diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index ba5826eb686..397a6066139 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -4534,7 +4534,7 @@ Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq {{ ... }}' - 记录、序列或计算表达式无效。序列表达式的格式应为“seq {{ ... }}” + 记录、序列或计算表达式无效。序列表达式的格式应为“seq {{ ... }}” diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index b039caf9e93..4fd20e12e57 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -4534,7 +4534,7 @@ Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq {{ ... }}' - 無效的記錄、循序項或計算運算式。循序項運算式應該是 'seq {{ ... }}' 形式。 + 無效的記錄、循序項或計算運算式。循序項運算式應該是 'seq {{ ... }}' 形式。 From 005de12e29fb6ccf48c57eb5026d629458322d34 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Fri, 8 Nov 2024 09:39:37 +0100 Subject: [PATCH 4/6] Localized file check-in by OneLocBuild Task: Build definition ID 499: Build ID 2577103 (#17970) --- src/Compiler/xlf/FSStrings.cs.xlf | 2 +- src/Compiler/xlf/FSStrings.de.xlf | 2 +- src/Compiler/xlf/FSStrings.es.xlf | 2 +- src/Compiler/xlf/FSStrings.fr.xlf | 2 +- src/Compiler/xlf/FSStrings.it.xlf | 2 +- src/Compiler/xlf/FSStrings.ja.xlf | 2 +- src/Compiler/xlf/FSStrings.ko.xlf | 2 +- src/Compiler/xlf/FSStrings.pl.xlf | 2 +- src/Compiler/xlf/FSStrings.pt-BR.xlf | 2 +- src/Compiler/xlf/FSStrings.ru.xlf | 2 +- src/Compiler/xlf/FSStrings.tr.xlf | 2 +- src/Compiler/xlf/FSStrings.zh-Hans.xlf | 2 +- src/Compiler/xlf/FSStrings.zh-Hant.xlf | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Compiler/xlf/FSStrings.cs.xlf b/src/Compiler/xlf/FSStrings.cs.xlf index 20b53f76f45..86a6be9d7e0 100644 --- a/src/Compiler/xlf/FSStrings.cs.xlf +++ b/src/Compiler/xlf/FSStrings.cs.xlf @@ -154,7 +154,7 @@ Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. - Identifikátory proměnných psané velkými písmeny se ve vzorech obecně nedoporučují. Můžou označovat chybějící otevřenou deklaraci nebo špatně napsaný název vzoru. + Identifikátory proměnných psané velkými písmeny se ve vzorech obecně nedoporučují. Můžou označovat chybějící otevřenou deklaraci nebo špatně napsaný název vzoru. diff --git a/src/Compiler/xlf/FSStrings.de.xlf b/src/Compiler/xlf/FSStrings.de.xlf index f58d3a4711d..3b7f46a9769 100644 --- a/src/Compiler/xlf/FSStrings.de.xlf +++ b/src/Compiler/xlf/FSStrings.de.xlf @@ -154,7 +154,7 @@ Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. - Variablenbezeichner in Großbuchstaben sollten im Allgemeinen nicht in Mustern verwendet werden und können ein Hinweis auf eine fehlende open-Deklaration oder einen falsch geschriebenen Musternamen sein. + Variablenbezeichner in Großbuchstaben sollten im Allgemeinen nicht in Mustern verwendet werden und können ein Hinweis auf eine fehlende open-Deklaration oder einen falsch geschriebenen Musternamen sein. diff --git a/src/Compiler/xlf/FSStrings.es.xlf b/src/Compiler/xlf/FSStrings.es.xlf index 88a130d699d..f2b6d8ed1ca 100644 --- a/src/Compiler/xlf/FSStrings.es.xlf +++ b/src/Compiler/xlf/FSStrings.es.xlf @@ -154,7 +154,7 @@ Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. - En general, los identificadores de variables en mayúscula no deben usarse en patrones y pueden indicar una declaración abierta que falta o un nombre de patrón mal escrito. + En general, los identificadores de variables en mayúscula no deben usarse en patrones y pueden indicar una declaración abierta que falta o un nombre de patrón mal escrito. diff --git a/src/Compiler/xlf/FSStrings.fr.xlf b/src/Compiler/xlf/FSStrings.fr.xlf index 7d7badde4ed..f3621e55e63 100644 --- a/src/Compiler/xlf/FSStrings.fr.xlf +++ b/src/Compiler/xlf/FSStrings.fr.xlf @@ -154,7 +154,7 @@ Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. - Les identificateurs de variables en majuscules ne doivent généralement pas être utilisés dans les modèles. Ils peuvent indiquer une absence de déclaration open ou un nom de modèle mal orthographié. + Les identificateurs de variables en majuscules ne doivent généralement pas être utilisés dans les modèles. Ils peuvent indiquer une absence de déclaration open ou un nom de modèle mal orthographié. diff --git a/src/Compiler/xlf/FSStrings.it.xlf b/src/Compiler/xlf/FSStrings.it.xlf index f43c8e77851..d67bbd27dca 100644 --- a/src/Compiler/xlf/FSStrings.it.xlf +++ b/src/Compiler/xlf/FSStrings.it.xlf @@ -154,7 +154,7 @@ Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. - In genere è consigliabile non usare identificatori di variabili scritti in maiuscolo nei criteri perché potrebbero indicare una dichiarazione OPEN mancante o un nome di criterio con ortografia errata. + In genere è consigliabile non usare identificatori di variabili scritti in maiuscolo nei criteri perché potrebbero indicare una dichiarazione OPEN mancante o un nome di criterio con ortografia errata. diff --git a/src/Compiler/xlf/FSStrings.ja.xlf b/src/Compiler/xlf/FSStrings.ja.xlf index 6f0a3a978e9..486c2fac349 100644 --- a/src/Compiler/xlf/FSStrings.ja.xlf +++ b/src/Compiler/xlf/FSStrings.ja.xlf @@ -154,7 +154,7 @@ Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. - 通常、大文字の変数識別子はパターンに使用できません。また、欠落している open 宣言か、つづりが間違っているパターン名を示す可能性があります。 + 通常、大文字の変数識別子はパターンに使用できません。また、欠落している open 宣言か、つづりが間違っているパターン名を示す可能性があります。 diff --git a/src/Compiler/xlf/FSStrings.ko.xlf b/src/Compiler/xlf/FSStrings.ko.xlf index 43e0a0f1739..506b9b9e2de 100644 --- a/src/Compiler/xlf/FSStrings.ko.xlf +++ b/src/Compiler/xlf/FSStrings.ko.xlf @@ -154,7 +154,7 @@ Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. - 일반적으로 대문자 변수 식별자는 패턴에 사용하지 말아야 합니다. 이러한 식별자는 열려 있는 선언이 없거나 철자가 잘못된 패턴 이름을 나타낼 수 있습니다. + 일반적으로 대문자 변수 식별자는 패턴에 사용하지 말아야 합니다. 이러한 식별자는 열려 있는 선언이 없거나 철자가 잘못된 패턴 이름을 나타낼 수 있습니다. diff --git a/src/Compiler/xlf/FSStrings.pl.xlf b/src/Compiler/xlf/FSStrings.pl.xlf index 3096fca8dbf..30f8155bfc8 100644 --- a/src/Compiler/xlf/FSStrings.pl.xlf +++ b/src/Compiler/xlf/FSStrings.pl.xlf @@ -154,7 +154,7 @@ Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. - Identyfikatory zmiennych pisane wielkimi literami nie powinny być na ogół używane we wzorcach i mogą oznaczać brak deklaracji otwierającej lub błąd pisowni w nazwie wzorca. + Identyfikatory zmiennych pisane wielkimi literami nie powinny być na ogół używane we wzorcach i mogą oznaczać brak deklaracji otwierającej lub błąd pisowni w nazwie wzorca. diff --git a/src/Compiler/xlf/FSStrings.pt-BR.xlf b/src/Compiler/xlf/FSStrings.pt-BR.xlf index ea48f4c3545..cf7e3a94822 100644 --- a/src/Compiler/xlf/FSStrings.pt-BR.xlf +++ b/src/Compiler/xlf/FSStrings.pt-BR.xlf @@ -154,7 +154,7 @@ Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. - Identificadores de variáveis em maiúsculas geralmente não devem ser usados em padrões, podendo indicar uma declaração aberta ausente ou um nome de padrão escrito incorretamente. + Identificadores de variáveis em maiúsculas geralmente não devem ser usados em padrões, podendo indicar uma declaração aberta ausente ou um nome de padrão escrito incorretamente. diff --git a/src/Compiler/xlf/FSStrings.ru.xlf b/src/Compiler/xlf/FSStrings.ru.xlf index 7cb20b5e8de..34278a4b234 100644 --- a/src/Compiler/xlf/FSStrings.ru.xlf +++ b/src/Compiler/xlf/FSStrings.ru.xlf @@ -154,7 +154,7 @@ Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. - Идентификаторы переменных в верхнем регистре обычно не должны использоваться в шаблонах, и могут указывать на отсутствующую открытую декларацию или неправильно написанное имя шаблона. + Идентификаторы переменных в верхнем регистре обычно не должны использоваться в шаблонах, и могут указывать на отсутствующую открытую декларацию или неправильно написанное имя шаблона. diff --git a/src/Compiler/xlf/FSStrings.tr.xlf b/src/Compiler/xlf/FSStrings.tr.xlf index 9c65fabe248..a2601885c52 100644 --- a/src/Compiler/xlf/FSStrings.tr.xlf +++ b/src/Compiler/xlf/FSStrings.tr.xlf @@ -154,7 +154,7 @@ Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. - Büyük harfli değişken tanımlayıcıları desenlerde genel olarak kullanılmamalıdır. Bunlar, eksik bir açık bildirimin veya yanlış yazılmış bir desen adının göstergesi olabilirler. + Büyük harfli değişken tanımlayıcıları desenlerde genel olarak kullanılmamalıdır. Bunlar, eksik bir açık bildirimin veya yanlış yazılmış bir desen adının göstergesi olabilirler. diff --git a/src/Compiler/xlf/FSStrings.zh-Hans.xlf b/src/Compiler/xlf/FSStrings.zh-Hans.xlf index c895f08ec60..66a54f3d2bb 100644 --- a/src/Compiler/xlf/FSStrings.zh-Hans.xlf +++ b/src/Compiler/xlf/FSStrings.zh-Hans.xlf @@ -154,7 +154,7 @@ Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. - 通常不得在模式中使用大写的变量标识符,存在它们可能表示缺少某个开放声明或某个模式名称拼写错误。 + 通常不得在模式中使用大写的变量标识符,存在它们可能表示缺少某个开放声明或某个模式名称拼写错误。 diff --git a/src/Compiler/xlf/FSStrings.zh-Hant.xlf b/src/Compiler/xlf/FSStrings.zh-Hant.xlf index d81a539866e..35280cee60f 100644 --- a/src/Compiler/xlf/FSStrings.zh-Hant.xlf +++ b/src/Compiler/xlf/FSStrings.zh-Hant.xlf @@ -154,7 +154,7 @@ Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. - 通常不應在樣式中使用大寫的變數識別碼。這可能表示缺少公開宣告或樣式名稱拼字錯誤。 + 通常不應在樣式中使用大寫的變數識別碼。這可能表示缺少公開宣告或樣式名稱拼字錯誤。 From 3dc980eeb06dd912f1e6fe5d06a23a67a4b659e7 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Thu, 28 Nov 2024 03:20:05 -0800 Subject: [PATCH 5/6] Merge main to release/dev17.13 (#18080) * Add -sign to build.sh (#18024) * Fix singing problems (#18040) * Skip flaky test (#18051) * Remove support for `System.AggressiveAttributeTrimming` feature switch. (#18039) Co-authored-by: Kevin Ransom (msft) Co-authored-by: Petr * Update some internal guidelines (#18052) * simplify temp dirs in service (#18046) Co-authored-by: Kevin Ransom (msft) * Add Contributing.md (#18043) * contributing * Update CONTRIBUTING.md * Update CONTRIBUTING.md Co-authored-by: Tomas Grosup * Update CONTRIBUTING.md Co-authored-by: Vlad Zarytovskii * Update CONTRIBUTING.md Co-authored-by: Petr * Update CONTRIBUTING.md --------- Co-authored-by: Tomas Grosup Co-authored-by: Vlad Zarytovskii Co-authored-by: Petr * [main] Update dependencies from dotnet/arcade (#17729) * Update dependencies from https://github.com/dotnet/arcade build 20240913.2 Microsoft.SourceBuild.Intermediate.arcade , Microsoft.DotNet.Arcade.Sdk From Version 9.0.0-beta.24462.3 -> To Version 9.0.0-beta.24463.2 * Update dependencies from https://github.com/dotnet/arcade build 20240916.2 Microsoft.SourceBuild.Intermediate.arcade , Microsoft.DotNet.Arcade.Sdk From Version 9.0.0-beta.24463.2 -> To Version 9.0.0-beta.24466.2 * Update dependencies from https://github.com/dotnet/arcade build 20240923.1 Microsoft.SourceBuild.Intermediate.arcade , Microsoft.DotNet.Arcade.Sdk From Version 9.0.0-beta.24466.2 -> To Version 9.0.0-beta.24473.1 * Update dependencies from https://github.com/dotnet/arcade build 20241001.3 Microsoft.SourceBuild.Intermediate.arcade , Microsoft.DotNet.Arcade.Sdk From Version 9.0.0-beta.24473.1 -> To Version 9.0.0-beta.24501.3 * Update dependencies from https://github.com/dotnet/arcade build 20241003.2 Microsoft.SourceBuild.Intermediate.arcade , Microsoft.DotNet.Arcade.Sdk From Version 9.0.0-beta.24501.3 -> To Version 9.0.0-beta.24503.2 * Update dependencies from https://github.com/dotnet/arcade build 20241008.3 Microsoft.SourceBuild.Intermediate.arcade , Microsoft.DotNet.Arcade.Sdk From Version 9.0.0-beta.24503.2 -> To Version 9.0.0-beta.24508.3 * Update dependencies from https://github.com/dotnet/arcade build 20241009.3 Microsoft.SourceBuild.Intermediate.arcade , Microsoft.DotNet.Arcade.Sdk From Version 9.0.0-beta.24508.3 -> To Version 9.0.0-beta.24509.3 * Update dependencies from https://github.com/dotnet/arcade build 20241016.2 Microsoft.SourceBuild.Intermediate.arcade , Microsoft.DotNet.Arcade.Sdk From Version 9.0.0-beta.24509.3 -> To Version 9.0.0-beta.24516.2 * Update dependencies from https://github.com/dotnet/arcade build 20241112.13 Microsoft.SourceBuild.Intermediate.arcade , Microsoft.DotNet.Arcade.Sdk From Version 9.0.0-beta.24462.3 -> To Version 9.0.0-beta.24562.13 * Update dependencies from https://github.com/dotnet/arcade build 20241122.2 Microsoft.SourceBuild.Intermediate.arcade , Microsoft.DotNet.Arcade.Sdk From Version 9.0.0-beta.24462.3 -> To Version 9.0.0-beta.24572.2 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Vlad Zarytovskii * Refactor AsyncMemoize, introduce AsyncLazy (#18002) * refactor AsyncMemoize, introduce AsyncLazy * use lock free mb in tests * remove unnecessary prop * update il baselines * rename * add requestCount name Co-authored-by: Petr Pokorny * improve as reviewed * lock for TryGet * more locks * ilverify * deallocate computation when completed * ilverify * style * typo --------- Co-authored-by: Petr Pokorny * Fix crashdump paths in CI (#18065) * Various updates to ILVerify (#18060) * Update azure-pipelines-PR.yml * Add null annotation to Async.SwitchToContext (#18059) --------- Co-authored-by: Ella Hathaway <67609881+ellahathaway@users.noreply.github.com> Co-authored-by: Petr Co-authored-by: Petr Pokorny Co-authored-by: Theodore Tsirpanis Co-authored-by: Kevin Ransom (msft) Co-authored-by: Jakub Majocha <1760221+majocha@users.noreply.github.com> Co-authored-by: Tomas Grosup Co-authored-by: Vlad Zarytovskii Co-authored-by: dotnet-maestro[bot] <42748379+dotnet-maestro[bot]@users.noreply.github.com> Co-authored-by: dotnet-maestro[bot] Co-authored-by: Petr Pokorny Co-authored-by: Ch13 --- CONTRIBUTING.md | 106 +++ DEVGUIDE.md | 8 +- INTERNAL.md | 24 +- azure-pipelines-PR.yml | 32 +- docs/release-notes/.FSharp.Core/9.0.200.md | 1 + eng/Version.Details.xml | 8 +- eng/build.sh | 6 + .../steps/get-delegation-sas.yml | 11 +- eng/common/internal/Tools.csproj | 25 - eng/common/sdk-task.ps1 | 2 +- eng/common/templates-official/job/job.yml | 1 + eng/common/templates/job/job.yml | 1 + eng/common/tools.ps1 | 6 +- global.json | 4 +- src/Compiler/Facilities/AsyncMemoize.fs | 686 +++++------------- src/Compiler/Facilities/AsyncMemoize.fsi | 17 +- src/Compiler/Service/TransparentCompiler.fs | 4 +- src/FSharp.Core/FSharp.Core.fsproj | 1 - src/FSharp.Core/ILLink.LinkAttributes.xml | 179 ----- src/FSharp.Core/async.fs | 4 - src/FSharp.Core/async.fsi | 2 +- .../CompilerService/AsyncLock.fs | 26 - .../CompilerService/AsyncMemoize.fs | 340 +++++---- .../FSharp.Compiler.ComponentTests.fsproj | 1 - .../FSharpChecker/TransparentCompiler.fs | 60 +- tests/FSharp.Compiler.Service.Tests/Common.fs | 73 +- .../ExprTests.fs | 59 +- .../GeneratedCodeSymbolsTests.fs | 12 +- .../ScriptOptionsTests.fs | 6 +- tests/FSharp.Test.Utilities/CompilerAssert.fs | 17 +- tests/FSharp.Test.Utilities/TestFramework.fs | 6 +- {eng => tests/ILVerify}/ilverify.ps1 | 40 +- ...y_FSharp.Compiler.Service_Debug_net9.0.bsl | 12 +- ....Compiler.Service_Debug_netstandard2.0.bsl | 12 +- ...FSharp.Compiler.Service_Release_net9.0.bsl | 12 +- ...ompiler.Service_Release_netstandard2.0.bsl | 12 +- ...erify_FSharp.Core_Debug_netstandard2.0.bsl | 0 ...erify_FSharp.Core_Debug_netstandard2.1.bsl | 0 ...ify_FSharp.Core_Release_netstandard2.0.bsl | 0 ...ify_FSharp.Core_Release_netstandard2.1.bsl | 0 40 files changed, 684 insertions(+), 1132 deletions(-) create mode 100644 CONTRIBUTING.md delete mode 100644 src/FSharp.Core/ILLink.LinkAttributes.xml delete mode 100644 tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncLock.fs rename {eng => tests/ILVerify}/ilverify.ps1 (80%) rename {eng => tests/ILVerify}/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl (98%) rename {eng => tests/ILVerify}/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl (98%) rename {eng => tests/ILVerify}/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl (98%) rename {eng => tests/ILVerify}/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl (98%) rename {eng => tests/ILVerify}/ilverify_FSharp.Core_Debug_netstandard2.0.bsl (100%) rename {eng => tests/ILVerify}/ilverify_FSharp.Core_Debug_netstandard2.1.bsl (100%) rename {eng => tests/ILVerify}/ilverify_FSharp.Core_Release_netstandard2.0.bsl (100%) rename {eng => tests/ILVerify}/ilverify_FSharp.Core_Release_netstandard2.1.bsl (100%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000000..b8c7c63108a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,106 @@ +# Contributing to F# + +One of the easiest ways to contribute is to participate in discussions on GitHub issues. You can also contribute by submitting pull requests with code changes. + +## General feedback and discussions? + +Start a [discussion](https://github.com/dotnet/fsharp/discussions) on the [repository issue tracker](https://github.com/dotnet/fsharp/issues). + +## Bugs and feature requests? + +❗ **IMPORTANT: If you want to report a security-related issue, please see the `Reporting security issues and bugs` section below.** + +Before reporting a new issue, try to find an existing issue if one already exists. If it already exists, upvote (👍) it. Also, consider adding a comment with your unique scenarios and requirements related to that issue. Upvotes and clear details on the issue's impact help us prioritize the most important issues to be worked on sooner rather than later. If you can't find one, that's okay, we'd rather get a duplicate report than none. + +If you can't find an existing issue, log a new issue in this GitHub repository. + +## Creating Issues + +- **DO** use a descriptive title that identifies the issue to be addressed or the requested feature. For example, when describing an issue where the compiler is not behaving as expected, write your bug title in terms of what the compiler should do rather than what it is doing – “F# compiler should report FS1234 when Xyz is used in Abcd.” +- **DO** specify a detailed description of the issue or requested feature. +- **DO** provide the following for bug reports + - Describe the expected behavior and the actual behavior. If it is not self-evident such as in the case of a crash, provide an explanation for why the expected behavior is expected. + - Provide an example with source code / projects that reproduce the issue. + - Specify any relevant exception messages and stack traces. +- **DO** subscribe to notifications for the created issue in case there are any follow up questions. + +## Reporting security issues and bugs + +Security issues and bugs should be reported privately, via email, to the Microsoft Security Response Center (MSRC) secure@microsoft.com. You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Further information, including the MSRC PGP key, can be found in the [Security TechCenter](https://technet.microsoft.com/security/ff852094.aspx). + +## Writing Code + +### Finding an issue to work on + + Over the years we've seen many PRs targeting areas, which we didn't plan to expand further at the time. In many of these these cases we had to say `no` to those PRs and close them. That, obviously, is not a great outcome for us. And it's especially bad for the contributor, as they've spent a lot of effort preparing the change. + To resolve this problem, we've decided to separate a bucket of issues, which would be great candidates for community members to contribute to. We mark these issues with the `help wanted` label. [help wanted](https://github.com/dotnet/fsharp/labels/help%20wanted) + + Within that set, we have additionally marked issues that are good candidates for first-time contributors. Here: [Good first issue](https://github.com/dotnet/fsharp/labels/good%20first%20issue) + + If you would like to make a contribution to an area not documented here, first open an issue with a description of the change you would like to make and the problem it solves so it can be discussed before a pull request is submitted. + +### The primary customers of the F# repository are users of the dotnet SDK, Visual Studio, Rider and Ionide. At all times their experience is paramount in our mind. + + We are very accepting of community pull requests, there are however, a set of firm considerations that we hold to when reviewing PRs and determining what to merge. These have been developed over the years to maintain the quality of the product and the experience that F# developers have when installing and upgrading the dotnet SDK and Visual Studio. + +- Does the change fix something that needs fixing, is there an issue, does the issue indicate a real problem? +- Does the change improve the readability of something that needs improvement? +- Does the change add a feature that is approved for adding? +- Does the code match or improve of the existing codebase? +- Is the performance improvement measured and can regressions be identified? +- Will our existing customers be able to without effort upgrading the **Major** release of an SDK or VS? +- Will our existing customers be able to without effort upgrading the **Minor** release of an SDK or VS? +- This change is not binary breaking (i.e. does not break VS, Rider or Ionide)? +- Does it have adequate testing? +- Do all existing tests run unmodified? + +In general answers to the above should be **Yes**. A **No** to any of them is not disqualifying of the PR, however a no answer will need an explanation and a discussion. + +There are additional considerations +- Is the risk of accepting this change High or even Medium, these really refer to how much of the existing user or codebase is impacted. How likely do we feel we are to revert the changes later. + For an acceptable PR with a high risk, we will definitely need to discuss mitigations for the risk. A decision to upgrade the SDK or VS needs to be always low risk for our customers, they have businesses to run, they don't want to have to deal with our - risky behavior. We may defer or delay risky PRs into a later release or abandon it. +- Is the change as small as possible +- Should it be chopped up into smaller, yet independently valuable and releasable to production, chunks +- Is the cost of reviewing the change worth the improvement made by the change +Again, some PR’s are too big or provide too little value to merge. + + +### Resources to help you get started + +Here are some resources to help you get started on how to contribute code or new content. + +- [Developers Guide](https://github.com/dotnet/fsharp/blob/main/DEVGUIDE.md) to get started on building the source code on your own. +- [Test Guide](https://github.com/dotnet/fsharp/blob/main/TESTGUIDE.md) how to build run and work with test cases. +- [F# compiler guide](https://github.com/dotnet/fsharp/blob/main/docs/index.md) +- [F# language specification](https://fsharp.org/specs/language-spec/) +- [F# language design](https://github.com/fsharp/fslang-design/) +- [F# language suggestions](https://github.com/fsharp/fslang-suggestions/) +- [help wanted](https://github.com/dotnet/fsharp/labels/help%20wanted) where to start + +### Submitting a pull request + +You will need to sign a [Contributor License Agreement](https://cla.dotnetfoundation.org/) when submitting your pull request. To complete the Contributor License Agreement (CLA), you will need to follow the instructions provided by the CLA bot when you send the pull request. This needs to only be done once for any .NET Foundation OSS project. + +If you don't know what a pull request is read this article: . Make sure the repository can build and all tests pass. Familiarize yourself with the project workflow and our coding conventions. + +- **DO** ensure submissions pass all Azure DevOps legs and are merge conflict free. +- **DO** submit language feature requests as issues in the [F# language](https://github.com/fsharp/fslang-suggestions) repos. Please note: approved in principle does not guarantee acceptance. +- **DO NOT** submit language features as PRs to this repo first, or they will likely be declined. +- **DO** submit issues for other features. This facilitates discussion of a feature separately from its implementation, and increases the acceptance rates for pull requests. +- **DO NOT** submit large code formatting changes without discussing with the team first. + +### Reviewing pull requests + +Our repository gets a high volume of pull requests and reviewing each of them is a significant time commitment. Our team priorities often force us to focus on reviewing a subset of the active pull requests at a given time. + +### Feedback + +Contributors will review your pull request and provide feedback. + +## Merging pull requests + +When your pull request has had the feedback addressed, and it has been signed off by two or more core team reviewers with commit access, and all checks are green, we will commit it. + +## Code of conduct + +See [CODE-OF-CONDUCT.md](./CODE-OF-CONDUCT.md) diff --git a/DEVGUIDE.md b/DEVGUIDE.md index b3ed65611c4..cf3a9419481 100644 --- a/DEVGUIDE.md +++ b/DEVGUIDE.md @@ -228,7 +228,8 @@ dotnet test tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fs ### Updating ILVerify baselines -These control IL for the core modules of the compiler. The baselines are located in the `eng` folder and look like: +These are IL baseline tests for the core assemblies of the compiler (FSharp.Core and FSharp.Compiler.Service). The baselines are located in the `tests/ILVerify` folder and look like: + ``` ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl @@ -240,7 +241,10 @@ ilverify_FSharp.Core_Release_netstandard2.0.bsl ilverify_FSharp.Core_Release_netstandard2.1.bsl ``` -If you want to update them, run the [ilverify.ps1]([url](https://github.com/dotnet/fsharp/blob/main/eng/ilverify.ps1)) script in PowerShell. The script will create `.actual` files. If the differences make sense, replace the original baselines with the actual files. +If you want to update them, either + +1. Run the [ilverify.ps1]([url](https://github.com/dotnet/fsharp/blob/main/tests/ILVerify/ilverify.ps1)) script in PowerShell. The script will create `.actual` files. If the differences make sense, replace the original baselines with the actual files. +2. Set the `TEST_UPDATE_BSL` to `1` (please refer to "Updating baselines in tests" section in this file) **and** run `ilverify.ps1` - this will automatically replace baselines. After that, please carefully review the change and push it to your branch if it makes sense. ## Automated Source Code Formatting diff --git a/INTERNAL.md b/INTERNAL.md index 6207180fd31..51cb12efd57 100644 --- a/INTERNAL.md +++ b/INTERNAL.md @@ -38,7 +38,7 @@ their respective branches. [VS 16.1](https://dev.azure.com/devdiv/DevDiv/_release?definitionId=1669&_a=releases) -VS 16.0 and prior were done manually +VS 16.0 and prior were done manually. ## VS Insertions as part of the build definition @@ -64,6 +64,7 @@ it's a good idea to check the previous link for any old or stalled insertions in Update the `insertTargetBranch` value at the bottom of `azure-pipelines.yml` in the appropriate release branch. E.g., when VS 17.3 snapped and switched to ask mode, [this PR](https://github.com/dotnet/fsharp/pull/13456/files) correctly updates the insertion target so that future builds from that F# branch will get auto-inserted to VS. ### When VS `main` is open for insertions for preview releases of VS: + 0. Disable auto-merges from `main` to **current** release branch, please make a change for the following file and create a pull request: https://github.com/dotnet/roslyn-tools/blob/6d7c182c46f8319d7922561e2c1586c7aadce19e/src/GitHubCreateMergePRs/config.xml#L52-L74 > You should comment out the `main -> release/devXX.X` flow until step #4 is completed (``) @@ -131,6 +132,23 @@ Since github issue filtering is currently not flexible enough, that query was ge Invoke-WebRequest -Uri "https://api.github.com/repos/dotnet/fsharp/labels?per_page=100" | ConvertFrom-Json | % { $_.name } | ? { $_.StartsWith("Area-") } | % { Write-Host -NoNewLine ('-label:"' + $_ + '" ') } ``` -## Other links +## Fix problems with the internal source mirror + +The repo is [here](https://dev.azure.com/dnceng/internal/_git/dotnet-fsharp), the CI is [here](https://dnceng.visualstudio.com/internal/_build?definitionId=499). + +If something breaks in the CI there and you want to experiment, the general workflow is the following: +1. Make a branch +2. Make a change +3. Run the build from your branch. If needed, set the "skipTests" variable to "true" - can save time at this stage. +4. Once the problem and the fix is identified, make a PR to THIS (dotnet/fsharp) repo - it will propagate to the internal mirror just afterwards. +5. Delete all your work in the internal repo. + +**DO NOT** try to push to the internal repo - this will mess up the flows. **DO NOT** create PRs to not confuse anyone. + +You need the following permissions to do the above investigations: +- "Generic contribute" +- "Create branch" +- "Queue builds" +- "Edit queue build configuration" -[Internal source mirror](https://dev.azure.com/dnceng/internal/_git/dotnet-fsharp). +If anything, reach out to the "First Responders" team. \ No newline at end of file diff --git a/azure-pipelines-PR.yml b/azure-pipelines-PR.yml index 7d11a931c24..75d0484cac9 100644 --- a/azure-pipelines-PR.yml +++ b/azure-pipelines-PR.yml @@ -229,7 +229,7 @@ stages: env: DOTNET_DbgEnableMiniDump: 1 DOTNET_DbgMiniDumpType: 3 # Triage dump, 1 for mini, 2 for Heap, 3 for triage, 4 for full. Don't use 4 unless you know what you're doing. - DOTNET_DbgMiniDumpName: $(Build.SourcesDirectory)\artifacts\log\$(_configuration)\$(Build.BuildId)-%e-%p-%t.dmp + DOTNET_DbgMiniDumpName: $(Build.SourcesDirectory)\artifacts\log\Release\$(Build.BuildId)-%e-%p-%t.dmp NativeToolsOnMachine: true displayName: Build @@ -247,8 +247,8 @@ stages: condition: failed() continueOnError: true inputs: - PathToPublish: '$(Build.SourcesDirectory)\artifacts\log\$(_configuration)' - ArtifactName: 'Windows $(_configuration) $(_testKind) process dumps' + PathToPublish: '$(Build.SourcesDirectory)\artifacts\log\Release' + ArtifactName: 'Windows Release WindowsLangVersionPreview process dumps' ArtifactType: Container parallel: true @@ -269,7 +269,7 @@ stages: env: DOTNET_DbgEnableMiniDump: 1 DOTNET_DbgMiniDumpType: 3 # Triage dump, 1 for mini, 2 for Heap, 3 for triage, 4 for full. Don't use 4 unless you know what you're doing. - DOTNET_DbgMiniDumpName: $(Build.SourcesDirectory)\artifacts\log\$(_configuration)\$(Build.BuildId)-%e-%p-%t.dmp + DOTNET_DbgMiniDumpName: $(Build.SourcesDirectory)\artifacts\log\Release\$(Build.BuildId)-%e-%p-%t.dmp NativeToolsOnMachine: true displayName: Build @@ -287,8 +287,8 @@ stages: condition: failed() continueOnError: true inputs: - PathToPublish: '$(Build.SourcesDirectory)\artifacts\log\$(_configuration)' - ArtifactName: 'Windows $(_configuration) $(_testKind) process dumps' + PathToPublish: '$(Build.SourcesDirectory)\artifacts\log\Release' + ArtifactName: 'Windows Release WindowsNoRealsig_testCoreclr process dumps' ArtifactType: Container parallel: true @@ -309,7 +309,7 @@ stages: env: DOTNET_DbgEnableMiniDump: 1 DOTNET_DbgMiniDumpType: 3 # Triage dump, 1 for mini, 2 for Heap, 3 for triage, 4 for full. Don't use 4 unless you know what you're doing. - DOTNET_DbgMiniDumpName: $(Build.SourcesDirectory)\artifacts\log\$(_configuration)\$(Build.BuildId)-%e-%p-%t.dmp + DOTNET_DbgMiniDumpName: $(Build.SourcesDirectory)\artifacts\log\Release\$(Build.BuildId)-%e-%p-%t.dmp NativeToolsOnMachine: true displayName: Build @@ -327,8 +327,8 @@ stages: condition: failed() continueOnError: true inputs: - PathToPublish: '$(Build.SourcesDirectory)\artifacts\log\$(_configuration)' - ArtifactName: 'Windows $(_configuration) $(_testKind) process dumps' + PathToPublish: '$(Build.SourcesDirectory)\artifacts\log\Release' + ArtifactName: 'Windows Release WindowsNoRealsig_testDesktop process dumps' ArtifactType: Container parallel: true @@ -349,7 +349,7 @@ stages: env: DOTNET_DbgEnableMiniDump: 1 DOTNET_DbgMiniDumpType: 3 # Triage dump, 1 for mini, 2 for Heap, 3 for triage, 4 for full. Don't use 4 unless you know what you're doing. - DOTNET_DbgMiniDumpName: $(Build.SourcesDirectory)\artifacts\log\$(_configuration)\$(Build.BuildId)-%e-%p-%t.dmp + DOTNET_DbgMiniDumpName: $(Build.SourcesDirectory)\artifacts\log\Release\$(Build.BuildId)-%e-%p-%t.dmp NativeToolsOnMachine: true displayName: Build @@ -367,8 +367,8 @@ stages: condition: failed() continueOnError: true inputs: - PathToPublish: '$(Build.SourcesDirectory)\artifacts\log\$(_configuration)' - ArtifactName: 'Windows $(_configuration) $(_testKind) process dumps' + PathToPublish: '$(Build.SourcesDirectory)\artifacts\log\Release' + ArtifactName: 'Windows Release WindowsStrictIndentation process dumps' ArtifactType: Container parallel: true @@ -385,7 +385,7 @@ stages: env: DOTNET_DbgEnableMiniDump: 1 DOTNET_DbgMiniDumpType: 3 # Triage dump, 1 for mini, 2 for Heap, 3 for triage, 4 for full. Don't use 4 unless you know what you're doing. - DOTNET_DbgMiniDumpName: $(Build.SourcesDirectory)\artifacts\log\$(_configuration)\$(Build.BuildId)-%e-%p-%t.dmp + DOTNET_DbgMiniDumpName: $(Build.SourcesDirectory)\artifacts\log\Release\$(Build.BuildId)-%e-%p-%t.dmp NativeToolsOnMachine: true displayName: Build @@ -403,8 +403,8 @@ stages: condition: failed() continueOnError: true inputs: - PathToPublish: '$(Build.SourcesDirectory)\artifacts\log\$(_configuration)' - ArtifactName: 'Windows $(_configuration) $(_testKind) process dumps' + PathToPublish: '$(Build.SourcesDirectory)\artifacts\log\Release' + ArtifactName: 'Windows Release WindowsNoStrictIndentation process dumps' ArtifactType: Container parallel: true @@ -825,6 +825,6 @@ stages: installationPath: $(Agent.ToolsDirectory)/dotnet - script: dotnet tool restore displayName: Restore dotnet tools - - pwsh: .\eng\ilverify.ps1 + - pwsh: .\tests\ILVerify\ilverify.ps1 displayName: Run ILVerify workingDirectory: $(Build.SourcesDirectory) diff --git a/docs/release-notes/.FSharp.Core/9.0.200.md b/docs/release-notes/.FSharp.Core/9.0.200.md index 2ea077abe4b..fdcc65f5537 100644 --- a/docs/release-notes/.FSharp.Core/9.0.200.md +++ b/docs/release-notes/.FSharp.Core/9.0.200.md @@ -1,6 +1,7 @@ ### Fixed * Fix exception on Post after MailboxProcessor was disposed ([Issue #17849](https://github.com/dotnet/fsharp/issues/17849), [PR #17922](https://github.com/dotnet/fsharp/pull/17922)) +* Fix missing null annotation in Async.SwitchToContext ([Issue #18055](https://github.com/dotnet/fsharp/issues/18055), [PR #18059](https://github.com/dotnet/fsharp/pull/18059)) ### Added diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index dc43fb9cd4e..888e3f23f89 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -42,14 +42,14 @@ - + https://github.com/dotnet/arcade - 91b9734abbad751d575c002b30778c88d978993c + b41381d5cd633471265e9cd72e933a7048e03062 - + https://github.com/dotnet/arcade - 91b9734abbad751d575c002b30778c88d978993c + b41381d5cd633471265e9cd72e933a7048e03062 diff --git a/eng/build.sh b/eng/build.sh index c4abb23f6f1..e6e27732c8f 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -20,6 +20,7 @@ usage() echo " --rebuild Rebuild all projects" echo " --pack Build nuget packages" echo " --publish Publish build artifacts" + echo " --sign Sign build artifacts" echo " --help Print help and exit" echo "" echo "Test actions:" @@ -58,6 +59,7 @@ build=false rebuild=false pack=false publish=false +sign=false test_core_clr=false test_compilercomponent_tests=false test_benchmarks=false @@ -129,6 +131,9 @@ while [[ $# > 0 ]]; do --publish) publish=true ;; + --sign) + sign=true + ;; --testcoreclr|--test|-t) test_core_clr=true ;; @@ -297,6 +302,7 @@ function BuildSolution { /p:Rebuild=$rebuild \ /p:Pack=$pack \ /p:Publish=$publish \ + /p:Sign=$sign \ /p:UseRoslynAnalyzers=$enable_analyzers \ /p:ContinuousIntegrationBuild=$ci \ /p:QuietRestore=$quiet_restore \ diff --git a/eng/common/core-templates/steps/get-delegation-sas.yml b/eng/common/core-templates/steps/get-delegation-sas.yml index d2901470a7f..9db5617ea7d 100644 --- a/eng/common/core-templates/steps/get-delegation-sas.yml +++ b/eng/common/core-templates/steps/get-delegation-sas.yml @@ -31,7 +31,16 @@ steps: # Calculate the expiration of the SAS token and convert to UTC $expiry = (Get-Date).AddHours(${{ parameters.expiryInHours }}).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") - $sas = az storage container generate-sas --account-name ${{ parameters.storageAccount }} --name ${{ parameters.container }} --permissions ${{ parameters.permissions }} --expiry $expiry --auth-mode login --as-user -o tsv + # Temporarily work around a helix issue where SAS tokens with / in them will cause incorrect downloads + # of correlation payloads. https://github.com/dotnet/dnceng/issues/3484 + $sas = "" + do { + $sas = az storage container generate-sas --account-name ${{ parameters.storageAccount }} --name ${{ parameters.container }} --permissions ${{ parameters.permissions }} --expiry $expiry --auth-mode login --as-user -o tsv + if ($LASTEXITCODE -ne 0) { + Write-Error "Failed to generate SAS token." + exit 1 + } + } while($sas.IndexOf('/') -ne -1) if ($LASTEXITCODE -ne 0) { Write-Error "Failed to generate SAS token." diff --git a/eng/common/internal/Tools.csproj b/eng/common/internal/Tools.csproj index db46d5582eb..32f79dfb340 100644 --- a/eng/common/internal/Tools.csproj +++ b/eng/common/internal/Tools.csproj @@ -6,31 +6,6 @@ false false - - - - - - - - - - - - - diff --git a/eng/common/sdk-task.ps1 b/eng/common/sdk-task.ps1 index aab40de3fd9..4f0546dce12 100644 --- a/eng/common/sdk-task.ps1 +++ b/eng/common/sdk-task.ps1 @@ -64,7 +64,7 @@ try { $GlobalJson.tools | Add-Member -Name "vs" -Value (ConvertFrom-Json "{ `"version`": `"16.5`" }") -MemberType NoteProperty } if( -not ($GlobalJson.tools.PSObject.Properties.Name -match "xcopy-msbuild" )) { - $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.10.0-pre.4.0" -MemberType NoteProperty + $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.12.0" -MemberType NoteProperty } if ($GlobalJson.tools."xcopy-msbuild".Trim() -ine "none") { $xcopyMSBuildToolsFolder = InitializeXCopyMSBuild $GlobalJson.tools."xcopy-msbuild" -install $true diff --git a/eng/common/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml index 3d16b41c78c..605692d2fb7 100644 --- a/eng/common/templates-official/job/job.yml +++ b/eng/common/templates-official/job/job.yml @@ -1,6 +1,7 @@ parameters: # Sbom related params enableSbom: true + runAsPublic: false PackageVersion: 9.0.0 BuildDropPath: '$(Build.SourcesDirectory)/artifacts' diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml index 07d317bf8f9..d1aeb92fcea 100644 --- a/eng/common/templates/job/job.yml +++ b/eng/common/templates/job/job.yml @@ -4,6 +4,7 @@ parameters: componentGovernanceIgnoreDirectories: '' # Sbom related params enableSbom: true + runAsPublic: false PackageVersion: 9.0.0 BuildDropPath: '$(Build.SourcesDirectory)/artifacts' diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 9574f4eb9df..aa94fb17459 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -383,8 +383,8 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = # If the version of msbuild is going to be xcopied, # use this version. Version matches a package here: - # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DotNet.Arcade.MSBuild.Xcopy/versions/17.10.0-pre.4.0 - $defaultXCopyMSBuildVersion = '17.10.0-pre.4.0' + # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DotNet.Arcade.MSBuild.Xcopy/versions/17.12.0 + $defaultXCopyMSBuildVersion = '17.12.0' if (!$vsRequirements) { if (Get-Member -InputObject $GlobalJson.tools -Name 'vs') { @@ -900,7 +900,7 @@ function IsWindowsPlatform() { } function Get-Darc($version) { - $darcPath = "$TempDir\darc\$(New-Guid)" + $darcPath = "$TempDir\darc\$([guid]::NewGuid())" if ($version -ne $null) { & $PSScriptRoot\darc-init.ps1 -toolpath $darcPath -darcVersion $version | Out-Host } else { diff --git a/global.json b/global.json index 6d23934c7ed..9a3de25e397 100644 --- a/global.json +++ b/global.json @@ -11,13 +11,13 @@ "Microsoft.VisualStudio.Component.FSharp" ] }, - "xcopy-msbuild": "17.8.5" + "xcopy-msbuild": "17.12.0" }, "native-tools": { "perl": "5.38.2.2" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24462.3", + "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24572.2", "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23255.2" } } diff --git a/src/Compiler/Facilities/AsyncMemoize.fs b/src/Compiler/Facilities/AsyncMemoize.fs index af1a52e5e5d..88b0b84bb8c 100644 --- a/src/Compiler/Facilities/AsyncMemoize.fs +++ b/src/Compiler/Facilities/AsyncMemoize.fs @@ -1,18 +1,101 @@ namespace Internal.Utilities.Collections open System -open System.Collections.Generic open System.Diagnostics open System.IO open System.Threading open System.Threading.Tasks +open System.Runtime.CompilerServices +open System.Runtime.ExceptionServices -open FSharp.Compiler -open FSharp.Compiler.BuildGraph -open FSharp.Compiler.Diagnostics open FSharp.Compiler.DiagnosticsLogger open Internal.Utilities.Library -open System.Runtime.CompilerServices + +type AsyncLazyState<'t> = + | Initial of computation: Async<'t> + | Running of initialComputation: Async<'t> * work: Task<'t> * CancellationTokenSource * requestCount: int + | Completed of result: 't + | Faulted of exn + +/// Represents a computation that will execute only once but can be requested by multiple clients. +/// It keeps track of the number of requests. When all clients cancel their requests, the underlying computation will also cancel and can be restarted. +/// If cancelUnawaited is set to false, the computation will run to completion even when all requests are canceled. +type AsyncLazy<'t> private (initial: AsyncLazyState<'t>, cancelUnawaited: bool, cacheException: bool) = + + let stateUpdateSync = obj() + let mutable state = initial + + let cancelIfUnawaited () = + match state with + | Running(computation, _, cts, 0) -> + cts.Cancel() + state <- Initial computation + | _ -> () + + let afterRequest () = + match state with + | Running(computation, work, _, _) when work.IsCompleted -> + state <- + try + Completed work.Result + with + | exn -> + if cacheException then Faulted exn else Initial computation + | Running(c, work, cts, count) -> + state <- Running(c, work, cts, count - 1) + if cancelUnawaited then cancelIfUnawaited () + | _ -> () // Nothing more to do if another request already transitioned the state. + + let detachable (work: Task<'t>) = + async { + try + let! ct = Async.CancellationToken + let options = TaskContinuationOptions.ExecuteSynchronously + try + return! + // Using ContinueWith with a CancellationToken allows detaching from the running 'work' task. + // This ensures the lazy 'work' and its awaiting requests can be independently managed + // by separate CancellationTokenSources, enabling individual cancellation. + // Essentially, if this async computation is canceled, it won't wait for the 'work' to complete + // but will immediately proceed to the finally block. + work.ContinueWith((fun (t: Task<_>) -> t.Result), ct, options, TaskScheduler.Current) + |> Async.AwaitTask + // Cancellation check before entering the `with` ensures TaskCanceledException coming from the ContinueWith task will never be raised here. + // The cancellation continuation will always be called in case of cancellation. + with exn -> return raise exn + finally + lock stateUpdateSync afterRequest + } + + let request () = + match state with + | Initial computation -> + let cts = new CancellationTokenSource() + let work = Async.StartAsTask(computation, cancellationToken = cts.Token) + state <- Running (computation, work, cts, 1) + detachable work + | Running (c, work, cts, count) -> + state <- Running (c, work, cts, count + 1) + detachable work + | Completed result -> + async { return result } + | Faulted exn -> + async { return raise exn } + + // computation will deallocate after state transition to Completed ot Faulted. + new (computation, ?cancelUnawaited: bool, ?cacheException) = + AsyncLazy(Initial computation, defaultArg cancelUnawaited true, defaultArg cacheException false) + + member _.Request() = lock stateUpdateSync request + + member _.CancelIfUnawaited() = lock stateUpdateSync cancelIfUnawaited + + member _.State = state + + member this.TryResult = + match state with + | Completed result -> Some result + | _ -> None [] module internal Utils = @@ -29,52 +112,6 @@ module internal Utils = $"{dir}{Path.GetFileName path}" - let replayDiagnostics (logger: DiagnosticsLogger) = Seq.iter ((<|) logger.DiagnosticSink) - - [] - let (|TaskCancelled|_|) (ex: exn) = - match ex with - | :? System.Threading.Tasks.TaskCanceledException as tce -> ValueSome tce - //| :? System.AggregateException as ae -> - // if ae.InnerExceptions |> Seq.forall (fun e -> e :? System.Threading.Tasks.TaskCanceledException) then - // ae.InnerExceptions |> Seq.tryHead |> Option.map (fun e -> e :?> System.Threading.Tasks.TaskCanceledException) - // else - // None - | _ -> ValueNone - -type internal StateUpdate<'TValue> = - | CancelRequest - | OriginatorCanceled - | JobCompleted of 'TValue * (PhasedDiagnostic * FSharpDiagnosticSeverity) list - | JobFailed of exn * (PhasedDiagnostic * FSharpDiagnosticSeverity) list - -type internal MemoizeReply<'TValue> = - | New of CancellationToken - | Existing of Task<'TValue> - -type internal MemoizeRequest<'TValue> = GetOrCompute of Async<'TValue> * CancellationToken - -[] -type internal Job<'TValue> = - | Running of TaskCompletionSource<'TValue> * CancellationTokenSource * Async<'TValue> * DateTime * ResizeArray - | Completed of 'TValue * (PhasedDiagnostic * FSharpDiagnosticSeverity) list - | Canceled of DateTime - | Failed of DateTime * exn // TODO: probably we don't need to keep this - - member this.DebuggerDisplay = - match this with - | Running(_, cts, _, ts, _) -> - let cancellation = - if cts.IsCancellationRequested then - " ! Cancellation Requested" - else - "" - - $"Running since {ts.ToShortTimeString()}{cancellation}" - | Completed(value, diags) -> $"Completed {value}" + (if diags.Length > 0 then $" ({diags.Length})" else "") - | Canceled _ -> "Canceled" - | Failed(_, ex) -> $"Failed {ex}" - type internal JobEvent = | Requested | Started @@ -87,6 +124,7 @@ type internal JobEvent = | Strengthened | Failed | Cleared + static member AllEvents = [Requested; Started; Restarted; Finished; Canceled; Evicted; Collected; Weakened; Strengthened; Failed; Cleared] type internal ICacheKey<'TKey, 'TVersion> = abstract member GetKey: unit -> 'TKey @@ -111,40 +149,7 @@ type private KeyData<'TKey, 'TVersion> = Version: 'TVersion } -type internal AsyncLock() = - - let semaphore = new SemaphoreSlim(1, 1) - - member _.Semaphore = semaphore - - member _.Do(f) = - task { - do! semaphore.WaitAsync() - - try - return! f () - finally - semaphore.Release() |> ignore - } - - interface IDisposable with - member _.Dispose() = semaphore.Dispose() - -type internal CachingDiagnosticsLogger(originalLogger: DiagnosticsLogger option) = - inherit DiagnosticsLogger($"CachingDiagnosticsLogger") - - let capturedDiagnostics = ResizeArray() - - override _.ErrorCount = - originalLogger - |> Option.map (fun x -> x.ErrorCount) - |> Option.defaultValue capturedDiagnostics.Count - - override _.DiagnosticSink(diagnostic: PhasedDiagnostic, severity: FSharpDiagnosticSeverity) = - originalLogger |> Option.iter (fun x -> x.DiagnosticSink(diagnostic, severity)) - capturedDiagnostics.Add(diagnostic, severity) - - member _.CapturedDiagnostics = capturedDiagnostics |> Seq.toList +type Job<'t> = AsyncLazy * CapturingDiagnosticsLogger> [] type internal AsyncMemoize<'TKey, 'TVersion, 'TValue when 'TKey: equality and 'TVersion: equality @@ -153,342 +158,39 @@ type internal AsyncMemoize<'TKey, 'TVersion, 'TValue when 'TKey: equality and 'T and 'TVersion:not null #endif > - (?keepStrongly, ?keepWeakly, ?name: string, ?cancelDuplicateRunningJobs: bool) = + (?keepStrongly, ?keepWeakly, ?name: string, ?cancelUnawaitedJobs: bool, ?cancelDuplicateRunningJobs: bool) = let name = defaultArg name "N/A" + let cancelUnawaitedJobs = defaultArg cancelUnawaitedJobs true let cancelDuplicateRunningJobs = defaultArg cancelDuplicateRunningJobs false let event = Event<_>() - let mutable errors = 0 + let eventCounts = [for j in JobEvent.AllEvents -> j, ref 0] |> dict let mutable hits = 0 - let mutable started = 0 - let mutable completed = 0 - let mutable canceled = 0 - let mutable restarted = 0 - let mutable failed = 0 - let mutable evicted = 0 - let mutable collected = 0 - let mutable strengthened = 0 - let mutable cleared = 0 - - let mutable updates_in_flight = 0 - - let mutable cancel_ct_registration_original = 0 - let mutable cancel_exception_original = 0 - let mutable cancel_original_processed = 0 - let mutable cancel_ct_registration_subsequent = 0 - let mutable cancel_exception_subsequent = 0 - let mutable cancel_subsequent_processed = 0 - - let failures = ResizeArray() - let mutable avgDurationMs = 0.0 + let mutable duration = 0L + + let keyTuple (keyData: KeyData<_, _>) = keyData.Label, keyData.Key, keyData.Version + + let logK (eventType: JobEvent) key = + Interlocked.Increment(eventCounts[eventType]) |> ignore + event.Trigger(eventType, key) + + let log eventType keyData = logK eventType (keyTuple keyData) let cache = LruCache<'TKey, 'TVersion, Job<'TValue>>( keepStrongly = defaultArg keepStrongly 100, keepWeakly = defaultArg keepWeakly 200, - requiredToKeep = - (function - | Running _ -> true - | Job.Canceled at when at > DateTime.Now.AddMinutes -5.0 -> true - | Job.Failed(at, _) when at > DateTime.Now.AddMinutes -5.0 -> true - | _ -> false), event = (function - | CacheEvent.Evicted -> - (fun k -> - Interlocked.Increment &evicted |> ignore - event.Trigger(JobEvent.Evicted, k)) - | CacheEvent.Collected -> - (fun k -> - Interlocked.Increment &collected |> ignore - event.Trigger(JobEvent.Collected, k)) - | CacheEvent.Weakened -> (fun k -> event.Trigger(JobEvent.Weakened, k)) - | CacheEvent.Strengthened -> - (fun k -> - Interlocked.Increment &strengthened |> ignore - event.Trigger(JobEvent.Strengthened, k)) - | CacheEvent.Cleared -> - (fun k -> - Interlocked.Increment &cleared |> ignore - event.Trigger(JobEvent.Cleared, k))) - ) - - let requestCounts = Dictionary, int>() - let cancellationRegistrations = Dictionary<_, _>() - - let saveRegistration key registration = - cancellationRegistrations[key] <- - match cancellationRegistrations.TryGetValue key with - | true, registrations -> registration :: registrations - | _ -> [ registration ] - - let cancelRegistration key = - match cancellationRegistrations.TryGetValue key with - | true, registrations -> - for r: CancellationTokenRegistration in registrations do - r.Dispose() - - cancellationRegistrations.Remove key |> ignore - | _ -> () - - let incrRequestCount key = - requestCounts[key] <- - if requestCounts.ContainsKey key then - requestCounts[key] + 1 - else - 1 - - let decrRequestCount key = - if requestCounts.ContainsKey key then - requestCounts[key] <- requestCounts[key] - 1 - - let log (eventType, keyData: KeyData<_, _>) = - event.Trigger(eventType, (keyData.Label, keyData.Key, keyData.Version)) - - let lock = new AsyncLock() - - let processRequest post (key: KeyData<_, _>, msg) diagnosticLogger = - - lock.Do(fun () -> - task { - - let cached, otherVersions = cache.GetAll(key.Key, key.Version) - - let result = - match msg, cached with - | GetOrCompute _, Some(Completed(result, diags)) -> - Interlocked.Increment &hits |> ignore - diags |> replayDiagnostics diagnosticLogger - Existing(Task.FromResult result) - | GetOrCompute(_, ct), Some(Running(tcs, _, _, _, loggers)) -> - Interlocked.Increment &hits |> ignore - incrRequestCount key - - ct.Register(fun _ -> - let _name = name - Interlocked.Increment &cancel_ct_registration_subsequent |> ignore - post (key, CancelRequest)) - |> saveRegistration key - - loggers.Add diagnosticLogger - - Existing tcs.Task - - | GetOrCompute(computation, ct), None - | GetOrCompute(computation, ct), Some(Job.Canceled _) - | GetOrCompute(computation, ct), Some(Job.Failed _) -> - Interlocked.Increment &started |> ignore - incrRequestCount key - - ct.Register(fun _ -> - let _name = name - Interlocked.Increment &cancel_ct_registration_original |> ignore - post (key, OriginatorCanceled)) - |> saveRegistration key - - let cts = new CancellationTokenSource() - - cache.Set( - key.Key, - key.Version, - key.Label, - (Running( - TaskCompletionSource<'TValue>(TaskCreationOptions.RunContinuationsAsynchronously), - cts, - computation, - DateTime.Now, - ResizeArray() - )) - ) - - otherVersions - |> Seq.choose (function - | v, Running(_tcs, cts, _, _, _) -> Some(v, cts) - | _ -> None) - |> Seq.iter (fun (_v, cts) -> - use _ = Activity.start $"{name}: Duplicate running job" [| "key", key.Label |] - //System.Diagnostics.Trace.TraceWarning($"{name} Duplicate {key.Label}") - if cancelDuplicateRunningJobs then - //System.Diagnostics.Trace.TraceWarning("Canceling") - cts.Cancel()) - - New cts.Token - - log (Requested, key) - return result - }) - - let internalError key message = - let ex = exn (message) - failures.Add(key, ex) - Interlocked.Increment &errors |> ignore - // raise ex -- Suppose there's no need to raise here - where does it even go? - - let processStateUpdate post (key: KeyData<_, _>, action: StateUpdate<_>) = - lock.Do(fun () -> - task { - - let cached = cache.TryGet(key.Key, key.Version) - - match action, cached with - - | OriginatorCanceled, Some(Running(tcs, cts, computation, _, _)) -> - - Interlocked.Increment &cancel_original_processed |> ignore - - decrRequestCount key - - if requestCounts[key] < 1 then - cancelRegistration key - cts.Cancel() - tcs.TrySetCanceled() |> ignore - // Remember the job in case it completes after cancellation - cache.Set(key.Key, key.Version, key.Label, Job.Canceled DateTime.Now) - requestCounts.Remove key |> ignore - log (Canceled, key) - Interlocked.Increment &canceled |> ignore - use _ = Activity.start $"{name}: Canceled job" [| "key", key.Label |] - () - - else - // We need to restart the computation - Task.Run(fun () -> - Async.StartAsTask( - async { - - let cachingLogger = new CachingDiagnosticsLogger(None) - - try - // TODO: Should unify starting and restarting - log (Restarted, key) - Interlocked.Increment &restarted |> ignore - System.Diagnostics.Trace.TraceInformation $"{name} Restarted {key.Label}" - let currentLogger = DiagnosticsThreadStatics.DiagnosticsLogger - DiagnosticsThreadStatics.DiagnosticsLogger <- cachingLogger - - try - let! result = computation - post (key, (JobCompleted(result, cachingLogger.CapturedDiagnostics))) - return () - finally - DiagnosticsThreadStatics.DiagnosticsLogger <- currentLogger - with - | TaskCancelled _ -> - Interlocked.Increment &cancel_exception_subsequent |> ignore - post (key, CancelRequest) - () - | ex -> post (key, (JobFailed(ex, cachingLogger.CapturedDiagnostics))) - } - ), - cts.Token) - |> ignore - - | CancelRequest, Some(Running(tcs, cts, _c, _, _)) -> - - Interlocked.Increment &cancel_subsequent_processed |> ignore - - decrRequestCount key - - if requestCounts[key] < 1 then - cancelRegistration key - cts.Cancel() - tcs.TrySetCanceled() |> ignore - // Remember the job in case it completes after cancellation - cache.Set(key.Key, key.Version, key.Label, Job.Canceled DateTime.Now) - requestCounts.Remove key |> ignore - log (Canceled, key) - Interlocked.Increment &canceled |> ignore - use _ = Activity.start $"{name}: Canceled job" [| "key", key.Label |] - () - - // Probably in some cases cancellation can be fired off even after we just unregistered it - | CancelRequest, None - | CancelRequest, Some(Completed _) - | CancelRequest, Some(Job.Canceled _) - | CancelRequest, Some(Job.Failed _) - | OriginatorCanceled, None - | OriginatorCanceled, Some(Completed _) - | OriginatorCanceled, Some(Job.Canceled _) - | OriginatorCanceled, Some(Job.Failed _) -> () - - | JobFailed(ex, diags), Some(Running(tcs, _cts, _c, _ts, loggers)) -> - cancelRegistration key - cache.Set(key.Key, key.Version, key.Label, Job.Failed(DateTime.Now, ex)) - requestCounts.Remove key |> ignore - log (Failed, key) - Interlocked.Increment &failed |> ignore - failures.Add(key.Label, ex) - - for logger in loggers do - diags |> replayDiagnostics logger - - tcs.TrySetException ex |> ignore - - | JobCompleted(result, diags), Some(Running(tcs, _cts, _c, started, loggers)) -> - cancelRegistration key - cache.Set(key.Key, key.Version, key.Label, (Completed(result, diags))) - requestCounts.Remove key |> ignore - log (Finished, key) - Interlocked.Increment &completed |> ignore - let duration = float (DateTime.Now - started).Milliseconds - - avgDurationMs <- - if completed < 2 then - duration - else - avgDurationMs + (duration - avgDurationMs) / float completed - - for logger in loggers do - diags |> replayDiagnostics logger - - if tcs.TrySetResult result = false then - internalError key.Label "Invalid state: Completed job already completed" - - // Sometimes job can be canceled but it still manages to complete (or fail) - | JobFailed _, Some(Job.Canceled _) - | JobCompleted _, Some(Job.Canceled _) -> () - - // Job can't be evicted from cache while it's running because then subsequent requesters would be waiting forever - | JobFailed _, None -> internalError key.Label "Invalid state: Running job missing in cache (failed)" - - | JobCompleted _, None -> internalError key.Label "Invalid state: Running job missing in cache (completed)" - - | JobFailed(ex, _diags), Some(Completed(_job, _diags2)) -> - internalError key.Label $"Invalid state: Failed Completed job \n%A{ex}" - - | JobCompleted(_result, _diags), Some(Completed(_job, _diags2)) -> - internalError key.Label "Invalid state: Double-Completed job" - - | JobFailed(ex, _diags), Some(Job.Failed(_, ex2)) -> - internalError key.Label $"Invalid state: Double-Failed job \n%A{ex} \n%A{ex2}" - - | JobCompleted(_result, _diags), Some(Job.Failed(_, ex2)) -> - internalError key.Label $"Invalid state: Completed Failed job \n%A{ex2}" - }) - - let rec post msg = - Interlocked.Increment &updates_in_flight |> ignore - backgroundTask { - do! processStateUpdate post msg - Interlocked.Decrement &updates_in_flight |> ignore - } - |> ignore - - member this.Get'(key, computation) = - - let wrappedKey = - { new ICacheKey<_, _> with - member _.GetKey() = key - member _.GetVersion() = Unchecked.defaultof<_> - member _.GetLabel() = match key.ToString() with | null -> "" | s -> s - } - - this.Get(wrappedKey, computation) + | CacheEvent.Evicted -> logK JobEvent.Evicted + | CacheEvent.Collected -> logK JobEvent.Collected + | CacheEvent.Weakened -> logK JobEvent.Weakened + | CacheEvent.Strengthened -> logK JobEvent.Strengthened + | CacheEvent.Cleared -> logK JobEvent.Cleared)) member _.Get(key: ICacheKey<_, _>, computation) = - let key = { Label = key.GetLabel() @@ -496,136 +198,114 @@ type internal AsyncMemoize<'TKey, 'TVersion, 'TValue when 'TKey: equality and 'T Version = key.GetVersion() } - async { - let! ct = Async.CancellationToken + let wrappedComputation = + async { + use! _handler = Async.OnCancel (fun () -> log Canceled key) + let sw = Stopwatch.StartNew() + log Started key + let logger = CapturingDiagnosticsLogger "cache" + SetThreadDiagnosticsLoggerNoUnwind logger + + match! computation |> Async.Catch with + | Choice1Of2 result -> + log Finished key + Interlocked.Add(&duration, sw.ElapsedMilliseconds) |> ignore + return Result.Ok result, logger + | Choice2Of2 exn -> + log Failed key + return Result.Error exn, logger + } - let callerDiagnosticLogger = DiagnosticsThreadStatics.DiagnosticsLogger + let getOrAdd () = + let cached, otherVersions = cache.GetAll(key.Key, key.Version) - match! - processRequest post (key, GetOrCompute(computation, ct)) callerDiagnosticLogger - |> Async.AwaitTask - with - | New internalCt -> + let countHit v = Interlocked.Increment &hits |> ignore; v + let cacheSetNewJob () = + let job = Job(wrappedComputation, cancelUnawaited = cancelUnawaitedJobs) + cache.Set(key.Key, key.Version, key.Label, job) + job - let linkedCtSource = CancellationTokenSource.CreateLinkedTokenSource(ct, internalCt) - let cachingLogger = new CachingDiagnosticsLogger(Some callerDiagnosticLogger) + otherVersions, - try - return! - Async.StartAsTask( - async { - // TODO: Should unify starting and restarting - let currentLogger = DiagnosticsThreadStatics.DiagnosticsLogger - DiagnosticsThreadStatics.DiagnosticsLogger <- cachingLogger - - log (Started, key) - - try - let! result = computation - post (key, (JobCompleted(result, cachingLogger.CapturedDiagnostics))) - return result - finally - DiagnosticsThreadStatics.DiagnosticsLogger <- currentLogger - }, - cancellationToken = linkedCtSource.Token - ) - |> Async.AwaitTask - with - | TaskCancelled ex -> - // TODO: do we need to do anything else here? Presumably it should be done by the registration on - // the cancellation token or before we triggered our own cancellation + cached + |> Option.map countHit + |> Option.defaultWith cacheSetNewJob - // Let's send this again just in case. It seems sometimes it's not triggered from the registration? + async { + let otherVersions, job = lock cache getOrAdd - Interlocked.Increment &cancel_exception_original |> ignore + log Requested key - post (key, (OriginatorCanceled)) - return raise ex - | ex -> - post (key, (JobFailed(ex, cachingLogger.CapturedDiagnostics))) - return raise ex + if cancelDuplicateRunningJobs && not cancelUnawaitedJobs then + otherVersions |> Seq.map snd |> Seq.iter _.CancelIfUnawaited() - | Existing job -> return! job |> Async.AwaitTask + use _ = new CompilationGlobalsScope() + let! result, logger = job.Request() + logger.CommitDelayedDiagnostics DiagnosticsThreadStatics.DiagnosticsLogger + match result with + | Ok result -> + return result + | Error exn -> + return raise exn } member _.TryGet(key: 'TKey, predicate: 'TVersion -> bool) : 'TValue option = - let versionsAndJobs = cache.GetAll(key) - - versionsAndJobs - |> Seq.tryPick (fun (version, job) -> - match predicate version, job with - | true, Completed(completed, _) -> Some completed - | _ -> None) + lock cache <| fun () -> + cache.GetAll(key) + |> Seq.tryPick (fun (version, job) -> + match predicate version, job.TryResult with + | true, Some(Ok result, _) -> Some result + | _ -> None) - member _.Clear() = cache.Clear() + member _.Clear() = lock cache cache.Clear - member _.Clear predicate = cache.Clear predicate + member _.Clear predicate = lock cache <| fun () -> cache.Clear predicate member val Event = event.Publish member this.OnEvent = this.Event.Add - member _.Count = lock.Do(fun () -> Task.FromResult cache.Count).Result + member this.Count = lock cache <| fun () -> cache.Count - member _.Updating = updates_in_flight > 0 - - member _.Locked = lock.Semaphore.CurrentCount < 1 + member this.DebuggerDisplay = - member _.Running = - cache.GetValues() - |> Seq.filter (function - | _, _, Running _ -> true - | _ -> false) - |> Seq.toArray + let cachedJobs = cache.GetValues() |> Seq.map (fun (_,_,job) -> job) - member this.DebuggerDisplay = - let locked = if this.Locked then " [LOCKED]" else "" + let jobStateName = function + | Initial _ -> nameof Initial + | Running _ -> nameof Running + | Completed _ -> nameof Completed + | Faulted _ -> nameof Faulted - let valueStats = - cache.GetValues() - |> Seq.countBy (function - | _, _, Running _ -> "Running" - | _, _, Completed _ -> "Completed" - | _, _, Job.Canceled _ -> "Canceled" - | _, _, Job.Failed _ -> "Failed") - |> Map + let valueStats = cachedJobs |> Seq.countBy (_.State >> jobStateName) |> Map + let getStat key = valueStats.TryFind key |> Option.defaultValue 0 let running = - valueStats.TryFind "Running" - |> Option.map (sprintf " Running: %d ") - |> Option.defaultValue "" + let count = getStat "Running" + if count > 0 then $" Running {count}" else "" - let avgDuration = avgDurationMs |> sprintf "| Avg: %.0f ms" + let finished = eventCounts[Finished].Value + let avgDuration = if finished = 0 then "" else $"| Avg: %.0f{float duration / float finished} ms" - let hitRatio = - if started > 0 then - $" (%.0f{float hits / (float (started + hits)) * 100.0} %%)" - else - "" + let requests = eventCounts[Requested].Value + let hitRatio = if requests = 0 then "" else $" (%.0f{float hits / (float (requests)) * 100.0} %%)" + + let faulted = getStat "Faulted" + let failed = eventCounts[Failed].Value let stats = - [| - if errors + failed > 0 then + seq { + if faulted + failed > 0 then " (_!_) " - if errors > 0 then $"| ERRORS: {errors} " else "" - if failed > 0 then $"| FAILED: {failed} " else "" + for j in eventCounts.Keys do + let count = eventCounts[j].Value + if count > 0 then $"| {j}: {count}" else "" $"| hits: {hits}{hitRatio} " - if started > 0 then $"| started: {started} " else "" - if completed > 0 then $"| completed: {completed} " else "" - if canceled > 0 then $"| canceled: {canceled} " else "" - if restarted > 0 then $"| restarted: {restarted} " else "" - if evicted > 0 then $"| evicted: {evicted} " else "" - if collected > 0 then $"| collected: {collected} " else "" - if cleared > 0 then $"| cleared: {cleared} " else "" - if strengthened > 0 then - $"| strengthened: {strengthened} " - else - "" - |] + } |> String.concat "" - $"{locked}{running}{cache.DebuggerDisplay} {stats}{avgDuration}" + $"{running} {cache.DebuggerDisplay} {stats}{avgDuration}" /// A drop-in replacement for AsyncMemoize that disables caching and just runs the computation every time. [] @@ -640,4 +320,4 @@ type internal AsyncMemoizeDisabled<'TKey, 'TVersion, 'TValue when 'TKey: equalit Interlocked.Increment &requests |> ignore computation - member _.DebuggerDisplay = $"(disabled) requests: {requests}" + member _.DebuggerDisplay = $"(disabled) requests: {requests}" \ No newline at end of file diff --git a/src/Compiler/Facilities/AsyncMemoize.fsi b/src/Compiler/Facilities/AsyncMemoize.fsi index d86352d9987..37d2d397fe2 100644 --- a/src/Compiler/Facilities/AsyncMemoize.fsi +++ b/src/Compiler/Facilities/AsyncMemoize.fsi @@ -9,9 +9,6 @@ module internal Utils = /// Return file name with one directory above it val shortPath: path: string -> string - [] - val (|TaskCancelled|_|): ex: exn -> TaskCanceledException voption - type internal JobEvent = | Requested | Started @@ -39,13 +36,6 @@ type Extensions = [] static member internal WithExtraVersion: cacheKey: ICacheKey<'a, 'b> * extraVersion: 'c -> ICacheKey<'a, ('b * 'c)> -type internal AsyncLock = - interface System.IDisposable - - new: unit -> AsyncLock - - member Do: f: (unit -> #Task<'b>) -> Task<'b> - /// /// A cache/memoization for computations that makes sure that the same computation will only be computed once even if it's needed /// at multiple places/times. @@ -62,9 +52,10 @@ type internal AsyncMemoize<'TKey, 'TVersion, 'TValue when 'TKey: equality and 'T /// Maximum number of strongly held results to keep in the cache /// Maximum number of weakly held results to keep in the cache /// Name of the cache - used in tracing messages + /// Cancels a job when all the awaiting requests are canceled. If set to false, unawaited job will run to completion and it's result will be cached. /// If true, when a job is started, all other jobs with the same key will be canceled. new: - ?keepStrongly: int * ?keepWeakly: int * ?name: string * ?cancelDuplicateRunningJobs: bool -> + ?keepStrongly: int * ?keepWeakly: int * ?name: string * ?cancelUnawaitedJobs: bool * ?cancelDuplicateRunningJobs: bool -> AsyncMemoize<'TKey, 'TVersion, 'TValue> member Clear: unit -> unit @@ -73,8 +64,6 @@ type internal AsyncMemoize<'TKey, 'TVersion, 'TValue when 'TKey: equality and 'T member Get: key: ICacheKey<'TKey, 'TVersion> * computation: Async<'TValue> -> Async<'TValue> - member Get': key: 'TKey * computation: Async<'TValue> -> Async<'TValue> - member TryGet: key: 'TKey * predicate: ('TVersion -> bool) -> 'TValue option member Event: IEvent @@ -83,8 +72,6 @@ type internal AsyncMemoize<'TKey, 'TVersion, 'TValue when 'TKey: equality and 'T member Count: int - member Updating: bool - /// A drop-in replacement for AsyncMemoize that disables caching and just runs the computation every time. type internal AsyncMemoizeDisabled<'TKey, 'TVersion, 'TValue when 'TKey: equality and 'TVersion: equality> = diff --git a/src/Compiler/Service/TransparentCompiler.fs b/src/Compiler/Service/TransparentCompiler.fs index 5158ac7f25c..d0fb6b63768 100644 --- a/src/Compiler/Service/TransparentCompiler.fs +++ b/src/Compiler/Service/TransparentCompiler.fs @@ -1821,9 +1821,7 @@ type internal TransparentCompiler Trace.TraceInformation($"Using in-memory project reference: {name}") return assemblyDataResult - with - | TaskCancelled ex -> return raise ex - | ex -> + with ex -> errorR (exn ($"Error while computing assembly data for project {projectSnapshot.Label}: {ex}")) return ProjectAssemblyDataResult.Unavailable true } diff --git a/src/FSharp.Core/FSharp.Core.fsproj b/src/FSharp.Core/FSharp.Core.fsproj index 97a02162fa4..b0abd5048bd 100644 --- a/src/FSharp.Core/FSharp.Core.fsproj +++ b/src/FSharp.Core/FSharp.Core.fsproj @@ -64,7 +64,6 @@ Microsoft.FSharp.Core.SR FSCore.resx - diff --git a/src/FSharp.Core/ILLink.LinkAttributes.xml b/src/FSharp.Core/ILLink.LinkAttributes.xml deleted file mode 100644 index 47a3ff01f02..00000000000 --- a/src/FSharp.Core/ILLink.LinkAttributes.xml +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/FSharp.Core/async.fs b/src/FSharp.Core/async.fs index 1c5138b93dc..959d47d0aab 100644 --- a/src/FSharp.Core/async.fs +++ b/src/FSharp.Core/async.fs @@ -868,11 +868,7 @@ module AsyncPrimitives = /// - Initial cancellation check /// - Call syncCtxt.Post with exception protection. This may fail as it is arbitrary user code -#if BUILDING_WITH_LKG || NO_NULLCHECKING_LIB_SUPPORT let CreateSwitchToAsync (syncCtxt: SynchronizationContext) = -#else - let CreateSwitchToAsync (syncCtxt: SynchronizationContext | null) = -#endif MakeAsyncWithCancelCheck(fun ctxt -> ctxt.PostWithTrampoline syncCtxt ctxt.cont) /// - Initial cancellation check diff --git a/src/FSharp.Core/async.fsi b/src/FSharp.Core/async.fsi index 1cd02f9694b..e01ba0d8d75 100644 --- a/src/FSharp.Core/async.fsi +++ b/src/FSharp.Core/async.fsi @@ -647,7 +647,7 @@ namespace Microsoft.FSharp.Control /// Threads and Contexts /// /// - static member SwitchToContext : syncContext:System.Threading.SynchronizationContext -> Async + static member SwitchToContext : syncContext:(System.Threading.SynchronizationContext | null) -> Async /// Creates an asynchronous computation that captures the current /// success, exception and cancellation continuations. The callback must diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncLock.fs b/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncLock.fs deleted file mode 100644 index ef4b69a3910..00000000000 --- a/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncLock.fs +++ /dev/null @@ -1,26 +0,0 @@ -module CompilerService.AsyncLock - -open Internal.Utilities.Collections - -open Xunit -open System.Threading.Tasks - - -[] -let ``Async lock works`` () = - task { - use lock = new AsyncLock() - - let mutable x = 0 - - let job () = task { - let y = x - do! Task.Delay(10) - x <- y + 1 - } - - let jobs = [ for _ in 1..100 -> lock.Do job ] - let! _ = Task.WhenAll(jobs) - - Assert.Equal(100, x) - } \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs b/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs index e178ccaa911..2c0b6c311be 100644 --- a/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs +++ b/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs @@ -11,40 +11,58 @@ open FSharp.Compiler.Diagnostics open Xunit -let tap f x = f x; x +let internal observe (cache: AsyncMemoize<_,_,_>) = -let internal record (cache: AsyncMemoize<_,_,_>) = + let collected = new MailboxProcessor<_>(fun _ -> async {}) - let events = Collections.Concurrent.ConcurrentQueue() + let arrivals = MailboxProcessor.Start(fun inbox -> + let rec loop events = async { + let! (e, (_, k, _)) = inbox.Receive() + let events = (e, k) :: events + printfn $"{k}: {e}" + collected.Post events + do! loop events + } + loop [] + ) + + cache.Event.Add arrivals.Post - let waitForIdle() = SpinWait.SpinUntil(fun () -> not cache.Updating) + let next () = collected.Receive(10_000) - waitForIdle() - cache.Event - |> Event.map (fun (e, (_, k, _)) -> e, k) - |> Event.add events.Enqueue + next + +let rec awaitEvents next condition = + async { + match! next () with + | events when condition events -> return events + | _ -> return! awaitEvents next condition + } - let getEvents () = - waitForIdle() - events |> List.ofSeq |> tap (printfn "events: %A") +let rec eventsWhen next condition = + awaitEvents next condition |> Async.RunSynchronously - getEvents +let waitUntil next condition = + eventsWhen next condition |> ignore -let check getEvents assertFunction = - let actual = getEvents() - assertFunction actual +let expect next (expected: 't list) = + let actual = eventsWhen next (List.length >> (=) expected.Length) + Assert.Equal<'t list>(expected, actual |> List.rev) -let waitUntil getEvents condition = - while getEvents() |> condition |> not do () +let countOf value events = + events |> Seq.filter (fst >> (=) value) |> Seq.length -let recorded (expected: 't list) (actual: 't list) = - Assert.Equal<'t>(expected, actual) +let received event = function (a, _) :: _ when a = event -> true | _ -> false -let countOf value count events = - events |> Seq.filter (fst >> (=) value) |> Seq.length |> (=) count +let internal wrapKey key = + { new ICacheKey<_, _> with + member _.GetKey() = key + member _.GetVersion() = Unchecked.defaultof<_> + member _.GetLabel() = match key.ToString() with | null -> "" | s -> s + } -let received value events = - events |> List.tryLast |> Option.map (fst >> (=) value) |> Option.defaultValue false +let assertTaskCanceled (task: Task<_>) = + Assert.ThrowsAnyAsync(fun () -> task).Result |> ignore [] let ``Basics``() = @@ -54,16 +72,16 @@ let ``Basics``() = } let memoize = AsyncMemoize() - let events = record memoize + let events = observe memoize let result = seq { - memoize.Get'(5, computation 5) - memoize.Get'(5, computation 5) - memoize.Get'(2, computation 2) - memoize.Get'(5, computation 5) - memoize.Get'(3, computation 3) - memoize.Get'(2, computation 2) + memoize.Get(wrapKey 5, computation 5) + memoize.Get(wrapKey 5, computation 5) + memoize.Get(wrapKey 2, computation 2) + memoize.Get(wrapKey 5, computation 5) + memoize.Get(wrapKey 3, computation 3) + memoize.Get(wrapKey 2, computation 2) } |> Async.Parallel |> Async.RunSynchronously @@ -72,138 +90,148 @@ let ``Basics``() = Assert.Equal(expected, result) - check events <| fun events -> - let groups = events |> Seq.groupBy snd |> Seq.toList - Assert.Equal(3, groups.Length) - for key, events in groups do - Assert.Equal>(Set [ Requested, key; Started, key; Finished, key ], Set events) + let events = eventsWhen events (countOf Finished >> (=) 3) + + let groups = events |> Seq.groupBy snd |> Seq.toList + Assert.Equal(3, groups.Length) + for key, events in groups do + Assert.Equal>(Set [ Requested, key; Started, key; Finished, key ], Set events) [] -let ``We can cancel a job`` () = - task { +let ``We can disconnect a request from a running job`` () = - let jobStarted = new ManualResetEventSlim(false) - let cts = new CancellationTokenSource() - let ctsCancelled = new ManualResetEventSlim(false) + let cts = new CancellationTokenSource() + let canFinish = new ManualResetEventSlim(false) - let computation = async { - use! _catch = Async.OnCancel ignore - jobStarted.Set() - ctsCancelled.Wait() - do! async { } - failwith "Should be canceled before it gets here" - } + let computation = async { + canFinish.Wait() + } + + let memoize = AsyncMemoize<_, int, _>(cancelUnawaitedJobs = false, cancelDuplicateRunningJobs = true) + let events = observe memoize + + let key = 1 - let memoize = AsyncMemoize<_, int, _>() - let events = record memoize + let task1 = Async.StartAsTask( memoize.Get(wrapKey 1, computation), cancellationToken = cts.Token) - let key = 1 + waitUntil events (received Started) + cts.Cancel() - let _task1 = Async.StartAsTask( memoize.Get'(1, computation), cancellationToken = cts.Token) + assertTaskCanceled task1 - jobStarted.Wait() - cts.Cancel() - ctsCancelled.Set() + canFinish.Set() |> ignore - check events recorded - [ Requested, key - Started, key - Canceled, key ] + expect events + [ Requested, key + Started, key + Finished, key ] + +[] +let ``We can cancel a job`` () = + + let cts = new CancellationTokenSource() + + let computation = async { + while true do + do! Async.Sleep 1000 } + let memoize = AsyncMemoize<_, int, _>() + let events = observe memoize + + let key = 1 + + let task1 = Async.StartAsTask( memoize.Get(wrapKey 1, computation), cancellationToken = cts.Token) + + waitUntil events (received Started) + + cts.Cancel() + + assertTaskCanceled task1 + + expect events + [ Requested, key + Started, key + Canceled, key ] + [] let ``Job is restarted if first requestor cancels`` () = - let jobStarted = new SemaphoreSlim(0) + let jobCanComplete = new ManualResetEventSlim(false) - let jobCanComplete = new ManualResetEventSlim(false) + let computation key = async { + jobCanComplete.Wait() + return key * 2 + } - let computation key = async { - jobStarted.Release() |> ignore + let memoize = AsyncMemoize<_, int, _>() + let events = observe memoize - jobCanComplete.Wait() - return key * 2 - } + use cts1 = new CancellationTokenSource() - let memoize = AsyncMemoize<_, int, _>() - let events = record memoize + let key = 1 - use cts1 = new CancellationTokenSource() + let _task1 = Async.StartAsTask( memoize.Get(wrapKey key, computation key), cancellationToken = cts1.Token) - let key = 1 + waitUntil events (received Started) + cts1.Cancel() - let _task1 = Async.StartAsTask( memoize.Get'(key, computation key), cancellationToken = cts1.Token) + waitUntil events (received Canceled) - jobStarted.Wait() - let task2 = Async.StartAsTask( memoize.Get'(key, computation key)) - let task3 = Async.StartAsTask( memoize.Get'(key, computation key)) + let task2 = Async.StartAsTask( memoize.Get(wrapKey key, computation key)) - waitUntil events (countOf Requested 3) + waitUntil events (countOf Started >> (=) 2) - cts1.Cancel() + jobCanComplete.Set() |> ignore - jobCanComplete.Set() |> ignore + Assert.Equal(2, task2.Result) - jobStarted.Wait() + expect events + [ Requested, key + Started, key + Canceled, key + Requested, key + Started, key + Finished, key ] - Assert.Equal(2, task2.Result) - Assert.Equal(2, task3.Result) - - check events recorded - [ Requested, key - Started, key - Requested, key - Requested, key - Restarted, key - Finished, key ] [] -let ``Job is restarted if first requestor cancels but keeps running if second requestor cancels`` () = - let jobStarted = new ManualResetEventSlim(false) +let ``Job keeps running if only one requestor cancels`` () = - let jobCanComplete = new ManualResetEventSlim(false) + let jobCanComplete = new ManualResetEventSlim(false) - let computation key = async { - jobStarted.Set() |> ignore - jobCanComplete.Wait() - return key * 2 - } + let computation key = async { + jobCanComplete.Wait() + return key * 2 + } - let memoize = AsyncMemoize<_, int, _>() - let events = record memoize - - use cts1 = new CancellationTokenSource() - use cts2 = new CancellationTokenSource() - - let key = 1 + let memoize = AsyncMemoize<_, int, _>() + let events = observe memoize - let _task1 = Async.StartAsTask( memoize.Get'(key, computation key), cancellationToken = cts1.Token) + use cts = new CancellationTokenSource() - jobStarted.Wait() - jobStarted.Reset() |> ignore + let key = 1 - let _task2 = Async.StartAsTask( memoize.Get'(key, computation key), cancellationToken = cts2.Token) - let task3 = Async.StartAsTask( memoize.Get'(key, computation key)) + let task1 = Async.StartAsTask( memoize.Get(wrapKey key, computation key)) - waitUntil events (countOf Requested 3) + waitUntil events (received Started) - cts1.Cancel() + let task2 = Async.StartAsTask( memoize.Get(wrapKey key, computation key) |> Async.Ignore, cancellationToken = cts.Token) - jobStarted.Wait() + waitUntil events (countOf Requested >> (=) 2) - cts2.Cancel() + cts.Cancel() - jobCanComplete.Set() |> ignore + assertTaskCanceled task2 - Assert.Equal(2, task3.Result) + jobCanComplete.Set() |> ignore - check events recorded - [ Requested, key - Started, key - Requested, key - Requested, key - Restarted, key - Finished, key ] + Assert.Equal(2, task1.Result) + expect events + [ Requested, key + Started, key + Requested, key + Finished, key ] type ExpectedException() = inherit Exception() @@ -290,7 +318,7 @@ let ``Stress test`` () = let timeoutMs = rng.Next(minTimeout, maxTimeout) let key = keys[rng.Next keys.Length] let result = key * 2 - let job = cache.Get'(key, computation durationMs result) + let job = cache.Get(wrapKey key, computation durationMs result) let cts = new CancellationTokenSource() let runningJob = Async.StartAsTask(job, cancellationToken = cts.Token) cts.CancelAfter timeoutMs @@ -328,60 +356,56 @@ let ``Stress test`` () = Assert.True ((float completed) > ((float started) * 0.1), "Less than 10 % completed jobs") -[] -[] -[] -let ``Cancel running jobs with the same key`` cancelDuplicate expectFinished = - let cache = AsyncMemoize(cancelDuplicateRunningJobs=cancelDuplicate) - - let mutable started = 0 - let mutable finished = 0 +[] +let ``Cancel running jobs with the same key`` () = + let cache = AsyncMemoize(cancelUnawaitedJobs = false, cancelDuplicateRunningJobs = true) - let job1started = new ManualResetEventSlim(false) - let job1finished = new ManualResetEventSlim(false) + let events = observe cache let jobCanContinue = new ManualResetEventSlim(false) - let job2started = new ManualResetEventSlim(false) - let job2finished = new ManualResetEventSlim(false) - - let work onStart onFinish = async { - Interlocked.Increment &started |> ignore - onStart() |> ignore + let work = async { jobCanContinue.Wait() - do! Async.Sleep 100 - Interlocked.Increment &finished |> ignore - onFinish() |> ignore } - let key1 = + let key version = { new ICacheKey<_, _> with member _.GetKey() = 1 - member _.GetVersion() = 1 - member _.GetLabel() = "key1" } + member _.GetVersion() = version + member _.GetLabel() = $"key1 {version}" } - cache.Get(key1, work job1started.Set job1finished.Set) |> Async.Catch |> Async.Ignore |> Async.Start + let cts = new CancellationTokenSource() - job1started.Wait() + let jobsToCancel = + [ for i in 1 .. 10 -> Async.StartAsTask(cache.Get(key i , work), cancellationToken = cts.Token) ] - let key2 = - { new ICacheKey<_, _> with - member _.GetKey() = key1.GetKey() - member _.GetVersion() = key1.GetVersion() + 1 - member _.GetLabel() = "key2" } + waitUntil events (countOf Started >> (=) 10) + + // detach requests from their running computations + cts.Cancel() + + for job in jobsToCancel do assertTaskCanceled job - cache.Get(key2, work job2started.Set job2finished.Set ) |> Async.Catch |> Async.Ignore |> Async.Start + let job = cache.Get(key 11, work) |> Async.StartAsTask - job2started.Wait() + // up til now the jobs should have been running unobserved + let current = eventsWhen events (received Requested) + Assert.Equal(0, current |> countOf Canceled) + + // new request should cancel the unobserved jobs + waitUntil events (received Started) jobCanContinue.Set() |> ignore - - job2finished.Wait() - - if not cancelDuplicate then - job1finished.Wait() - Assert.Equal((2, expectFinished), (started, finished)) + job.Wait() + + let events = eventsWhen events (received Finished) + + Assert.Equal(0, events |> countOf Failed) + + Assert.Equal(10, events |> countOf Canceled) + + Assert.Equal(1, events |> countOf Finished) type DummyException(msg) = inherit Exception(msg) diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index ffc935a2075..a1a46d7a99e 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -300,7 +300,6 @@ - diff --git a/tests/FSharp.Compiler.ComponentTests/FSharpChecker/TransparentCompiler.fs b/tests/FSharp.Compiler.ComponentTests/FSharpChecker/TransparentCompiler.fs index b05096303d4..4b5987f65e5 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharpChecker/TransparentCompiler.fs +++ b/tests/FSharp.Compiler.ComponentTests/FSharpChecker/TransparentCompiler.fs @@ -33,17 +33,13 @@ let internal recordAllEvents groupBy = let mutable cache : AsyncMemoize<_,_,_> option = None let events = ConcurrentQueue() - let waitForIdle() = SpinWait.SpinUntil(fun () -> not cache.Value.Updating) - let observe (getCache: CompilerCaches -> AsyncMemoize<_,_,_>) (checker: FSharpChecker) = cache <- Some (getCache checker.Caches) - waitForIdle() cache.Value.Event |> Event.map (fun (e, k) -> groupBy k, e) |> Event.add events.Enqueue let getEvents () = - waitForIdle() events |> List.ofSeq observe, getEvents @@ -51,7 +47,7 @@ let internal recordAllEvents groupBy = let getFileNameKey (_l, (f: string, _p), _) = Path.GetFileName f // TODO: currently the label for DependecyGraph cache is $"%d{fileSnapshots.Length} files ending with {lastFile}" -let getDependecyGraphKey (_l, _, _) = failwith "not implemented" +let getDependecyGraphKey (_l, _, _) = failwith "not implemented" let internal recordEvents groupBy = let observe, getEvents = recordAllEvents groupBy @@ -293,7 +289,7 @@ let ``We don't check files that are not depended on`` () = let observe, check = recordEvents getFileNameKey - ProjectWorkflowBuilder(project, useTransparentCompiler = true) { + ProjectWorkflowBuilder(project, useTransparentCompiler = true) { withChecker (observe _.TcIntermediate) updateFile "First" updatePublicSurface checkFile "Last" expectOk @@ -448,7 +444,7 @@ let fuzzingTest seed (project: SyntheticProject) = task { let builder = ProjectWorkflowBuilder(project, useTransparentCompiler = true, autoStart = false) let checker = builder.Checker - + // Force creation and caching of options do! SaveAndCheckProject project checker false |> Async.Ignore @@ -600,7 +596,7 @@ let fuzzingTest seed (project: SyntheticProject) = task { builder.DeleteProjectDir() } -[] +[] [] [] [] @@ -712,7 +708,7 @@ let ``What happens if bootstrapInfoStatic needs to be recomputed`` _ = giraffeProject.Workflow { updateFile "Helpers" (fun f -> { f with SignatureFile = Custom (f.SignatureFile.CustomText + "\n") }) checkFile "EndpointRouting" expectOk - withChecker (fun checker -> + withChecker (fun checker -> async { checker.Caches.BootstrapInfoStatic.Clear() checker.Caches.BootstrapInfo.Clear() @@ -722,7 +718,7 @@ let ``What happens if bootstrapInfoStatic needs to be recomputed`` _ = }) updateFile "Core" (fun f -> { f with SignatureFile = Custom (f.SignatureFile.CustomText + "\n") }) checkFile "EndpointRouting" expectOk - } + } module ParsedInputHashing = @@ -776,7 +772,7 @@ let ``TypeCheck last file in project with transparent compiler`` useTransparentC let responseFile = FileInfo responseFile let syntheticProject = mkSyntheticProjectForResponseFile responseFile - let workflow = + let workflow = ProjectWorkflowBuilder( syntheticProject, isExistingProject = true, @@ -793,7 +789,7 @@ let ``TypeCheck last file in project with transparent compiler`` useTransparentC | Some lastFile -> workflow { - clearCache + clearCache checkFile lastFile expectOk } @@ -803,13 +799,13 @@ let ``LoadClosure for script is computed once`` () = sourceFile "First" []) let observe, getEvents = recordAllEvents getFileNameKey - + ProjectWorkflowBuilder(project, useTransparentCompiler = true) { withChecker (observe _.ScriptClosure) checkFile "First" expectOk } |> ignore - + Assert.Empty(getEvents()) [] @@ -819,7 +815,7 @@ let ``LoadClosure for script is recomputed after changes`` () = sourceFile "First" []) let observe, check = recordEvents getFileNameKey - + ProjectWorkflowBuilder(project, useTransparentCompiler = true) { withChecker (observe _.ScriptClosure) checkFile "First" expectOk @@ -830,12 +826,12 @@ let ``LoadClosure for script is recomputed after changes`` () = } |> ignore check (fileName "First") [Weakened; Requested; Started; Finished; Weakened; Requested; Started; Finished] - + [] let ``TryGetRecentCheckResultsForFile returns None before first call to ParseAndCheckFileInProject`` () = let project = SyntheticProject.Create( sourceFile "First" []) - + ProjectWorkflowBuilder(project) { clearCache tryGetRecentCheckResults "First" expectNone @@ -845,7 +841,7 @@ let ``TryGetRecentCheckResultsForFile returns None before first call to ParseAnd let ``TryGetRecentCheckResultsForFile returns result after first call to ParseAndCheckFileInProject`` () = let project = SyntheticProject.Create( sourceFile "First" [] ) - + ProjectWorkflowBuilder(project) { tryGetRecentCheckResults "First" expectSome } |> ignore @@ -854,7 +850,7 @@ let ``TryGetRecentCheckResultsForFile returns result after first call to ParseAn let ``TryGetRecentCheckResultsForFile returns no result after edit`` () = let project = SyntheticProject.Create( sourceFile "First" []) - + ProjectWorkflowBuilder(project) { tryGetRecentCheckResults "First" expectSome updateFile "First" updatePublicSurface @@ -862,13 +858,13 @@ let ``TryGetRecentCheckResultsForFile returns no result after edit`` () = checkFile "First" expectOk tryGetRecentCheckResults "First" expectSome } |> ignore - + [] let ``TryGetRecentCheckResultsForFile returns result after edit of other file`` () = let project = SyntheticProject.Create( sourceFile "First" [], sourceFile "Second" ["First"]) - + ProjectWorkflowBuilder(project) { tryGetRecentCheckResults "First" expectSome tryGetRecentCheckResults "Second" expectSome @@ -901,7 +897,7 @@ let ``Unused warning should still produce after parse warning`` useTransparentCo // There should be parse warning because of the space in the file name: // warning FS0221: The declarations in this file will be placed in an implicit module 'As 01' based on the file name 'As 01.fs'. // However this is not a valid F# identifier, so the contents will not be accessible from other files. Consider renaming the file or adding a 'module' or 'namespace' declaration at the top of the file. - + let project = { SyntheticProject.Create( { sourceFile "As 01" [] with @@ -914,7 +910,7 @@ do printfn "Hello from F#" """ SignatureFile = No - + }) with AutoAddModules = false OtherOptions = [ @@ -939,7 +935,7 @@ printfn "Hello from F#" checkResults.Diagnostics |> Array.exists (fun diag -> diag.Severity = FSharpDiagnosticSeverity.Warning && diag.ErrorNumber = 1182) Assert.True(hasCheckWarning, "Expected post inference warning FS1182") - + ProjectWorkflowBuilder(project, useTransparentCompiler = useTransparentCompiler) { checkFile "As 01" expectTwoWarnings } @@ -959,12 +955,12 @@ type private LoadClosureTestShim(currentFileSystem: IFileSystem) = let mutable bDidUpdate = false let asStream (v:string) = new MemoryStream(System.Text.Encoding.UTF8.GetBytes v) let knownFiles = set [ "a.fsx"; "b.fsx"; "c.fsx" ] - + member val aFsx = "#load \"b.fsx\"" member val bFsxInitial = "" member val bFsxUpdate = "#load \"c.fsx\"" member val cFsx = "" - + member x.DocumentSource (fileName: string) = async { if not (knownFiles.Contains fileName) then @@ -978,7 +974,7 @@ type private LoadClosureTestShim(currentFileSystem: IFileSystem) = } member x.UpdateB () = bDidUpdate <- true - + override _.FileExistsShim(path) = if knownFiles.Contains path then true else currentFileSystem.FileExistsShim(path) override _.GetFullPathShim(fileName) = @@ -996,7 +992,7 @@ type private LoadClosureTestShim(currentFileSystem: IFileSystem) = ) module TestsMutatingFileSystem = - + [] [] [] @@ -1010,7 +1006,7 @@ module TestsMutatingFileSystem = if System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription.StartsWith(".NET Framework") then None else - Some false + Some false try let checker = FSharpChecker.Create(useTransparentCompiler = useTransparentCompiler) @@ -1034,7 +1030,7 @@ module TestsMutatingFileSystem = match snd checkResults with | FSharpCheckFileAnswer.Aborted -> failwith "Did not expected FSharpCheckFileAnswer.Aborted" | FSharpCheckFileAnswer.Succeeded checkFileResults -> Assert.Equal(0, checkFileResults.Diagnostics.Length) - + // Update b.fsx, it should now load c.fsx fileSystemShim.UpdateB() @@ -1081,7 +1077,7 @@ let ``Parsing with cache and without project snapshot`` () = async { let checker = FSharpChecker.Create(useTransparentCompiler = true) let fileName = "B.fs" - let parsingOptions = { FSharpParsingOptions.Default with SourceFiles = [| "A.fs"; fileName; "C.fs" |] } + let parsingOptions = { FSharpParsingOptions.Default with SourceFiles = [| "A.fs"; fileName; "C.fs" |] } let sourceText = SourceText.ofString """ module B @@ -1091,7 +1087,7 @@ let b : int = ExtraIdentUserNeverWroteRulezzz let! parseResult = checker.ParseFile(fileName, sourceText, parsingOptions, cache = true) Assert.False(parseResult.ParseHadErrors) Assert.True(Array.isEmpty parseResult.Diagnostics) - + let! parseAgainResult = checker.ParseFile(fileName, sourceText, parsingOptions, cache = true) Assert.False(parseAgainResult.ParseHadErrors) Assert.True(Array.isEmpty parseAgainResult.Diagnostics) diff --git a/tests/FSharp.Compiler.Service.Tests/Common.fs b/tests/FSharp.Compiler.Service.Tests/Common.fs index 986e2be5132..18276ae39a9 100644 --- a/tests/FSharp.Compiler.Service.Tests/Common.fs +++ b/tests/FSharp.Compiler.Service.Tests/Common.fs @@ -473,63 +473,16 @@ let assertRange Assert.Equal(Position.mkPos expectedStartLine expectedStartColumn, actualRange.Start) Assert.Equal(Position.mkPos expectedEndLine expectedEndColumn, actualRange.End) -[] -module TempDirUtils = - let getTempPath dir = - Path.Combine(tempDirectoryOfThisTestRun.Value.FullName, dir) - - /// Returns the file name part of a temp file name created with tryCreateTemporaryFileName () - /// and an added process id and thread id to ensure uniqueness between threads. - let getTempFileName() = - let tempFileName = getTemporaryFileName () - try - let tempFile, tempExt = Path.GetFileNameWithoutExtension tempFileName, Path.GetExtension tempFileName - let procId, threadId = Process.GetCurrentProcess().Id, Thread.CurrentThread.ManagedThreadId - String.concat "" [tempFile; "_"; string procId; "_"; string threadId; tempExt] // ext includes dot - finally - try - FileSystem.FileDeleteShim tempFileName - with _ -> () - - /// Given just a file name, returns it with changed extension located in %TEMP%\ExprTests - let getTempFilePathChangeExt dir tmp ext = - Path.Combine(getTempPath dir, Path.ChangeExtension(tmp, ext)) - - /// If it doesn't exists, create a folder 'ExprTests' in local user's %TEMP% folder - let createTempDir dirName = - let tempPath = getTempPath dirName - do - if Directory.Exists tempPath then () - else Directory.CreateDirectory tempPath |> ignore - - /// Clean up after a test is run. If you need to inspect the create *.fs files, change this function to do nothing, or just break here. - let cleanupTempFiles dirName files = - { new IDisposable with - member _.Dispose() = - for fileName in files do - try - // cleanup: only the source file is written to the temp dir. - FileSystem.FileDeleteShim fileName - with _ -> () - - try - // remove the dir when empty - let tempPath = getTempPath dirName - if Directory.GetFiles tempPath |> Array.isEmpty then - Directory.Delete tempPath - with _ -> () } - - let createProjectOptions dirName fileSources extraArgs = - let fileNames = fileSources |> List.map (fun _ -> getTempFileName()) - let temp2 = getTempFileName() - let fileNames = fileNames |> List.map (fun temp1 -> getTempFilePathChangeExt dirName temp1 ".fs") - let dllName = getTempFilePathChangeExt dirName temp2 ".dll" - let projFileName = getTempFilePathChangeExt dirName temp2 ".fsproj" - - createTempDir dirName - for fileSource: string, fileName in List.zip fileSources fileNames do - FileSystem.OpenFileForWriteShim(fileName).Write(fileSource) - let args = [| yield! extraArgs; yield! mkProjectCommandLineArgs (dllName, []) |] - let options = { checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) with SourceFiles = fileNames |> List.toArray } - - cleanupTempFiles dirName (fileNames @ [dllName; projFileName]), options +let createProjectOptions fileSources extraArgs = + let tempDir = createTemporaryDirectory() + let temp2 = getTemporaryFileNameInDirectory tempDir + let dllName = changeExtension temp2 ".dll" + let projFileName = changeExtension temp2 ".fsproj" + + let sourceFiles = + [| for fileSource: string in fileSources do + let fileName = changeExtension (getTemporaryFileNameInDirectory tempDir) ".fs" + FileSystem.OpenFileForWriteShim(fileName).Write(fileSource) + fileName |] + let args = [| yield! extraArgs; yield! mkProjectCommandLineArgs (dllName, []) |] + { checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) with SourceFiles = sourceFiles } diff --git a/tests/FSharp.Compiler.Service.Tests/ExprTests.fs b/tests/FSharp.Compiler.Service.Tests/ExprTests.fs index 251e1fc3a91..7a594db1e38 100644 --- a/tests/FSharp.Compiler.Service.Tests/ExprTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/ExprTests.fs @@ -13,6 +13,8 @@ open FSharp.Compiler.Service.Tests.Common open FSharp.Compiler.Symbols open FSharp.Compiler.Symbols.FSharpExprPatterns +open TestFramework + type FSharpCore = | FC45 | FC46 @@ -593,7 +595,7 @@ let testMutableVar = mutableVar 1 let testMutableConst = mutableConst () """ - let createOptionsWithArgs args = createProjectOptions dirName [ fileSource1; fileSource2 ] args + let createOptionsWithArgs args = createProjectOptions [ fileSource1; fileSource2 ] args let createOptions() = createOptionsWithArgs [] @@ -659,8 +661,7 @@ let test{0}ToStringOperator (e1:{1}) = string e1 /// This test is run in unison with its optimized counterpart below [] let ``Test Unoptimized Declarations Project1`` () = - let cleanup, options = Project1.createOptionsWithArgs [ "--langversion:preview" ] - use _holder = cleanup + let options = Project1.createOptionsWithArgs [ "--langversion:preview" ] let exprChecker = FSharpChecker.Create(keepAssemblyContents=true, useTransparentCompiler=CompilerAssertHelpers.UseTransparentCompiler) let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate @@ -798,8 +799,7 @@ let ``Test Unoptimized Declarations Project1`` () = [] let ``Test Optimized Declarations Project1`` () = - let cleanup, options = Project1.createOptionsWithArgs [ "--langversion:preview" ] - use _holder = cleanup + let options = Project1.createOptionsWithArgs [ "--langversion:preview" ] let exprChecker = FSharpChecker.Create(keepAssemblyContents=true, useTransparentCompiler=CompilerAssertHelpers.UseTransparentCompiler) let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate @@ -938,15 +938,13 @@ let ``Test Optimized Declarations Project1`` () = let testOperators dnName fsName excludedTests expectedUnoptimized expectedOptimized = - let tempFileName = getTempFileName() - let filePath = getTempFilePathChangeExt dirName tempFileName ".fs" - let dllPath =getTempFilePathChangeExt dirName tempFileName ".dll" - let projFilePath = getTempFilePathChangeExt dirName tempFileName ".fsproj" + let tempFileName = getTemporaryFileName() + let filePath = changeExtension tempFileName ".fs" + let dllPath =changeExtension tempFileName ".dll" + let projFilePath = changeExtension tempFileName ".fsproj" let exprChecker = FSharpChecker.Create(keepAssemblyContents=true, useTransparentCompiler=true) begin - use _cleanup = cleanupTempFiles dirName [filePath; dllPath; projFilePath] - createTempDir dirName let source = String.Format(Project1.operatorTests, dnName, fsName) let replace (s:string) r = s.Replace("let " + r, "// let " + r) let fileSource = excludedTests |> List.fold replace source @@ -3128,7 +3126,7 @@ let BigSequenceExpression(outFileOpt,docFileOpt,baseAddressOpt) = """ - let createOptions() = createProjectOptions dirName [fileSource1] [] + let createOptions() = createProjectOptions [fileSource1] [] #if !NETFRAMEWORK && DEBUG [] @@ -3136,8 +3134,7 @@ let BigSequenceExpression(outFileOpt,docFileOpt,baseAddressOpt) = [] #endif let ``Test expressions of declarations stress big expressions`` () = - let cleanup, options = ProjectStressBigExpressions.createOptions() - use _holder = cleanup + let options = ProjectStressBigExpressions.createOptions() let exprChecker = FSharpChecker.Create(keepAssemblyContents=true, useTransparentCompiler=CompilerAssertHelpers.UseTransparentCompiler) let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate @@ -3155,8 +3152,7 @@ let ``Test expressions of declarations stress big expressions`` () = [] #endif let ``Test expressions of optimized declarations stress big expressions`` () = - let cleanup, options = ProjectStressBigExpressions.createOptions() - use _holder = cleanup + let options = ProjectStressBigExpressions.createOptions() let exprChecker = FSharpChecker.Create(keepAssemblyContents=true, useTransparentCompiler=CompilerAssertHelpers.UseTransparentCompiler) let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate @@ -3211,12 +3207,11 @@ let f7() = callXY (C()) (D()) let f8() = callXY (D()) (C()) """ - let createOptions() = createProjectOptions dirName [fileSource1] ["--langversion:7.0"] + let createOptions() = createProjectOptions [fileSource1] ["--langversion:7.0"] [] let ``Test ProjectForWitnesses1`` () = - let cleanup, options = ProjectForWitnesses1.createOptions() - use _holder = cleanup + let options = ProjectForWitnesses1.createOptions() let exprChecker = FSharpChecker.Create(keepAssemblyContents=true, useTransparentCompiler=CompilerAssertHelpers.UseTransparentCompiler) let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate @@ -3259,8 +3254,7 @@ let ``Test ProjectForWitnesses1`` () = [] let ``Test ProjectForWitnesses1 GetWitnessPassingInfo`` () = - let cleanup, options = ProjectForWitnesses1.createOptions() - use _holder = cleanup + let options = ProjectForWitnesses1.createOptions() let exprChecker = FSharpChecker.Create(keepAssemblyContents=true, useTransparentCompiler=CompilerAssertHelpers.UseTransparentCompiler) let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate @@ -3335,12 +3329,11 @@ type MyNumberWrapper = { MyNumber: MyNumber } """ - let createOptions() = createProjectOptions dirName [fileSource1] ["--langversion:7.0"] + let createOptions() = createProjectOptions [fileSource1] ["--langversion:7.0"] [] let ``Test ProjectForWitnesses2`` () = - let cleanup, options = ProjectForWitnesses2.createOptions() - use _holder = cleanup + let options = ProjectForWitnesses2.createOptions() let exprChecker = FSharpChecker.Create(keepAssemblyContents=true, useTransparentCompiler=CompilerAssertHelpers.UseTransparentCompiler) let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate @@ -3391,12 +3384,11 @@ let s2 = sign p1 """ - let createOptions() = createProjectOptions dirName [fileSource1] ["--langversion:7.0"] + let createOptions() = createProjectOptions [fileSource1] ["--langversion:7.0"] [] let ``Test ProjectForWitnesses3`` () = - let cleanup, options = createProjectOptions dirName [ ProjectForWitnesses3.fileSource1 ] ["--langversion:7.0"] - use _holder = cleanup + let options = createProjectOptions [ ProjectForWitnesses3.fileSource1 ] ["--langversion:7.0"] let exprChecker = FSharpChecker.Create(keepAssemblyContents=true, useTransparentCompiler=CompilerAssertHelpers.UseTransparentCompiler) let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate @@ -3426,8 +3418,7 @@ let ``Test ProjectForWitnesses3`` () = [] let ``Test ProjectForWitnesses3 GetWitnessPassingInfo`` () = - let cleanup, options = ProjectForWitnesses3.createOptions() - use _holder = cleanup + let options = ProjectForWitnesses3.createOptions() let exprChecker = FSharpChecker.Create(keepAssemblyContents=true, useTransparentCompiler=CompilerAssertHelpers.UseTransparentCompiler) let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate @@ -3485,12 +3476,11 @@ let isNullQuoted (ts : 't[]) = """ - let createOptions() = createProjectOptions dirName [fileSource1] ["--langversion:7.0"] + let createOptions() = createProjectOptions [fileSource1] ["--langversion:7.0"] [] let ``Test ProjectForWitnesses4 GetWitnessPassingInfo`` () = - let cleanup, options = ProjectForWitnesses4.createOptions() - use _holder = cleanup + let options = ProjectForWitnesses4.createOptions() let exprChecker = FSharpChecker.Create(keepAssemblyContents=true, useTransparentCompiler=CompilerAssertHelpers.UseTransparentCompiler) let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate @@ -3523,12 +3513,11 @@ module N.M let rec f = new System.EventHandler(fun _ _ -> f.Invoke(null,null)) """ - let createOptions() = createProjectOptions dirName [fileSource1] [] + let createOptions() = createProjectOptions [fileSource1] [] [] let ``Test NoWarn HashDirective`` () = - let cleanup, options = ProjectForNoWarnHashDirective.createOptions() - use _holder = cleanup + let options = ProjectForNoWarnHashDirective.createOptions() let exprChecker = FSharpChecker.Create(keepAssemblyContents=true, useTransparentCompiler=CompilerAssertHelpers.UseTransparentCompiler) let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate diff --git a/tests/FSharp.Compiler.Service.Tests/GeneratedCodeSymbolsTests.fs b/tests/FSharp.Compiler.Service.Tests/GeneratedCodeSymbolsTests.fs index 66b9782fb29..5fac752952c 100644 --- a/tests/FSharp.Compiler.Service.Tests/GeneratedCodeSymbolsTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/GeneratedCodeSymbolsTests.fs @@ -5,9 +5,6 @@ open FSharp.Compiler.CodeAnalysis open FSharp.Compiler.Service.Tests.Common open FSharp.Compiler.Symbols -[] -let dirName = "GeneratedCodeSymbolsTests" - [] let ``IsUnionCaseTester for Is* member in a class`` () = let source = """ @@ -16,8 +13,7 @@ module Lib type T () = member x.IsM = 1 """ - let cleanup, options = createProjectOptions dirName [ source ] [ "--langversion:preview" ] - use _holder = cleanup + let options = createProjectOptions [ source ] [ "--langversion:preview" ] let exprChecker = FSharpChecker.Create(keepAssemblyContents=true, useTransparentCompiler=false) let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate @@ -46,8 +42,7 @@ module Lib type T = A | B """ - let cleanup, options = createProjectOptions dirName [ source ] [ "--langversion:preview" ] - use _holder = cleanup + let options = createProjectOptions [ source ] [ "--langversion:preview" ] let exprChecker = FSharpChecker.Create(keepAssemblyContents=true, useTransparentCompiler=false) let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate @@ -80,8 +75,7 @@ type T = member x.IsC with get () = false """ - let cleanup, options = createProjectOptions dirName [ source ] [ "--langversion:preview" ] - use _holder = cleanup + let options = createProjectOptions [ source ] [ "--langversion:preview" ] let exprChecker = FSharpChecker.Create(keepAssemblyContents=true, useTransparentCompiler=false) let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate diff --git a/tests/FSharp.Compiler.Service.Tests/ScriptOptionsTests.fs b/tests/FSharp.Compiler.Service.Tests/ScriptOptionsTests.fs index 2d197af0398..328272defb8 100644 --- a/tests/FSharp.Compiler.Service.Tests/ScriptOptionsTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/ScriptOptionsTests.fs @@ -41,9 +41,9 @@ let ``can generate options for different frameworks regardless of execution envi [] [] let ``can resolve nuget packages to right target framework for different frameworks regardless of execution environment``(flag) = - let path = DirectoryInfo(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)).FullName - let file = (getTemporaryFileNameInDirectory path) + ".fsx" - let scriptFullPath = Path.Combine(path, file) + let dir = DirectoryInfo(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)) + let file = (getTemporaryFileNameInDirectory dir) + ".fsx" + let scriptFullPath = Path.Combine(dir.FullName, file) let scriptSource = """ #r "nuget: FSharp.Data, 3.3.3" open System diff --git a/tests/FSharp.Test.Utilities/CompilerAssert.fs b/tests/FSharp.Test.Utilities/CompilerAssert.fs index 202f7704a9d..5253ef16934 100644 --- a/tests/FSharp.Test.Utilities/CompilerAssert.fs +++ b/tests/FSharp.Test.Utilities/CompilerAssert.fs @@ -444,7 +444,7 @@ module CompilerAssertHelpers = let name = match nameOpt with | Some name -> name - | _ -> getTemporaryFileNameInDirectory outputDirectory.FullName + | _ -> getTemporaryFileNameInDirectory outputDirectory let outputFilePath = Path.ChangeExtension (Path.Combine(outputDirectory.FullName, name), if isExe then ".exe" else ".dll") let sources = @@ -508,7 +508,7 @@ module CompilerAssertHelpers = let compile isExe options (source:SourceCodeFileKind) f = let outputFilePath = Path.ChangeExtension (getTemporaryFileName (), if isExe then ".exe" else ".dll") - let tempDir = Path.GetDirectoryName outputFilePath + let tempDir = Directory.GetParent outputFilePath let sourceFile = match source.GetSourceText with @@ -521,10 +521,7 @@ module CompilerAssertHelpers = // On Disk file source - try - f (rawCompile outputFilePath isExe options TargetFramework.Current [sourceFile]) - finally - try Directory.Delete(tempDir, true) with | _ -> () + f (rawCompile outputFilePath isExe options TargetFramework.Current [sourceFile]) let rec compileCompilationAux outputDirectory ignoreWarnings (cmpl: Compilation) : (FSharpDiagnostic[] * exn option * string) * string list = @@ -548,7 +545,7 @@ module CompilerAssertHelpers = res, (deps @ deps2) - and evaluateReferences (outputPath:DirectoryInfo) ignoreWarnings (cmpl: Compilation) : string[] * string list = + and evaluateReferences (outputDir:DirectoryInfo) ignoreWarnings (cmpl: Compilation) : string[] * string list = match cmpl with | Compilation(_, _, _, _, cmpls, _, _) -> let compiledRefs = @@ -556,13 +553,13 @@ module CompilerAssertHelpers = |> List.map (fun cmpl -> match cmpl with | CompilationReference (cmpl, staticLink) -> - compileCompilationAux outputPath ignoreWarnings cmpl, staticLink + compileCompilationAux outputDir ignoreWarnings cmpl, staticLink | TestCompilationReference (cmpl) -> let fileName = match cmpl with | TestCompilation.CSharp c when not (String.IsNullOrWhiteSpace c.AssemblyName) -> c.AssemblyName - | _ -> getTemporaryFileNameInDirectory outputPath.FullName - let tmp = Path.Combine(outputPath.FullName, Path.ChangeExtension(fileName, ".dll")) + | _ -> getTemporaryFileNameInDirectory outputDir + let tmp = Path.Combine(outputDir.FullName, Path.ChangeExtension(fileName, ".dll")) cmpl.EmitAsFile tmp (([||], None, tmp), []), false) diff --git a/tests/FSharp.Test.Utilities/TestFramework.fs b/tests/FSharp.Test.Utilities/TestFramework.fs index ada5bf3363e..f50452eff9e 100644 --- a/tests/FSharp.Test.Utilities/TestFramework.fs +++ b/tests/FSharp.Test.Utilities/TestFramework.fs @@ -29,8 +29,10 @@ let createTemporaryDirectory () = let getTemporaryFileName () = createTemporaryDirectory().FullName ++ getShortId() -let getTemporaryFileNameInDirectory (directory: string) = - directory ++ getShortId() +let changeExtension path extension = Path.ChangeExtension(path, extension) + +let getTemporaryFileNameInDirectory (directory: DirectoryInfo) = + directory.FullName ++ getShortId() // Well, this function is AI generated. let rec copyDirectory (sourceDir: string) (destinationDir: string) (recursive: bool) = diff --git a/eng/ilverify.ps1 b/tests/ILVerify/ilverify.ps1 similarity index 80% rename from eng/ilverify.ps1 rename to tests/ILVerify/ilverify.ps1 index 3fd8f9eda64..760724c27c6 100644 --- a/eng/ilverify.ps1 +++ b/tests/ILVerify/ilverify.ps1 @@ -4,11 +4,12 @@ Write-Host "Checking whether running on Windows: $IsWindows" -[string] $repo_path = (Get-Item -Path $PSScriptRoot).Parent +[string] $repo_path = (Get-Item -Path $PSScriptRoot).Parent.Parent Write-Host "Repository path: $repo_path" [string] $script = if ($IsWindows) { Join-Path $repo_path "build.cmd" } else { Join-Path $repo_path "build.sh" } +[string] $additional_arguments = if ($IsWindows) { "-noVisualStudio" } else { "" } # Set configurations to build [string[]] $configurations = @("Debug", "Release") @@ -29,7 +30,7 @@ $projects = @{ # Run build script for each configuration (NOTE: We don't build Proto) foreach ($configuration in $configurations) { Write-Host "Building $configuration configuration..." - & $script -c $configuration + & $script -c $configuration $additional_arguments if ($LASTEXITCODE -ne 0 -And $LASTEXITCODE -ne '') { Write-Host "Build failed for $configuration configuration (last exit code: $LASTEXITCODE)." exit 1 @@ -111,14 +112,20 @@ foreach ($project in $projects.Keys) { } } - $baseline_file = Join-Path $repo_path "eng" "ilverify_${project}_${configuration}_${tfm}.bsl" + $baseline_file = Join-Path $repo_path "tests/ILVerify" "ilverify_${project}_${configuration}_${tfm}.bsl" $baseline_actual_file = [System.IO.Path]::ChangeExtension($baseline_file, 'bsl.actual') if (-not (Test-Path $baseline_file)) { Write-Host "Baseline file not found: $baseline_file" - $ilverify_output | Set-Content $baseline_actual_file - $failed = $true + if ($env:TEST_UPDATE_BSL -eq "1") { + Write-Host "Creating initial baseline file: $baseline_file" + $ilverify_output | Set-Content $baseline_file + } else { + Write-Host "Creating .actual baseline file: $baseline_actual_file" + $ilverify_output | Set-Content $baseline_actual_file + $failed = $true + } continue } @@ -127,8 +134,14 @@ foreach ($project in $projects.Keys) { if ($baseline.Length -eq 0) { Write-Host "Baseline file is empty: $baseline_file" - $ilverify_output | Set-Content $baseline_actual_file - $failed = $true + if ($env:TEST_UPDATE_BSL -eq "1") { + Write-Host "Updating empty baseline file: $baseline_file" + $ilverify_output | Set-Content $baseline_file + } else { + Write-Host "Creating initial .actual baseline file: $baseline_actual_file" + $ilverify_output | Set-Content $baseline_actual_file + $failed = $true + } continue } @@ -142,10 +155,19 @@ foreach ($project in $projects.Keys) { Write-Host "ILverify output does not match baseline, differences:" $cmp | Format-Table | Out-String | Write-Host - $ilverify_output | Set-Content $baseline_actual_file + + # Update baselines if TEST_UPDATE_BSL is set to 1 + if ($env:TEST_UPDATE_BSL -eq "1") { + Write-Host "Updating baseline file: $baseline_file" + $ilverify_output | Set-Content $baseline_file + } else { + $ilverify_output | Set-Content $baseline_actual_file + } $failed = $true continue } + + } } } @@ -155,4 +177,4 @@ if ($failed) { exit 1 } -exit 0 +exit 0 \ No newline at end of file diff --git a/eng/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl similarity index 98% rename from eng/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl rename to tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl index 527bb371db2..d59c7d2adda 100644 --- a/eng/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl @@ -21,14 +21,14 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3510-779::Invoke([S.P.CoreLib]System.Tuple`3)][offset 0x000001E5][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3510-791::Invoke([S.P.CoreLib]System.Tuple`3)][offset 0x000001E5][found Char] Unexpected type on the stack. [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.Interactive.Shell+Utilities+pointerToNativeInt@110::Invoke(object)][offset 0x00000007] Unmanaged pointers are not a verifiable type. [IL]: Error [StackUnexpected]: : .$FSharpCheckerResults+dataTipOfReferences@2205::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000084][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-491::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-491::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-491::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000082][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-491::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000008B][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-491::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000094][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-504::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-504::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-504::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000082][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-504::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000008B][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-504::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000094][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.StaticLinking+TypeForwarding::followTypeForwardForILTypeRef([FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.IL+ILTypeRef)][offset 0x00000010][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions::getCompilerOption([FSharp.Compiler.Service]FSharp.Compiler.CompilerOptions+CompilerOption, [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1)][offset 0x000000E6][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions::AddPathMapping([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, string)][offset 0x0000000B][found Char] Unexpected type on the stack. diff --git a/eng/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl similarity index 98% rename from eng/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl rename to tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl index 164060143d0..be76953ef7d 100644 --- a/eng/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl @@ -28,18 +28,18 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLine(string, int32)][offset 0x00000039][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3510-779::Invoke([S.P.CoreLib]System.Tuple`3)][offset 0x000001E5][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3510-791::Invoke([S.P.CoreLib]System.Tuple`3)][offset 0x000001E5][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiInteractionProcessor::CompletionsForPartialLID([FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompilerState, string)][offset 0x0000001B][found Char] Unexpected type on the stack. [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.Interactive.Shell+Utilities+pointerToNativeInt@110::Invoke(object)][offset 0x00000007] Unmanaged pointers are not a verifiable type. [IL]: Error [StackUnexpected]: : .$FSharpCheckerResults+dataTipOfReferences@2205::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000084][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseMemberFunctionAndValues@176::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue)][offset 0x00000059][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseEntity@218::GenerateNext([S.P.CoreLib]System.Collections.Generic.IEnumerable`1&)][offset 0x000000DA][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.ParsedInput+visitor@1423-6::VisitExpr([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, [FSharp.Compiler.Service]FSharp.Compiler.Syntax.SynExpr)][offset 0x00000605][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-491::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-491::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-491::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000082][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-491::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000008B][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-491::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000094][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-504::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-504::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-504::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000082][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-504::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000008B][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-504::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000094][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$Symbols+fullName@2490-1::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000015][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CreateILModule+MainModuleBuilder::ConvertProductVersionToILVersionInfo(string)][offset 0x00000011][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.StaticLinking+TypeForwarding::followTypeForwardForILTypeRef([FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.IL+ILTypeRef)][offset 0x00000010][found Char] Unexpected type on the stack. diff --git a/eng/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl similarity index 98% rename from eng/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl rename to tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl index 7de0bcd6baf..1c6248ec60a 100644 --- a/eng/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl @@ -21,13 +21,13 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3510-835::Invoke([S.P.CoreLib]System.Tuple`3)][offset 0x000001C7][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3510-831::Invoke([S.P.CoreLib]System.Tuple`3)][offset 0x000001C7][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$FSharpCheckerResults+GetReferenceResolutionStructuredToolTipText@2205::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000076][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-528::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-528::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-528::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000064][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-528::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000006D][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-528::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000076][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-525::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-525::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-525::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000064][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-525::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000006D][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-525::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000076][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Driver+ProcessCommandLineFlags@301-1::Invoke(string)][offset 0x0000000B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Driver+ProcessCommandLineFlags@301-1::Invoke(string)][offset 0x00000014][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.StaticLinking+TypeForwarding::followTypeForwardForILTypeRef([FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.IL+ILTypeRef)][offset 0x00000010][found Char] Unexpected type on the stack. diff --git a/eng/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl similarity index 98% rename from eng/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl rename to tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl index 21b484b426d..c358adc7976 100644 --- a/eng/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl @@ -28,17 +28,17 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLine(string, int32)][offset 0x00000032][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3510-835::Invoke([S.P.CoreLib]System.Tuple`3)][offset 0x000001C7][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3510-831::Invoke([S.P.CoreLib]System.Tuple`3)][offset 0x000001C7][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiInteractionProcessor::CompletionsForPartialLID([FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompilerState, string)][offset 0x00000024][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$FSharpCheckerResults+GetReferenceResolutionStructuredToolTipText@2205::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000076][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseMemberFunctionAndValues@176::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue)][offset 0x0000002B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseEntity@218::GenerateNext([S.P.CoreLib]System.Collections.Generic.IEnumerable`1&)][offset 0x000000BB][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.ParsedInput+visitor@1423-11::VisitExpr([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, [FSharp.Compiler.Service]FSharp.Compiler.Syntax.SynExpr)][offset 0x00000618][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-528::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-528::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-528::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000064][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-528::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000006D][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-528::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000076][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-525::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-525::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-525::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000064][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-525::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000006D][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-525::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000076][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$Symbols+fullName@2490-3::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000030][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Driver+ProcessCommandLineFlags@301-1::Invoke(string)][offset 0x0000000B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Driver+ProcessCommandLineFlags@301-1::Invoke(string)][offset 0x00000014][found Char] Unexpected type on the stack. diff --git a/eng/ilverify_FSharp.Core_Debug_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Core_Debug_netstandard2.0.bsl similarity index 100% rename from eng/ilverify_FSharp.Core_Debug_netstandard2.0.bsl rename to tests/ILVerify/ilverify_FSharp.Core_Debug_netstandard2.0.bsl diff --git a/eng/ilverify_FSharp.Core_Debug_netstandard2.1.bsl b/tests/ILVerify/ilverify_FSharp.Core_Debug_netstandard2.1.bsl similarity index 100% rename from eng/ilverify_FSharp.Core_Debug_netstandard2.1.bsl rename to tests/ILVerify/ilverify_FSharp.Core_Debug_netstandard2.1.bsl diff --git a/eng/ilverify_FSharp.Core_Release_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Core_Release_netstandard2.0.bsl similarity index 100% rename from eng/ilverify_FSharp.Core_Release_netstandard2.0.bsl rename to tests/ILVerify/ilverify_FSharp.Core_Release_netstandard2.0.bsl diff --git a/eng/ilverify_FSharp.Core_Release_netstandard2.1.bsl b/tests/ILVerify/ilverify_FSharp.Core_Release_netstandard2.1.bsl similarity index 100% rename from eng/ilverify_FSharp.Core_Release_netstandard2.1.bsl rename to tests/ILVerify/ilverify_FSharp.Core_Release_netstandard2.1.bsl From 6a93b9976d7f98673428ab5a4e2af96e02118d33 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Thu, 12 Dec 2024 07:32:19 -0800 Subject: [PATCH 6/6] Merge main to release/dev17.13 (#18131) * Backport :: Bugfix :: Support `ldelem.u8`, `ldelem.u` opcode aliases (#18081) (#18096) * Streamlining test deps a bit (#18022) * Streamlining test deps a bit * up * Format ILVerify output a bit (#18120) * fix for race condition in FileIndex.fileIndexOfFile (#18008) * fix for race condition in FileIndex.fileIndexOfFile * fantomas * fixed ilverify baselines (just a single line number changed) * add release notes entry * FileToIndex: Added unlocked read so that lock is entered for new files only * update ilverify baselines (changed line numbers only) * Fix ILVerify --------- Co-authored-by: Petr Co-authored-by: Vlad Zarytovskii * Update F# build version to 200 * Fix how much is trimmed from an interp string part (#18123) * Fix how much is trimmed from an interp string part Only trim last 2 characters if they are "%s" and the '%' is not escaped * Add release note --------- Co-authored-by: Adam Boniecki * Sink: report SynPat.ArrayOrList type (#18127) --------- Co-authored-by: Tomas Grosup Co-authored-by: Petr Co-authored-by: Martin <29605222+Martin521@users.noreply.github.com> Co-authored-by: Vlad Zarytovskii Co-authored-by: Adam Boniecki <20281641+abonie@users.noreply.github.com> Co-authored-by: Adam Boniecki Co-authored-by: Alex Berezhnykh Co-authored-by: Kevin Ransom (msft) --- .../.FSharp.Compiler.Service/9.0.200.md | 4 +- eng/Versions.props | 2 +- src/Compiler/Checking/CheckPatterns.fs | 1 + .../Checking/Expressions/CheckExpressions.fs | 2 +- src/Compiler/Utilities/range.fs | 69 ++++++++++--------- .../BasicProvider.Tests.fsproj | 1 - .../ComboProvider.Tests.fsproj | 1 - .../FSharp.Compiler.ComponentTests.fsproj | 1 + .../Language/InterpolatedStringsTests.fs | 11 +++ .../Miscellaneous/FileIndex.fs | 21 ++++++ tests/ILVerify/ilverify.ps1 | 4 +- ...y_FSharp.Compiler.Service_Debug_net9.0.bsl | 2 +- ....Compiler.Service_Debug_netstandard2.0.bsl | 2 +- ...FSharp.Compiler.Service_Release_net9.0.bsl | 2 +- ...ompiler.Service_Release_netstandard2.0.bsl | 2 +- 15 files changed, 82 insertions(+), 43 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Miscellaneous/FileIndex.fs diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md index 7c7f9652b19..33125ff07ed 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md @@ -15,7 +15,8 @@ * Fix locals allocating for the special `copyOfStruct` defensive copy ([PR #18025](https://github.com/dotnet/fsharp/pull/18025)) * Fix lowering of computed array expressions when the expression consists of a simple mapping from a `uint64` or `unativeint` array. [PR #18081](https://github.com/dotnet/fsharp/pull/18081) * Add missing nullable-metadata for C# consumers of records,exceptions and DU subtypes generated from F# code. [PR #18079](https://github.com/dotnet/fsharp/pull/18079) - +* Fix a race condition in file book keeping in the compiler service ([#18008](https://github.com/dotnet/fsharp/pull/18008)) +* Fix trimming '%' characters when lowering interpolated string to a concat call [PR #18123](https://github.com/dotnet/fsharp/pull/18123) ### Added @@ -25,6 +26,7 @@ * Added type conversions cache, only enabled for compiler runs, guarded by language version preview ([PR #17668](https://github.com/dotnet/fsharp/pull/17668)) * Added project property ParallelCompilation which turns on graph based type checking, parallel ILXGen and parallel optimization. By default on for users of langversion=preview ([PR #17948](https://github.com/dotnet/fsharp/pull/17948)) * Adding warning when consuming generic method returning T|null for types not supporting nullness (structs,anons,tuples) ([PR #18057](https://github.com/dotnet/fsharp/pull/18057)) +* Sink: report SynPat.ArrayOrList type ([PR #18127](https://github.com/dotnet/fsharp/pull/18127)) ### Changed diff --git a/eng/Versions.props b/eng/Versions.props index 0245a0d620c..cd72f859965 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -184,7 +184,7 @@ 3.1.0 5.0.0-preview.7.20364.11 5.0.0-preview.7.20364.11 - 17.4.0 + 17.11.1 13.0.3 1.0.0-beta2-dev3 2.18.48 diff --git a/src/Compiler/Checking/CheckPatterns.fs b/src/Compiler/Checking/CheckPatterns.fs index 3f97cf81780..0c496517fd4 100644 --- a/src/Compiler/Checking/CheckPatterns.fs +++ b/src/Compiler/Checking/CheckPatterns.fs @@ -313,6 +313,7 @@ and TcPat warnOnUpper (cenv: cenv) env valReprInfo vFlags (patEnv: TcPatLinearEn TcPat warnOnUpper cenv env None vFlags patEnv ty p | SynPat.ArrayOrList (isArray, args, m) -> + CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, ty, env.AccessRights) TcPatArrayOrList warnOnUpper cenv env vFlags patEnv ty isArray args m | SynPat.Record (flds, m) -> diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs index b13e3d01d12..16dc49c1a61 100644 --- a/src/Compiler/Checking/Expressions/CheckExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs @@ -174,7 +174,7 @@ let (|WithTrailingStringSpecifierRemoved|) (s: string) = let i = s.AsSpan(0, s.Length - 2).LastIndexOfAnyExcept '%' let diff = s.Length - 2 - i if diff &&& 1 <> 0 then - s[..i] + s[..s.Length - 3] else s else diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs index 6d0002a97ba..09633136dbe 100755 --- a/src/Compiler/Utilities/range.fs +++ b/src/Compiler/Utilities/range.fs @@ -196,38 +196,43 @@ type FileIndexTable() = match fileToIndexTable.TryGetValue filePath with | true, idx -> idx | _ -> - - // Try again looking for a normalized entry. - let normalizedFilePath = - if normalize then - FileSystem.NormalizePathShim filePath - else - filePath - - match fileToIndexTable.TryGetValue normalizedFilePath with - | true, idx -> - // Record the non-normalized entry if necessary - if filePath <> normalizedFilePath then - lock fileToIndexTable (fun () -> fileToIndexTable[filePath] <- idx) - - // Return the index - idx - - | _ -> - lock fileToIndexTable (fun () -> - // Get the new index - let idx = indexToFileTable.Count - - // Record the normalized entry - indexToFileTable.Add normalizedFilePath - fileToIndexTable[normalizedFilePath] <- idx - - // Record the non-normalized entry if necessary - if filePath <> normalizedFilePath then - fileToIndexTable[filePath] <- idx - - // Return the index - idx) + // If a write operation can happen, we have to lock the whole read-check-write to avoid race conditions + lock fileToIndexTable + <| fun () -> + match fileToIndexTable.TryGetValue filePath with + | true, idx -> idx + | _ -> + + // Try again looking for a normalized entry. + let normalizedFilePath = + if normalize then + FileSystem.NormalizePathShim filePath + else + filePath + + match fileToIndexTable.TryGetValue normalizedFilePath with + | true, idx -> + // Record the non-normalized entry if necessary + if filePath <> normalizedFilePath then + fileToIndexTable[filePath] <- idx + + // Return the index + idx + + | _ -> + // Get the new index + let idx = indexToFileTable.Count + + // Record the normalized entry + indexToFileTable.Add normalizedFilePath + fileToIndexTable[normalizedFilePath] <- idx + + // Record the non-normalized entry if necessary + if filePath <> normalizedFilePath then + fileToIndexTable[filePath] <- idx + + // Return the index + idx member t.IndexToFile n = if n < 0 then diff --git a/tests/EndToEndBuildTests/BasicProvider/BasicProvider.Tests/BasicProvider.Tests.fsproj b/tests/EndToEndBuildTests/BasicProvider/BasicProvider.Tests/BasicProvider.Tests.fsproj index 4e4aef01856..4bc1b805799 100644 --- a/tests/EndToEndBuildTests/BasicProvider/BasicProvider.Tests/BasicProvider.Tests.fsproj +++ b/tests/EndToEndBuildTests/BasicProvider/BasicProvider.Tests/BasicProvider.Tests.fsproj @@ -21,7 +21,6 @@ content\myfiles\ - diff --git a/tests/EndToEndBuildTests/ComboProvider/ComboProvider.Tests/ComboProvider.Tests.fsproj b/tests/EndToEndBuildTests/ComboProvider/ComboProvider.Tests/ComboProvider.Tests.fsproj index d4d410bacd4..69a4cd8855d 100644 --- a/tests/EndToEndBuildTests/ComboProvider/ComboProvider.Tests/ComboProvider.Tests.fsproj +++ b/tests/EndToEndBuildTests/ComboProvider/ComboProvider.Tests/ComboProvider.Tests.fsproj @@ -18,7 +18,6 @@ - diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 4338fbd807b..e8f044ed2f4 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -317,6 +317,7 @@ + diff --git a/tests/FSharp.Compiler.ComponentTests/Language/InterpolatedStringsTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/InterpolatedStringsTests.fs index b4e2cc8eab9..e7c18f0d679 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/InterpolatedStringsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/InterpolatedStringsTests.fs @@ -130,6 +130,17 @@ type Foo () = |> compile |> shouldSucceed + [] + let ``Percent signs and format specifiers with string expression`` () = + Fsx """ +let x = "abc" +let s = $"%%%s{x}%%" +printfn "%s" s + """ + |> compileExeAndRun + |> shouldSucceed + |> withStdOutContains "%abc%" + [] // Test different number of interpolated string parts [] diff --git a/tests/FSharp.Compiler.ComponentTests/Miscellaneous/FileIndex.fs b/tests/FSharp.Compiler.ComponentTests/Miscellaneous/FileIndex.fs new file mode 100644 index 00000000000..0d5caabb982 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Miscellaneous/FileIndex.fs @@ -0,0 +1,21 @@ +module Miscellaneous.FileIndex + +open FSharp.Compiler.Text +open System.Threading.Tasks +open Xunit + +// This is a regression test for a bug that existed in FileIndex.fileIndexOfFile +[] +let NoRaceCondition() = + let parallelOptions = ParallelOptions() + let mutable count = 10000 + while count > 0 do + let file = $"test{count}.fs" + let files = Array.create 2 file + let indices = Array.create 2 -1 + let getFileIndex i = indices[i] <- FileIndex.fileIndexOfFile files[i] + Parallel.For(0, files.Length, parallelOptions, getFileIndex) |> ignore + if indices[0] <> indices[1] then + Assert.Fail $"Found different indices: {indices[0]} and {indices[1]}" + count <- count - 1 + \ No newline at end of file diff --git a/tests/ILVerify/ilverify.ps1 b/tests/ILVerify/ilverify.ps1 index 23618d1a1b1..ab1e2d316c2 100644 --- a/tests/ILVerify/ilverify.ps1 +++ b/tests/ILVerify/ilverify.ps1 @@ -162,7 +162,7 @@ foreach ($project in $projects.Keys) { } else { Write-Host "ILverify output does not match baseline, differences:" - $cmp | Format-Table | Out-String | Write-Host + $cmp | Format-Table -AutoSize -Wrap | Out-String | Write-Host # Update baselines if TEST_UPDATE_BSL is set to 1 if ($env:TEST_UPDATE_BSL -eq "1") { @@ -185,4 +185,4 @@ if ($failed) { exit 1 } -exit 0 \ No newline at end of file +exit 0 diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl index c527d99ccf5..03328728f4c 100644 --- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl @@ -59,7 +59,7 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x0000000B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x00000021][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000CD][found Char] Unexpected type on the stack. -[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@543::System.Collections.Generic.IEqualityComparer.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method. +[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@548::System.Collections.Generic.IEqualityComparer.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method. [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000037][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000043][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack. diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl index 7d4eff968ac..a863787a54e 100644 --- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl @@ -84,7 +84,7 @@ [IL]: Error [StackUnexpected]: : Internal.Utilities.FSharpEnvironment+probePathForDotnetHost@321::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000028][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.SimulatedMSBuildReferenceResolver+Pipe #6 input at line 68@68::FSharp.Compiler.CodeAnalysis.ILegacyReferenceResolver.Resolve([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyResolutionEnvironment, [S.P.CoreLib]System.Tuple`2[], string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, string, string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, string, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>>)][offset 0x0000034D][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000CD][found Char] Unexpected type on the stack. -[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@543::System.Collections.Generic.IEqualityComparer.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method. +[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@548::System.Collections.Generic.IEqualityComparer.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method. [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000037][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000043][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack. diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl index a930478a45e..d1f7525cef2 100644 --- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl @@ -85,7 +85,7 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x0000000B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x00000021][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000B6][found Char] Unexpected type on the stack. -[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@543::System.Collections.Generic.IEqualityComparer.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method. +[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@548::System.Collections.Generic.IEqualityComparer.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method. [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000035][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000041][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack. diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl index b97ede137b1..9de22b5cd79 100644 --- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl @@ -111,7 +111,7 @@ [IL]: Error [StackUnexpected]: : Internal.Utilities.FSharpEnvironment::probePathForDotnetHost@320([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x0000002A][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.SimulatedMSBuildReferenceResolver+SimulatedMSBuildResolver@68::FSharp.Compiler.CodeAnalysis.ILegacyReferenceResolver.Resolve([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyResolutionEnvironment, [S.P.CoreLib]System.Tuple`2[], string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, string, string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, string, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>>)][offset 0x000002F5][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000B6][found Char] Unexpected type on the stack. -[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@543::System.Collections.Generic.IEqualityComparer.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method. +[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@548::System.Collections.Generic.IEqualityComparer.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method. [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000035][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000041][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.