From b73be1584c2a4ea3228b80cc1569e3b1b741cf33 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Wed, 17 Jul 2024 20:30:43 +0100 Subject: [PATCH] [RFC FS-1060] Nullness checking (#15181) * squash * squash * move adhoc tests and clean errors * fix up constraint solving and adhoc testing * remove tests * fantomas * skip fails * fix tests * fix up test baselines for change in order in checking * update tests * don't overwrite baselines * fix some test failures * skip warnings * skip warnings * fix warning logic * fix tests * fix sizes * fix build * fantomas and validation update * corrections to self-use * [WIP] [RFC FS-1060] Nullness checking (applied to codebase) (#15265) * enablement * enablement * fix build * fix build * fantomas * selective adoption * Revert "[WIP] [RFC FS-1060] Nullness checking (applied to codebase) (#15265)" (#15309) This reverts commit 559c058144129e0a42de3f66f9844c60e9c620f9. * Fixes * Feature/nullness - parsing of constraints (#15753) * Feature/nullness - parsing of constraints for: 'T: not null .... syntax in Type argument specification appType | NULL ... for specifying types * applying changed syntax * positive.fs updated * positive.fs paranthesis * fixing "parse warning Remove spaces between the type name and type parameter, e.g. "C<'T>", not "C <'T>". Type parameters must be placed directly adjacent to the type name." * positive .bsl updated * Please mighty fantomas * Feature nullness metadata export (#15981) * fix merge mistake * fix build * fantomas * bsl fix * il tests update * fix test * tests fixed * fantomas * fix tests * trim test * trimming test * trim check * now? * IL tests * il tests * trim test * trim * one more time * Merge main to feature/nullness (#16366) * Fixes #16359 - correctly handle imports with 0 length public key tokens (#16363) * Parser: recover on unfinished record decls, fix field ranges (#16357) * Parser: recover on unfinished record decls, fix field ranges * Fantomas * Better diagnostic ranges for fields * More parser tests * Update surface area * Fix xml doc test * Update baselines * Update src/Compiler/SyntaxTree/SyntaxTree.fsi Co-authored-by: Edgar Gonzalez * Add MutableKeyword to SynFieldTrivia. (#11) * Simplify * Fantomas --------- Co-authored-by: Edgar Gonzalez Co-authored-by: Florian Verdonck --------- Co-authored-by: Kevin Ransom (msft) Co-authored-by: Eugene Auduchinok Co-authored-by: Edgar Gonzalez Co-authored-by: Florian Verdonck Co-authored-by: Tomas Grosup * syntax tree layout * Nullness-related aggressive trimming of FSharp.Core (#16387) * Merge main to feature/nullness (#16397) * [main] Update dependencies from dnceng/internal/dotnet-optimization (#16150) * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231019.5 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime From Version 1.0.0-prerelease.23515.2 -> To Version 1.0.0-prerelease.23519.5 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231019.5 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime From Version 1.0.0-prerelease.23515.2 -> To Version 1.0.0-prerelease.23519.5 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231021.3 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime From Version 1.0.0-prerelease.23515.2 -> To Version 1.0.0-prerelease.23521.3 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231021.3 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime From Version 1.0.0-prerelease.23515.2 -> To Version 1.0.0-prerelease.23521.3 --------- Co-authored-by: dotnet-maestro[bot] * [main] Update dependencies from dotnet/arcade (#16241) * Update dependencies from https://github.com/dotnet/arcade build 20231106.5 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23556.5 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231106.5 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23556.5 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231106.5 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23556.5 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231106.5 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23556.5 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231106.5 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23556.5 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231106.5 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23556.5 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231106.5 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23556.5 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231114.4 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23564.4 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231114.4 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23564.4 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231114.4 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23564.4 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231114.4 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23564.4 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231114.4 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23564.4 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231114.4 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23564.4 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231114.4 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23564.4 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231114.4 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23564.4 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231114.4 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23564.4 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231114.4 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23564.4 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231114.4 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23564.4 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231114.4 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23564.4 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231114.4 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23564.4 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231114.4 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23564.4 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231114.4 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23564.4 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231114.4 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23564.4 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231114.4 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23564.4 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231130.1 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23580.1 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231130.1 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23580.1 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231130.1 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23580.1 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231130.1 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23580.1 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20231130.1 Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.23463.1 -> To Version 8.0.0-beta.23580.1 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23426.1 -> To Version 1.0.0-beta.23475.1 (parent: Microsoft.DotNet.Arcade.Sdk --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Vlad Zarytovskii Co-authored-by: Tomas Grosup * Name resolution: don't search extension members in type abbreviations (#16390) * Name resolution: don't search extension members in type abbreviations * Add test * Revert "[main] Update dependencies from dotnet/arcade (#16241)" (#16396) This reverts commit f219a9905961c285d598dcead51936f2c2972263. * trimmed size updated --------- Co-authored-by: dotnet-maestro[bot] <42748379+dotnet-maestro[bot]@users.noreply.github.com> Co-authored-by: dotnet-maestro[bot] Co-authored-by: Vlad Zarytovskii Co-authored-by: Tomas Grosup Co-authored-by: Eugene Auduchinok * Nullness interop - import of C#-emitted metadata (#16423) * Nullness - include in QuickInfo and in general in "typeEnc" (string representation of a type) (#16555) * failing test * todo for IL import * explanation added * il meta parsing * flags evaluation * you shall passs * evaluateFirstOrderNullnessAndAdvance * import il type with nullness * type import * IL nullness import fields, props, events, method args, method return types - nullness imported from IL * test rename * fantomas * get stack trace on error * split ilmethod's type * fix crashes for Csharp style extensions * solve coexistance of nullness and Is* properties of DUs * updating tests * clean tests * fantomas * fantomas one more time * importing nullness for generic typars * print failing ivals, let's see * write even more! * isolated failing test - combo of module rec, signature file, IVT * another attempt * format * test * hide tests * Remove 'specialname' for DU case tester * format * warning as error * update baseline netcore * nullable errors not in desktop framework * surface area, trimming * surface area * cosmetic cleanup & annotations * Rename to ILMethParentTypeInfo * making vMapFold tail recursive * physical nullnessEquiv * format * Commenting SkipNullness usages * Nullness work - activity module * Remove strict generic 'T:null' import * Null|NonNull pattern also for regular compilation * Backported Null|NonNull active pattern * one more time * revert * Show nullness in quickinfo and in general in type representations * Merge main to feature/nullness (#16539) Merge of main + syntax conflict resolution + semantic conflict resolution * release notes * Fix ILType.Array import (#16585) * Nullness - reading+writing metadata for 'inherits' and interface implementations (#16597) * ILGenerator test case * Nullness :: Format string %s should allow nullable string (#16656) * Nullness:: Unchecked.nonNull for FSharp.Core (#16654) * Nullness :: Pattern matching with null should mark input for subsequent clauses as without null + support for matching nulls in tuples (#16659) * Feature nullness - support overrides of nullness annotation in the imported object hierarchy (#16711) * Improve type inference w.r.t. nullness in printing (#16681) * Update tests/AheadOfTime/Trimming/check.ps1 * Fix merge errors * il tests reflecting visibility change * Nullness feature :: New warning for functions insisting on a (WithNull) argument + typar equality fix (#16853) Null-handling functions now have the option to raise a warning when they are called with a known-to-be-withoutNull argument. That way, API authors (incl. Fsharp.Core) can help with cleaning code from superflous null checks. While doing it, a strange error kept coming when using Option.ofObj and other functions with a (T | null) typar. It turned out that nullness info had been striped from nullable typars on stripTyparEqnsAux calls in some occasions, leading to treating all typars as 'KnownWithoutNull' even when that was not true. * Feature nullness - propper guards against ` | null ` on unsupported types (#16907) TODOs resolved: * mkAppTy resolved * mkFunTyWithNullness * delayed checks of post-infered values for nullness-carrying capabilities * Feature nullness :: warn also for 'obj' type (since it can be infered for null literal) (#16962) * Nullness feature :: various bugfixes (#17080) * Bugfix - matching aliased nullable should strip nullness Eliminating nullness after pattern matching null (that is , for subsequent patterns) must visit contents of abbreviations as well. Otherwise it does not work with the Maybe type whcih we use in the compiler. * Making 'obj' work with new 'not null' constraints in fslib functions Bugfix: obj cannot be passed to generic typars which require T: not null, such as the NonNull active pattern. This commit fixes it. * Bugfix - false 'useless null' warning in nested applications Error fixed: Error on useless null checkwith nullness constraint propagation in code like this:let meTry = Option.ofObj (Path.GetDirectoryName "")`. The warning about 'useless Option.ofObj' points to the string literal, ignoring the string literal is first passed to an API which may return null * Fix import for C# extension methods Bugfix for: C# extension methods which put "?" on the this argument are wrongly interpreted by moving the nullability elsewhere. See AsMemory from System.Memory.dll , this treats byteArray.ToMemory() as resulting in a Memory which is clearly wrong. Also, this now allows to call C# extension methods with ?this to be invoked on a nullable value. * LinkedList First,Last bugfix There was a bug of LinkedList .First and .Last properties not returning nullable nodes. This was fixed by improved byte import in previous commit, adding a regression test for guarding this. * Bugfix: Solve nullness for typars This fixes a bug where `not null` generic constraint was incorrectly passed between two typars:`T1 | null` with not null constraint on T1, and T2 without constraints. This occured when calling Option.ofObj(..) when the inner expression caused solving of generic type arguments, e.g. after (|>) or (id) function. This uses additional inference variable to unify them. * updating IL tests * One more try * surface area * trimmed size * trimmed size * fix issues for plain 'dotnet build Fsharp.Compiler.Service.sln` * update FSharpCoreShippedPackageVersionValue * Wkraround attributetargets issue by using 'obj'. This removes 3x box and adds 1x unbox. * Feature nullness :: Bugfixes (#17102) * Ignore Nullness applied on structs (C# allows T? when when T is a struct) * Bigfix: Working with CLI events in Fsharp * Bugfix: Mutable binding initially assigned to null should not need type annotation * Solving `let mutable cache = null` via type inference * Enforcing TyparConstraint.IsReferenceType when WithNull type is used * Nullness-related constraint consistency * Bugfix for emitting Nullable attrs for C# * Automated command ran: fantomas Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com> * Feature nullness :: Try infer without null even when function/method arg is marked as nullable (#17269) * Feature nullness :: apply nullness annotations to usages of 'obj' in Fsharp.Core (#17284) * resolve build error from auto-merge * Feature nullness :: Cleanups, Test reorg, fix incrementalbuild cache behavior (#17309) * Fix TransparentCompiler - it should report PostInference errors if it only encountered a warning (reported as an error due to confiig) * fix build issues * resolve semantic merge error * Nullness subsumption when used for contravariant typars * fix nullness plain build (#17404) * Update docs/release-notes/.FSharp.Compiler.Service/8.0.300.md * Update release notes * Update check.ps1 * Update check.ps1 --------- Co-authored-by: Vlad Zarytovskii Co-authored-by: Tomas Grosup Co-authored-by: dotnet bot Co-authored-by: Kevin Ransom (msft) Co-authored-by: Eugene Auduchinok Co-authored-by: Edgar Gonzalez Co-authored-by: Florian Verdonck Co-authored-by: dotnet-maestro[bot] <42748379+dotnet-maestro[bot]@users.noreply.github.com> Co-authored-by: dotnet-maestro[bot] Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: psfinaki --- .fantomasignore | 17 + .gitignore | 3 + FSharp.Benchmarks.sln | 3 +- FSharp.Profiles.props | 30 + .../.FSharp.Compiler.Service/9.0.100.md | 4 + docs/release-notes/.Language/preview.md | 1 + src/Compiler/AbstractIL/il.fs | 32 +- src/Compiler/AbstractIL/il.fsi | 32 +- src/Compiler/AbstractIL/ilmorph.fs | 2 +- src/Compiler/AbstractIL/ilread.fs | 24 +- src/Compiler/AbstractIL/ilwrite.fs | 16 +- src/Compiler/Checking/AccessibilityLogic.fs | 4 +- src/Compiler/Checking/AttributeChecking.fs | 11 +- .../Checking/AugmentWithHashCompare.fs | 40 +- src/Compiler/Checking/CheckDeclarations.fs | 19 +- src/Compiler/Checking/CheckExpressions.fs | 194 +- src/Compiler/Checking/CheckFormatStrings.fs | 3 +- src/Compiler/Checking/CheckPatterns.fs | 2 +- src/Compiler/Checking/ConstraintSolver.fs | 1974 +++++++++++------ src/Compiler/Checking/ConstraintSolver.fsi | 52 +- src/Compiler/Checking/InfoReader.fs | 19 +- src/Compiler/Checking/MethodCalls.fs | 21 +- src/Compiler/Checking/MethodOverrides.fs | 4 +- src/Compiler/Checking/NameResolution.fs | 10 +- src/Compiler/Checking/NicePrint.fs | 130 +- .../Checking/PatternMatchCompilation.fs | 4 +- src/Compiler/Checking/PostInferenceChecks.fs | 24 +- src/Compiler/Checking/QuotationTranslator.fs | 4 +- src/Compiler/Checking/SignatureConformance.fs | 2 +- src/Compiler/Checking/SignatureHash.fs | 1 + src/Compiler/Checking/TypeHierarchy.fs | 72 +- src/Compiler/Checking/TypeHierarchy.fsi | 17 +- src/Compiler/Checking/TypeRelations.fs | 8 +- src/Compiler/Checking/import.fs | 237 +- src/Compiler/Checking/import.fsi | 42 +- src/Compiler/Checking/infos.fs | 156 +- src/Compiler/Checking/infos.fsi | 10 +- src/Compiler/CodeGen/EraseClosures.fs | 6 +- src/Compiler/CodeGen/EraseUnions.fs | 162 +- src/Compiler/CodeGen/IlxGen.fs | 200 +- src/Compiler/CodeGen/IlxGenSupport.fs | 297 ++- src/Compiler/CodeGen/IlxGenSupport.fsi | 5 +- .../DependencyManager/DependencyProvider.fs | 2 + .../DependencyManager/DependencyProvider.fsi | 2 + src/Compiler/Driver/CompilerConfig.fs | 10 +- src/Compiler/Driver/CompilerConfig.fsi | 10 +- src/Compiler/Driver/CompilerDiagnostics.fs | 75 +- src/Compiler/Driver/CompilerImports.fs | 323 ++- src/Compiler/Driver/CompilerImports.fsi | 9 +- src/Compiler/Driver/CompilerOptions.fs | 8 + .../GraphChecking/FileContentMapping.fs | 3 + src/Compiler/Driver/StaticLinking.fs | 6 +- src/Compiler/FSComp.txt | 18 + src/Compiler/FSStrings.resx | 15 + src/Compiler/FSharp.Compiler.Service.fsproj | 2 +- src/Compiler/Facilities/DiagnosticsLogger.fs | 3 + src/Compiler/Facilities/DiagnosticsLogger.fsi | 3 + src/Compiler/Facilities/LanguageFeatures.fs | 3 + src/Compiler/Facilities/LanguageFeatures.fsi | 1 + src/Compiler/Interactive/fsi.fs | 12 +- .../Legacy/LegacyHostedCompilerForTesting.fs | 12 +- .../Optimize/LowerComputedCollections.fs | 2 +- src/Compiler/Optimize/Optimizer.fs | 8 +- src/Compiler/Service/FSharpCheckerResults.fs | 7 +- src/Compiler/Service/IncrementalBuild.fs | 13 +- src/Compiler/Service/IncrementalBuild.fsi | 3 +- src/Compiler/Service/QuickParse.fs | 2 +- .../Service/SemanticClassification.fs | 1 - .../Service/SemanticClassification.fsi | 1 - .../Service/ServiceDeclarationLists.fs | 2 +- src/Compiler/Service/ServiceLexing.fs | 1 + .../Service/ServiceParamInfoLocations.fs | 1 + src/Compiler/Service/ServiceParseTreeWalk.fs | 2 + src/Compiler/Service/ServiceParsedInputOps.fs | 6 + src/Compiler/Service/TransparentCompiler.fs | 5 +- src/Compiler/Symbols/Exprs.fs | 45 +- src/Compiler/Symbols/SymbolHelpers.fs | 1 + src/Compiler/Symbols/Symbols.fs | 22 + src/Compiler/Symbols/Symbols.fsi | 6 + src/Compiler/SyntaxTree/LexFilter.fs | 6 + src/Compiler/SyntaxTree/PrettyNaming.fs | 9 + src/Compiler/SyntaxTree/PrettyNaming.fsi | 8 + src/Compiler/SyntaxTree/SyntaxTree.fs | 9 + src/Compiler/SyntaxTree/SyntaxTree.fsi | 8 + src/Compiler/TypedTree/TcGlobals.fs | 128 +- src/Compiler/TypedTree/TypeProviders.fs | 365 ++- src/Compiler/TypedTree/TypeProviders.fsi | 94 +- src/Compiler/TypedTree/TypedTree.fs | 181 +- src/Compiler/TypedTree/TypedTree.fsi | 59 +- src/Compiler/TypedTree/TypedTreeBasics.fs | 108 +- src/Compiler/TypedTree/TypedTreeBasics.fsi | 18 +- src/Compiler/TypedTree/TypedTreeOps.fs | 327 ++- src/Compiler/TypedTree/TypedTreeOps.fsi | 31 +- src/Compiler/TypedTree/TypedTreePickle.fs | 238 +- src/Compiler/TypedTree/TypedTreePickle.fsi | 3 +- src/Compiler/TypedTree/tainted.fs | 12 +- src/Compiler/TypedTree/tainted.fsi | 6 +- src/Compiler/Utilities/Activity.fs | 19 +- src/Compiler/Utilities/illib.fs | 52 +- src/Compiler/Utilities/illib.fsi | 8 + src/Compiler/Utilities/lib.fs | 8 +- src/Compiler/Utilities/lib.fsi | 14 +- src/Compiler/Utilities/sformat.fs | 36 +- src/Compiler/pars.fsy | 176 +- src/Compiler/xlf/FSComp.txt.cs.xlf | 70 + src/Compiler/xlf/FSComp.txt.de.xlf | 70 + src/Compiler/xlf/FSComp.txt.es.xlf | 70 + src/Compiler/xlf/FSComp.txt.fr.xlf | 70 + src/Compiler/xlf/FSComp.txt.it.xlf | 70 + src/Compiler/xlf/FSComp.txt.ja.xlf | 70 + src/Compiler/xlf/FSComp.txt.ko.xlf | 70 + src/Compiler/xlf/FSComp.txt.pl.xlf | 70 + src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 70 + src/Compiler/xlf/FSComp.txt.ru.xlf | 70 + src/Compiler/xlf/FSComp.txt.tr.xlf | 70 + src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 70 + src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 70 + src/Compiler/xlf/FSStrings.cs.xlf | 25 + src/Compiler/xlf/FSStrings.de.xlf | 25 + src/Compiler/xlf/FSStrings.es.xlf | 25 + src/Compiler/xlf/FSStrings.fr.xlf | 25 + src/Compiler/xlf/FSStrings.it.xlf | 25 + src/Compiler/xlf/FSStrings.ja.xlf | 25 + src/Compiler/xlf/FSStrings.ko.xlf | 25 + src/Compiler/xlf/FSStrings.pl.xlf | 25 + src/Compiler/xlf/FSStrings.pt-BR.xlf | 25 + src/Compiler/xlf/FSStrings.ru.xlf | 25 + src/Compiler/xlf/FSStrings.tr.xlf | 25 + src/Compiler/xlf/FSStrings.zh-Hans.xlf | 25 + src/Compiler/xlf/FSStrings.zh-Hant.xlf | 25 + src/FSharp.Build/FSharpCommandLineBuilder.fs | 9 +- src/FSharp.Build/FSharpEmbedResourceText.fs | 5 + src/FSharp.Build/Fsc.fs | 17 +- src/FSharp.Build/SubstituteText.fs | 2 +- src/FSharp.Core/ILLink.LinkAttributes.xml | 6 + src/FSharp.Core/ILLink.Substitutions.xml | 5 + src/FSharp.Core/Linq.fs | 12 +- src/FSharp.Core/Linq.fsi | 6 +- src/FSharp.Core/Query.fs | 14 +- src/FSharp.Core/array.fs | 13 + src/FSharp.Core/async.fs | 14 +- src/FSharp.Core/async.fsi | 10 +- src/FSharp.Core/event.fs | 18 +- src/FSharp.Core/event.fsi | 4 +- src/FSharp.Core/fslib-extra-pervasives.fs | 5 +- src/FSharp.Core/fslib-extra-pervasives.fsi | 4 +- src/FSharp.Core/local.fs | 4 + src/FSharp.Core/local.fsi | 4 +- src/FSharp.Core/map.fs | 2 +- src/FSharp.Core/map.fsi | 2 +- src/FSharp.Core/math/z.fs | 8 +- src/FSharp.Core/math/z.fsi | 4 +- src/FSharp.Core/option.fs | 28 + src/FSharp.Core/option.fsi | 30 +- src/FSharp.Core/prim-types-prelude.fs | 5 + src/FSharp.Core/prim-types-prelude.fsi | 10 + src/FSharp.Core/prim-types.fs | 170 +- src/FSharp.Core/prim-types.fsi | 187 +- src/FSharp.Core/printf.fs | 94 +- src/FSharp.Core/printf.fsi | 6 +- src/FSharp.Core/quotations.fs | 18 +- src/FSharp.Core/quotations.fsi | 18 +- src/FSharp.Core/reflect.fs | 84 +- src/FSharp.Core/reflect.fsi | 61 +- src/FSharp.Core/resumable.fs | 2 +- src/FSharp.Core/resumable.fsi | 2 +- src/FSharp.Core/seqcore.fs | 4 +- src/FSharp.Core/seqcore.fsi | 2 +- src/FSharp.Core/set.fs | 2 +- src/FSharp.Core/set.fsi | 2 +- src/fsi/console.fs | 32 +- tests/AheadOfTime/Trimming/check.ps1 | 5 +- .../fsc/misc/compiler_help_output.bsl | 1 + .../AttributeUsage/AttributeUsage.fs | 4 +- .../MethodsAndProperties.fs | 15 +- .../PartiallyOverridenProperty.fs | 15 + .../BindingExpressions/BindingExpressions.fs | 10 +- .../Expressions/BindingExpressions/in05.fs | 4 +- ...tring01.fs.RealInternalSignatureOff.il.bsl | 2 +- ...String01.fs.RealInternalSignatureOn.il.bsl | 2 +- .../EmittedIL/Nullness/AnonRecords.fs | 14 + .../Nullness/AnonRecords.fs.il.net472.bsl | 876 ++++++++ .../Nullness/AnonRecords.fs.il.netcore.bsl | 719 ++++++ .../EmittedIL/Nullness/CsharpConsumer.cs | 32 + .../EmittedIL/Nullness/CurriedFunctions.fs | 10 + .../CurriedFunctions.fs.il.net472.bsl | 204 ++ .../CurriedFunctions.fs.il.netcore.bsl | 139 ++ .../EmittedIL/Nullness/CustomPipe.fs | 3 + .../Nullness/CustomPipe.fs.il.net472.bsl | 123 + .../Nullness/CustomPipe.fs.il.netcore.bsl | 58 + .../EmittedIL/Nullness/CustomType.fs | 25 + .../Nullness/CustomType.fs.il.net472.bsl | 369 +++ .../Nullness/CustomType.fs.il.netcore.bsl | 304 +++ .../EmittedIL/Nullness/GenericStructDu.fs | 11 + .../Nullness/GenericStructDu.fs.il.net472.bsl | 626 ++++++ .../GenericStructDu.fs.il.netcore.bsl | 404 ++++ .../EmittedIL/Nullness/ModuleLevelBindings.fs | 8 + .../ModuleLevelBindings.fs.il.net472.bsl | 229 ++ .../ModuleLevelBindings.fs.il.netcore.bsl | 164 ++ .../Nullness/ModuleLevelFunctions.fs | 10 + .../ModuleLevelFunctions.fs.il.net472.bsl | 216 ++ .../ModuleLevelFunctions.fs.il.netcore.bsl | 148 ++ .../Nullness/ModuleLevelFunctionsOpt.fs | 10 + .../ModuleLevelFunctionsOpt.fs.il.net472.bsl | 213 ++ .../ModuleLevelFunctionsOpt.fs.il.netcore.bsl | 145 ++ .../EmittedIL/Nullness/NullAsTrueValue.fs | 23 + .../Nullness/NullAsTrueValue.fs.il.net472.bsl | 656 ++++++ .../NullAsTrueValue.fs.il.netcore.bsl | 499 +++++ .../EmittedIL/Nullness/NullableInheritance.fs | 24 + .../NullableInheritance.fs.il.net472.bsl | 275 +++ .../NullableInheritance.fs.il.netcore.bsl | 209 ++ .../EmittedIL/Nullness/NullnessMetadata.fs | 183 ++ .../EmittedIL/Nullness/Records.fs | 25 + .../Nullness/Records.fs.il.net472.bsl | 449 ++++ .../Nullness/Records.fs.il.netcore.bsl | 292 +++ .../EmittedIL/Nullness/ReferenceDU.fs | 18 + .../Nullness/ReferenceDU.fs.il.net472.bsl | 747 +++++++ .../Nullness/ReferenceDU.fs.il.netcore.bsl | 590 +++++ .../EmittedIL/Nullness/StructDU.fs | 13 + .../Nullness/StructDU.fs.il.net472.bsl | 578 +++++ .../Nullness/StructDU.fs.il.netcore.bsl | 349 +++ .../EmittedIL/Nullness/SupportsNull.fs | 43 + .../Nullness/SupportsNull.fs.il.net472.bsl | 276 +++ .../Nullness/SupportsNull.fs.il.netcore.bsl | 212 ++ .../EmittedIL/TupleElimination.fs | 23 +- .../ErrorMessages/TypeEqualsMissingTests.fs | 24 +- .../FSharp.Compiler.ComponentTests.fsproj | 5 + .../FSharpChecker/TransparentCompiler.fs | 1 - .../Language/DiscriminatedUnionTests.fs | 2 + .../Language/DotLambdaTests.fs | 2 +- .../Nullness/NullableCsharpImportTests.fs | 229 ++ .../NullableLibraryConstructsTests.fs | 59 + .../Nullness/NullableReferenceTypesTests.fs | 902 ++++++++ .../Nullness/NullableRegressionTests.fs | 125 ++ .../Language/Nullness/existing-negative.fs | 52 + ...existing-negative.fs.checknulls_on.err.bsl | 10 + ...ting-negative.fs.nullness_disabled.err.bsl | 3 + .../Language/Nullness/existing-positive.fs | 69 + ...existing-positive.fs.checknulls_on.err.bsl | 8 + ...ting-positive.fs.nullness_disabled.err.bsl | 0 .../Language/Nullness/library-functions.fs | 41 + ...library-functions.fs.checknulls_on.err.bsl | 13 + ...ary-functions.fs.nullness_disabled.err.bsl | 0 .../Language/Nullness/micro.fs | 13 + .../Language/Nullness/micro.fsi | 3 + .../Nullness/positive-defaultValue-bug.fs | 13 + ...aultValue-bug.fs.nullness_disabled.err.bsl | 2 + .../using-nullness-syntax-positive.fs | 237 ++ ...s-syntax-positive.fs.checknulls_on.err.bsl | 35 + ...ntax-positive.fs.nullness_disabled.err.bsl | 4 + .../Miscellaneous/MigratedCoreTests.fs | 4 +- ...ervice.SurfaceArea.netstandard20.debug.bsl | 119 +- ...vice.SurfaceArea.netstandard20.release.bsl | 92 +- .../FSharp.Compiler.Service.Tests.fsproj | 6 + .../ModuleReaderCancellationTests.fs | 8 +- .../PatternMatchCompilationTests.fs | 26 +- .../expected-help-output.bsl | 2 + ...p.Core.SurfaceArea.netstandard20.debug.bsl | 18 + ...Core.SurfaceArea.netstandard20.release.bsl | 18 + ...p.Core.SurfaceArea.netstandard21.debug.bsl | 18 + ...Core.SurfaceArea.netstandard21.release.bsl | 18 + .../Microsoft.FSharp.Core/OptionModule.fs | 2 +- tests/FSharp.Test.Utilities/Compiler.fs | 4 + tests/FSharp.Test.Utilities/ILChecker.fs | 6 + .../NullableOptionalRegressionTests.fs | 3 +- .../core/printing/output.1000.stdout.bsl | 2 +- .../core/printing/output.200.stdout.bsl | 2 +- .../fsharp/core/printing/output.47.stdout.bsl | 2 +- .../core/printing/output.multiemit.stdout.bsl | 2 +- .../core/printing/output.off.stdout.bsl | 2 +- tests/fsharp/core/printing/output.stdout.bsl | 2 +- tests/fsharp/tests.fs | 64 +- tests/fsharp/typecheck/sigs/neg04.bsl | 8 +- tests/fsharp/typecheck/sigs/neg06.bsl | 30 - tests/fsharp/typecheck/sigs/neg07.bsl | 12 +- tests/fsharp/typecheck/sigs/neg106.bsl | 8 - tests/fsharp/typecheck/sigs/neg106.vsbsl | 8 - tests/fsharp/typecheck/sigs/neg111.bsl | 2 - tests/fsharp/typecheck/sigs/neg112.bsl | 2 - tests/fsharp/typecheck/sigs/neg119b.bsl | 21 +- tests/fsharp/typecheck/sigs/neg133.bsl | 2 - tests/fsharp/typecheck/sigs/neg15.bsl | 4 - tests/fsharp/typecheck/sigs/neg16.bsl | 2 - tests/fsharp/typecheck/sigs/neg20.bsl | 66 +- tests/fsharp/typecheck/sigs/neg29.bsl | 4 +- tests/fsharp/typecheck/sigs/neg30.bsl | 4 - tests/fsharp/typecheck/sigs/neg32.bsl | 4 - tests/fsharp/typecheck/sigs/neg48.bsl | 22 - tests/fsharp/typecheck/sigs/neg63.bsl | 2 - tests/fsharp/typecheck/sigs/neg64.vsbsl | 2 - tests/fsharp/typecheck/sigs/neg66.vsbsl | 2 - tests/fsharp/typecheck/sigs/neg67.vsbsl | 8 - tests/fsharp/typecheck/sigs/neg68.vsbsl | 2 - tests/fsharp/typecheck/sigs/neg69.vsbsl | 99 +- tests/fsharp/typecheck/sigs/neg70.vsbsl | 2 - tests/fsharp/typecheck/sigs/neg71.vsbsl | 8 - tests/fsharp/typecheck/sigs/neg72.vsbsl | 2 - tests/fsharp/typecheck/sigs/neg73.vsbsl | 2 - tests/fsharp/typecheck/sigs/neg79.vsbsl | 2 - tests/fsharp/typecheck/sigs/neg80.vsbsl | 2 - tests/fsharp/typecheck/sigs/neg84.vsbsl | 2 - tests/fsharp/typecheck/sigs/neg86.vsbsl | 2 - tests/fsharp/typecheck/sigs/neg89.bsl | 34 - tests/fsharp/typecheck/sigs/neg90.bsl | 2 - tests/fsharp/typecheck/sigs/neg95.bsl | 2 +- tests/fsharp/typecheck/sigs/neg96.bsl | 2 - tests/fsharp/typecheck/sigs/neg_byref_11.bsl | 6 - tests/fsharp/typecheck/sigs/neg_byref_12.bsl | 4 - tests/fsharp/typecheck/sigs/neg_byref_14.bsl | 4 - tests/fsharp/typecheck/sigs/neg_byref_16.bsl | 2 - tests/fsharp/typecheck/sigs/neg_byref_20.bsl | 2 - tests/fsharp/typecheck/sigs/neg_byref_22.bsl | 5 - tests/fsharp/typecheck/sigs/neg_byref_3.bsl | 4 - tests/fsharp/typecheck/sigs/neg_byref_7.bsl | 12 - tests/fsharp/typecheck/sigs/neg_byref_8.bsl | 12 - .../fsharp/typecheck/sigs/version50/neg20.bsl | 66 +- .../fsi/help/help40-nologo.437.1033.bsl | 2 + .../fsi/help/help40.437.1033.bsl | 2 + .../Nullness/AbstractClassProperty.fs | 3 + .../Nullness/AbstractClassProperty.fs.bsl | 60 + .../SyntaxTree/Nullness/DuCaseStringOrNull.fs | 1 + .../Nullness/DuCaseStringOrNull.fs.bsl | 38 + .../Nullness/DuCaseTuplePrecedence.fs | 1 + .../Nullness/DuCaseTuplePrecedence.fs.bsl | 45 + .../data/SyntaxTree/Nullness/ExplicitField.fs | 4 + .../SyntaxTree/Nullness/ExplicitField.fs.bsl | 31 + .../FunctionArgAsPatternWithNullCase.fs | 1 + .../FunctionArgAsPatternWithNullCase.fs.bsl | 46 + .../GenericFunctionReturnTypeNotStructNull.fs | 1 + ...ericFunctionReturnTypeNotStructNull.fs.bsl | 42 + .../Nullness/GenericFunctionTyparNotNull.fs | 1 + .../GenericFunctionTyparNotNull.fs.bsl | 36 + .../Nullness/GenericFunctionTyparNull.fs | 1 + .../Nullness/GenericFunctionTyparNull.fs.bsl | 36 + .../SyntaxTree/Nullness/GenericTypeNotNull.fs | 1 + .../Nullness/GenericTypeNotNull.fs.bsl | 27 + .../GenericTypeNotNullAndOtherConstraint.fs | 1 + ...enericTypeNotNullAndOtherConstraint.fs.bsl | 29 + ...tructAndOtherConstraint-I_am_Still_Sane.fs | 1 + ...tAndOtherConstraint-I_am_Still_Sane.fs.bsl | 34 + .../SyntaxTree/Nullness/GenericTypeNull.fs | 1 + .../Nullness/GenericTypeNull.fs.bsl | 27 + ...enericTypeOtherConstraintAndThenNotNull.fs | 1 + ...icTypeOtherConstraintAndThenNotNull.fs.bsl | 29 + .../data/SyntaxTree/Nullness/IntListOrNull.fs | 1 + .../SyntaxTree/Nullness/IntListOrNull.fs.bsl | 37 + .../Nullness/IntListOrNullOrNullOrNull.fs | 1 + .../Nullness/IntListOrNullOrNullOrNull.fs.bsl | 39 + .../SyntaxTree/Nullness/MatchWithTypeCast.fs | 2 + .../Nullness/MatchWithTypeCast.fs.bsl | 23 + .../Nullness/MatchWithTypeCastParens.fs | 2 + .../Nullness/MatchWithTypeCastParens.fs.bsl | 23 + ...chWithTypeCastParensAndSeparateNullCase.fs | 2 + ...thTypeCastParensAndSeparateNullCase.fs.bsl | 26 + .../Nullness/NullAnnotatedExpression.fs | 1 + .../Nullness/NullAnnotatedExpression.fs.bsl | 65 + .../RegressionAnnotatedInlinePatternMatch.fs | 2 + ...gressionAnnotatedInlinePatternMatch.fs.bsl | 29 + .../Nullness/RegressionChoiceType.fs | 7 + .../Nullness/RegressionChoiceType.fs.bsl | 55 + .../SyntaxTree/Nullness/RegressionListType.fs | 3 + .../Nullness/RegressionListType.fs.bsl | 65 + .../Nullness/RegressionOneLinerOptionType.fs | 1 + .../RegressionOneLinerOptionType.fs.bsl | 38 + .../Nullness/RegressionOptionType.fs | 3 + .../Nullness/RegressionOptionType.fs.bsl | 64 + .../Nullness/RegressionOrPattern.fs | 3 + .../Nullness/RegressionOrPattern.fs.bsl | 40 + .../Nullness/RegressionResultType.fs | 7 + .../Nullness/RegressionResultType.fs.bsl | 56 + .../Nullness/SignatureInAbstractMember.fs | 2 + .../Nullness/SignatureInAbstractMember.fs.bsl | 60 + .../data/SyntaxTree/Nullness/StringOrNull.fs | 1 + .../SyntaxTree/Nullness/StringOrNull.fs.bsl | 31 + .../Nullness/StringOrNullInFunctionArg.fs | 1 + .../Nullness/StringOrNullInFunctionArg.fs.bsl | 36 + .../TypeAbbreviationAddingWithNull.fs | 1 + .../TypeAbbreviationAddingWithNull.fs.bsl | 24 + tests/service/data/TestTP/ProvidedTypes.fs | 1 - vsintegration/src/FSharp.VS.FSI/fsiBasis.fs | 5 +- .../Tests.LanguageService.QuickInfo.fs | 4 +- 381 files changed, 20622 insertions(+), 2630 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/PartiallyOverridenProperty.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/AnonRecords.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/AnonRecords.fs.il.net472.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/AnonRecords.fs.il.netcore.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CsharpConsumer.cs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs.il.net472.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs.il.netcore.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomPipe.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomPipe.fs.il.net472.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomPipe.fs.il.netcore.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomType.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomType.fs.il.net472.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomType.fs.il.netcore.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericStructDu.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericStructDu.fs.il.net472.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericStructDu.fs.il.netcore.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelBindings.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelBindings.fs.il.net472.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelBindings.fs.il.netcore.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctions.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctions.fs.il.net472.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctions.fs.il.netcore.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctionsOpt.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctionsOpt.fs.il.net472.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctionsOpt.fs.il.netcore.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullAsTrueValue.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullAsTrueValue.fs.il.net472.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullAsTrueValue.fs.il.netcore.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullableInheritance.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullableInheritance.fs.il.net472.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullableInheritance.fs.il.netcore.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullnessMetadata.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/Records.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/Records.fs.il.net472.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/Records.fs.il.netcore.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ReferenceDU.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ReferenceDU.fs.il.net472.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ReferenceDU.fs.il.netcore.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/StructDU.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/StructDU.fs.il.net472.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/StructDU.fs.il.netcore.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/SupportsNull.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/SupportsNull.fs.il.net472.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/SupportsNull.fs.il.netcore.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableCsharpImportTests.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableLibraryConstructsTests.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs.checknulls_on.err.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs.nullness_disabled.err.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-positive.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-positive.fs.checknulls_on.err.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-positive.fs.nullness_disabled.err.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs.checknulls_on.err.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs.nullness_disabled.err.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/micro.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/micro.fsi create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/positive-defaultValue-bug.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/positive-defaultValue-bug.fs.nullness_disabled.err.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.checknulls_on.err.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.nullness_disabled.err.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/AbstractClassProperty.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/AbstractClassProperty.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/ExplicitField.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/ExplicitField.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/FunctionArgAsPatternWithNullCase.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/FunctionArgAsPatternWithNullCase.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericFunctionReturnTypeNotStructNull.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericFunctionReturnTypeNotStructNull.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNull.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNull.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericTypeNotNull.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericTypeNotNull.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericTypeNotNullAndOtherConstraint.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericTypeNotNullAndOtherConstraint.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/MatchWithTypeCast.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/MatchWithTypeCast.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParens.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParens.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParensAndSeparateNullCase.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParensAndSeparateNullCase.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/NullAnnotatedExpression.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/NullAnnotatedExpression.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionListType.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionListType.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionOneLinerOptionType.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionOneLinerOptionType.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionOrPattern.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionOrPattern.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionResultType.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionResultType.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/SignatureInAbstractMember.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/SignatureInAbstractMember.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/StringOrNull.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/StringOrNull.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/TypeAbbreviationAddingWithNull.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/TypeAbbreviationAddingWithNull.fs.bsl diff --git a/.fantomasignore b/.fantomasignore index d142916bd16..6b568034be7 100644 --- a/.fantomasignore +++ b/.fantomasignore @@ -88,6 +88,23 @@ src/FSharp.Core/Query.fs src/FSharp.Core/seqcore.fs +# fsharp (to investigate) + +**/TypeProviders.fsi +**/tainted.fsi + +# uses nullness features + +**/DependencyProvider.fsi +src/FSharp.Core/array.fs +src/FSharp.Core/option.fsi +src/FSharp.Core/option.fs +src/fsi/console.fs +src/FSharp.Build/FSharpCommandLineBuilder.fs +src/Compiler/Utilities/sformat.fs +src/Compiler/Utilities/illib.fsi +src/Compiler/Utilities/illib.fs + # Fantomas limitations on implementation files (to investigate) src/Compiler/AbstractIL/ilwrite.fs diff --git a/.gitignore b/.gitignore index e6d289dd19b..f0dbae4d2f3 100644 --- a/.gitignore +++ b/.gitignore @@ -127,3 +127,6 @@ nCrunchTemp_* tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.actual *.vsp /tests/AheadOfTime/Trimming/output.txt +*.svclog +micro.exe +positive.exe \ No newline at end of file diff --git a/FSharp.Benchmarks.sln b/FSharp.Benchmarks.sln index 83f1a6c3bf7..f77afff1c10 100644 --- a/FSharp.Benchmarks.sln +++ b/FSharp.Benchmarks.sln @@ -1,5 +1,4 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 +Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.1.32113.165 MinimumVisualStudioVersion = 10.0.40219.1 diff --git a/FSharp.Profiles.props b/FSharp.Profiles.props index 66e46a32b08..4627fcace39 100644 --- a/FSharp.Profiles.props +++ b/FSharp.Profiles.props @@ -1,6 +1,36 @@ + + + + false + + + + + false + + + + false + NO_CHECKNULLS;BUILDING_WITH_LKG;NO_NULLCHECKING_LIB_SUPPORT;$(DefineConstants) + false + + + + $(OtherFlags) /langversion:preview + + + + $(OtherFlags) /checknulls + + + + + $(NoWarn);3271 + NO_CHECKNULLS;$(DefineConstants) + diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md index 7282b2d0b50..a2454c414f5 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md @@ -1,9 +1,13 @@ ### Fixed + * Compiler hangs when compiling inline recursive invocation ([Issue #17376](https://github.com/dotnet/fsharp/issues/17376), [PR #17394](https://github.com/dotnet/fsharp/pull/17394)) ### Added +* Support for nullable reference types ([PR #15181](https://github.com/dotnet/fsharp/pull/15181)) + ### Changed + * Change compiler default setting realsig+ when building assemblies ([Issue #17384](https://github.com/dotnet/fsharp/issues/17384), [PR #17378](https://github.com/dotnet/fsharp/pull/17385)) * Change compiler default setting for compressedMetadata ([Issue #17379](https://github.com/dotnet/fsharp/issues/17379), [PR #17383](https://github.com/dotnet/fsharp/pull/17383)) diff --git a/docs/release-notes/.Language/preview.md b/docs/release-notes/.Language/preview.md index 7b25b17a179..6c2d5f0597b 100644 --- a/docs/release-notes/.Language/preview.md +++ b/docs/release-notes/.Language/preview.md @@ -2,6 +2,7 @@ * Speed up `for x in xs -> …` in list & array comprehensions in certain scenarios. ([PR #16948](https://github.com/dotnet/fsharp/pull/16948)) * Lower integral ranges to fast loops in more cases and optimize list and array construction from ranges. ([PR #16650](https://github.com/dotnet/fsharp/pull/16650), [PR #16832](https://github.com/dotnet/fsharp/pull/16832)) +* Support for nullable reference types ([PR #15181](https://github.com/dotnet/fsharp/pull/15181)) * Better generic unmanaged structs handling. ([Language suggestion #692](https://github.com/fsharp/fslang-suggestions/issues/692), [PR #12154](https://github.com/dotnet/fsharp/pull/12154)) * Bidirectional F#/C# interop for 'unmanaged' constraint. ([PR #12154](https://github.com/dotnet/fsharp/pull/12154)) * Make `.Is*` discriminated union properties visible. ([Language suggestion #222](https://github.com/fsharp/fslang-suggestions/issues/222), [PR #16341](https://github.com/dotnet/fsharp/pull/16341)) diff --git a/src/Compiler/AbstractIL/il.fs b/src/Compiler/AbstractIL/il.fs index 66b736f87c3..ecfa0636247 100644 --- a/src/Compiler/AbstractIL/il.fs +++ b/src/Compiler/AbstractIL/il.fs @@ -2629,6 +2629,7 @@ type ILTypeDef attributes: TypeAttributes, layout: ILTypeDefLayout, implements: ILTypes, + implementsCustomAttrs: (ILAttributesStored * int) list option, genericParams: ILGenericParameterDefs, extends: ILType option, methods: ILMethodDefs, @@ -2651,6 +2652,7 @@ type ILTypeDef attributes, layout, implements, + implementsCustomAttrs, genericParams, extends, methods, @@ -2667,6 +2669,7 @@ type ILTypeDef attributes, layout, implements, + implementsCustomAttrs, genericParams, extends, methods, @@ -2677,7 +2680,7 @@ type ILTypeDef properties, additionalFlags, storeILSecurityDecls securityDecls, - customAttrs, + storeILCustomAttrs customAttrs, NoMetadataIdx ) @@ -2693,6 +2696,8 @@ type ILTypeDef member _.Implements = implements + member _.ImplementsCustomAttrs = implementsCustomAttrs + member _.Extends = extends member _.Methods = methods @@ -2732,7 +2737,8 @@ type ILTypeDef ?properties, ?newAdditionalFlags, ?customAttrs, - ?securityDecls + ?securityDecls, + ?implementsCustomAttrs ) = ILTypeDef( name = defaultArg name x.Name, @@ -2741,6 +2747,7 @@ type ILTypeDef genericParams = defaultArg genericParams x.GenericParams, nestedTypes = defaultArg nestedTypes x.NestedTypes, implements = defaultArg implements x.Implements, + implementsCustomAttrs = defaultArg implementsCustomAttrs x.ImplementsCustomAttrs, extends = defaultArg extends x.Extends, methods = defaultArg methods x.Methods, securityDecls = defaultArg securityDecls x.SecurityDecls, @@ -2749,7 +2756,7 @@ type ILTypeDef events = defaultArg events x.Events, properties = defaultArg properties x.Properties, additionalFlags = defaultArg newAdditionalFlags additionalFlags, - customAttrs = defaultArg customAttrs (storeILCustomAttrs x.CustomAttrs) + customAttrs = defaultArg customAttrs (x.CustomAttrs) ) member x.CustomAttrs: ILAttributes = @@ -3439,6 +3446,11 @@ type ILGlobals(primaryScopeRef: ILScopeRef, equivPrimaryAssemblyRefs: ILAssembly let mkSysILTypeRef nm = mkILTyRef (primaryScopeRef, nm) + let byteIlType = ILType.Value(mkILNonGenericTySpec (mkSysILTypeRef tname_Byte)) + + let stringIlType = + mkILBoxedType (mkILNonGenericTySpec (mkSysILTypeRef tname_String)) + member _.primaryAssemblyScopeRef = primaryScopeRef member x.primaryAssemblyRef = @@ -3456,7 +3468,7 @@ type ILGlobals(primaryScopeRef: ILScopeRef, equivPrimaryAssemblyRefs: ILAssembly member val typ_Object = mkILBoxedType (mkILNonGenericTySpec (mkSysILTypeRef tname_Object)) - member val typ_String = mkILBoxedType (mkILNonGenericTySpec (mkSysILTypeRef tname_String)) + member val typ_String = stringIlType member val typ_Array = mkILBoxedType (mkILNonGenericTySpec (mkSysILTypeRef tname_Array)) @@ -3470,7 +3482,11 @@ type ILGlobals(primaryScopeRef: ILScopeRef, equivPrimaryAssemblyRefs: ILAssembly member val typ_Int64 = ILType.Value(mkILNonGenericTySpec (mkSysILTypeRef tname_Int64)) - member val typ_Byte = ILType.Value(mkILNonGenericTySpec (mkSysILTypeRef tname_Byte)) + member val typ_Byte = byteIlType + + member val typ_ByteArray = ILType.Array(ILArrayShape.SingleDimensional, byteIlType) + + member val typ_StringArray = ILType.Array(ILArrayShape.SingleDimensional, stringIlType) member val typ_UInt16 = ILType.Value(mkILNonGenericTySpec (mkSysILTypeRef tname_UInt16)) @@ -4231,12 +4247,13 @@ let mkILGenericClass (nm, access, genparams, extends, impl, methods, fields, nes attributes = attributes, genericParams = genparams, implements = impl, + implementsCustomAttrs = None, layout = ILTypeDefLayout.Auto, extends = Some extends, methods = methods, fields = fields, nestedTypes = nestedTypes, - customAttrs = storeILCustomAttrs attrs, + customAttrs = attrs, methodImpls = emptyILMethodImpls, properties = props, events = events, @@ -4255,12 +4272,13 @@ let mkRawDataValueTypeDef (iltyp_ValueType: ILType) (nm, size, pack) = ||| TypeAttributes.BeforeFieldInit ||| TypeAttributes.AnsiClass), implements = [], + implementsCustomAttrs = None, extends = Some iltyp_ValueType, layout = ILTypeDefLayout.Explicit { Size = Some size; Pack = Some pack }, methods = emptyILMethods, fields = emptyILFields, nestedTypes = emptyILTypeDefs, - customAttrs = emptyILCustomAttrsStored, + customAttrs = emptyILCustomAttrs, methodImpls = emptyILMethodImpls, properties = emptyILProperties, events = emptyILEvents, diff --git a/src/Compiler/AbstractIL/il.fsi b/src/Compiler/AbstractIL/il.fsi index d6673131060..a89b343f9ea 100644 --- a/src/Compiler/AbstractIL/il.fsi +++ b/src/Compiler/AbstractIL/il.fsi @@ -869,7 +869,13 @@ type ILAttributes = /// Represents the efficiency-oriented storage of ILAttributes in another item. [] -type ILAttributesStored +type ILAttributesStored = + /// Computed by ilread.fs based on metadata index + | Reader of (int32 -> ILAttribute[]) + /// Already computed + | Given of ILAttributes + + member GetCustomAttrs: int32 -> ILAttributes /// Method parameters and return values. [] @@ -1070,6 +1076,8 @@ type ILMethodDef = member IsEntryPoint: bool member GenericParams: ILGenericParameterDefs member CustomAttrs: ILAttributes + member MetadataIndex: int32 + member CustomAttrsStored: ILAttributesStored member ParameterTypes: ILTypes member IsIL: bool member Code: ILCode option @@ -1243,6 +1251,10 @@ type ILFieldDef = member CustomAttrs: ILAttributes + member MetadataIndex: int32 + + member CustomAttrsStored: ILAttributesStored + member IsStatic: bool member IsSpecialName: bool @@ -1326,6 +1338,8 @@ type ILEventDef = member FireMethod: ILMethodRef option member OtherMethods: ILMethodRef list member CustomAttrs: ILAttributes + member MetadataIndex: int32 + member CustomAttrsStored: ILAttributesStored member IsSpecialName: bool member IsRTSpecialName: bool @@ -1388,6 +1402,8 @@ type ILPropertyDef = member Init: ILFieldInit option member Args: ILTypes member CustomAttrs: ILAttributes + member MetadataIndex: int32 + member CustomAttrsStored: ILAttributesStored member IsSpecialName: bool member IsRTSpecialName: bool @@ -1498,6 +1514,7 @@ type ILTypeDef = attributes: TypeAttributes * layout: ILTypeDefLayout * implements: ILTypes * + implementsCustomAttrs: (ILAttributesStored * int) list option * genericParams: ILGenericParameterDefs * extends: ILType option * methods: ILMethodDefs * @@ -1518,6 +1535,7 @@ type ILTypeDef = attributes: TypeAttributes * layout: ILTypeDefLayout * implements: ILTypes * + implementsCustomAttrs: (ILAttributesStored * int) list option * genericParams: ILGenericParameterDefs * extends: ILType option * methods: ILMethodDefs * @@ -1528,7 +1546,7 @@ type ILTypeDef = properties: ILPropertyDefs * additionalFlags: ILTypeDefAdditionalFlags * securityDecls: ILSecurityDecls * - customAttrs: ILAttributesStored -> + customAttrs: ILAttributes -> ILTypeDef member Name: string @@ -1537,6 +1555,7 @@ type ILTypeDef = member Layout: ILTypeDefLayout member NestedTypes: ILTypeDefs member Implements: ILTypes + member ImplementsCustomAttrs: (ILAttributesStored * int) list option member Extends: ILType option member Methods: ILMethodDefs member SecurityDecls: ILSecurityDecls @@ -1545,6 +1564,8 @@ type ILTypeDef = member Events: ILEventDefs member Properties: ILPropertyDefs member CustomAttrs: ILAttributes + member MetadataIndex: int32 + member CustomAttrsStored: ILAttributesStored member IsClass: bool member IsStruct: bool member IsInterface: bool @@ -1593,8 +1614,9 @@ type ILTypeDef = ?events: ILEventDefs * ?properties: ILPropertyDefs * ?newAdditionalFlags: ILTypeDefAdditionalFlags * - ?customAttrs: ILAttributesStored * - ?securityDecls: ILSecurityDecls -> + ?customAttrs: ILAttributes * + ?securityDecls: ILSecurityDecls * + ?implementsCustomAttrs: (ILAttributesStored * int) list option -> ILTypeDef /// Represents a prefix of information for ILTypeDef. @@ -1890,11 +1912,13 @@ type internal ILGlobals = member typ_Enum: ILType member typ_Object: ILType member typ_String: ILType + member typ_StringArray: ILType member typ_Type: ILType member typ_Array: ILType member typ_IntPtr: ILType member typ_UIntPtr: ILType member typ_Byte: ILType + member typ_ByteArray: ILType member typ_Int16: ILType member typ_Int32: ILType member typ_Int64: ILType diff --git a/src/Compiler/AbstractIL/ilmorph.fs b/src/Compiler/AbstractIL/ilmorph.fs index 334ed93d212..b4305791076 100644 --- a/src/Compiler/AbstractIL/ilmorph.fs +++ b/src/Compiler/AbstractIL/ilmorph.fs @@ -378,7 +378,7 @@ let rec tdef_ty2ty_ilmbody2ilmbody_mdefs2mdefs isInKnownSet enc fs (tdef: ILType methodImpls = mimpls_ty2ty fTyInCtxtR tdef.MethodImpls, events = edefs_ty2ty fTyInCtxtR tdef.Events, properties = pdefs_ty2ty fTyInCtxtR tdef.Properties, - customAttrs = storeILCustomAttrs (cattrs_ty2ty fTyInCtxtR tdef.CustomAttrs) + customAttrs = cattrs_ty2ty fTyInCtxtR tdef.CustomAttrs ) and tdefs_ty2ty_ilmbody2ilmbody_mdefs2mdefs isInKnownSet enc fs tdefs = diff --git a/src/Compiler/AbstractIL/ilread.fs b/src/Compiler/AbstractIL/ilread.fs index 1535078bfe0..17b97c5e9c2 100644 --- a/src/Compiler/AbstractIL/ilread.fs +++ b/src/Compiler/AbstractIL/ilread.fs @@ -930,8 +930,7 @@ let mkCacheGeneric lowMem _inbase _nm (sz: int) = if lowMem then (fun f x -> f x) else - let mutable cache = Unchecked.defaultof<_> - + let mutable cache = null #if STATISTICS let mutable _count = 0 @@ -1155,6 +1154,7 @@ type ILMetadataReader = customAttrsReader_Module: ILAttributesStored customAttrsReader_Assembly: ILAttributesStored customAttrsReader_TypeDef: ILAttributesStored + customAttrsReader_InterfaceImpl: ILAttributesStored customAttrsReader_GenericParam: ILAttributesStored customAttrsReader_FieldDef: ILAttributesStored customAttrsReader_MethodDef: ILAttributesStored @@ -1425,11 +1425,16 @@ let seekReadParamRow (ctxt: ILMetadataReader) mdv idx = (flags, seq, nameIdx) /// Read Table InterfaceImpl. -let seekReadInterfaceImplRow (ctxt: ILMetadataReader) mdv idx = +let private seekReadInterfaceImplRow (ctxt: ILMetadataReader) mdv idx = let mutable addr = ctxt.rowAddr TableNames.InterfaceImpl idx let tidx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr let intfIdx = seekReadTypeDefOrRefOrSpecIdx ctxt mdv &addr - (tidx, intfIdx) + + struct {| + TypeIdx = tidx + IntfIdx = intfIdx + IntImplIdx = idx + |} /// Read Table MemberRef. let seekReadMemberRefRow (ctxt: ILMetadataReader) mdv idx = @@ -2192,7 +2197,10 @@ and typeDefReader ctxtH : ILTypeDefStored = let mdefs = seekReadMethods ctxt numTypars methodsIdx endMethodsIdx let fdefs = seekReadFields ctxt (numTypars, hasLayout) fieldsIdx endFieldsIdx let nested = seekReadNestedTypeDefs ctxt idx - let impls = seekReadInterfaceImpls ctxt mdv numTypars idx + + let impls, intImplsAttrs = + seekReadInterfaceImpls ctxt mdv numTypars idx |> List.unzip + let mimpls = seekReadMethodImpls ctxt numTypars idx let props = seekReadProperties ctxt numTypars idx let events = seekReadEvents ctxt numTypars idx @@ -2204,6 +2212,7 @@ and typeDefReader ctxtH : ILTypeDefStored = layout = layout, nestedTypes = nested, implements = impls, + implementsCustomAttrs = Some intImplsAttrs, extends = super, methods = mdefs, securityDeclsStored = ctxt.securityDeclsReader_TypeDef, @@ -2240,10 +2249,10 @@ and seekReadInterfaceImpls (ctxt: ILMetadataReader) mdv numTypars tidx = seekReadIndexedRows ( ctxt.getNumRows TableNames.InterfaceImpl, seekReadInterfaceImplRow ctxt mdv, - fst, + (fun x -> x.TypeIdx), simpleIndexCompare tidx, isSorted ctxt TableNames.InterfaceImpl, - (snd >> seekReadTypeDefOrRef ctxt numTypars AsObject []) + (fun x -> (seekReadTypeDefOrRef ctxt numTypars AsObject [] x.IntfIdx), (ctxt.customAttrsReader_InterfaceImpl, x.IntImplIdx)) ) and seekReadGenericParams ctxt numTypars (a, b) : ILGenericParameterDefs = @@ -4539,6 +4548,7 @@ let openMetadataReader customAttrsReader_Module = customAttrsReader ctxtH hca_Module customAttrsReader_Assembly = customAttrsReader ctxtH hca_Assembly customAttrsReader_TypeDef = customAttrsReader ctxtH hca_TypeDef + customAttrsReader_InterfaceImpl = customAttrsReader ctxtH hca_InterfaceImpl customAttrsReader_GenericParam = customAttrsReader ctxtH hca_GenericParam customAttrsReader_FieldDef = customAttrsReader ctxtH hca_FieldDef customAttrsReader_MethodDef = customAttrsReader ctxtH hca_MethodDef diff --git a/src/Compiler/AbstractIL/ilwrite.fs b/src/Compiler/AbstractIL/ilwrite.fs index f41c8aaa08d..c4c43f6a5fc 100644 --- a/src/Compiler/AbstractIL/ilwrite.fs +++ b/src/Compiler/AbstractIL/ilwrite.fs @@ -554,6 +554,8 @@ type cenv = methodDefIdxs: Dictionary + implementsIdxs: Dictionary + propertyDefs: MetadataTable eventDefs: MetadataTable @@ -1281,7 +1283,7 @@ and GetTypeAsImplementsRow cenv env tidx ty = TypeDefOrRefOrSpec (tdorTag, tdorRow) |] and GenImplementsPass2 cenv env tidx ty = - AddUnsharedRow cenv TableNames.InterfaceImpl (GetTypeAsImplementsRow cenv env tidx ty) |> ignore + AddUnsharedRow cenv TableNames.InterfaceImpl (GetTypeAsImplementsRow cenv env tidx ty) and GetKeyForEvent tidx (x: ILEventDef) = EventKey (tidx, x.Name) @@ -1317,7 +1319,8 @@ and GenTypeDefPass2 pidx enc cenv (tdef: ILTypeDef) = // Now generate or assign index numbers for tables referenced by the maps. // Don't yet generate contents of these tables - leave that to pass3, as // code may need to embed these entries. - tdef.Implements |> List.iter (GenImplementsPass2 cenv env tidx) + cenv.implementsIdxs[tidx] <- tdef.Implements |> List.map (GenImplementsPass2 cenv env tidx) + tdef.Fields.AsList() |> List.iter (GenFieldDefPass2 tdef cenv tidx) tdef.Methods |> Seq.iter (GenMethodDefPass2 tdef cenv tidx) // Generation of property & event definitions for **ref assemblies** is checking existence of generated method definitions. @@ -2866,6 +2869,14 @@ let rec GenTypeDefPass3 enc cenv (tdef: ILTypeDef) = try let env = envForTypeDef tdef let tidx = GetIdxForTypeDef cenv (TdKey(enc, tdef.Name)) + + match tdef.ImplementsCustomAttrs with + | None -> () + | Some attrList -> + attrList + |> List.zip cenv.implementsIdxs[tidx] + |> List.iter (fun (impIdx,(attrs,metadataIdx)) -> GenCustomAttrsPass3Or4 cenv (hca_InterfaceImpl,impIdx) (attrs.GetCustomAttrs metadataIdx)) + tdef.Properties.AsList() |> List.iter (GenPropertyPass3 cenv env) tdef.Events.AsList() |> List.iter (GenEventPass3 cenv env) tdef.Fields.AsList() |> List.iter (GenFieldDefPass3 tdef cenv env) @@ -3130,6 +3141,7 @@ let generateIL ( methodDefIdxsByKey = MetadataTable<_>.New("method defs", EqualityComparer.Default) // This uses reference identity on ILMethodDef objects methodDefIdxs = Dictionary<_, _>(100, HashIdentity.Reference) + implementsIdxs = Dictionary<_, _>(100, HashIdentity.Structural) propertyDefs = MetadataTable<_>.New("property defs", EqualityComparer.Default) eventDefs = MetadataTable<_>.New("event defs", EqualityComparer.Default) typeDefs = MetadataTable<_>.New("type defs", EqualityComparer.Default) diff --git a/src/Compiler/Checking/AccessibilityLogic.fs b/src/Compiler/Checking/AccessibilityLogic.fs index 4a70f268ddf..052befa7a0c 100644 --- a/src/Compiler/Checking/AccessibilityLogic.fs +++ b/src/Compiler/Checking/AccessibilityLogic.fs @@ -243,8 +243,8 @@ let IsILEventInfoAccessible g amap m ad einfo = let private IsILMethInfoAccessible g amap m adType ad ilminfo = match ilminfo with - | ILMethInfo (_, ty, None, mdef, _) -> IsILTypeAndMemberAccessible g amap m adType ad (ILTypeInfo.FromType g ty) mdef.Access - | ILMethInfo (_, _, Some declaringTyconRef, mdef, _) -> IsILMemberAccessible g amap m declaringTyconRef ad mdef.Access + | ILMethInfo (_, IlType ty, mdef, _) -> IsILTypeAndMemberAccessible g amap m adType ad ty mdef.Access + | ILMethInfo (_, CSharpStyleExtension(declaring=declaringTyconRef), mdef, _) -> IsILMemberAccessible g amap m declaringTyconRef ad mdef.Access let GetILAccessOfILPropInfo (ILPropInfo(tinfo, pdef)) = let tdef = tinfo.RawMetadata diff --git a/src/Compiler/Checking/AttributeChecking.fs b/src/Compiler/Checking/AttributeChecking.fs index 2564a54bdd3..d550aaccba4 100644 --- a/src/Compiler/Checking/AttributeChecking.fs +++ b/src/Compiler/Checking/AttributeChecking.fs @@ -90,7 +90,8 @@ type AttribInfo = match x with | FSAttribInfo(_g, Attrib(tcref, _, _, _, _, _, _)) -> tcref | ILAttribInfo (g, amap, scoref, a, m) -> - let ty = RescopeAndImportILType scoref amap m [] a.Method.DeclaringType + // We are skipping nullness check here because this reference is an attribute usage, nullness does not apply. + let ty = RescopeAndImportILTypeSkipNullness scoref amap m [] a.Method.DeclaringType tcrefOfAppTy g ty member x.ConstructorArguments = @@ -104,7 +105,8 @@ type AttribInfo = | ILAttribInfo (_g, amap, scoref, cattr, m) -> let parms, _args = decodeILAttribData cattr [ for argTy, arg in Seq.zip cattr.Method.FormalArgTypes parms -> - let ty = RescopeAndImportILType scoref amap m [] argTy + // We are skipping nullness check here because this reference is an attribute usage, nullness does not apply. + let ty = RescopeAndImportILTypeSkipNullness scoref amap m [] argTy let obj = evalILAttribElem arg ty, obj ] @@ -119,7 +121,8 @@ type AttribInfo = | ILAttribInfo (_g, amap, scoref, cattr, m) -> let _parms, namedArgs = decodeILAttribData cattr [ for nm, argTy, isProp, arg in namedArgs -> - let ty = RescopeAndImportILType scoref amap m [] argTy + // We are skipping nullness check here because this reference is an attribute usage, nullness does not apply. + let ty = RescopeAndImportILTypeSkipNullness scoref amap m [] argTy let obj = evalILAttribElem arg let isField = not isProp ty, nm, isField, obj ] @@ -537,7 +540,7 @@ let IsSecurityAttribute (g: TcGlobals) amap (casmap : IDictionary) match casmap.TryGetValue tcs with | true, c -> c | _ -> - let exists = ExistsInEntireHierarchyOfType (fun t -> typeEquiv g t (mkAppTy attr.TyconRef [])) g amap m AllowMultiIntfInstantiations.Yes (mkAppTy tcref []) + let exists = ExistsInEntireHierarchyOfType (fun t -> typeEquiv g t (mkWoNullAppTy attr.TyconRef [])) g amap m AllowMultiIntfInstantiations.Yes (mkWoNullAppTy tcref []) casmap[tcs] <- exists exists | ValueNone -> false diff --git a/src/Compiler/Checking/AugmentWithHashCompare.fs b/src/Compiler/Checking/AugmentWithHashCompare.fs index 4326ac6ccfc..8d82a32ac4e 100644 --- a/src/Compiler/Checking/AugmentWithHashCompare.fs +++ b/src/Compiler/Checking/AugmentWithHashCompare.fs @@ -15,12 +15,12 @@ open FSharp.Compiler.TypedTreeOps open FSharp.Compiler.TypeHierarchy let mkIComparableCompareToSlotSig (g: TcGlobals) = - TSlotSig("CompareTo", g.mk_IComparable_ty, [], [], [ [ TSlotParam(Some("obj"), g.obj_ty, false, false, false, []) ] ], Some g.int_ty) + TSlotSig("CompareTo", g.mk_IComparable_ty, [], [], [ [ TSlotParam(Some("obj"), g.obj_ty_withNulls, false, false, false, []) ] ], Some g.int_ty) let mkGenericIComparableCompareToSlotSig (g: TcGlobals) ty = TSlotSig( "CompareTo", - (mkAppTy g.system_GenericIComparable_tcref [ ty ]), + (mkWoNullAppTy g.system_GenericIComparable_tcref [ ty ]), [], [], [ [ TSlotParam(Some("obj"), ty, false, false, false, []) ] ], @@ -35,7 +35,7 @@ let mkIStructuralComparableCompareToSlotSig (g: TcGlobals) = [], [ [ - TSlotParam(None, (mkRefTupledTy g [ g.obj_ty; g.IComparer_ty ]), false, false, false, []) + TSlotParam(None, (mkRefTupledTy g [ g.obj_ty_withNulls; g.IComparer_ty ]), false, false, false, []) ] ], Some g.int_ty @@ -44,7 +44,7 @@ let mkIStructuralComparableCompareToSlotSig (g: TcGlobals) = let mkGenericIEquatableEqualsSlotSig (g: TcGlobals) ty = TSlotSig( "Equals", - (mkAppTy g.system_GenericIEquatable_tcref [ ty ]), + (mkWoNullAppTy g.system_GenericIEquatable_tcref [ ty ]), [], [], [ [ TSlotParam(Some("obj"), ty, false, false, false, []) ] ], @@ -59,7 +59,7 @@ let mkIStructuralEquatableEqualsSlotSig (g: TcGlobals) = [], [ [ - TSlotParam(None, (mkRefTupledTy g [ g.obj_ty; g.IEqualityComparer_ty ]), false, false, false, []) + TSlotParam(None, (mkRefTupledTy g [ g.obj_ty_withNulls; g.IEqualityComparer_ty ]), false, false, false, []) ] ], Some g.bool_ty @@ -76,10 +76,10 @@ let mkIStructuralEquatableGetHashCodeSlotSig (g: TcGlobals) = ) let mkGetHashCodeSlotSig (g: TcGlobals) = - TSlotSig("GetHashCode", g.obj_ty, [], [], [ [] ], Some g.int_ty) + TSlotSig("GetHashCode", g.obj_ty_noNulls, [], [], [ [] ], Some g.int_ty) let mkEqualsSlotSig (g: TcGlobals) = - TSlotSig("Equals", g.obj_ty, [], [], [ [ TSlotParam(Some("obj"), g.obj_ty, false, false, false, []) ] ], Some g.bool_ty) + TSlotSig("Equals", g.obj_ty_noNulls, [], [], [ [ TSlotParam(Some("obj"), g.obj_ty_withNulls, false, false, false, []) ] ], Some g.bool_ty) //------------------------------------------------------------------------- // Helpers associated with code-generation of comparison/hash augmentations @@ -89,22 +89,22 @@ let mkThisTy g ty = if isStructTy g ty then mkByrefTy g ty else ty let mkCompareObjTy g ty = - mkFunTy g (mkThisTy g ty) (mkFunTy g g.obj_ty g.int_ty) + mkFunTy g (mkThisTy g ty) (mkFunTy g g.obj_ty_withNulls g.int_ty) let mkCompareTy g ty = mkFunTy g (mkThisTy g ty) (mkFunTy g ty g.int_ty) let mkCompareWithComparerTy g ty = - mkFunTy g (mkThisTy g ty) (mkFunTy g (mkRefTupledTy g [ g.obj_ty; g.IComparer_ty ]) g.int_ty) + mkFunTy g (mkThisTy g ty) (mkFunTy g (mkRefTupledTy g [ g.obj_ty_withNulls; g.IComparer_ty ]) g.int_ty) let mkEqualsObjTy g ty = - mkFunTy g (mkThisTy g ty) (mkFunTy g g.obj_ty g.bool_ty) + mkFunTy g (mkThisTy g ty) (mkFunTy g g.obj_ty_withNulls g.bool_ty) let mkEqualsTy g ty = mkFunTy g (mkThisTy g ty) (mkFunTy g ty g.bool_ty) let mkEqualsWithComparerTy g ty = - mkFunTy g (mkThisTy g ty) (mkFunTy g (mkRefTupledTy g [ g.obj_ty; g.IEqualityComparer_ty ]) g.bool_ty) + mkFunTy g (mkThisTy g ty) (mkFunTy g (mkRefTupledTy g [ g.obj_ty_withNulls; g.IEqualityComparer_ty ]) g.bool_ty) let mkEqualsWithComparerTyExact g ty = mkFunTy g (mkThisTy g ty) (mkFunTy g (mkRefTupledTy g [ ty; g.IEqualityComparer_ty ]) g.bool_ty) @@ -424,7 +424,7 @@ let mkExnEquality (g: TcGlobals) exnref (exnc: Tycon) = let cases = [ - mkCase (DecisionTreeTest.IsInst(g.exn_ty, mkAppTy exnref []), mbuilder.AddResultTarget(expr)) + mkCase (DecisionTreeTest.IsInst(g.exn_ty, mkWoNullAppTy exnref []), mbuilder.AddResultTarget(expr)) ] let dflt = Some(mbuilder.AddResultTarget(mkFalse g m)) @@ -455,7 +455,7 @@ let mkExnEqualityWithComparer g exnref (exnc: Tycon) thise thatobje (thatv, that let cases = [ - mkCase (DecisionTreeTest.IsInst(g.exn_ty, mkAppTy exnref []), mbuilder.AddResultTarget(expr)) + mkCase (DecisionTreeTest.IsInst(g.exn_ty, mkWoNullAppTy exnref []), mbuilder.AddResultTarget(expr)) ] let dflt = mbuilder.AddResultTarget(mkFalse g m) @@ -1131,7 +1131,7 @@ let CheckAugmentationAttribs isImplementation g amap (tycon: Tycon) = hasNominalInterface g.system_GenericIComparable_tcref let hasExplicitEquals = - tycon.HasOverride g "Equals" [ g.obj_ty ] + tycon.HasOverride g "Equals" [ g.obj_ty_ambivalent ] || hasNominalInterface g.tcref_System_IStructuralEquatable let hasExplicitGenericEquals = hasNominalInterface g.system_GenericIEquatable_tcref @@ -1407,13 +1407,13 @@ let MakeBindingsForCompareAugmentation g (tycon: Tycon) = let tinst, ty = mkMinimalTy g tcref let thisv, thise = mkThisVar g m ty - let thatobjv, thatobje = mkCompGenLocal m "obj" g.obj_ty + let thatobjv, thatobje = mkCompGenLocal m "obj" g.obj_ty_ambivalent let comparee = if isUnitTy g ty then mkZero g m else - let thate = mkCoerceExpr (thatobje, ty, m, g.obj_ty) + let thate = mkCoerceExpr (thatobje, ty, m, g.obj_ty_ambivalent) mkApps g ((exprForValRef m vref2, vref2.Type), (if isNil tinst then [] else [ tinst ]), [ thise; thate ], m) @@ -1450,8 +1450,8 @@ let MakeBindingsForCompareWithComparerAugmentation g (tycon: Tycon) = let compv, compe = mkCompGenLocal m "comp" g.IComparer_ty let thisv, thise = mkThisVar g m ty - let thatobjv, thatobje = mkCompGenLocal m "obj" g.obj_ty - let thate = mkCoerceExpr (thatobje, ty, m, g.obj_ty) + let thatobjv, thatobje = mkCompGenLocal m "obj" g.obj_ty_ambivalent + let thate = mkCoerceExpr (thatobje, ty, m, g.obj_ty_ambivalent) let rhs = let comparee = comparef g tcref tycon (thisv, thise) (thatobjv, thate) compe @@ -1509,7 +1509,7 @@ let MakeBindingsForEqualityWithComparerAugmentation (g: TcGlobals) (tycon: Tycon let withcEqualsExpr = let tinst, ty = mkMinimalTy g tcref let thisv, thise = mkThisVar g m ty - let thatobjv, thatobje = mkCompGenLocal m "obj" g.obj_ty + let thatobjv, thatobje = mkCompGenLocal m "obj" g.obj_ty_ambivalent let thatv, thate = mkCompGenLocal m "that" ty let compv, compe = mkCompGenLocal m "comp" g.IEqualityComparer_ty @@ -1605,7 +1605,7 @@ let MakeBindingsForEqualsAugmentation (g: TcGlobals) (tycon: Tycon) = let tinst, ty = mkMinimalTy g tcref let thisv, thise = mkThisVar g m ty - let thatobjv, thatobje = mkCompGenLocal m "obj" g.obj_ty + let thatobjv, thatobje = mkCompGenLocal m "obj" g.obj_ty_ambivalent let equalse = if isUnitTy g ty then diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index b85bce8a198..cfedc7b334b 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -777,7 +777,7 @@ module AddAugmentationDeclarations = let tcaug = tycon.TypeContents let ty = if tcref.Deref.IsFSharpException then g.exn_ty else generalizedTyconRef g tcref let m = tycon.Range - let genericIComparableTy = mkAppTy g.system_GenericIComparable_tcref [ty] + let genericIComparableTy = mkWoNullAppTy g.system_GenericIComparable_tcref [ty] let hasExplicitIComparable = tycon.HasInterface g g.mk_IComparable_ty @@ -867,7 +867,7 @@ module AddAugmentationDeclarations = let m = tycon.Range // Note: tycon.HasOverride only gives correct results after we've done the type augmentation - let hasExplicitObjectEqualsOverride = tycon.HasOverride g "Equals" [g.obj_ty] + let hasExplicitObjectEqualsOverride = tycon.HasOverride g "Equals" [g.obj_ty_ambivalent] let hasExplicitGenericIEquatable = tcaugHasNominalInterface g tcaug g.system_GenericIEquatable_tcref if hasExplicitGenericIEquatable then @@ -881,7 +881,7 @@ module AddAugmentationDeclarations = let vspec1, vspec2 = AugmentTypeDefinitions.MakeValsForEqualsAugmentation g tcref tcaug.SetEquals (mkLocalValRef vspec1, mkLocalValRef vspec2) if not tycon.IsFSharpException then - PublishInterface cenv env.DisplayEnv tcref m true (mkAppTy g.system_GenericIEquatable_tcref [ty]) + PublishInterface cenv env.DisplayEnv tcref m true (mkWoNullAppTy g.system_GenericIEquatable_tcref [ty]) PublishValueDefn cenv env ModuleOrMemberBinding vspec1 PublishValueDefn cenv env ModuleOrMemberBinding vspec2 AugmentTypeDefinitions.MakeBindingsForEqualsAugmentation g tycon @@ -1592,7 +1592,7 @@ module MutRecBindingChecking = if tcref.IsStructOrEnumTycon then Some (incrCtorInfo, mkUnit g tcref.Range, false), defnCs else - let inheritsExpr, _ = TcNewExpr cenv envForDecls tpenv g.obj_ty None true (SynExpr.Const (SynConst.Unit, tcref.Range)) tcref.Range + let inheritsExpr, _ = TcNewExpr cenv envForDecls tpenv g.obj_ty_noNulls None true (SynExpr.Const (SynConst.Unit, tcref.Range)) tcref.Range // If there is no 'inherits' and no simple non-static 'let' of a non-method then add a debug point at the entry to the constructor over the type name itself. let addDebugPointAtImplicitCtorArguments = @@ -1974,8 +1974,8 @@ let TcMutRecDefns_Phase2 (cenv: cenv) envInitial mBinds scopem mutRecNSInfo (env if (generatedCompareToValues && typeEquiv g intfTyR g.mk_IComparable_ty) || (generatedCompareToWithComparerValues && typeEquiv g intfTyR g.mk_IStructuralComparable_ty) || - (generatedCompareToValues && typeEquiv g intfTyR (mkAppTy g.system_GenericIComparable_tcref [ty])) || - (generatedHashAndEqualsWithComparerValues && typeEquiv g intfTyR (mkAppTy g.system_GenericIEquatable_tcref [ty])) || + (generatedCompareToValues && typeEquiv g intfTyR (mkWoNullAppTy g.system_GenericIComparable_tcref [ty])) || + (generatedHashAndEqualsWithComparerValues && typeEquiv g intfTyR (mkWoNullAppTy g.system_GenericIEquatable_tcref [ty])) || (generatedHashAndEqualsWithComparerValues && typeEquiv g intfTyR g.mk_IStructuralEquatable_ty) then errorR(Error(FSComp.SR.tcDefaultImplementationForInterfaceHasAlreadyBeenAdded(), intfTy.Range)) @@ -3305,7 +3305,7 @@ module EstablishTypeDefinitionCores = if isTyparTy g ty then if firstPass then errorR(Error(FSComp.SR.tcCannotInheritFromVariableType(), m)) - Some g.obj_ty // a "super" that is a variable type causes grief later + Some g.obj_ty_noNulls // a "super" that is a variable type causes grief later else Some ty | _ -> @@ -3320,7 +3320,7 @@ module EstablishTypeDefinitionCores = super |> Option.map (fun ty -> if isFunTy g ty then let a,b = destFunTy g ty - mkAppTy g.fastFunc_tcr [a; b] + mkWoNullAppTy g.fastFunc_tcr [a; b] else ty) // Publish the super type @@ -3371,7 +3371,6 @@ module EstablishTypeDefinitionCores = tycon.TypeContents.tcaug_super |> Option.iter (fun ty -> if not (TypeNullIsExtraValue g m ty) then errorR (Error(FSComp.SR.tcAllowNullTypesMayOnlyInheritFromAllowNullTypes(), m))) tycon.ImmediateInterfaceTypesOfFSharpTycon |> List.iter (fun ty -> if not (TypeNullIsExtraValue g m ty) then errorR (Error(FSComp.SR.tcAllowNullTypesMayOnlyInheritFromAllowNullTypes(), m))) - let structLayoutAttributeCheck allowed = let explicitKind = int32 System.Runtime.InteropServices.LayoutKind.Explicit match structLayoutAttr with @@ -3723,7 +3722,7 @@ module EstablishTypeDefinitionCores = // validate ConditionalAttribute, should it be applied (it's only valid on a type if the type is an attribute type) match attrs |> List.tryFind (IsMatchingFSharpAttribute g g.attrib_ConditionalAttribute) with | Some _ -> - if not(ExistsInEntireHierarchyOfType (fun t -> typeEquiv g t (mkAppTy g.tcref_System_Attribute [])) g cenv.amap m AllowMultiIntfInstantiations.Yes thisTy) then + if not(ExistsInEntireHierarchyOfType (fun t -> typeEquiv g t (mkWoNullAppTy g.tcref_System_Attribute [])) g cenv.amap m AllowMultiIntfInstantiations.Yes thisTy) then errorR(Error(FSComp.SR.tcConditionalAttributeUsage(), m)) | _ -> () diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 6bdf94ed9ff..edc3212bcfa 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -483,8 +483,9 @@ let UnifyOverallType (cenv: cenv) (env: TcEnv) m overallTy actualTy = match overallTy with | MustConvertTo(isMethodArg, reqdTy) when g.langVersion.SupportsFeature LanguageFeature.AdditionalTypeDirectedConversions -> let actualTy = tryNormalizeMeasureInType g actualTy - let reqdTy = tryNormalizeMeasureInType g reqdTy - if AddCxTypeEqualsTypeUndoIfFailed env.DisplayEnv cenv.css m reqdTy actualTy then + let reqdTy = tryNormalizeMeasureInType g reqdTy + let reqTyForUnification = reqTyForArgumentNullnessInference g actualTy reqdTy + if AddCxTypeEqualsTypeUndoIfFailed env.DisplayEnv cenv.css m reqTyForUnification actualTy then () else // try adhoc type-directed conversions @@ -830,10 +831,10 @@ let TcConst (cenv: cenv) (overallTy: TType) m env synConst = let measureTy = match synConst with | SynConst.Measure(synMeasure = SynMeasure.Anon _) -> - (mkAppTy tcr [TType_measure (Measure.Var (NewAnonTypar (TyparKind.Measure, m, TyparRigidity.Anon, (if iszero then TyparStaticReq.None else TyparStaticReq.HeadType), TyparDynamicReq.No)))]) + (mkWoNullAppTy tcr [TType_measure (Measure.Var (NewAnonTypar (TyparKind.Measure, m, TyparRigidity.Anon, (if iszero then TyparStaticReq.None else TyparStaticReq.HeadType), TyparDynamicReq.No)))]) - | SynConst.Measure(synMeasure = ms) -> mkAppTy tcr [TType_measure (tcMeasure ms)] - | _ -> mkAppTy tcr [TType_measure Measure.One] + | SynConst.Measure(synMeasure = ms) -> mkWoNullAppTy tcr [TType_measure (tcMeasure ms)] + | _ -> mkWoNullAppTy tcr [TType_measure Measure.One] unif measureTy let expandedMeasurablesEnabled = @@ -853,7 +854,7 @@ let TcConst (cenv: cenv) (overallTy: TType) m env synConst = unif g.float_ty Const.Double f | SynConst.Decimal f -> - unif (mkAppTy g.decimal_tcr []) + unif (mkWoNullAppTy g.decimal_tcr []) Const.Decimal f | SynConst.SByte i -> unif g.sbyte_ty @@ -1015,6 +1016,49 @@ let TranslatePartialValReprInfo tps (PrelimValReprInfo (argsData, retData)) = // Members //------------------------------------------------------------------------- +let TcAddNullnessToType (warn: bool) (cenv: cenv) (env: TcEnv) nullness innerTyC m = + let g = cenv.g + if g.langFeatureNullness then + if TypeNullNever g innerTyC then + let tyString = NicePrint.minimalStringOfType env.DisplayEnv innerTyC + errorR(Error(FSComp.SR.tcTypeDoesNotHaveAnyNull(tyString), m)) + + match tryAddNullnessToTy nullness innerTyC with + + | None -> + let tyString = NicePrint.minimalStringOfType env.DisplayEnv innerTyC + errorR(Error(FSComp.SR.tcTypeDoesNotHaveAnyNull(tyString), m)) + innerTyC + + | Some innerTyCWithNull -> + // The inner type is not allowed to support null or use null as a representation value. + // For example "int option?" is not allowed, nor "string??". + // + // For variable types in FSharp.Core we make an exception because we must allow + // val toObj: value: 'T option -> 'T | null when 'T : not struct (* and 'T : not null *) + // wihout implying 'T is not null. This is because it is legitimate to use this + // function to "collapse" null and obj-null-coming-from-option using such a function. + + if not g.compilingFSharpCore || not (isTyparTy g innerTyC) then + AddCxTypeDefnNotSupportsNull env.DisplayEnv cenv.css m NoTrace innerTyC + AddCxTypeIsReferenceType env.DisplayEnv cenv.css m NoTrace innerTyC + + if not g.compilingFSharpCore && isTyparTy g innerTyC then + // A typar might be later infered into a type not supporting `| null|, like tuple or anon. + // Repeat the check in post inference + AddCxTypeCanCarryNullnessInfo env.DisplayEnv cenv.css m innerTyC nullness + + innerTyCWithNull + + else + if warn then + warning(Error(FSComp.SR.tcNullnessCheckingNotEnabled(), m)) + innerTyC + +//------------------------------------------------------------------------- +// Members +//------------------------------------------------------------------------- + let ComputeLogicalName (id: Ident) (memberFlags: SynMemberFlags) = match memberFlags.MemberKind with | SynMemberKind.ClassConstructor -> ".cctor" @@ -2140,7 +2184,7 @@ module GeneralizationHelpers = match tp.Constraints |> List.partition (function TyparConstraint.CoercesTo _ -> true | _ -> false) with | [TyparConstraint.CoercesTo(tgtTy, _)], others -> // Throw away null constraints if they are implied - if others |> List.exists (function TyparConstraint.SupportsNull _ -> not (TypeSatisfiesNullConstraint g m tgtTy) | _ -> true) + if others |> List.exists (function TyparConstraint.SupportsNull _ -> not (TypeNullIsExtraValue g m tgtTy) | _ -> true) then None else Some tgtTy | _ -> None @@ -2953,7 +2997,7 @@ let TcRuntimeTypeTest isCast isOperator (cenv: cenv) denv m tgtTy srcTy = else error(Error(FSComp.SR.tcTypeTestErased(NicePrint.minimalStringOfType denv tgtTy, NicePrint.minimalStringOfType denv (stripTyEqnsWrtErasure EraseAll g tgtTy)), m)) else - for ety in getErasedTypes g tgtTy do + for ety in getErasedTypes g tgtTy true do if isMeasureTy g ety then warning(Error(FSComp.SR.tcTypeTestLosesMeasures(NicePrint.minimalStringOfType denv ety), m)) else @@ -3059,7 +3103,7 @@ let BuildDisposableCleanup (cenv: cenv) env m (v: Val) = else let disposeObjVar, disposeObjExpr = mkCompGenLocal m "objectToDispose" g.system_IDisposable_ty let disposeExpr, _ = BuildPossiblyConditionalMethodCall cenv env PossiblyMutates m false disposeMethod NormalValUse [] [disposeObjExpr] [] None - let inputExpr = mkCoerceExpr(exprForVal v.Range v, g.obj_ty, m, v.Type) + let inputExpr = mkCoerceExpr(exprForVal v.Range v, g.obj_ty_ambivalent, m, v.Type) mkIsInstConditional g m g.system_IDisposable_ty inputExpr disposeObjVar disposeExpr (mkUnit g m) /// Build call to get_OffsetToStringData as part of 'fixed' @@ -3299,7 +3343,7 @@ let AnalyzeArbitraryExprAsEnumerable (cenv: cenv) (env: TcEnv) localAlloc m expr // e.g. MatchCollection typeEquiv g g.int32_ty ty || // e.g. EnvDTE.Documents.Item - typeEquiv g g.obj_ty ty + typeEquiv g g.obj_ty_ambivalent ty | _ -> false match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AllResults cenv env m ad "get_Item" tyToSearchForGetEnumeratorAndItem with @@ -3377,7 +3421,7 @@ let AnalyzeArbitraryExprAsEnumerable (cenv: cenv) (env: TcEnv) localAlloc m expr match probe exprTyAsSeq with | Some res -> res | None -> - let ienumerable = mkAppTy g.tcref_System_Collections_IEnumerable [] + let ienumerable = mkWoNullAppTy g.tcref_System_Collections_IEnumerable [] match probe ienumerable with | Some res -> res | None -> @@ -4039,6 +4083,13 @@ let rec TcTyparConstraint ridx (cenv: cenv) newOk checkConstraints occ (env: TcE | SynTypeConstraint.WhereTyparSupportsNull(tp, m) -> TcSimpleTyparConstraint cenv env newOk tpenv tp m AddCxTypeUseSupportsNull + | SynTypeConstraint.WhereTyparNotSupportsNull(tp, m) -> + if g.langFeatureNullness then + TcSimpleTyparConstraint cenv env newOk tpenv tp m AddCxTypeDefnNotSupportsNull + else + warning(Error(FSComp.SR.tcNullnessCheckingNotEnabled(), m)) + tpenv + | SynTypeConstraint.WhereTyparIsComparable(tp, m) -> TcSimpleTyparConstraint cenv env newOk tpenv tp m AddCxTypeMustSupportComparison @@ -4408,7 +4459,7 @@ and TcTypeOrMeasure kindOpt (cenv: cenv) newOk checkConstraints occ (iwsam: Warn match synTy with | SynType.LongIdent(SynLongIdent([], _, _)) -> // special case when type name is absent - i.e. empty inherit part in type declaration - g.obj_ty, tpenv + g.obj_ty_ambivalent, tpenv | SynType.LongIdent synLongId -> TcLongIdentType kindOpt cenv newOk checkConstraints occ iwsam env tpenv synLongId @@ -4456,11 +4507,18 @@ and TcTypeOrMeasure kindOpt (cenv: cenv) newOk checkConstraints occ (iwsam: Warn | SynType.StaticConstant (synConst, m) -> TcTypeStaticConstant kindOpt tpenv synConst m + | SynType.StaticConstantNull m | SynType.StaticConstantNamed (_, _, m) | SynType.StaticConstantExpr (_, m) -> errorR(Error(FSComp.SR.parsInvalidLiteralInType(), m)) NewErrorType (), tpenv + | SynType.WithNull(innerTy, ambivalent, m) -> + let innerTyC, tpenv = TcTypeAndRecover cenv newOk checkConstraints occ WarnOnIWSAM.Yes env tpenv innerTy + let nullness = if ambivalent then KnownAmbivalentToNull else KnownWithNull + let tyWithNull = TcAddNullnessToType false cenv env nullness innerTyC m + tyWithNull, tpenv + | SynType.MeasurePower(ty, exponent, m) -> TcTypeMeasurePower kindOpt cenv newOk checkConstraints occ env tpenv ty exponent m @@ -4612,7 +4670,7 @@ and TcFunctionType (cenv: cenv) newOk checkConstraints occ env tpenv domainTy re and TcArrayType (cenv: cenv) newOk checkConstraints occ env tpenv rank elemTy m = let g = cenv.g let elemTy, tpenv = TcTypeAndRecover cenv newOk checkConstraints occ WarnOnIWSAM.Yes env tpenv elemTy - let tyR = mkArrayTy g rank elemTy m + let tyR = mkArrayTy g rank g.knownWithoutNull elemTy m tyR, tpenv and TcTypeParameter kindOpt (cenv: cenv) env newOk tpenv tp = @@ -4637,8 +4695,9 @@ and TcTypeWithConstraints (cenv: cenv) env newOk checkConstraints occ tpenv synT and TcTypeHashConstraint (cenv: cenv) env newOk checkConstraints occ tpenv synTy m = let tp = TcAnonTypeOrMeasure (Some TyparKind.Type) cenv TyparRigidity.WarnIfNotRigid TyparDynamicReq.Yes newOk m let ty, tpenv = TcTypeAndRecover cenv newOk checkConstraints occ WarnOnIWSAM.No env tpenv synTy - AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css m NoTrace ty (mkTyparTy tp) - tp.AsType, tpenv + let tpTy = mkTyparTy tp + AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css m NoTrace ty tpTy + tpTy, tpenv // (x: 't & #I1 & #I2) // (x: #I1 & #I2) @@ -4661,7 +4720,8 @@ and TcIntersectionConstraint (cenv: cenv) env newOk checkConstraints occ tpenv s | _ -> tpenv ) tpenv - tp.AsType, tpenv + let tpTy = tp.AsType KnownAmbivalentToNull // TODO: NULLNESS + tpTy, tpenv and TcTypeStaticConstant kindOpt tpenv c m = match c, kindOpt with @@ -4815,7 +4875,7 @@ and TcStaticConstantParameter (cenv: cenv) (env: TcEnv) tpenv kind (StripParenTy | SynConst.Double n when typeEquiv g g.float_ty kind -> record(g.float_ty); box (n: double) | SynConst.Char n when typeEquiv g g.char_ty kind -> record(g.char_ty); box (n: char) | SynConst.String (s, _, _) - | SynConst.SourceIdentifier (_, s, _) when (not (isNull s)) && typeEquiv g g.string_ty kind -> record(g.string_ty); box (s: string) + | SynConst.SourceIdentifier (_, s, _) when typeEquiv g g.string_ty kind -> record(g.string_ty); box (s: string) | SynConst.Bool b when typeEquiv g g.bool_ty kind -> record(g.bool_ty); box (b: bool) | _ -> fail() v, tpenv @@ -4844,7 +4904,6 @@ and TcStaticConstantParameter (cenv: cenv) (env: TcEnv) tpenv kind (StripParenTy | Const.Single n -> record(g.float32_ty); box (n: single) | Const.Double n -> record(g.float_ty); box (n: double) | Const.Char n -> record(g.char_ty); box (n: char) - | Const.String null -> fail() | Const.String s -> record(g.string_ty); box (s: string) | Const.Bool b -> record(g.bool_ty); box (b: bool) | _ -> fail() @@ -4968,7 +5027,7 @@ and TcProvidedTypeApp (cenv: cenv) env tpenv tcref args m = // We put the type name check after the 'isDirectReferenceToGenerated' check because we need the 'isDirectReferenceToGenerated' error to be shown for generated types checkTypeName() if hasNoArgs then - mkAppTy tcref [], tpenv + mkWoNullAppTy tcref [], tpenv else let ty = Import.ImportProvidedType cenv.amap m providedTypeAfterStaticArguments ty, tpenv @@ -5019,7 +5078,7 @@ and TcTypeApp (cenv: cenv) newOk checkConstraints occ env tpenv m tcref pathType List.iter2 (UnifyTypes cenv env m) tinst actualArgTys // Try to decode System.Tuple --> F# tuple types etc. - let ty = g.decompileType tcref actualArgTys + let ty = g.decompileType tcref actualArgTys g.knownWithoutNull ty, tpenv @@ -5034,7 +5093,7 @@ and TcTypeOrMeasureAndRecover kindOpt (cenv: cenv) newOk checkConstraints occ iw match kindOpt, newOk with | Some TyparKind.Measure, NoNewTypars -> TType_measure Measure.One | Some TyparKind.Measure, _ -> TType_measure (NewErrorMeasure ()) - | _, NoNewTypars -> g.obj_ty + | _, NoNewTypars -> g.obj_ty_ambivalent | _ -> NewErrorType () recoveryTy, tpenv @@ -5106,10 +5165,14 @@ and ConvSynPatToSynExpr synPat = /// Check a long identifier 'Case' or 'Case argsR' that has been resolved to an active pattern case and TcPatLongIdentActivePatternCase warnOnUpper (cenv: cenv) (env: TcEnv) vFlags patEnv ty (mLongId, item, apref, args, m) = let g = cenv.g - let (TcPatLinearEnv(tpenv, names, takenNames)) = patEnv let (APElemRef (apinfo, vref, idx, isStructRetTy)) = apref + let cenv = + match g.checkNullness,TryFindLocalizedFSharpStringAttribute g g.attrib_WarnOnWithoutNullArgumentAttribute vref.Attribs with + | true, (Some _ as warnMsg) -> {cenv with css.WarnWhenUsingWithoutNullOnAWithNullTarget = warnMsg} + | _ -> cenv + // Report information about the 'active recognizer' occurrence to IDE CallNameResolutionSink cenv.tcSink (mLongId, env.NameEnv, item, emptyTyparInst, ItemOccurence.Pattern, env.eAccessRights) @@ -5142,9 +5205,11 @@ and TcPatLongIdentActivePatternCase warnOnUpper (cenv: cenv) (env: TcEnv) vFlags | TyparConstraint.IsDelegate _ | TyparConstraint.IsEnum _ | TyparConstraint.IsNonNullableStruct _ + | TyparConstraint.NotSupportsNull _ | TyparConstraint.IsUnmanaged _ | TyparConstraint.RequiresDefaultConstructor _ | TyparConstraint.SimpleChoice _ + | TyparConstraint.NotSupportsNull _ | TyparConstraint.SupportsNull _ -> false)) let caseRetTy = @@ -5279,6 +5344,7 @@ and TcExprFlex (cenv: cenv) flex compat (desiredTy: TType) (env: TcEnv) tpenv (s if flex then let argTy = NewInferenceType g + (destTyparTy g argTy).SetSupportsNullFlex(true) if compat then (destTyparTy g argTy).SetIsCompatFlex(true) @@ -5792,7 +5858,8 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE | SynExpr.Null m -> TcNonControlFlowExpr env <| fun env -> AddCxTypeUseSupportsNull env.DisplayEnv cenv.css m NoTrace overallTy.Commit - mkNull m overallTy.Commit, tpenv + let tyWithNull = addNullnessToTy KnownWithNull overallTy.Commit + mkNull m tyWithNull, tpenv | SynExpr.Lazy (synInnerExpr, m) -> TcNonControlFlowExpr env <| fun env -> @@ -7526,7 +7593,7 @@ and TcInterpolatedStringExpr cenv (overallTy: OverallTy) env m tpenv (parts: Syn let fillExprsBoxed = (argTys, fillExprs) ||> List.map2 (mkCallBox g m) - let argsExpr = mkArray (g.obj_ty, fillExprsBoxed, m) + let argsExpr = mkArray (g.obj_ty_withNulls, fillExprsBoxed, m) let percentATysExpr = if percentATys.Length = 0 then mkNull m (mkArrayType g g.system_Type_ty) @@ -7553,7 +7620,7 @@ and TcInterpolatedStringExpr cenv (overallTy: OverallTy) env m tpenv (parts: Syn let fillExprsBoxed = (argTys, fillExprs) ||> List.map2 (mkCallBox g m) let dotnetFormatStringExpr = mkString g m dotnetFormatString - let argsExpr = mkArray (g.obj_ty, fillExprsBoxed, m) + let argsExpr = mkArray (g.obj_ty_withNulls, fillExprsBoxed, m) // FormattableString are *always* turned into FormattableStringFactory.Create calls, boxing each argument let createExpr, _ = BuildPossiblyConditionalMethodCall cenv env NeverMutates m false createFormattableStringMethod NormalValUse [] [dotnetFormatStringExpr; argsExpr] [] None @@ -7695,7 +7762,7 @@ and TcRecdExpr cenv overallTy env tpenv (inherits, withExprOpt, synRecdFields, m | None -> [] | Some(tinst, tcref, _, fldsList) -> - let gtyp = mkAppTy tcref tinst + let gtyp = mkWoNullAppTy tcref tinst UnifyTypes cenv env mWholeExpr overallTy gtyp [ for n, v in fldsList do @@ -8499,11 +8566,11 @@ and TcApplicationThen (cenv: cenv) (overallTy: OverallTy) env tpenv mExprAndArg | _ -> synArg - let arg, tpenv = + let (arg, tpenv), cenv = // treat left and right of '||' and '&&' as control flow, so for example // f expr1 && g expr2 // will have debug points on "f expr1" and "g expr2" - let env = + let env,cenv = match leftExpr with | ApplicableExpr(expr=Expr.Val (vref, _, _)) | ApplicableExpr(expr=Expr.App (Expr.Val (vref, _, _), _, _, [_], _)) @@ -8511,10 +8578,17 @@ and TcApplicationThen (cenv: cenv) (overallTy: OverallTy) env tpenv mExprAndArg || valRefEq g vref g.and2_vref || valRefEq g vref g.or_vref || valRefEq g vref g.or2_vref -> - { env with eIsControlFlow = true } - | _ -> env - - TcExprFlex2 cenv domainTy env false tpenv synArg + { env with eIsControlFlow = true },cenv + | ApplicableExpr(expr=Expr.Val (valRef=vref)) + | ApplicableExpr(expr=Expr.App (funcExpr=Expr.Val (valRef=vref))) -> + match TryFindLocalizedFSharpStringAttribute g g.attrib_WarnOnWithoutNullArgumentAttribute vref.Attribs with + | Some _ as msg -> env,{ cenv with css.WarnWhenUsingWithoutNullOnAWithNullTarget = msg} + | None when cenv.css.WarnWhenUsingWithoutNullOnAWithNullTarget <> None -> + env, { cenv with css.WarnWhenUsingWithoutNullOnAWithNullTarget = None} + | None -> env,cenv + | _ -> env,cenv + + TcExprFlex2 cenv domainTy env false tpenv synArg, cenv let exprAndArg, resultTy = buildApp cenv leftExpr resultTy arg mExprAndArg TcDelayed cenv overallTy env tpenv mExprAndArg exprAndArg resultTy atomicFlag delayed @@ -9382,10 +9456,13 @@ and TcLookupThen cenv overallTy env tpenv mObjExpr objExpr objExprTy longId dela let objArgs = [objExpr] - // 'base' calls use a different resolution strategy when finding methods. - let findFlag = - let baseCall = IsBaseCall objArgs - (if baseCall then PreferOverrides else IgnoreOverrides) + let findFlag = + // 'base' calls use a different resolution strategy when finding methods + // nullness checks need the overrides, since those can change nullable semantics (e.g. ToString from BCL) + if (g.checkNullness && g.langFeatureNullness) || IsBaseCall objArgs then + PreferOverrides + else + IgnoreOverrides // Canonicalize inference problem prior to '.' lookup on variable types if isTyparTy g objExprTy then @@ -9576,7 +9653,8 @@ and TcEventItemThen (cenv: cenv) overallTy env tpenv mItem mExprAndItem objDetai | None, false -> error (Error (FSComp.SR.tcEventIsNotStatic nm, mItem)) | _ -> () - let delTy = einfo.GetDelegateType(cenv.amap, mItem) + // The F# wrappers around events are null safe (impl is in FSharp.Core). Therefore, from an F# perspective, the type of the delegate can be considered Not Null. + let delTy = einfo.GetDelegateType(cenv.amap, mItem) |> replaceNullnessOfTy KnownWithoutNull let (SigOfFunctionForDelegate(delInvokeMeth, delArgTys, _, _)) = GetSigOfFunctionForDelegate cenv.infoReader delTy mItem ad let objArgs = Option.toList (Option.map fst objDetails) MethInfoChecks g cenv.amap true None objArgs env.eAccessRights mItem delInvokeMeth @@ -9605,7 +9683,7 @@ and TcEventItemThen (cenv: cenv) overallTy env tpenv mItem mExprAndItem objDetai (let dv, de = mkCompGenLocal mItem "eventDelegate" delTy let callExpr, _ = BuildPossiblyConditionalMethodCall cenv env PossiblyMutates mItem false einfo.RemoveMethod NormalValUse [] objVars [de] None mkLambda mItem dv (callExpr, g.unit_ty)) - (let fvty = mkFunTy g g.obj_ty (mkFunTy g argsTy g.unit_ty) + (let fvty = mkFunTy g g.obj_ty_withNulls (mkFunTy g argsTy g.unit_ty) let fv, fe = mkCompGenLocal mItem "callback" fvty let createExpr = BuildNewDelegateExpr (Some einfo, g, cenv.amap, delTy, delInvokeMeth, delArgTys, fe, fvty, mItem) mkLambda mItem fv (createExpr, delTy))) @@ -9991,7 +10069,7 @@ and TcAdhocChecksOnLibraryMethods (cenv: cenv) (env: TcEnv) isInstance (finalCal if (isInstance && finalCalledMethInfo.IsInstance && - typeEquiv g finalCalledMethInfo.ApparentEnclosingType g.obj_ty && + typeEquiv g finalCalledMethInfo.ApparentEnclosingType g.obj_ty_ambivalent && (finalCalledMethInfo.LogicalName = "GetHashCode" || finalCalledMethInfo.LogicalName = "Equals")) then for objArg in objArgs do @@ -10564,10 +10642,13 @@ and TcMatchPattern cenv inputTy env tpenv (synPat: SynPat) (synWhenExprOpt: SynE and TcMatchClauses cenv inputTy (resultTy: OverallTy) env tpenv clauses = let mutable first = true let isFirst() = if first then first <- false; true else false - List.mapFold (fun clause -> TcMatchClause cenv inputTy resultTy env (isFirst()) clause) tpenv clauses + let resultList,(tpEnv,_input) = + List.mapFold (fun (unscopedTyParEnv,inputTy) -> TcMatchClause cenv inputTy resultTy env (isFirst()) unscopedTyParEnv) (tpenv,inputTy) clauses + resultList,tpEnv and TcMatchClause cenv inputTy (resultTy: OverallTy) env isFirst tpenv synMatchClause = let (SynMatchClause(synPat, synWhenExprOpt, synResultExpr, patm, spTgt, _)) = synMatchClause + let pat, whenExprOpt, vspecs, envinner, tpenv = TcMatchPattern cenv inputTy env tpenv synPat synWhenExprOpt let resultEnv = @@ -10582,8 +10663,37 @@ and TcMatchClause cenv inputTy (resultTy: OverallTy) env isFirst tpenv synMatchC let resultExpr, tpenv = TcExprThatCanBeCtorBody cenv resultTy resultEnv tpenv synResultExpr let target = TTarget(vspecs, resultExpr, None) + + let inputTypeForNextPatterns= + let removeNull t = + let stripped = stripTyEqns cenv.g t + replaceNullnessOfTy KnownWithoutNull stripped + let rec isWild (p:Pattern) = + match p with + | TPat_wild _ -> true + | TPat_as (p,_,_) -> isWild p + | TPat_disjs(patterns,_) -> patterns |> List.exists isWild + | TPat_conjs(patterns,_) -> patterns |> List.forall isWild + | TPat_tuple (_,pats,_,_) -> pats |> List.forall isWild + | _ -> false + + let rec eliminateNull (ty:TType) (p:Pattern) = + match p with + | TPat_null _ -> removeNull ty + | TPat_as (p,_,_) -> eliminateNull ty p + | TPat_disjs(patterns,_) -> (ty,patterns) ||> List.fold eliminateNull + | TPat_tuple (_,pats,_,_) -> + match stripTyparEqns ty with + // In a tuple of size N, if 1 elem is matched for null and N-1 are wild => subsequent clauses can strip nullness + | TType_tuple(ti,tys) when tys.Length = pats.Length && (pats |> List.count (isWild >> not)) = 1 -> + TType_tuple(ti, List.map2 eliminateNull tys pats) + | _ -> ty + | _ -> ty + match whenExprOpt with + | None -> eliminateNull inputTy pat + | _ -> inputTy - MatchClause(pat, whenExprOpt, target, patm), tpenv + MatchClause(pat, whenExprOpt, target, patm), (tpenv,inputTypeForNextPatterns) and TcStaticOptimizationConstraint cenv env tpenv c = let g = cenv.g @@ -12164,7 +12274,7 @@ and TcLetrecBinding | None -> let reqdThisValTy = if isByrefTy g reqdThisValTy then destByrefTy g reqdThisValTy else reqdThisValTy let enclosingTyconRef = tcrefOfAppTy g reqdThisValTy - reqdThisValTy, (mkAppTy enclosingTyconRef (List.map mkTyparTy enclosingDeclaredTypars)), vspec.Range + reqdThisValTy, (mkWoNullAppTy enclosingTyconRef (List.map mkTyparTy enclosingDeclaredTypars)), vspec.Range | Some thisVal -> reqdThisValTy, thisVal.Type, thisVal.Range if not (AddCxTypeEqualsTypeUndoIfFailed envRec.DisplayEnv cenv.css rangeForCheck actualThisValTy reqdThisValTy) then diff --git a/src/Compiler/Checking/CheckFormatStrings.fs b/src/Compiler/Checking/CheckFormatStrings.fs index ec8b4ae2b91..1264cbbcb86 100644 --- a/src/Compiler/Checking/CheckFormatStrings.fs +++ b/src/Compiler/Checking/CheckFormatStrings.fs @@ -449,7 +449,8 @@ let parseFormatStringInternal checkOtherFlags ch collectSpecifierLocation fragLine fragCol 1 let i = skipPossibleInterpolationHole (i+1) - parseLoop ((posi, g.string_ty) :: acc) (i, fragLine, fragCol+1) fragments + let stringTy = if g.checkNullness && g.langFeatureNullness then g.string_ty_ambivalent else g.string_ty + parseLoop ((posi, stringTy) :: acc) (i, fragLine, fragCol+1) fragments | 'O' -> checkOtherFlags ch diff --git a/src/Compiler/Checking/CheckPatterns.fs b/src/Compiler/Checking/CheckPatterns.fs index 79758a01327..d2a6b566ab2 100644 --- a/src/Compiler/Checking/CheckPatterns.fs +++ b/src/Compiler/Checking/CheckPatterns.fs @@ -446,7 +446,7 @@ and TcRecordPat warnOnUpper cenv env vFlags patEnv ty fieldPats m = | None -> (fun _ -> TPat_error m), patEnv | Some(tinst, tcref, fldsmap, _fldsList) -> - let gtyp = mkAppTy tcref tinst + let gtyp = mkWoNullAppTy tcref tinst let inst = List.zip (tcref.Typars m) tinst UnifyTypes cenv env m ty gtyp diff --git a/src/Compiler/Checking/ConstraintSolver.fs b/src/Compiler/Checking/ConstraintSolver.fs index 1cdfe136f7d..91c17302e98 100644 --- a/src/Compiler/Checking/ConstraintSolver.fs +++ b/src/Compiler/Checking/ConstraintSolver.fs @@ -69,6 +69,64 @@ open FSharp.Compiler.TypedTreeOps open FSharp.Compiler.TypeHierarchy open FSharp.Compiler.TypeRelations +#if !NO_TYPEPROVIDERS +open FSharp.Compiler.TypeProviders +#endif + +//------------------------------------------------------------------------- +// Generate type variables and record them in within the scope of the +// compilation environment, which currently corresponds to the scope +// of the constraint resolution carried out by type checking. +//------------------------------------------------------------------------- + +let compgenId = mkSynId Range.range0 unassignedTyparName + +let NewCompGenTypar (kind, rigid, staticReq, dynamicReq, error) = + Construct.NewTypar(kind, rigid, SynTypar(compgenId, staticReq, true), error, dynamicReq, [], false, false) + +let AnonTyparId m = mkSynId m unassignedTyparName + +let NewAnonTypar (kind, m, rigid, var, dyn) = + Construct.NewTypar (kind, rigid, SynTypar(AnonTyparId m, var, true), false, dyn, [], false, false) + +let NewNamedInferenceMeasureVar (_m, rigid, var, id) = + Construct.NewTypar(TyparKind.Measure, rigid, SynTypar(id, var, false), false, TyparDynamicReq.No, [], false, false) + +let NewInferenceMeasurePar () = + NewCompGenTypar (TyparKind.Measure, TyparRigidity.Flexible, TyparStaticReq.None, TyparDynamicReq.No, false) + +let NewErrorTypar () = + NewCompGenTypar (TyparKind.Type, TyparRigidity.Flexible, TyparStaticReq.None, TyparDynamicReq.No, true) + +let NewErrorType () = + mkTyparTy (NewErrorTypar ()) + +let FreshenTypar (g: TcGlobals) rigid (tp: Typar) = + let clearStaticReq = g.langVersion.SupportsFeature LanguageFeature.InterfacesWithAbstractStaticMembers + let staticReq = if clearStaticReq then TyparStaticReq.None else tp.StaticReq + let dynamicReq = if rigid = TyparRigidity.Rigid then TyparDynamicReq.Yes else TyparDynamicReq.No + NewCompGenTypar (tp.Kind, rigid, staticReq, dynamicReq, false) + +// QUERY: should 'rigid' ever really be 'true'? We set this when we know +// we are going to have to generalize a typar, e.g. when implementing a +// abstract generic method slot. But we later check the generalization +// condition anyway, so we could get away with a non-rigid typar. This +// would sort of be cleaner, though give errors later. +let FreshenAndFixupTypars g m rigid fctps tinst tpsorig = + let tps = tpsorig |> List.map (FreshenTypar g rigid) + let renaming, tinst = FixupNewTypars m fctps tinst tpsorig tps + tps, renaming, tinst + +let FreshenTypeInst g m tpsorig = + FreshenAndFixupTypars g m TyparRigidity.Flexible [] [] tpsorig + +let FreshMethInst g m fctps tinst tpsorig = + FreshenAndFixupTypars g m TyparRigidity.Flexible fctps tinst tpsorig + +let FreshenMethInfo m (minfo: MethInfo) = + let _, _, tpTys = FreshMethInst minfo.TcGlobals m (minfo.GetFormalTyparsOfDeclaringType m) minfo.DeclaringTypeInst minfo.FormalMethodTypars + tpTys + //------------------------------------------------------------------------- // Unification of types: solve/record equality constraints // Subsumption of types: solve/record subtyping constraints @@ -161,7 +219,15 @@ exception ConstraintSolverTypesNotInEqualityRelation of displayEnv: DisplayEnv * exception ConstraintSolverTypesNotInSubsumptionRelation of displayEnv: DisplayEnv * argTy: TType * paramTy: TType * callRange: range * parameterRange: range -exception ConstraintSolverMissingConstraint of displayEnv: DisplayEnv * Typar * TyparConstraint * range * range +exception ConstraintSolverMissingConstraint of displayEnv: DisplayEnv * Typar * TyparConstraint * range * range + +exception ConstraintSolverNullnessWarningEquivWithTypes of DisplayEnv * TType * TType * NullnessInfo * NullnessInfo * range * range + +exception ConstraintSolverNullnessWarningWithTypes of DisplayEnv * TType * TType * NullnessInfo * NullnessInfo * range * range + +exception ConstraintSolverNullnessWarningWithType of DisplayEnv * TType * NullnessInfo * range * range + +exception ConstraintSolverNullnessWarning of string * range * range exception ConstraintSolverError of string * range * range @@ -202,6 +268,7 @@ type ConstraintSolverState = /// Checks to run after all inference is complete. PostInferenceChecksFinal: ResizeArray unit> + WarnWhenUsingWithoutNullOnAWithNullTarget: string option } static member New(g, amap, infoReader, tcVal) = @@ -211,7 +278,8 @@ type ConstraintSolverState = InfoReader = infoReader TcVal = tcVal PostInferenceChecksPreDefaults = ResizeArray() - PostInferenceChecksFinal = ResizeArray() } + PostInferenceChecksFinal = ResizeArray() + WarnWhenUsingWithoutNullOnAWithNullTarget = None } member this.PushPostInferenceCheck (preDefaults, check) = if preDefaults then @@ -240,6 +308,9 @@ type ConstraintSolverEnv = // Is this speculative, with a trace allowing undo, and trial method overload resolution IsSpeculativeForMethodOverloading: bool + // Can this ignore the 'must support null' constraint, e.g. in a mutable assignment scenario + IsSupportsNullFlex: bool + /// Indicates that when unifying ty1 = ty2, only type variables in ty1 may be solved. Constraints /// can't be added to type variables in ty2 MatchingOnly: bool @@ -276,6 +347,7 @@ let MakeConstraintSolverEnv contextInfo css m denv = EquivEnv = TypeEquivEnv.Empty DisplayEnv = denv IsSpeculativeForMethodOverloading = false + IsSupportsNullFlex = false ExtraRigidTypars = emptyFreeTypars } @@ -650,22 +722,23 @@ let SolveTypIsCompatFlex (csenv: ConstraintSolverEnv) trace req ty = else CompleteD -let SubstMeasureWarnIfRigid (csenv: ConstraintSolverEnv) trace (v: Typar) ms = trackErrors { - if v.Rigidity.WarnIfUnified && not (isAnyParTy csenv.g (TType_measure ms)) then - // NOTE: we grab the name eagerly to make sure the type variable prints as a type variable - let tpnmOpt = if v.IsCompilerGenerated then None else Some v.Name - do! SolveTypStaticReq csenv trace v.StaticReq (TType_measure ms) - SubstMeasure v ms - return! WarnD(NonRigidTypar(csenv.DisplayEnv, tpnmOpt, v.Range, TType_measure (Measure.Var v), TType_measure ms, csenv.m)) - else - // Propagate static requirements from 'tp' to 'ty' - do! SolveTypStaticReq csenv trace v.StaticReq (TType_measure ms) - SubstMeasure v ms - if v.Rigidity = TyparRigidity.Anon && measureEquiv csenv.g ms Measure.One then - return! WarnD(Error(FSComp.SR.csCodeLessGeneric(), v.Range)) - else - () - } +let SubstMeasureWarnIfRigid (csenv: ConstraintSolverEnv) trace (v: Typar) ms = + trackErrors { + if v.Rigidity.WarnIfUnified && not (isAnyParTy csenv.g (TType_measure ms)) then + // NOTE: we grab the name eagerly to make sure the type variable prints as a type variable + let tpnmOpt = if v.IsCompilerGenerated then None else Some v.Name + do! SolveTypStaticReq csenv trace v.StaticReq (TType_measure ms) + SubstMeasure v ms + return! WarnD(NonRigidTypar(csenv.DisplayEnv, tpnmOpt, v.Range, TType_measure (Measure.Var v), TType_measure ms, csenv.m)) + else + // Propagate static requirements from 'tp' to 'ty' + do! SolveTypStaticReq csenv trace v.StaticReq (TType_measure ms) + SubstMeasure v ms + if v.Rigidity = TyparRigidity.Anon && measureEquiv csenv.g ms Measure.One then + return! WarnD(Error(FSComp.SR.csCodeLessGeneric(), v.Range)) + else + () + } let IsRigid (csenv: ConstraintSolverEnv) (tp: Typar) = tp.Rigidity = TyparRigidity.Rigid @@ -873,111 +946,198 @@ let CheckWarnIfRigid (csenv: ConstraintSolverEnv) ty1 (r: Typar) ty = /// Add the constraint "ty1 = ty" to the constraint problem, where ty1 is a type variable. /// Propagate all effects of adding this constraint, e.g. to solve other variables -let rec SolveTyparEqualsTypePart1 (csenv: ConstraintSolverEnv) m2 (trace: OptionalTrace) ty1 r ty = trackErrors { - // The types may still be equivalent due to abbreviations, which we are trying not to eliminate - if typeEquiv csenv.g ty1 ty then () else - // The famous 'occursCheck' check to catch "infinite types" like 'a = list<'a> - see also https://github.com/dotnet/fsharp/issues/1170 - if occursCheck csenv.g r ty then return! ErrorD (ConstraintSolverInfiniteTypes(csenv.DisplayEnv, csenv.eContextInfo, ty1, ty, csenv.m, m2)) else - // Note: warn _and_ continue! - do! CheckWarnIfRigid csenv ty1 r ty - // Record the solution before we solve the constraints, since - // We may need to make use of the equation when solving the constraints. - // Record a entry in the undo trace if one is provided - trace.Exec (fun () -> r.typar_solution <- Some ty) (fun () -> r.typar_solution <- None) - } - -and SolveTyparEqualsTypePart2 (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) (r: Typar) ty = trackErrors { - // Only solve constraints if this is not an error var - if r.IsFromError then () else - - // Check to see if this type variable is relevant to any trait constraints. - // If so, re-solve the relevant constraints. - if csenv.SolverState.ExtraCxs.ContainsKey r.Stamp then - do! RepeatWhileD ndeep (fun ndeep -> SolveRelevantMemberConstraintsForTypar csenv ndeep PermitWeakResolution.No trace r) - - // Re-solve the other constraints associated with this type variable - return! SolveTypMeetsTyparConstraints csenv ndeep m2 trace ty r +let rec SolveTyparEqualsTypePart1 (csenv: ConstraintSolverEnv) m2 (trace: OptionalTrace) ty1 r ty = + trackErrors { + // The types may still be equivalent due to abbreviations, which we are trying not to eliminate + if typeEquiv csenv.g ty1 ty then () else + // The famous 'occursCheck' check to catch "infinite types" like 'a = list<'a> - see also https://github.com/dotnet/fsharp/issues/1170 + if occursCheck csenv.g r ty then return! ErrorD (ConstraintSolverInfiniteTypes(csenv.DisplayEnv, csenv.eContextInfo, ty1, ty, csenv.m, m2)) else + // Note: warn _and_ continue! + do! CheckWarnIfRigid csenv ty1 r ty + // Record the solution before we solve the constraints, since + // We may need to make use of the equation when solving the constraints. + // Record a entry in the undo trace if one is provided + + //let ty1AllowsNull = r.Constraints |> List.exists (function | TyparConstraint.SupportsNull _ -> true | _ -> false ) + //let tyAllowsNull() = TypeNullIsExtraValueNew csenv.g m2 ty + //if ty1AllowsNull && not (tyAllowsNull()) then + // trace.Exec (fun () -> r.typar_solution <- Some (ty |> replaceNullnessOfTy csenv.g.knownWithNull)) (fun () -> r.typar_solution <- None) + //else + // trace.Exec (fun () -> r.typar_solution <- Some ty) (fun () -> r.typar_solution <- None) + trace.Exec (fun () -> r.typar_solution <- Some ty) (fun () -> r.typar_solution <- None) + } + +and SolveTyparEqualsTypePart2 (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) (r: Typar) ty = + trackErrors { + // Only solve constraints if this is not an error var + if r.IsFromError then () else - } + // Check to see if this type variable is relevant to any trait constraints. + // If so, re-solve the relevant constraints. + if csenv.SolverState.ExtraCxs.ContainsKey r.Stamp then + do! RepeatWhileD ndeep (fun ndeep -> SolveRelevantMemberConstraintsForTypar csenv ndeep PermitWeakResolution.No trace r) -/// Apply the constraints on 'typar' to the type 'ty' -and SolveTypMeetsTyparConstraints (csenv: ConstraintSolverEnv) ndeep m2 trace ty (r: Typar) = trackErrors { - let g = csenv.g + // Re-solve the other constraints associated with this type variable + return! SolveTypMeetsTyparConstraints csenv ndeep m2 trace ty r - // Propagate compat flex requirements from 'tp' to 'ty' - do! SolveTypIsCompatFlex csenv trace r.IsCompatFlex ty + } - // Propagate dynamic requirements from 'tp' to 'ty' - do! SolveTypDynamicReq csenv trace r.DynamicReq ty +/// Apply the constraints on 'typar' to the type 'ty' +and SolveTypMeetsTyparConstraints (csenv: ConstraintSolverEnv) ndeep m2 trace ty (r: Typar) = + trackErrors { + let g = csenv.g - // Propagate static requirements from 'tp' to 'ty' - do! SolveTypStaticReq csenv trace r.StaticReq ty + // Propagate compat flex requirements from 'tp' to 'ty' + do! SolveTypIsCompatFlex csenv trace r.IsCompatFlex ty - if not (g.langVersion.SupportsFeature LanguageFeature.InterfacesWithAbstractStaticMembers) then - // Propagate static requirements from 'tp' to 'ty' - // - // If IWSAMs are not supported then this is done on a per-type-variable basis when constraints - // are applied - see other calls to SolveTypStaticReq + // Propagate dynamic requirements from 'tp' to 'ty' + do! SolveTypDynamicReq csenv trace r.DynamicReq ty + + // Propagate static requirements from 'tp' to 'ty' do! SolveTypStaticReq csenv trace r.StaticReq ty - // Solve constraints on 'tp' w.r.t. 'ty' - for e in r.Constraints do - do! - match e with - | TyparConstraint.DefaultsTo (priority, dty, m) -> - if typeEquiv g ty dty then - CompleteD - else - match tryDestTyparTy g ty with - | ValueNone -> CompleteD - | ValueSome destTypar -> - AddConstraint csenv ndeep m2 trace destTypar (TyparConstraint.DefaultsTo(priority, dty, m)) - - | TyparConstraint.SupportsNull m2 -> SolveTypeUseSupportsNull csenv ndeep m2 trace ty - | TyparConstraint.IsEnum(underlyingTy, m2) -> SolveTypeIsEnum csenv ndeep m2 trace ty underlyingTy - | TyparConstraint.SupportsComparison(m2) -> SolveTypeSupportsComparison csenv ndeep m2 trace ty - | TyparConstraint.SupportsEquality(m2) -> SolveTypeSupportsEquality csenv ndeep m2 trace ty - | TyparConstraint.IsDelegate(aty, bty, m2) -> SolveTypeIsDelegate csenv ndeep m2 trace ty aty bty - | TyparConstraint.IsNonNullableStruct m2 -> SolveTypeIsNonNullableValueType csenv ndeep m2 trace ty - | TyparConstraint.IsUnmanaged m2 -> SolveTypeIsUnmanaged csenv ndeep m2 trace ty - | TyparConstraint.IsReferenceType m2 -> SolveTypeIsReferenceType csenv ndeep m2 trace ty - | TyparConstraint.RequiresDefaultConstructor m2 -> SolveTypeRequiresDefaultConstructor csenv ndeep m2 trace ty - | TyparConstraint.SimpleChoice(tys, m2) -> SolveTypeChoice csenv ndeep m2 trace ty tys - | TyparConstraint.CoercesTo(ty2, m2) -> SolveTypeSubsumesTypeKeepAbbrevs csenv ndeep m2 trace None ty2 ty - | TyparConstraint.MayResolveMember(traitInfo, m2) -> - SolveMemberConstraint csenv false PermitWeakResolution.No ndeep m2 trace traitInfo |> OperationResult.ignore - } + if not (g.langVersion.SupportsFeature LanguageFeature.InterfacesWithAbstractStaticMembers) then + // Propagate static requirements from 'tp' to 'ty' + // + // If IWSAMs are not supported then this is done on a per-type-variable basis when constraints + // are applied - see other calls to SolveTypStaticReq + do! SolveTypStaticReq csenv trace r.StaticReq ty + + // Solve constraints on 'tp' w.r.t. 'ty' + for e in r.Constraints do + do! + match e with + | TyparConstraint.DefaultsTo (priority, dty, m) -> + if typeEquiv g ty dty then + CompleteD + else + match tryDestTyparTy g ty with + | ValueNone -> CompleteD + | ValueSome destTypar -> + AddConstraint csenv ndeep m2 trace destTypar (TyparConstraint.DefaultsTo(priority, dty, m)) + + | TyparConstraint.NotSupportsNull m2 -> SolveTypeUseNotSupportsNull csenv ndeep m2 trace ty + | TyparConstraint.SupportsNull m2 -> SolveTypeUseSupportsNull csenv ndeep m2 trace ty + | TyparConstraint.IsEnum(underlyingTy, m2) -> SolveTypeIsEnum csenv ndeep m2 trace ty underlyingTy + | TyparConstraint.SupportsComparison(m2) -> SolveTypeSupportsComparison csenv ndeep m2 trace ty + | TyparConstraint.SupportsEquality(m2) -> SolveTypeSupportsEquality csenv ndeep m2 trace ty + | TyparConstraint.IsDelegate(aty, bty, m2) -> SolveTypeIsDelegate csenv ndeep m2 trace ty aty bty + | TyparConstraint.IsNonNullableStruct m2 -> SolveTypeIsNonNullableValueType csenv ndeep m2 trace ty + | TyparConstraint.IsUnmanaged m2 -> SolveTypeIsUnmanaged csenv ndeep m2 trace ty + | TyparConstraint.IsReferenceType m2 -> SolveTypeIsReferenceType csenv ndeep m2 trace ty + | TyparConstraint.RequiresDefaultConstructor m2 -> SolveTypeRequiresDefaultConstructor csenv ndeep m2 trace ty + | TyparConstraint.SimpleChoice(tys, m2) -> SolveTypeChoice csenv ndeep m2 trace ty tys + | TyparConstraint.CoercesTo(ty2, m2) -> SolveTypeSubsumesTypeKeepAbbrevs csenv ndeep m2 trace None ty2 ty + | TyparConstraint.MayResolveMember(traitInfo, m2) -> + SolveMemberConstraint csenv false PermitWeakResolution.No ndeep m2 trace traitInfo |> OperationResult.ignore + } + +and shouldWarnUselessNullCheck (csenv:ConstraintSolverEnv) = + csenv.g.checkNullness && + csenv.IsSpeculativeForMethodOverloading = false && + csenv.SolverState.WarnWhenUsingWithoutNullOnAWithNullTarget.IsSome +// nullness1: actual +// nullness2: expected +and SolveNullnessEquiv (csenv: ConstraintSolverEnv) m2 (trace: OptionalTrace) ty1 ty2 nullness1 nullness2 = + match nullness1, nullness2 with + | Nullness.Variable nv1, Nullness.Variable nv2 when nv1 === nv2 -> + CompleteD + | Nullness.Variable nv1, _ when nv1.IsSolved -> + SolveNullnessEquiv csenv m2 trace ty1 ty2 nv1.Solution nullness2 + | _, Nullness.Variable nv2 when nv2.IsSolved -> + SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nv2.Solution + | Nullness.Variable nv1, _ -> + trace.Exec (fun () -> nv1.Set nullness2) (fun () -> nv1.Unset()) + CompleteD + | _, Nullness.Variable nv2 -> + trace.Exec (fun () -> nv2.Set nullness1) (fun () -> nv2.Unset()) + CompleteD + | Nullness.Known n1, Nullness.Known n2 -> + match n1, n2 with + | NullnessInfo.AmbivalentToNull, _ -> CompleteD + | _, NullnessInfo.AmbivalentToNull -> CompleteD + | NullnessInfo.WithNull, NullnessInfo.WithNull -> CompleteD + | NullnessInfo.WithoutNull, NullnessInfo.WithoutNull -> CompleteD + // Warn for 'strict "must pass null"` APIs like Option.ofObj + | NullnessInfo.WithNull, NullnessInfo.WithoutNull when shouldWarnUselessNullCheck csenv -> + WarnD(Error(FSComp.SR.tcPassingWithoutNullToANullableExpectingFunc (csenv.SolverState.WarnWhenUsingWithoutNullOnAWithNullTarget.Value),m2)) + // Allow expected of WithNull and actual of WithoutNull except for specially marked APIs (handled above) + | NullnessInfo.WithNull, NullnessInfo.WithoutNull -> CompleteD + | _ -> + if csenv.g.checkNullness then + WarnD(ConstraintSolverNullnessWarningEquivWithTypes(csenv.DisplayEnv, ty1, ty2, n1, n2, csenv.m, m2)) + else + CompleteD -and SolveTyparEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) ty1 ty = trackErrors { - let m = csenv.m - do! DepthCheck ndeep m - match ty1 with - | TType_var (r, _) - | TType_measure (Measure.Var r) -> - do! SolveTyparEqualsTypePart1 csenv m2 trace ty1 r ty - do! SolveTyparEqualsTypePart2 csenv ndeep m2 trace r ty - | _ -> failwith "SolveTyparEqualsType" +// nullness1: target +// nullness2: source +and SolveNullnessSubsumesNullness (csenv: ConstraintSolverEnv) m2 (trace: OptionalTrace) ty1 ty2 nullness1 nullness2 = + match nullness1, nullness2 with + | Nullness.Variable nv1, Nullness.Variable nv2 when nv1 === nv2 -> + CompleteD + | Nullness.Variable nv1, _ when nv1.IsSolved -> + SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 nv1.Solution nullness2 + | _, Nullness.Variable nv2 when nv2.IsSolved -> + SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 nullness1 nv2.Solution + | Nullness.Variable _nv1, Nullness.Known NullnessInfo.WithoutNull -> + CompleteD + | Nullness.Variable nv1, _ -> + trace.Exec (fun () -> nv1.Set nullness2) (fun () -> nv1.Unset()) + CompleteD + | _, Nullness.Variable nv2 -> + trace.Exec (fun () -> nv2.Set nullness1) (fun () -> nv2.Unset()) + CompleteD + | Nullness.Known n1, Nullness.Known n2 -> + match n1, n2 with + | NullnessInfo.AmbivalentToNull, _ -> CompleteD + | _, NullnessInfo.AmbivalentToNull -> CompleteD + | NullnessInfo.WithNull, NullnessInfo.WithNull -> CompleteD + | NullnessInfo.WithoutNull, NullnessInfo.WithoutNull -> CompleteD + // Warn for 'strict "must pass null"` APIs like Option.ofObj + | NullnessInfo.WithNull, NullnessInfo.WithoutNull when shouldWarnUselessNullCheck csenv -> + WarnD(Error(FSComp.SR.tcPassingWithoutNullToANullableExpectingFunc (csenv.SolverState.WarnWhenUsingWithoutNullOnAWithNullTarget.Value),m2)) + // Allow target of WithNull and actual of WithoutNull + | NullnessInfo.WithNull, NullnessInfo.WithoutNull -> + CompleteD + | NullnessInfo.WithoutNull, NullnessInfo.WithNull -> + if csenv.g.checkNullness then + WarnD(ConstraintSolverNullnessWarningWithTypes(csenv.DisplayEnv, ty1, ty2, n1, n2, csenv.m, m2)) + else + CompleteD + +and SolveTyparEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) ty1 ty = + trackErrors { + let m = csenv.m + do! DepthCheck ndeep m + match ty1 with + | TType_var (r, _) + | TType_measure (Measure.Var r) -> + do! SolveTyparEqualsTypePart1 csenv m2 trace ty1 r ty + do! SolveTyparEqualsTypePart2 csenv ndeep m2 trace r ty + | _ -> failwith "SolveTyparEqualsType" } // Like SolveTyparEqualsType but asserts all typar equalities simultaneously instead of one by one -and SolveTyparsEqualTypes (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) tpTys tys = trackErrors { - do! (tpTys, tys) ||> Iterate2D (fun tpTy ty -> - match tpTy with - | TType_var (r, _) - | TType_measure (Measure.Var r) -> - SolveTyparEqualsTypePart1 csenv m2 trace tpTy r ty - | _ -> - failwith "SolveTyparsEqualTypes") - - do! (tpTys, tys) ||> Iterate2D (fun tpTy ty -> - match tpTy with - | TType_var (r, _) - | TType_measure (Measure.Var r) -> - SolveTyparEqualsTypePart2 csenv ndeep m2 trace r ty - | _ -> - failwith "SolveTyparsEqualTypes") - } +and SolveTyparsEqualTypes (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) tpTys tys = + trackErrors { + do! Iterate2D ( + fun tpTy ty -> + match tpTy with + | TType_var (r, _) + | TType_measure (Measure.Var r) -> + SolveTyparEqualsTypePart1 csenv m2 trace tpTy r ty + | _ -> + failwith "SolveTyparsEqualTypes") tpTys tys + do! Iterate2D ( + fun tpTy ty -> + match tpTy with + | TType_var (r, _) + | TType_measure (Measure.Var r) -> + SolveTyparEqualsTypePart2 csenv ndeep m2 trace r ty + | _ -> + failwith "SolveTyparsEqualTypes") tpTys tys + } and SolveAnonInfoEqualsAnonInfo (csenv: ConstraintSolverEnv) m2 (anonInfo1: AnonRecdTypeInfo) (anonInfo2: AnonRecdTypeInfo) = if evalTupInfoIsStruct anonInfo1.TupInfo <> evalTupInfoIsStruct anonInfo2.TupInfo then @@ -1070,59 +1230,153 @@ and SolveTypeEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTr let sty1 = stripTyEqnsA csenv.g canShortcut ty1 let sty2 = stripTyEqnsA csenv.g canShortcut ty2 - match sty1, sty2 with + let csenv = + match ty1 with + | TType.TType_var(r,_) when r.typar_flags.IsSupportsNullFlex -> + { csenv with IsSupportsNullFlex = true} + | _ -> csenv + match sty1, sty2 with // type vars inside forall-types may be alpha-equivalent - | TType_var (tp1, _), TType_var (tp2, _) when typarEq tp1 tp2 || (match aenv.EquivTypars.TryFind tp1 with | Some tpTy1 when typeEquiv g tpTy1 ty2 -> true | _ -> false) -> - CompleteD + | TType_var (tp1, nullness1), TType_var (tp2, nullness2) when typarEq tp1 tp2 || (match aenv.EquivTypars.TryFind tp1 with | Some tpTy1 when typeEquiv g tpTy1 ty2 -> true | _ -> false) -> + SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nullness2 + + | TType_var (tp1, nullness1), TType_var (tp2, nullness2) when PreferUnifyTypar tp1 tp2 -> + match nullness1.TryEvaluate(), nullness2.TryEvaluate() with + // Unifying 'T1? and 'T2? + | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithNull -> + SolveTyparEqualsType csenv ndeep m2 trace sty1 (TType_var (tp2, g.knownWithoutNull)) + | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithoutNull -> + let tpNew = NewCompGenTypar(TyparKind.Type, TyparRigidity.Flexible, TyparStaticReq.None, TyparDynamicReq.No, false) + trackErrors { + do! SolveTypeEqualsType csenv ndeep m2 trace cxsln sty2 (TType_var(tpNew, g.knownWithNull)) + do! SolveTypeEqualsType csenv ndeep m2 trace cxsln (TType_var(tpNew, g.knownWithoutNull)) sty1 + } + //// Unifying 'T1 % and 'T2 % + //| ValueSome NullnessInfo.AmbivalentToNull, ValueSome NullnessInfo.AmbivalentToNull -> + // SolveTyparEqualsType csenv ndeep m2 trace sty1 (TType_var (tp2, g.knownWithoutNull)) + | _ -> + trackErrors { + do! SolveTyparEqualsType csenv ndeep m2 trace sty1 ty2 + let nullnessAfterSolution1 = combineNullness (nullnessOfTy g sty1) nullness1 + do! SolveNullnessEquiv csenv m2 trace ty1 ty2 nullnessAfterSolution1 nullness2 + } - // 'v1 = 'v2 - | TType_var (tp1, _), TType_var (tp2, _) when PreferUnifyTypar tp1 tp2 -> - SolveTyparEqualsType csenv ndeep m2 trace sty1 ty2 - // 'v1 = 'v2 - | TType_var (tp1, _), TType_var (tp2, _) when not csenv.MatchingOnly && PreferUnifyTypar tp2 tp1 -> - SolveTyparEqualsType csenv ndeep m2 trace sty2 ty1 + | TType_var (tp1, nullness1), TType_var (tp2, nullness2) when not csenv.MatchingOnly && PreferUnifyTypar tp2 tp1 -> + match nullness1.TryEvaluate(), nullness2.TryEvaluate() with + // Unifying 'T1? and 'T2? + | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithNull -> + SolveTyparEqualsType csenv ndeep m2 trace sty2 (TType_var (tp1, g.knownWithoutNull)) + | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithoutNull -> + let tpNew = NewCompGenTypar(TyparKind.Type, TyparRigidity.Flexible, TyparStaticReq.None, TyparDynamicReq.No, false) + trackErrors { + do! SolveTypeEqualsType csenv ndeep m2 trace cxsln sty2 (TType_var(tpNew, g.knownWithNull)) + do! SolveTypeEqualsType csenv ndeep m2 trace cxsln (TType_var(tpNew, g.knownWithoutNull)) sty1 + } + //// Unifying 'T1 % and 'T2 % + //| ValueSome NullnessInfo.AmbivalentToNull, ValueSome NullnessInfo.AmbivalentToNull -> + // SolveTyparEqualsType csenv ndeep m2 trace sty2 (TType_var (tp1, g.knownWithoutNull)) + | _ -> + // Unifying 'T1 ? and 'T2 % + // Unifying 'T1 % and 'T2 ? + trackErrors { + do! SolveTyparEqualsType csenv ndeep m2 trace sty2 ty1 + let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2 + do! SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nullnessAfterSolution2 + } - | TType_var (r, _), _ when not (IsRigid csenv r) -> - SolveTyparEqualsType csenv ndeep m2 trace sty1 ty2 + | TType_var (tp1, nullness1), _ when not (IsRigid csenv tp1) -> + match nullness1.TryEvaluate(), (nullnessOfTy g sty2).TryEvaluate() with + // Unifying 'T1? and 'T2? + | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithNull -> + SolveTyparEqualsType csenv ndeep m2 trace sty1 (replaceNullnessOfTy g.knownWithoutNull sty2) + | ValueSome NullnessInfo.WithoutNull, ValueSome NullnessInfo.WithoutNull when + csenv.IsSupportsNullFlex && + isAppTy g sty2 && + tp1.Constraints |> List.exists (function TyparConstraint.SupportsNull _ -> true | _ -> false) -> + let tpNew = NewCompGenTypar(TyparKind.Type, TyparRigidity.Flexible, TyparStaticReq.None, TyparDynamicReq.No, false) + trackErrors { + do! SolveTypeEqualsType csenv ndeep m2 trace cxsln (TType_var(tpNew, g.knownWithoutNull)) sty2 + do! SolveTypeEqualsType csenv ndeep m2 trace cxsln ty1 (TType_var(tpNew, g.knownWithNull)) + } + // Unifying 'T1 % and 'T2 % + //| ValueSome NullnessInfo.AmbivalentToNull, ValueSome NullnessInfo.AmbivalentToNull -> + // SolveTyparEqualsType csenv ndeep m2 trace sty1 (replaceNullnessOfTy g.knownWithoutNull sty2) + | _ -> + trackErrors { + do! SolveTyparEqualsType csenv ndeep m2 trace sty1 ty2 + let nullnessAfterSolution1 = combineNullness (nullnessOfTy g sty1) nullness1 + do! SolveNullnessEquiv csenv m2 trace ty1 ty2 nullnessAfterSolution1 (nullnessOfTy g sty2) + } - | _, TType_var (r, _) when not csenv.MatchingOnly && not (IsRigid csenv r) -> - SolveTyparEqualsType csenv ndeep m2 trace sty2 ty1 + | _, TType_var (tp2, nullness2) when not csenv.MatchingOnly && not (IsRigid csenv tp2) -> + match (nullnessOfTy g sty1).TryEvaluate(), nullness2.TryEvaluate() with + // Unifying 'T1? and 'T2? + | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithNull -> + SolveTyparEqualsType csenv ndeep m2 trace sty2 (replaceNullnessOfTy g.knownWithoutNull sty1) + // Unifying 'T1 % and 'T2 % + //| ValueSome NullnessInfo.AmbivalentToNull, ValueSome NullnessInfo.AmbivalentToNull -> + // SolveTyparEqualsType csenv ndeep m2 trace sty2 (replaceNullnessOfTy g.knownWithoutNull sty1) + | _ -> + trackErrors { + do! SolveTyparEqualsType csenv ndeep m2 trace sty2 ty1 + let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2 + do! SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) nullnessAfterSolution2 + } // Catch float<_>=float<1>, float32<_>=float32<1> and decimal<_>=decimal<1> - | _, TType_app (tc2, [ms], _) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty1 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms])) -> - SolveTypeEqualsType csenv ndeep m2 trace None ms (TType_measure Measure.One) + | (_, TType_app (tc2, [ms2], _)) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty1 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms2])) -> + trackErrors { + do! SolveTypeEqualsType csenv ndeep m2 trace None (TType_measure Measure.One) ms2 + do! SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2) + } - | TType_app (tc2, [ms], _), _ when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms])) -> - SolveTypeEqualsType csenv ndeep m2 trace None ms (TType_measure Measure.One) + | (TType_app (tc1, [ms1], _), _) when (tc1.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc1 [ms1])) -> + trackErrors { + do! SolveTypeEqualsType csenv ndeep m2 trace None ms1 (TType_measure Measure.One) + do! SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2) + } | TType_app (tc1, l1, _), TType_app (tc2, l2, _) when tyconRefEq g tc1 tc2 -> - SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2 - + trackErrors { + do! SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2 + do! SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2) + } | TType_app _, TType_app _ -> localAbortD - | TType_tuple (tupInfo1, l1), TType_tuple (tupInfo2, l2) -> - if evalTupInfoIsStruct tupInfo1 <> evalTupInfoIsStruct tupInfo2 then ErrorD (ConstraintSolverError(FSComp.SR.tcTupleStructMismatch(), csenv.m, m2)) else - SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2 + | TType_tuple (tupInfo1, l1), TType_tuple (tupInfo2, l2) -> + if evalTupInfoIsStruct tupInfo1 <> evalTupInfoIsStruct tupInfo2 then + ErrorD (ConstraintSolverError(FSComp.SR.tcTupleStructMismatch(), csenv.m, m2)) + else + SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2 - | TType_anon (anonInfo1, l1),TType_anon (anonInfo2, l2) -> trackErrors { + | TType_anon (anonInfo1, l1),TType_anon (anonInfo2, l2) -> + trackErrors { do! SolveAnonInfoEqualsAnonInfo csenv m2 anonInfo1 anonInfo2 do! SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2 - } - | TType_fun (domainTy1, rangeTy1, _), TType_fun (domainTy2, rangeTy2, _) -> - SolveFunTypeEqn csenv ndeep m2 trace None domainTy1 domainTy2 rangeTy1 rangeTy2 + } + + | TType_fun (domainTy1, rangeTy1, nullness1), TType_fun (domainTy2, rangeTy2, nullness2) -> + trackErrors { + do! SolveFunTypeEqn csenv ndeep m2 trace None domainTy1 domainTy2 rangeTy1 rangeTy2 + do! SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nullness2 + } | TType_measure ms1, TType_measure ms2 -> UnifyMeasures csenv trace ms1 ms2 - | TType_forall(tps1, bodyTy1), TType_forall(tps2, bodyTy2) -> - if tps1.Length <> tps2.Length then localAbortD else - let aenv = aenv.BindEquivTypars tps1 tps2 - let csenv = {csenv with EquivEnv = aenv } - if not (typarsAEquiv g aenv tps1 tps2) then localAbortD else - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace bodyTy1 bodyTy2 + | TType_forall(tps1, bodyTy1), TType_forall(tps2, bodyTy2) -> + if tps1.Length <> tps2.Length then + localAbortD + else + let aenv = aenv.BindEquivTypars tps1 tps2 + let csenv = {csenv with EquivEnv = aenv } + if not (typarsAEquiv g aenv tps1 tps2) then + localAbortD + else + SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace bodyTy1 bodyTy2 | TType_ucase (uc1, l1), TType_ucase (uc2, l2) when g.unionCaseRefEq uc1 uc2 -> SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2 @@ -1140,14 +1394,14 @@ and private SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln t | LocallyAbortOperationThatLosesAbbrevs -> ErrorD(ConstraintSolverTypesNotInEqualityRelation(csenv.DisplayEnv, ty1, ty2, csenv.m, m2, csenv.eContextInfo)) | err -> ErrorD err) -and SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln origl1 origl2 = - match origl1, origl2 with - | [], [] -> CompleteD - | _ -> +and SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln origl1 origl2 = + match origl1, origl2 with + | [], [] -> CompleteD + | _ -> // We unwind Iterate2D by hand here for performance reasons. - let rec loop l1 l2 = - match l1, l2 with - | [], [] -> CompleteD + let rec loop l1 l2 = + match l1, l2 with + | [], [] -> CompleteD | h1 :: t1, h2 :: t2 when t1.Length = t2.Length -> trackErrors { do! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln h1 h2 @@ -1157,10 +1411,43 @@ and SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln origl1 origl2 = ErrorD(ConstraintSolverTupleDiffLengths(csenv.DisplayEnv, csenv.eContextInfo, origl1, origl2, csenv.m, m2)) loop origl1 origl2 -and SolveFunTypeEqn csenv ndeep m2 trace cxsln domainTy1 domainTy2 rangeTy1 rangeTy2 = trackErrors { - do! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln domainTy1 domainTy2 - return! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln rangeTy1 rangeTy2 - } +and SolveTypeEqualsTypeWithContravarianceEqns (csenv:ConstraintSolverEnv) ndeep m2 trace cxsln origl1 origl2 typars = + let isContravariant (t:Typar) = + t.typar_opt_data + |> Option.map (fun d -> d.typar_is_contravariant) + |> Option.defaultValue(false) + + match origl1, origl2, typars with + | [], [], [] -> CompleteD + | _ -> + // We unwind Iterate2D by hand here for performance reasons. + let rec loop l1 l2 tps = + match l1, l2, tps with + | [], [], [] -> CompleteD + | h1 :: t1, h2 :: t2, hTp :: tTps when t1.Length = t2.Length && t1.Length = tTps.Length -> + trackErrors { + let h1 = + // For contravariant typars (` in C#'), if the required type is WithNull, the actual type can have any nullness it wants + // Without this added logic, their nullness would be forced to be equal. + if isContravariant hTp && (nullnessOfTy csenv.g h2).TryEvaluate() = ValueSome NullnessInfo.WithNull then + replaceNullnessOfTy csenv.g.knownWithNull h1 + else + h1 + + do! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln h1 h2 + do! loop t1 t2 tTps + } + | _ -> + ErrorD(ConstraintSolverTupleDiffLengths(csenv.DisplayEnv, csenv.eContextInfo, origl1, origl2, csenv.m, m2)) + loop origl1 origl2 typars + +and SolveFunTypeEqn csenv ndeep m2 trace cxsln domainTy1 domainTy2 rangeTy1 rangeTy2 = + trackErrors { + let g = csenv.g + let domainTy2 = reqTyForArgumentNullnessInference g domainTy1 domainTy2 + do! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln domainTy2 domainTy1 + return! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln rangeTy1 rangeTy2 + } // ty1: expected // ty2: actual @@ -1181,60 +1468,83 @@ and SolveTypeSubsumesType (csenv: ConstraintSolverEnv) ndeep m2 (trace: Optional let denv = csenv.DisplayEnv match sty1, sty2 with - | TType_var (tp1, _), _ -> + | TType_var (tp1, nullness1) , _ -> match aenv.EquivTypars.TryFind tp1 with | Some tpTy1 -> SolveTypeSubsumesType csenv ndeep m2 trace cxsln tpTy1 ty2 | _ -> match sty2 with - | TType_var (r2, _) when typarEq tp1 r2 -> CompleteD - | TType_var (r, _) when not csenv.MatchingOnly -> SolveTyparSubtypeOfType csenv ndeep m2 trace r ty1 + | TType_var (r2, nullness2) when typarEq tp1 r2 -> + SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nullness2 + | TType_var (r2, nullness2) when not csenv.MatchingOnly -> + trackErrors { + do! SolveTyparSubtypeOfType csenv ndeep m2 trace r2 ty1 + let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2 + do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 nullness1 nullnessAfterSolution2 + } | _ -> SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ty1 ty2 - | _, TType_var (r, _) when not csenv.MatchingOnly -> - SolveTyparSubtypeOfType csenv ndeep m2 trace r ty1 - - | TType_tuple (tupInfo1, l1), TType_tuple (tupInfo2, l2) -> - if evalTupInfoIsStruct tupInfo1 <> evalTupInfoIsStruct tupInfo2 then ErrorD (ConstraintSolverError(FSComp.SR.tcTupleStructMismatch(), csenv.m, m2)) else - SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2 (* nb. can unify since no variance *) + | _, TType_var (r2, nullness2) when not csenv.MatchingOnly -> + trackErrors { + do! SolveTyparSubtypeOfType csenv ndeep m2 trace r2 ty1 + let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2 + do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) nullnessAfterSolution2 + } - | TType_anon (anonInfo1, l1), TType_anon (anonInfo2, l2) -> trackErrors { + | TType_tuple (tupInfo1, l1), TType_tuple (tupInfo2, l2) -> + if evalTupInfoIsStruct tupInfo1 <> evalTupInfoIsStruct tupInfo2 then + ErrorD (ConstraintSolverError(FSComp.SR.tcTupleStructMismatch(), csenv.m, m2)) + else + SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2 (* nb. can unify since no variance *) + | TType_fun (domainTy1, rangeTy1, nullness1), TType_fun (domainTy2, rangeTy2, nullness2) -> + // nb. can unify since no variance + trackErrors { + do! SolveFunTypeEqn csenv ndeep m2 trace cxsln domainTy1 domainTy2 rangeTy1 rangeTy2 + do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 nullness1 nullness2 + } + | TType_anon (anonInfo1, l1), TType_anon (anonInfo2, l2) -> + trackErrors { do! SolveAnonInfoEqualsAnonInfo csenv m2 anonInfo1 anonInfo2 - do! SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2 (* nb. can unify since no variance *) + do! SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2 } - - | TType_fun (domainTy1, rangeTy1, _), TType_fun (domainTy2, rangeTy2, _) -> - SolveFunTypeEqn csenv ndeep m2 trace cxsln domainTy1 domainTy2 rangeTy1 rangeTy2 (* nb. can unify since no variance *) - | TType_measure ms1, TType_measure ms2 -> UnifyMeasures csenv trace ms1 ms2 // Enforce the identities float=float<1>, float32=float32<1> and decimal=decimal<1> - | _, TType_app (tc2, [ms], _) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty1 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms])) -> - SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms (TType_measure Measure.One) + | _, TType_app (tc2, [ms2], _) when tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty1 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms2]) -> + trackErrors { + do! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms2 (TType_measure Measure.One) + do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2) + } - | TType_app (tc2, [ms], _), _ when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms])) -> - SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms (TType_measure Measure.One) + | TType_app (tc1, [ms1], _), _ when tc1.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc1 [ms1]) -> + trackErrors { + do! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms1 (TType_measure Measure.One) + do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2) + } // Special subsumption rule for byref tags - | TType_app (tc1, l1, _), TType_app (tc2, l2, _) when tyconRefEq g tc1 tc2 && g.byref2_tcr.CanDeref && tyconRefEq g g.byref2_tcr tc1 -> - match l1, l2 with + | TType_app (tc1, l1, _) , TType_app (tc2, l2, _) when tyconRefEq g tc1 tc2 && g.byref2_tcr.CanDeref && tyconRefEq g g.byref2_tcr tc1 -> + match l1, l2 with | [ h1; tag1 ], [ h2; tag2 ] -> trackErrors { do! SolveTypeEqualsType csenv ndeep m2 trace None h1 h2 - match stripTyEqnsA csenv.g canShortcut tag1, stripTyEqnsA csenv.g canShortcut tag2 with - | TType_app(tagc1, [], _), TType_app(tagc2, [], _) - when (tyconRefEq g tagc2 g.byrefkind_InOut_tcr && + match stripTyEqnsA csenv.g canShortcut tag1, stripTyEqnsA csenv.g canShortcut tag2 with + | TType_app(tagc1, [], _), TType_app(tagc2, [], _) + when (tyconRefEq g tagc2 g.byrefkind_InOut_tcr && (tyconRefEq g tagc1 g.byrefkind_In_tcr || tyconRefEq g tagc1 g.byrefkind_Out_tcr) ) -> () | _ -> return! SolveTypeEqualsType csenv ndeep m2 trace cxsln tag1 tag2 } - | _ -> SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2 + | _ -> SolveTypeEqualsTypeWithContravarianceEqns csenv ndeep m2 trace cxsln l1 l2 tc1.TyparsNoRange - | TType_app (tc1, l1, _), TType_app (tc2, l2, _) when tyconRefEq g tc1 tc2 -> - SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2 + | TType_app (tc1, l1, _) , TType_app (tc2, l2, _) when tyconRefEq g tc1 tc2 -> + trackErrors { + do! SolveTypeEqualsTypeWithContravarianceEqns csenv ndeep m2 trace cxsln l1 l2 tc1.TyparsNoRange + do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2) + } | TType_ucase (uc1, l1), TType_ucase (uc2, l2) when g.unionCaseRefEq uc1 uc2 -> SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2 - | _ -> + | _ -> // By now we know the type is not a variable type // C :> obj ---> @@ -1298,7 +1608,7 @@ and DepthCheck ndeep m = and SolveDimensionlessNumericType (csenv: ConstraintSolverEnv) ndeep m2 trace ty = match getMeasureOfType csenv.g ty with | Some (tcref, _) -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace ty (mkAppTy tcref [TType_measure Measure.One]) + SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace ty (mkWoNullAppTy tcref [TType_measure Measure.One]) | None -> CompleteD @@ -1310,434 +1620,439 @@ and SolveDimensionlessNumericType (csenv: ConstraintSolverEnv) ndeep m2 trace ty /// will deal with the problem. /// /// 2. Some additional solutions are forced prior to generalization (permitWeakResolution= Yes or YesDuringCodeGen). See above -and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload permitWeakResolution ndeep m2 trace traitInfo : OperationResult = trackErrors { - let (TTrait(supportTys, nm, memFlags, traitObjAndArgTys, retTy, source, sln)) = traitInfo - // Do not re-solve if already solved - if sln.Value.IsSome then return true else +and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload permitWeakResolution ndeep m2 trace traitInfo : OperationResult = + trackErrors { + let (TTrait(supportTys, nm, memFlags, traitObjAndArgTys, retTy, source, sln)) = traitInfo + // Do not re-solve if already solved + if sln.Value.IsSome then return true else - let g = csenv.g - let m = csenv.m - let amap = csenv.amap - let aenv = csenv.EquivEnv - let denv = csenv.DisplayEnv + let g = csenv.g + let m = csenv.m + let amap = csenv.amap + let aenv = csenv.EquivEnv + let denv = csenv.DisplayEnv - let ndeep = ndeep + 1 - do! DepthCheck ndeep m + let ndeep = ndeep + 1 + do! DepthCheck ndeep m - // Remove duplicates from the set of types in the support - let supportTys = ListSet.setify (typeAEquiv g aenv) supportTys + // Remove duplicates from the set of types in the support + let supportTys = ListSet.setify (typeAEquiv g aenv) supportTys - // Rebuild the trait info after removing duplicates - let traitInfo = traitInfo.WithSupportTypes supportTys - let retTy = GetFSharpViewOfReturnType g retTy - - // Assert the object type if the constraint is for an instance member - if memFlags.IsInstance then - match supportTys, traitObjAndArgTys with - | [ty], h :: _ -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace h ty - | _ -> do! ErrorD (ConstraintSolverError(FSComp.SR.csExpectedArguments(), m, m2)) - - // Trait calls are only supported on pseudo type (variables) - if not (g.langVersion.SupportsFeature LanguageFeature.InterfacesWithAbstractStaticMembers) then - for e in supportTys do - do! SolveTypStaticReq csenv trace TyparStaticReq.HeadType e - - // SRTP constraints on rigid type parameters do not need to be solved - let isRigid = - supportTys |> List.forall (fun ty -> - match tryDestTyparTy g ty with - | ValueSome tp -> - match tp.Rigidity with - | TyparRigidity.Rigid - | TyparRigidity.WillBeRigid -> true - | _ -> false - | ValueNone -> false) + // Rebuild the trait info after removing duplicates + let traitInfo = traitInfo.WithSupportTypes supportTys + let retTy = GetFSharpViewOfReturnType g retTy + + // Assert the object type if the constraint is for an instance member + if memFlags.IsInstance then + match supportTys, traitObjAndArgTys with + | [ty], h :: _ -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace h ty + | _ -> do! ErrorD (ConstraintSolverError(FSComp.SR.csExpectedArguments(), m, m2)) + + // Trait calls are only supported on pseudo type (variables) + if not (g.langVersion.SupportsFeature LanguageFeature.InterfacesWithAbstractStaticMembers) then + for e in supportTys do + do! SolveTypStaticReq csenv trace TyparStaticReq.HeadType e + + // SRTP constraints on rigid type parameters do not need to be solved + let isRigid = + supportTys |> List.forall (fun ty -> + match tryDestTyparTy g ty with + | ValueSome tp -> + match tp.Rigidity with + | TyparRigidity.Rigid + | TyparRigidity.WillBeRigid -> true + | _ -> false + | ValueNone -> false) - let argTys = if memFlags.IsInstance then List.tail traitObjAndArgTys else traitObjAndArgTys + let argTys = if memFlags.IsInstance then List.tail traitObjAndArgTys else traitObjAndArgTys - let minfos = GetRelevantMethodsForTrait csenv permitWeakResolution nm traitInfo - - let! res = - trackErrors { - match minfos, supportTys, memFlags.IsInstance, nm, argTys with - | _, _, false, ("op_Division" | "op_Multiply"), [argTy1;argTy2] - when - // This simulates the existence of - // float * float -> float - // float32 * float32 -> float32 - // float<'u> * float<'v> -> float<'u 'v> - // float32<'u> * float32<'v> -> float32<'u 'v> - // decimal<'u> * decimal<'v> -> decimal<'u 'v> - // decimal<'u> * decimal -> decimal<'u> - // float32<'u> * float32<'v> -> float32<'u 'v> - // int * int -> int - // int64 * int64 -> int64 - // - // The rule is triggered by these sorts of inputs when permitWeakResolution=false - // float * float - // float * float32 // will give error - // decimal * decimal - // decimal * decimal <-- Note this one triggers even though "decimal" has some possibly-relevant methods - // float * Matrix // the rule doesn't trigger for this one since Matrix has overloads we can use and we prefer those instead - // float * Matrix // the rule doesn't trigger for this one since Matrix has overloads we can use and we prefer those instead - // - // The rule is triggered by these sorts of inputs when permitWeakResolution=true - // float * 'a - // 'a * float - // decimal<'u> * 'a - (let checkRuleAppliesInPreferenceToMethods argTy1 argTy2 = - // Check that at least one of the argument types is numeric - IsNumericOrIntegralEnumType g argTy1 && - // Check the other type is nominal, unless using weak resolution - IsBinaryOpOtherArgType g permitWeakResolution argTy2 && - // This next condition checks that either - // - Neither type contributes any methods OR - // - We have the special case "decimal<_> * decimal". In this case we have some - // possibly-relevant methods from "decimal" but we ignore them in this case. - (isNil minfos || (Option.isSome (getMeasureOfType g argTy1) && isDecimalTy g argTy2)) in - - checkRuleAppliesInPreferenceToMethods argTy1 argTy2 || - checkRuleAppliesInPreferenceToMethods argTy2 argTy1) -> - - match getMeasureOfType g argTy1 with - | Some (tcref, ms1) -> - let ms2 = freshMeasure () - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 (mkAppTy tcref [TType_measure ms2]) - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkAppTy tcref [TType_measure (Measure.Prod(ms1, if nm = "op_Multiply" then ms2 else Measure.Inv ms2))]) - return TTraitBuiltIn - - | _ -> - - match getMeasureOfType g argTy2 with - | Some (tcref, ms2) -> - let ms1 = freshMeasure () - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy1 (mkAppTy tcref [TType_measure ms1]) - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkAppTy tcref [TType_measure (Measure.Prod(ms1, if nm = "op_Multiply" then ms2 else Measure.Inv ms2))]) - return TTraitBuiltIn + let minfos = GetRelevantMethodsForTrait csenv permitWeakResolution nm traitInfo - | _ -> + let! res = + trackErrors { + match minfos, supportTys, memFlags.IsInstance, nm, argTys with + | _, _, false, ("op_Division" | "op_Multiply"), [argTy1;argTy2] + when + // This simulates the existence of + // float * float -> float + // float32 * float32 -> float32 + // float<'u> * float<'v> -> float<'u 'v> + // float32<'u> * float32<'v> -> float32<'u 'v> + // decimal<'u> * decimal<'v> -> decimal<'u 'v> + // decimal<'u> * decimal -> decimal<'u> + // float32<'u> * float32<'v> -> float32<'u 'v> + // int * int -> int + // int64 * int64 -> int64 + // + // The rule is triggered by these sorts of inputs when permitWeakResolution=false + // float * float + // float * float32 // will give error + // decimal * decimal + // decimal * decimal <-- Note this one triggers even though "decimal" has some possibly-relevant methods + // float * Matrix // the rule doesn't trigger for this one since Matrix has overloads we can use and we prefer those instead + // float * Matrix // the rule doesn't trigger for this one since Matrix has overloads we can use and we prefer those instead + // + // The rule is triggered by these sorts of inputs when permitWeakResolution=true + // float * 'a + // 'a * float + // decimal<'u> * 'a + (let checkRuleAppliesInPreferenceToMethods argTy1 argTy2 = + // Check that at least one of the argument types is numeric + IsNumericOrIntegralEnumType g argTy1 && + // Check the other type is nominal, unless using weak resolution + IsBinaryOpOtherArgType g permitWeakResolution argTy2 && + // This next condition checks that either + // - Neither type contributes any methods OR + // - We have the special case "decimal<_> * decimal". In this case we have some + // possibly-relevant methods from "decimal" but we ignore them in this case. + (isNil minfos || (Option.isSome (getMeasureOfType g argTy1) && isDecimalTy g argTy2)) in + + checkRuleAppliesInPreferenceToMethods argTy1 argTy2 || + checkRuleAppliesInPreferenceToMethods argTy2 argTy1) -> + + match getMeasureOfType g argTy1 with + | Some (tcref, ms1) -> + let ms2 = freshMeasure () + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 (mkWoNullAppTy tcref [TType_measure ms2]) + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkWoNullAppTy tcref [TType_measure (Measure.Prod(ms1, if nm = "op_Multiply" then ms2 else Measure.Inv ms2))]) + return TTraitBuiltIn - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1 - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1 - return TTraitBuiltIn - - | _, _, false, ("op_Addition" | "op_Subtraction" | "op_Modulus"), [argTy1;argTy2] - when // Ignore any explicit +/- overloads from any basic integral types - (minfos |> List.forall (fun (_, minfo) -> isIntegerTy g minfo.ApparentEnclosingType ) && - ( IsAddSubModType nm g argTy1 && IsBinaryOpOtherArgType g permitWeakResolution argTy2 - || IsAddSubModType nm g argTy2 && IsBinaryOpOtherArgType g permitWeakResolution argTy1)) -> - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1 - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1 - return TTraitBuiltIn - - | _, _, false, ("op_LessThan" | "op_LessThanOrEqual" | "op_GreaterThan" | "op_GreaterThanOrEqual" | "op_Equality" | "op_Inequality" ), [argTy1;argTy2] - when // Ignore any explicit overloads from any basic integral types - (minfos |> List.forall (fun (_, minfo) -> isIntegerTy g minfo.ApparentEnclosingType ) && - ( IsRelationalType g argTy1 && IsBinaryOpOtherArgType g permitWeakResolution argTy2 - || IsRelationalType g argTy2 && IsBinaryOpOtherArgType g permitWeakResolution argTy1)) -> - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1 - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy g.bool_ty - return TTraitBuiltIn - - // We pretend for uniformity that the numeric types have a static property called Zero and One - // As with constants, only zero is polymorphic in its units - | [], [ty], false, "get_Zero", [] - when isNumericType g ty || isCharTy g ty -> - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy ty - return TTraitBuiltIn - - | [], [ty], false, "get_One", [] - when isNumericType g ty || isCharTy g ty -> - do! SolveDimensionlessNumericType csenv ndeep m2 trace ty - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy ty - return TTraitBuiltIn - - | [], _, false, "DivideByInt", [argTy1;argTy2] - when isFpTy g argTy1 || isDecimalTy g argTy1 -> - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 g.int_ty - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1 - return TTraitBuiltIn - - // We pretend for uniformity that the 'string' and 'array' types have an indexer property called 'Item' - | [], [ty], true, "get_Item", [argTy1] - when isStringTy g ty -> - - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy1 g.int_ty - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy g.char_ty - return TTraitBuiltIn - - | [], [ty], true, "get_Item", argTys - when isArrayTy g ty -> - - if rankOfArrayTy g ty <> argTys.Length then - do! ErrorD(ConstraintSolverError(FSComp.SR.csIndexArgumentMismatch((rankOfArrayTy g ty), argTys.Length), m, m2)) - - for argTy in argTys do - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy g.int_ty - - let ety = destArrayTy g ty - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy ety - return TTraitBuiltIn - - | [], [ty], true, "set_Item", argTys - when isArrayTy g ty -> - - if rankOfArrayTy g ty <> argTys.Length - 1 then - do! ErrorD(ConstraintSolverError(FSComp.SR.csIndexArgumentMismatch((rankOfArrayTy g ty), (argTys.Length - 1)), m, m2)) - let argTys, lastTy = List.frontAndBack argTys - - for argTy in argTys do - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy g.int_ty - - let elemTy = destArrayTy g ty - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace lastTy elemTy - return TTraitBuiltIn - - | [], _, false, ("op_BitwiseAnd" | "op_BitwiseOr" | "op_ExclusiveOr"), [argTy1;argTy2] - when IsBitwiseOpType g argTy1 && IsBinaryOpOtherArgType g permitWeakResolution argTy2 - || IsBitwiseOpType g argTy2 && IsBinaryOpOtherArgType g permitWeakResolution argTy1 -> - - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1 - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1 - do! SolveDimensionlessNumericType csenv ndeep m2 trace argTy1 - return TTraitBuiltIn - - | [], _, false, ("op_LeftShift" | "op_RightShift"), [argTy1;argTy2] - when IsIntegerOrIntegerEnumTy g argTy1 -> - - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 g.int_ty - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1 - do! SolveDimensionlessNumericType csenv ndeep m2 trace argTy1 - return TTraitBuiltIn - - | _, _, false, "op_UnaryPlus", [argTy] - when IsNumericOrIntegralEnumType g argTy -> - - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy - return TTraitBuiltIn - - | _, _, false, "op_UnaryNegation", [argTy] - when isSignedIntegerTy g argTy || isFpTy g argTy || isDecimalTy g argTy -> - - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy - return TTraitBuiltIn - - | _, _, true, "get_Sign", [] - when IsSignType g supportTys.Head -> - - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy g.int32_ty - return TTraitBuiltIn - - | _, _, false, ("op_LogicalNot" | "op_OnesComplement"), [argTy] - when IsIntegerOrIntegerEnumTy g argTy -> - - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy - do! SolveDimensionlessNumericType csenv ndeep m2 trace argTy - return TTraitBuiltIn - - | _, _, false, "Abs", [argTy] - when isSignedIntegerTy g argTy || isFpTy g argTy || isDecimalTy g argTy -> - - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy - return TTraitBuiltIn - - | _, _, false, "Sqrt", [argTy1] - when isFpTy g argTy1 -> - match getMeasureOfType g argTy1 with - | Some (tcref, _) -> - let ms1 = freshMeasure () - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy1 (mkAppTy tcref [TType_measure (Measure.Prod (ms1, ms1))]) - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkAppTy tcref [TType_measure ms1]) - return TTraitBuiltIn - | None -> - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1 - return TTraitBuiltIn - - | _, _, false, ("Sin" | "Cos" | "Tan" | "Sinh" | "Cosh" | "Tanh" | "Atan" | "Acos" | "Asin" | "Exp" | "Ceiling" | "Floor" | "Round" | "Truncate" | "Log10" | "Log" | "Sqrt"), [argTy] - when isFpTy g argTy -> - - do! SolveDimensionlessNumericType csenv ndeep m2 trace argTy - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy - return TTraitBuiltIn - - // Conversions from non-decimal numbers / strings / chars to non-decimal numbers / chars are built-in - | _, _, false, "op_Explicit", [argTy] - when (// The input type. - (IsNonDecimalNumericOrIntegralEnumType g argTy || isStringTy g argTy || isCharTy g argTy) && - // The output type - (IsNonDecimalNumericOrIntegralEnumType g retTy || isCharTy g retTy)) -> - - return TTraitBuiltIn - - // Conversions from (including decimal) numbers / strings / chars to decimals are built-in - | _, _, false, "op_Explicit", [argTy] - when (// The input type. - (IsNumericOrIntegralEnumType g argTy || isStringTy g argTy || isCharTy g argTy) && - // The output type - (isDecimalTy g retTy)) -> - return TTraitBuiltIn - - // Conversions from decimal numbers to native integers are built-in - // The rest of decimal conversions are handled via op_Explicit lookup on System.Decimal (which also looks for op_Implicit) - | _, _, false, "op_Explicit", [argTy] - when (// The input type. - (isDecimalTy g argTy) && - // The output type - (isNativeIntegerTy g retTy)) -> - return TTraitBuiltIn - - | [], _, false, "Pow", [argTy1; argTy2] - when isFpTy g argTy1 -> - - do! SolveDimensionlessNumericType csenv ndeep m2 trace argTy1 - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1 - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1 - return TTraitBuiltIn - - | _, _, false, "Atan2", [argTy1; argTy2] - when isFpTy g argTy1 -> - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1 - match getMeasureOfType g argTy1 with - | None -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1 - | Some (tcref, _) -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkAppTy tcref [TType_measure Measure.One]) - return TTraitBuiltIn + | _ -> - | _ -> - // OK, this is not solved by a built-in constraint. - // Now look for real solutions - - // First look for a solution by a record property - let recdPropSearch = - let isGetProp = nm.StartsWithOrdinal("get_") - let isSetProp = nm.StartsWithOrdinal("set_") - if not isRigid && ((argTys.IsEmpty && isGetProp) || isSetProp) then - let propName = nm[4..] - let props = - supportTys |> List.choose (fun ty -> - match TryFindIntrinsicNamedItemOfType csenv.InfoReader (propName, AccessibleFromEverywhere, false) FindMemberFlag.IgnoreOverrides m ty with - | Some (RecdFieldItem rfinfo) - when (isGetProp || rfinfo.RecdField.IsMutable) && - (rfinfo.IsStatic = not memFlags.IsInstance) && - IsRecdFieldAccessible amap m AccessibleFromEverywhere rfinfo.RecdFieldRef && - not rfinfo.LiteralValue.IsSome && - not rfinfo.RecdField.IsCompilerGenerated -> - Some (rfinfo, isSetProp) - | _ -> None) - match props with - | [ prop ] -> Some prop - | _ -> None - else - None - - let anonRecdPropSearch = - let isGetProp = nm.StartsWithOrdinal("get_") - if not isRigid && isGetProp && memFlags.IsInstance then - let propName = nm[4..] - let props = - supportTys |> List.choose (fun ty -> - match TryFindAnonRecdFieldOfType g ty propName with - | Some (Item.AnonRecdField(anonInfo, tinst, i, _)) -> Some (anonInfo, tinst, i) - | _ -> None) - match props with - | [ prop ] -> Some prop - | _ -> None - else - None - - // Now check if there are no feasible solutions at all - match minfos, recdPropSearch, anonRecdPropSearch with - | [], None, None when MemberConstraintIsReadyForStrongResolution csenv traitInfo -> - if supportTys |> List.exists (isFunTy g) then - return! ErrorD (ConstraintSolverError(FSComp.SR.csExpectTypeWithOperatorButGivenFunction(ConvertValLogicalNameToDisplayNameCore nm), m, m2)) - elif supportTys |> List.exists (isAnyTupleTy g) then - return! ErrorD (ConstraintSolverError(FSComp.SR.csExpectTypeWithOperatorButGivenTuple(ConvertValLogicalNameToDisplayNameCore nm), m, m2)) - else - match nm, argTys with - | "op_Explicit", [argTy] -> - let argTyString = NicePrint.prettyStringOfTy denv argTy - let rtyString = NicePrint.prettyStringOfTy denv retTy - return! ErrorD (ConstraintSolverError(FSComp.SR.csTypeDoesNotSupportConversion(argTyString, rtyString), m, m2)) - | _ -> - let tyString = - match supportTys with - | [ty] -> NicePrint.minimalStringOfType denv ty - | _ -> supportTys |> List.map (NicePrint.minimalStringOfType denv) |> String.concat ", " - let opName = ConvertValLogicalNameToDisplayNameCore nm - let err = - match opName with - | "?>=" | "?>" | "?<=" | "?<" | "?=" | "?<>" - | ">=?" | ">?" | "<=?" | "?" - | "?>=?" | "?>?" | "?<=?" | "??" -> - if List.isSingleton supportTys then FSComp.SR.csTypeDoesNotSupportOperatorNullable(tyString, opName) - else FSComp.SR.csTypesDoNotSupportOperatorNullable(tyString, opName) - | _ -> - match supportTys, source.Value with - | [_], Some s when s.StartsWith("Operators.") -> - let opSource = s[10..] - if opSource = nm then FSComp.SR.csTypeDoesNotSupportOperator(tyString, opName) - else FSComp.SR.csTypeDoesNotSupportOperator(tyString, opSource) - | [_], Some s -> - FSComp.SR.csFunctionDoesNotSupportType(s, tyString, nm) - | [_], _ - -> FSComp.SR.csTypeDoesNotSupportOperator(tyString, opName) - | _, _ - -> FSComp.SR.csTypesDoNotSupportOperator(tyString, opName) - return! ErrorD(ConstraintSolverError(err, m, m2)) + match getMeasureOfType g argTy2 with + | Some (tcref, ms2) -> + let ms1 = freshMeasure () + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy1 (mkWoNullAppTy tcref [TType_measure ms1]) + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkWoNullAppTy tcref [TType_measure (Measure.Prod(ms1, if nm = "op_Multiply" then ms2 else Measure.Inv ms2))]) + return TTraitBuiltIn - | _ -> - let dummyExpr = mkUnit g m - let calledMethGroup = - minfos - // curried members may not be used to satisfy constraints - |> List.choose (fun (staticTy, minfo) -> - if minfo.IsCurried then None else - let callerArgs = - { Unnamed = [ (argTys |> List.map (fun argTy -> CallerArg(argTy, m, false, dummyExpr))) ] - Named = [ [ ] ] } - let minst = FreshenMethInfo m minfo - let objtys = minfo.GetObjArgTypes(amap, m, minst) - Some(CalledMeth(csenv.InfoReader, None, false, FreshenMethInfo, m, AccessibleFromEverywhere, minfo, minst, minst, None, objtys, callerArgs, false, false, None, Some staticTy))) - - let methOverloadResult, errors = - trace.CollectThenUndoOrCommit - (fun (a, _) -> Option.isSome a) - (fun trace -> ResolveOverloading csenv (WithTrace trace) nm ndeep (Some traitInfo) CallerArgs.Empty AccessibleFromEverywhere calledMethGroup false (Some (MustEqual retTy))) - - match anonRecdPropSearch, recdPropSearch, methOverloadResult with - | Some (anonInfo, tinst, i), None, None -> - // OK, the constraint is solved by a record property. Assert that the return types match. - let rty2 = List.item i tinst - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy rty2 - return TTraitSolvedAnonRecdProp(anonInfo, tinst, i) - - | None, Some (rfinfo, isSetProp), None -> - // OK, the constraint is solved by a record property. Assert that the return types match. - let rty2 = if isSetProp then g.unit_ty else rfinfo.FieldType - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy rty2 - return TTraitSolvedRecdProp(rfinfo, isSetProp) - - | None, None, Some (calledMeth: CalledMeth<_>) -> - // OK, the constraint is solved. - let minfo = calledMeth.Method - - do! errors - let isInstance = minfo.IsInstance - if isInstance <> memFlags.IsInstance then - return! - if isInstance then - ErrorD(ConstraintSolverError(FSComp.SR.csMethodFoundButIsNotStatic((NicePrint.minimalStringOfType denv minfo.ApparentEnclosingType), (ConvertValLogicalNameToDisplayNameCore nm), nm), m, m2 )) - else - ErrorD(ConstraintSolverError(FSComp.SR.csMethodFoundButIsStatic((NicePrint.minimalStringOfType denv minfo.ApparentEnclosingType), (ConvertValLogicalNameToDisplayNameCore nm), nm), m, m2 )) - else - do! CheckMethInfoAttributes g m None minfo - return TTraitSolved (minfo, calledMeth.CalledTyArgs, calledMeth.OptionalStaticType) - - | _ -> - do! AddUnsolvedMemberConstraint csenv ndeep m2 trace permitWeakResolution ignoreUnresolvedOverload traitInfo errors - return TTraitUnsolved - } - return! RecordMemberConstraintSolution csenv.SolverState m trace traitInfo res - } + | _ -> + + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1 + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1 + return TTraitBuiltIn + + | _, _, false, ("op_Addition" | "op_Subtraction" | "op_Modulus"), [argTy1;argTy2] + when // Ignore any explicit +/- overloads from any basic integral types + (minfos |> List.forall (fun (_, minfo) -> isIntegerTy g minfo.ApparentEnclosingType ) && + ( IsAddSubModType nm g argTy1 && IsBinaryOpOtherArgType g permitWeakResolution argTy2 + || IsAddSubModType nm g argTy2 && IsBinaryOpOtherArgType g permitWeakResolution argTy1)) -> + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1 + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1 + return TTraitBuiltIn + + | _, _, false, ("op_LessThan" | "op_LessThanOrEqual" | "op_GreaterThan" | "op_GreaterThanOrEqual" | "op_Equality" | "op_Inequality" ), [argTy1;argTy2] + when // Ignore any explicit overloads from any basic integral types + (minfos |> List.forall (fun (_, minfo) -> isIntegerTy g minfo.ApparentEnclosingType ) && + ( IsRelationalType g argTy1 && IsBinaryOpOtherArgType g permitWeakResolution argTy2 + || IsRelationalType g argTy2 && IsBinaryOpOtherArgType g permitWeakResolution argTy1)) -> + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1 + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy g.bool_ty + return TTraitBuiltIn + + // We pretend for uniformity that the numeric types have a static property called Zero and One + // As with constants, only zero is polymorphic in its units + | [], [ty], false, "get_Zero", [] + when isNumericType g ty || isCharTy g ty -> + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy ty + return TTraitBuiltIn + + | [], [ty], false, "get_One", [] + when isNumericType g ty || isCharTy g ty -> + do! SolveDimensionlessNumericType csenv ndeep m2 trace ty + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy ty + return TTraitBuiltIn + + | [], _, false, "DivideByInt", [argTy1;argTy2] + when isFpTy g argTy1 || isDecimalTy g argTy1 -> + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 g.int_ty + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1 + return TTraitBuiltIn + + // We pretend for uniformity that the 'string' and 'array' types have an indexer property called 'Item' + | [], [ty], true, "get_Item", [argTy1] + when isStringTy g ty -> + + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy1 g.int_ty + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy g.char_ty + return TTraitBuiltIn + + | [], [ty], true, "get_Item", argTys + when isArrayTy g ty -> + + if rankOfArrayTy g ty <> argTys.Length then + do! ErrorD(ConstraintSolverError(FSComp.SR.csIndexArgumentMismatch((rankOfArrayTy g ty), argTys.Length), m, m2)) + + for argTy in argTys do + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy g.int_ty + + let ety = destArrayTy g ty + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy ety + return TTraitBuiltIn + + | [], [ty], true, "set_Item", argTys + when isArrayTy g ty -> + + if rankOfArrayTy g ty <> argTys.Length - 1 then + do! ErrorD(ConstraintSolverError(FSComp.SR.csIndexArgumentMismatch((rankOfArrayTy g ty), (argTys.Length - 1)), m, m2)) + let argTys, lastTy = List.frontAndBack argTys + + for argTy in argTys do + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy g.int_ty + + let elemTy = destArrayTy g ty + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace lastTy elemTy + return TTraitBuiltIn + + | [], _, false, ("op_BitwiseAnd" | "op_BitwiseOr" | "op_ExclusiveOr"), [argTy1;argTy2] + when IsBitwiseOpType g argTy1 && IsBinaryOpOtherArgType g permitWeakResolution argTy2 + || IsBitwiseOpType g argTy2 && IsBinaryOpOtherArgType g permitWeakResolution argTy1 -> + + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1 + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1 + do! SolveDimensionlessNumericType csenv ndeep m2 trace argTy1 + return TTraitBuiltIn + + | [], _, false, ("op_LeftShift" | "op_RightShift"), [argTy1;argTy2] + when IsIntegerOrIntegerEnumTy g argTy1 -> + + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 g.int_ty + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1 + do! SolveDimensionlessNumericType csenv ndeep m2 trace argTy1 + return TTraitBuiltIn + + | _, _, false, "op_UnaryPlus", [argTy] + when IsNumericOrIntegralEnumType g argTy -> + + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy + return TTraitBuiltIn + + | _, _, false, "op_UnaryNegation", [argTy] + when isSignedIntegerTy g argTy || isFpTy g argTy || isDecimalTy g argTy -> + + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy + return TTraitBuiltIn + + | _, _, true, "get_Sign", [] + when IsSignType g supportTys.Head -> + + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy g.int32_ty + return TTraitBuiltIn + + | _, _, false, ("op_LogicalNot" | "op_OnesComplement"), [argTy] + when IsIntegerOrIntegerEnumTy g argTy -> + + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy + do! SolveDimensionlessNumericType csenv ndeep m2 trace argTy + return TTraitBuiltIn + + | _, _, false, "Abs", [argTy] + when isSignedIntegerTy g argTy || isFpTy g argTy || isDecimalTy g argTy -> + + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy + return TTraitBuiltIn + + | _, _, false, "Sqrt", [argTy1] + when isFpTy g argTy1 -> + match getMeasureOfType g argTy1 with + | Some (tcref, _) -> + let ms1 = freshMeasure () + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy1 (mkWoNullAppTy tcref [TType_measure (Measure.Prod (ms1, ms1))]) + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkWoNullAppTy tcref [TType_measure ms1]) + return TTraitBuiltIn + | None -> + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1 + return TTraitBuiltIn + + | _, _, false, ("Sin" | "Cos" | "Tan" | "Sinh" | "Cosh" | "Tanh" | "Atan" | "Acos" | "Asin" | "Exp" | "Ceiling" | "Floor" | "Round" | "Truncate" | "Log10" | "Log" | "Sqrt"), [argTy] + when isFpTy g argTy -> + + do! SolveDimensionlessNumericType csenv ndeep m2 trace argTy + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy + return TTraitBuiltIn + + // Conversions from non-decimal numbers / strings / chars to non-decimal numbers / chars are built-in + | _, _, false, "op_Explicit", [argTy] + when (// The input type. + (IsNonDecimalNumericOrIntegralEnumType g argTy || isStringTy g argTy || isCharTy g argTy) && + // The output type + (IsNonDecimalNumericOrIntegralEnumType g retTy || isCharTy g retTy)) -> + + return TTraitBuiltIn + + // Conversions from (including decimal) numbers / strings / chars to decimals are built-in + | _, _, false, "op_Explicit", [argTy] + when (// The input type. + (IsNumericOrIntegralEnumType g argTy || isStringTy g argTy || isCharTy g argTy) && + // The output type + (isDecimalTy g retTy)) -> + return TTraitBuiltIn + + // Conversions from decimal numbers to native integers are built-in + // The rest of decimal conversions are handled via op_Explicit lookup on System.Decimal (which also looks for op_Implicit) + | _, _, false, "op_Explicit", [argTy] + when (// The input type. + (isDecimalTy g argTy) && + // The output type + (isNativeIntegerTy g retTy)) -> + return TTraitBuiltIn + + | [], _, false, "Pow", [argTy1; argTy2] + when isFpTy g argTy1 -> + + do! SolveDimensionlessNumericType csenv ndeep m2 trace argTy1 + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1 + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1 + return TTraitBuiltIn + + | _, _, false, "Atan2", [argTy1; argTy2] + when isFpTy g argTy1 -> + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argTy2 argTy1 + match getMeasureOfType g argTy1 with + | None -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy1 + | Some (tcref, _) -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy (mkWoNullAppTy tcref [TType_measure Measure.One]) + return TTraitBuiltIn + + | _ -> + // OK, this is not solved by a built-in constraint. + // Now look for real solutions + + // First look for a solution by a record property + let recdPropSearch = + let isGetProp = nm.StartsWithOrdinal("get_") + let isSetProp = nm.StartsWithOrdinal("set_") + if not isRigid && ((argTys.IsEmpty && isGetProp) || isSetProp) then + let propName = nm[4..] + let props = + supportTys |> List.choose (fun ty -> + match TryFindIntrinsicNamedItemOfType csenv.InfoReader (propName, AccessibleFromEverywhere, false) FindMemberFlag.IgnoreOverrides m ty with + | Some (RecdFieldItem rfinfo) + when (isGetProp || rfinfo.RecdField.IsMutable) && + (rfinfo.IsStatic = not memFlags.IsInstance) && + IsRecdFieldAccessible amap m AccessibleFromEverywhere rfinfo.RecdFieldRef && + not rfinfo.LiteralValue.IsSome && + not rfinfo.RecdField.IsCompilerGenerated -> + Some (rfinfo, isSetProp) + | _ -> None) + match props with + | [ prop ] -> Some prop + | _ -> None + else + None + + let anonRecdPropSearch = + let isGetProp = nm.StartsWithOrdinal("get_") + if not isRigid && isGetProp && memFlags.IsInstance then + let propName = nm[4..] + let props = + supportTys |> List.choose (fun ty -> + match TryFindAnonRecdFieldOfType g ty propName with + | Some (Item.AnonRecdField(anonInfo, tinst, i, _)) -> Some (anonInfo, tinst, i) + | _ -> None) + match props with + | [ prop ] -> Some prop + | _ -> None + else + None + + // Now check if there are no feasible solutions at all + match minfos, recdPropSearch, anonRecdPropSearch with + | [], None, None when MemberConstraintIsReadyForStrongResolution csenv traitInfo -> + if supportTys |> List.exists (isFunTy g) then + return! ErrorD (ConstraintSolverError(FSComp.SR.csExpectTypeWithOperatorButGivenFunction(ConvertValLogicalNameToDisplayNameCore nm), m, m2)) + elif supportTys |> List.exists (isAnyTupleTy g) then + return! ErrorD (ConstraintSolverError(FSComp.SR.csExpectTypeWithOperatorButGivenTuple(ConvertValLogicalNameToDisplayNameCore nm), m, m2)) + else + match nm, argTys with + | "op_Explicit", [argTy] -> + let argTyString = NicePrint.prettyStringOfTy denv argTy + let rtyString = NicePrint.prettyStringOfTy denv retTy + return! ErrorD (ConstraintSolverError(FSComp.SR.csTypeDoesNotSupportConversion(argTyString, rtyString), m, m2)) + | _ -> + let tyString = + match supportTys with + | [ty] -> NicePrint.minimalStringOfType denv ty + | _ -> supportTys |> List.map (NicePrint.minimalStringOfType denv) |> String.concat ", " + let opName = ConvertValLogicalNameToDisplayNameCore nm + let err = + match opName with + | "?>=" | "?>" | "?<=" | "?<" | "?=" | "?<>" + | ">=?" | ">?" | "<=?" | "?" + | "?>=?" | "?>?" | "?<=?" | "??" -> + if List.isSingleton supportTys then FSComp.SR.csTypeDoesNotSupportOperatorNullable(tyString, opName) + else FSComp.SR.csTypesDoNotSupportOperatorNullable(tyString, opName) + | _ -> + match supportTys, source.Value with + | [_], Some s when s.StartsWith("Operators.") -> + let opSource = s[10..] + if opSource = nm then FSComp.SR.csTypeDoesNotSupportOperator(tyString, opName) + else FSComp.SR.csTypeDoesNotSupportOperator(tyString, opSource) + | [_], Some s -> + FSComp.SR.csFunctionDoesNotSupportType(s, tyString, nm) + | [_], _ + -> FSComp.SR.csTypeDoesNotSupportOperator(tyString, opName) + | _, _ + -> FSComp.SR.csTypesDoNotSupportOperator(tyString, opName) + return! ErrorD(ConstraintSolverError(err, m, m2)) + + | _ -> + let dummyExpr = mkUnit g m + let calledMethGroup = + minfos + // curried members may not be used to satisfy constraints + |> List.choose (fun (staticTy, minfo) -> + if minfo.IsCurried then + None + else + let callerArgs = + { + Unnamed = [ (argTys |> List.map (fun argTy -> CallerArg(argTy, m, false, dummyExpr))) ] + Named = [ [ ] ] + } + let minst = FreshenMethInfo m minfo + let objtys = minfo.GetObjArgTypes(amap, m, minst) + Some(CalledMeth(csenv.InfoReader, None, false, FreshenMethInfo, m, AccessibleFromEverywhere, minfo, minst, minst, None, objtys, callerArgs, false, false, None, Some staticTy))) + + let methOverloadResult, errors = + trace.CollectThenUndoOrCommit + (fun (a, _) -> Option.isSome a) + (fun trace -> ResolveOverloading csenv (WithTrace trace) nm ndeep (Some traitInfo) CallerArgs.Empty AccessibleFromEverywhere calledMethGroup false (Some (MustEqual retTy))) + + match anonRecdPropSearch, recdPropSearch, methOverloadResult with + | Some (anonInfo, tinst, i), None, None -> + // OK, the constraint is solved by a record property. Assert that the return types match. + let rty2 = List.item i tinst + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy rty2 + return TTraitSolvedAnonRecdProp(anonInfo, tinst, i) + + | None, Some (rfinfo, isSetProp), None -> + // OK, the constraint is solved by a record property. Assert that the return types match. + let rty2 = if isSetProp then g.unit_ty else rfinfo.FieldType + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy rty2 + return TTraitSolvedRecdProp(rfinfo, isSetProp) + + | None, None, Some (calledMeth: CalledMeth<_>) -> + // OK, the constraint is solved. + let minfo = calledMeth.Method + + do! errors + let isInstance = minfo.IsInstance + if isInstance <> memFlags.IsInstance then + return! + if isInstance then + ErrorD(ConstraintSolverError(FSComp.SR.csMethodFoundButIsNotStatic((NicePrint.minimalStringOfType denv minfo.ApparentEnclosingType), (ConvertValLogicalNameToDisplayNameCore nm), nm), m, m2 )) + else + ErrorD(ConstraintSolverError(FSComp.SR.csMethodFoundButIsStatic((NicePrint.minimalStringOfType denv minfo.ApparentEnclosingType), (ConvertValLogicalNameToDisplayNameCore nm), nm), m, m2 )) + else + do! CheckMethInfoAttributes g m None minfo + return TTraitSolved (minfo, calledMeth.CalledTyArgs, calledMeth.OptionalStaticType) + + | _ -> + do! AddUnsolvedMemberConstraint csenv ndeep m2 trace permitWeakResolution ignoreUnresolvedOverload traitInfo errors + return TTraitUnsolved + } + return! RecordMemberConstraintSolution csenv.SolverState m trace traitInfo res + } and AddUnsolvedMemberConstraint csenv ndeep m2 trace permitWeakResolution ignoreUnresolvedOverload traitInfo errors = trackErrors { @@ -1835,7 +2150,7 @@ and MemberConstraintSolutionOfMethInfo css m minfo minst staticTyOpt = match callMethInfoOpt, callExpr with | Some methInfo, Expr.Op (TOp.ILCall (_, _, _, _, NormalValUse, _, _, ilMethRef, _, methInst, _), [], args, m) when (args, (objArgVars@allArgVars)) ||> List.lengthsEqAndForall2 (fun a b -> match a with Expr.Val (v, _, _) -> valEq v.Deref b | _ -> false) -> - let declaringTy = ImportProvidedType amap m (methInfo.PApply((fun x -> x.DeclaringType), m)) + let declaringTy = ImportProvidedType amap m (methInfo.PApply((fun x -> nonNull x.DeclaringType), m)) if isILAppTy g declaringTy then let extOpt = None // EXTENSION METHODS FROM TYPE PROVIDERS: for extension methods coming from the type providers we would have something here. ILMethSln(declaringTy, extOpt, ilMethRef, methInst, staticTyOpt) @@ -2047,73 +2362,77 @@ and TraitsAreRelated (csenv: ConstraintSolverEnv) retry traitInfo1 traitInfo2 = // The 'retry' flag is passed when a rigid type variable is about to raise a missing constraint error // and the lengths of the support types are not equal (i.e. one is length 1, the other is length 2). // In this case the support types are first forced to be equal. -and EnforceConstraintConsistency (csenv: ConstraintSolverEnv) ndeep m2 trace retry tpc1 tpc2 = trackErrors { - let g = csenv.g - let amap = csenv.amap - let m = csenv.m - match tpc1, tpc2 with - | TyparConstraint.MayResolveMember(traitInfo1, _), TyparConstraint.MayResolveMember(traitInfo2, _) - when TraitsAreRelated csenv retry traitInfo1 traitInfo2 -> - let (TTrait(tys=tys1; objAndArgTys=argTys1; returnTyOpt=rty1)) = traitInfo1 - let (TTrait(tys=tys2; objAndArgTys=argTys2; returnTyOpt=rty2)) = traitInfo2 - if retry then - match tys1, tys2 with - | [ty1], [ty2] -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace ty1 ty2 - | [ty1], _ -> do! IterateD (SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace ty1) tys2 - | _, [ty2] -> do! IterateD (SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace ty2) tys1 - | _ -> () - do! Iterate2D (SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace) argTys1 argTys2 - let rty1 = GetFSharpViewOfReturnType g rty1 - let rty2 = GetFSharpViewOfReturnType g rty2 - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty1 rty2 - - | TyparConstraint.CoercesTo(ty1, _), TyparConstraint.CoercesTo(ty2, _) -> - // Record at most one subtype constraint for each head type. - // That is, we forbid constraints by both I and I. - // This works because the types on the r.h.s. of subtype - // constraints are head-types and so any further inferences are equational. - let collect ty = - let mutable res = [] - IterateEntireHierarchyOfType (fun x -> res <- x :: res) g amap m AllowMultiIntfInstantiations.No ty - List.rev res - let parents1 = collect ty1 - let parents2 = collect ty2 - for ty1Parent in parents1 do - for ty2Parent in parents2 do - if HaveSameHeadType g ty1Parent ty2Parent then - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace ty1Parent ty2Parent - - | TyparConstraint.IsEnum (unerlyingTy1, _), - TyparConstraint.IsEnum (unerlyingTy2, m2) -> - return! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace unerlyingTy1 unerlyingTy2 - - | TyparConstraint.IsDelegate (argsTy1, retTy1, _), - TyparConstraint.IsDelegate (argsTy2, retTy2, m2) -> - do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argsTy1 argsTy2 - return! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy1 retTy2 - - | TyparConstraint.SupportsComparison _, TyparConstraint.IsDelegate _ - | TyparConstraint.IsDelegate _, TyparConstraint.SupportsComparison _ - | TyparConstraint.IsNonNullableStruct _, TyparConstraint.IsReferenceType _ - | TyparConstraint.IsReferenceType _, TyparConstraint.IsNonNullableStruct _ -> - return! ErrorD (Error(FSComp.SR.csStructConstraintInconsistent(), m)) - - | TyparConstraint.IsUnmanaged _, TyparConstraint.IsReferenceType _ - | TyparConstraint.IsReferenceType _, TyparConstraint.IsUnmanaged _ -> - return! ErrorD (Error(FSComp.SR.csUnmanagedConstraintInconsistent(), m)) - - | TyparConstraint.SupportsComparison _, TyparConstraint.SupportsComparison _ - | TyparConstraint.SupportsEquality _, TyparConstraint.SupportsEquality _ - | TyparConstraint.SupportsNull _, TyparConstraint.SupportsNull _ - | TyparConstraint.IsNonNullableStruct _, TyparConstraint.IsNonNullableStruct _ - | TyparConstraint.IsUnmanaged _, TyparConstraint.IsUnmanaged _ - | TyparConstraint.IsReferenceType _, TyparConstraint.IsReferenceType _ - | TyparConstraint.RequiresDefaultConstructor _, TyparConstraint.RequiresDefaultConstructor _ - | TyparConstraint.SimpleChoice _, TyparConstraint.SimpleChoice _ -> - () - - | _ -> () - } +and EnforceConstraintConsistency (csenv: ConstraintSolverEnv) ndeep m2 trace retry tpc1 tpc2 = + trackErrors { + let g = csenv.g + let amap = csenv.amap + let m = csenv.m + match tpc1, tpc2 with + | TyparConstraint.MayResolveMember(traitInfo1, _), TyparConstraint.MayResolveMember(traitInfo2, _) + when TraitsAreRelated csenv retry traitInfo1 traitInfo2 -> + let (TTrait(tys=tys1; objAndArgTys=argTys1; returnTyOpt=rty1)) = traitInfo1 + let (TTrait(tys=tys2; objAndArgTys=argTys2; returnTyOpt=rty2)) = traitInfo2 + if retry then + match tys1, tys2 with + | [ty1], [ty2] -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace ty1 ty2 + | [ty1], _ -> do! IterateD (SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace ty1) tys2 + | _, [ty2] -> do! IterateD (SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace ty2) tys1 + | _ -> () + do! Iterate2D (SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace) argTys1 argTys2 + let rty1 = GetFSharpViewOfReturnType g rty1 + let rty2 = GetFSharpViewOfReturnType g rty2 + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty1 rty2 + + | TyparConstraint.CoercesTo(ty1, _), TyparConstraint.CoercesTo(ty2, _) -> + // Record at most one subtype constraint for each head type. + // That is, we forbid constraints by both I and I. + // This works because the types on the r.h.s. of subtype + // constraints are head-types and so any further inferences are equational. + let collect ty = + let mutable res = [] + IterateEntireHierarchyOfType (fun x -> res <- x :: res) g amap m AllowMultiIntfInstantiations.No ty + List.rev res + let parents1 = collect ty1 + let parents2 = collect ty2 + for ty1Parent in parents1 do + for ty2Parent in parents2 do + if HaveSameHeadType g ty1Parent ty2Parent then + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace ty1Parent ty2Parent + + | TyparConstraint.IsEnum (unerlyingTy1, _), TyparConstraint.IsEnum (unerlyingTy2, m2) -> + return! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace unerlyingTy1 unerlyingTy2 + + | TyparConstraint.IsDelegate (argsTy1, retTy1, _), TyparConstraint.IsDelegate (argsTy2, retTy2, m2) -> + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argsTy1 argsTy2 + return! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy1 retTy2 + + | TyparConstraint.SupportsComparison _, TyparConstraint.IsDelegate _ + | TyparConstraint.IsDelegate _, TyparConstraint.SupportsComparison _ + | TyparConstraint.IsNonNullableStruct _, TyparConstraint.IsReferenceType _ + | TyparConstraint.IsReferenceType _, TyparConstraint.IsNonNullableStruct _ -> + return! ErrorD (Error(FSComp.SR.csStructConstraintInconsistent(), m)) + + | TyparConstraint.SupportsNull _, TyparConstraint.NotSupportsNull _ + | TyparConstraint.NotSupportsNull _, TyparConstraint.SupportsNull _ -> + return! ErrorD (Error(FSComp.SR.csNullNotNullConstraintInconsistent(), m)) + + | TyparConstraint.IsUnmanaged _, TyparConstraint.IsReferenceType _ + | TyparConstraint.IsReferenceType _, TyparConstraint.IsUnmanaged _ -> + return! ErrorD (Error(FSComp.SR.csUnmanagedConstraintInconsistent(), m)) + + | TyparConstraint.SupportsComparison _, TyparConstraint.SupportsComparison _ + | TyparConstraint.SupportsEquality _, TyparConstraint.SupportsEquality _ + | TyparConstraint.SupportsNull _, TyparConstraint.SupportsNull _ + | TyparConstraint.NotSupportsNull _, TyparConstraint.NotSupportsNull _ + | TyparConstraint.IsNonNullableStruct _, TyparConstraint.IsNonNullableStruct _ + | TyparConstraint.IsUnmanaged _, TyparConstraint.IsUnmanaged _ + | TyparConstraint.IsReferenceType _, TyparConstraint.IsReferenceType _ + | TyparConstraint.RequiresDefaultConstructor _, TyparConstraint.RequiresDefaultConstructor _ + | TyparConstraint.SimpleChoice _, TyparConstraint.SimpleChoice _ -> + () + + | _ -> () + } // See when one constraint implies implies another. // 'a :> ty1 implies 'a :> 'ty2 if the head type name of ty2 (say T2) occursCheck anywhere in the hierarchy of ty1 @@ -2141,6 +2460,7 @@ and CheckConstraintImplication (csenv: ConstraintSolverEnv) tpc1 tpc2 = // comparison implies equality | TyparConstraint.SupportsComparison _, TyparConstraint.SupportsEquality _ | TyparConstraint.SupportsNull _, TyparConstraint.SupportsNull _ + | TyparConstraint.NotSupportsNull _, TyparConstraint.NotSupportsNull _ | TyparConstraint.IsNonNullableStruct _, TyparConstraint.IsNonNullableStruct _ | TyparConstraint.IsUnmanaged _, TyparConstraint.IsUnmanaged _ | TyparConstraint.IsReferenceType _, TyparConstraint.IsReferenceType _ @@ -2231,20 +2551,161 @@ and AddConstraint (csenv: ConstraintSolverEnv) ndeep m2 trace tp newConstraint () } -and SolveTypeUseSupportsNull (csenv: ConstraintSolverEnv) ndeep m2 trace ty = - let g = csenv.g - let m = csenv.m - let denv = csenv.DisplayEnv - match tryDestTyparTy g ty with - | ValueSome destTypar -> - AddConstraint csenv ndeep m2 trace destTypar (TyparConstraint.SupportsNull m) - | ValueNone -> - if TypeSatisfiesNullConstraint g m ty then CompleteD else - match ty with - | NullableTy g _ -> - ErrorD (ConstraintSolverError(FSComp.SR.csNullableTypeDoesNotHaveNull(NicePrint.minimalStringOfType denv ty), m, m2)) - | _ -> - ErrorD (ConstraintSolverError(FSComp.SR.csTypeDoesNotHaveNull(NicePrint.minimalStringOfType denv ty), m, m2)) +// preferConstraint: if the type is a type variable with an uncertain nullness, then +// this indicates whether we prefer to add a nullness constraint to the type variable itself, +// or whether we prefer to solve the nullness annotation. +// +// This is relevant for code like this: +// +// let isNull (value : 'T when 'T : null) = +// match box value with +// | null -> true +// | _ -> false +// +// let checkNonNull argName arg = +// if isNull arg then +// failwith (argName + " is null") +// +// Here the `'T: null` constraint is propagated by inference to checkNonNull. Which of these two types do we expect? +// +// val checkNonNull1: argName: string -> arg: 'T -> unit when 'T: null +// +// val checkNonNull2: argName: string -> arg: 'T | null -> unit +// +// When null checking is fully enabled, we prefer the latter. We can't always prefer it because it is a breaking change. +// +// Likewise consider +// +// let x = null +// +// What's the generalized type? +// val x: 'a when 'a: null +// val x: 'a | null when 'a: not null +// +// When null checking is fully enabled, we prefer the latter. We can't always prefer it because it is a breaking change. +and SolveTypeUseSupportsNull (csenv: ConstraintSolverEnv) ndeep m2 trace ty = + trackErrors { + let g = csenv.g + let m = csenv.m + let denv = csenv.DisplayEnv + if g.langFeatureNullness then + if TypeNullIsExtraValueNew g m ty then + () + elif isNullableTy g ty then + return! ErrorD (ConstraintSolverError(FSComp.SR.csNullableTypeDoesNotHaveNull(NicePrint.minimalStringOfType denv ty), m, m2)) + else + match tryDestTyparTy g ty with + | ValueSome tp -> + let nullness = nullnessOfTy g ty + match nullness.TryEvaluate() with + // NULLNESS TODO: This rule means turning on checkNullness changes type inference results for the cases + // mentioned in the comment above. THat's OK but needs to be documented in the RFC. + | ValueNone when not g.checkNullness -> + return! AddConstraint csenv ndeep m2 trace tp (TyparConstraint.SupportsNull m) + | ValueSome NullnessInfo.WithoutNull -> + return! AddConstraint csenv ndeep m2 trace tp (TyparConstraint.SupportsNull m) + | _ -> + if tp.Constraints |> List.exists (function | TyparConstraint.IsReferenceType _ -> true | _ -> false) |> not then + do! AddConstraint csenv ndeep m2 trace tp (TyparConstraint.IsReferenceType m) + return! SolveNullnessSupportsNull csenv ndeep m2 trace ty nullness + | _ -> + let nullness = nullnessOfTy g ty + do! SolveNullnessSupportsNull csenv ndeep m2 trace ty nullness + + // If checkNullness is off give the same errors as F# 4.5 + if not g.checkNullness && not (TypeNullIsExtraValue g m ty) then + return! ErrorD (ConstraintSolverError(FSComp.SR.csTypeDoesNotHaveNull(NicePrint.minimalStringOfType denv ty), m, m2)) + else + if TypeNullIsExtraValue g m ty then + () + elif isNullableTy g ty then + return! ErrorD (ConstraintSolverError(FSComp.SR.csNullableTypeDoesNotHaveNull(NicePrint.minimalStringOfType denv ty), m, m2)) + else + match tryDestTyparTy g ty with + | ValueSome tp -> + do! AddConstraint csenv ndeep m2 trace tp (TyparConstraint.SupportsNull m) + | ValueNone -> + return! ErrorD (ConstraintSolverError(FSComp.SR.csTypeDoesNotHaveNull(NicePrint.minimalStringOfType denv ty), m, m2)) + } + +and SolveNullnessSupportsNull (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) ty nullness = + trackErrors { + let g = csenv.g + let m = csenv.m + let denv = csenv.DisplayEnv + match nullness with + | Nullness.Variable nv -> + if nv.IsSolved then + do! SolveNullnessSupportsNull csenv ndeep m2 trace ty nv.Solution + else + trace.Exec (fun () -> nv.Set KnownWithNull) (fun () -> nv.Unset()) + | Nullness.Known n1 -> + match n1 with + | NullnessInfo.AmbivalentToNull -> () + | NullnessInfo.WithNull -> () + | NullnessInfo.WithoutNull -> + if g.checkNullness then + // TODO nullness: Shouldn't this be an error? We have a 'must support null' situation which is not being met. + return! WarnD(ConstraintSolverNullnessWarningWithType(denv, ty, n1, m, m2)) + } + +and SolveTypeUseNotSupportsNull (csenv: ConstraintSolverEnv) ndeep m2 trace ty = + trackErrors { + let g = csenv.g + let m = csenv.m + let denv = csenv.DisplayEnv + + if TypeNullIsTrueValue g ty then + // We can only give warnings here as F# 5.0 introduces these constraints into existing + // code via Option.ofObj and Option.toObj + do! WarnD (ConstraintSolverNullnessWarning(FSComp.SR.csTypeHasNullAsTrueValue(NicePrint.minimalStringOfType denv ty), m, m2)) + elif TypeNullIsExtraValueNew g m ty then + if g.checkNullness then + let denv = { denv with showNullnessAnnotations = Some true } + do! WarnD (ConstraintSolverNullnessWarning(FSComp.SR.csTypeHasNullAsExtraValue(NicePrint.minimalStringOfType denv ty), m, m2)) + else + match tryDestTyparTy g ty with + | ValueSome tp -> + do! AddConstraint csenv ndeep m2 trace tp (TyparConstraint.NotSupportsNull m) + | ValueNone -> + let nullness = nullnessOfTy g ty + do! SolveNullnessNotSupportsNull csenv ndeep m2 trace ty nullness + } + +and SolveNullnessNotSupportsNull (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) ty nullness = + trackErrors { + let g = csenv.g + let m = csenv.m + let denv = csenv.DisplayEnv + match nullness with + | Nullness.Variable nv -> + if nv.IsSolved then + do! SolveNullnessNotSupportsNull csenv ndeep m2 trace ty nv.Solution + else + trace.Exec (fun () -> nv.Set KnownWithoutNull) (fun () -> nv.Unset()) + | Nullness.Known n1 -> + match n1 with + | NullnessInfo.AmbivalentToNull -> () + | NullnessInfo.WithoutNull -> () + | NullnessInfo.WithNull -> + if g.checkNullness && TypeNullIsExtraValueNew g m ty then + let denv = { denv with showNullnessAnnotations = Some true } + return! WarnD(ConstraintSolverNullnessWarning(FSComp.SR.csTypeHasNullAsExtraValue(NicePrint.minimalStringOfType denv ty), m, m2)) + } + +and SolveTypeCanCarryNullness (csenv: ConstraintSolverEnv) ty nullness = + trackErrors { + let g = csenv.g + let m = csenv.m + let strippedTy = stripTyEqnsA g true ty + match tryAddNullnessToTy nullness strippedTy with + | Some _ -> + if isTyparTy g strippedTy && not (isReferenceTyparTy g strippedTy) then + return! AddConstraint csenv 0 m NoTrace (destTyparTy g strippedTy) (TyparConstraint.IsReferenceType m) + | None -> + let tyString = NicePrint.minimalStringOfType csenv.DisplayEnv strippedTy + return! ErrorD(Error(FSComp.SR.tcTypeDoesNotHaveAnyNull(tyString), m)) + } and SolveTypeSupportsComparison (csenv: ConstraintSolverEnv) ndeep m2 trace ty = let g = csenv.g @@ -2261,8 +2722,8 @@ and SolveTypeSupportsComparison (csenv: ConstraintSolverEnv) ndeep m2 trace ty = ErrorD (ConstraintSolverError(FSComp.SR.csTypeDoesNotSupportComparison1(NicePrint.minimalStringOfType denv ty), m, m2)) | _ -> match ty with - | SpecialComparableHeadType g tinst -> - tinst |> IterateD (SolveTypeSupportsComparison (csenv: ConstraintSolverEnv) ndeep m2 trace) + | SpecialComparableHeadType g tinst -> + IterateD (SolveTypeSupportsComparison (csenv: ConstraintSolverEnv) ndeep m2 trace) tinst | _ -> // Check the basic requirement - IComparable or IStructuralComparable or assumed if ExistsSameHeadTypeInHierarchy g amap m2 ty g.mk_IComparable_ty || @@ -2442,7 +2903,7 @@ and SolveTypeRequiresDefaultConstructor (csenv: ConstraintSolverEnv) ndeep m2 tr | ValueSome tp -> AddConstraint csenv ndeep m2 trace tp (TyparConstraint.RequiresDefaultConstructor m) | _ -> - if isStructTy g ty then + if isStructTy g ty && (isStructTupleTy g ty || isStructAnonRecdTy g ty || TypeHasDefaultValue g m ty) then if isStructTupleTy g ty then destStructTupleTy g ty |> IterateD (SolveTypeRequiresDefaultValue csenv ndeep m trace) elif isStructAnonRecdTy g ty then @@ -2544,7 +3005,13 @@ and CanMemberSigsMatchUpToCheck else ErrorD(Error (FSComp.SR.csMemberIsNotInstance(minfo.LogicalName), m)) else - MapCombineTDC2D subsumeTypes calledObjArgTys callerObjArgTys + // The object types must be non-null + let nonNullCalledObjArgTys = + if not calledMeth.Method.IsExtensionMember then + calledObjArgTys |> List.map (replaceNullnessOfTy g.knownWithoutNull) + else + calledObjArgTys + MapCombineTDC2D subsumeTypes nonNullCalledObjArgTys callerObjArgTys let! usesTDC3 = calledMeth.ArgSets |> MapCombineTDCD (fun argSet -> @@ -2669,25 +3136,27 @@ and ArgsMustSubsumeOrConvert isConstraint enforceNullableOptionalsKnownTypes // use known types from nullable optional args? (calledArg: CalledArg) - (callerArg: CallerArg<'T>) = trackErrors { + (callerArg: CallerArg<'T>) = + trackErrors { + let g = csenv.g + let m = callerArg.Range + let calledArgTy, usesTDC, eqn = AdjustCalledArgType csenv.InfoReader ad isConstraint enforceNullableOptionalsKnownTypes calledArg callerArg + + match eqn with + | Some (ty1, ty2, msg) -> + do! SolveTypeEqualsTypeWithReport csenv ndeep m trace cxsln ty1 ty2 + msg csenv.DisplayEnv + | None -> () - let g = csenv.g - let m = callerArg.Range - let calledArgTy, usesTDC, eqn = AdjustCalledArgType csenv.InfoReader ad isConstraint enforceNullableOptionalsKnownTypes calledArg callerArg - match eqn with - | Some (ty1, ty2, msg) -> - do! SolveTypeEqualsTypeWithReport csenv ndeep m trace cxsln ty1 ty2 - msg csenv.DisplayEnv - | None -> () - match usesTDC with - | TypeDirectedConversionUsed.Yes(warn, _, _) -> do! WarnD(warn csenv.DisplayEnv) - | TypeDirectedConversionUsed.No -> () - do! SolveTypeSubsumesTypeWithReport csenv ndeep m trace cxsln (Some calledArg.CalledArgumentType) calledArgTy callerArg.CallerArgumentType - if calledArg.IsParamArray && isArray1DTy g calledArgTy && not (isArray1DTy g callerArg.CallerArgumentType) then - return! ErrorD(Error(FSComp.SR.csMethodExpectsParams(), m)) - else - return usesTDC - } + match usesTDC with + | TypeDirectedConversionUsed.Yes(warn, _, _) -> do! WarnD(warn csenv.DisplayEnv) + | TypeDirectedConversionUsed.No -> () + do! SolveTypeSubsumesTypeWithReport csenv ndeep m trace cxsln (Some calledArg.CalledArgumentType) calledArgTy callerArg.CallerArgumentType + if calledArg.IsParamArray && isArray1DTy g calledArgTy && not (isArray1DTy g callerArg.CallerArgumentType) then + return! ErrorD(Error(FSComp.SR.csMethodExpectsParams(), m)) + else + return usesTDC + } // This is a slight variation on ArgsMustSubsumeOrConvert that adds contextual error report to the // subsumption check. The two could likely be combines. @@ -3272,7 +3741,13 @@ and GetMostApplicableOverload csenv ndeep candidates applicableMeths calledMethG 0 if c <> 0 then c else - 0 + // Properties are kept incl. almost-duplicates because of the partial-override possibility. + // E.g. base can have get,set and derived only get => we keep both props around until method resolution time. + // Now is the type to pick the better (more derived) one. + match candidate.AssociatedPropertyInfo,other.AssociatedPropertyInfo,candidate.Method.IsExtensionMember,other.Method.IsExtensionMember with + | Some p1, Some p2, false, false -> compareTypes p1.ApparentEnclosingType p2.ApparentEnclosingType + | _ -> 0 + let bestMethods = let indexedApplicableMeths = applicableMeths |> List.indexed @@ -3482,6 +3957,13 @@ let AddCxMethodConstraint denv css m trace traitInfo = (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) |> RaiseOperationResult +let AddCxTypeDefnNotSupportsNull denv css m trace ty = + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv + PostponeOnFailedMemberConstraintResolution csenv trace + (fun csenv -> SolveTypeUseNotSupportsNull csenv 0 m trace ty) + (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) + |> RaiseOperationResult + let AddCxTypeUseSupportsNull denv css m trace ty = let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv PostponeOnFailedMemberConstraintResolution csenv trace @@ -3489,6 +3971,12 @@ let AddCxTypeUseSupportsNull denv css m trace ty = (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) |> RaiseOperationResult +let AddCxTypeCanCarryNullnessInfo denv css m ty nullness = + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv + let canCarryNullnessCheck() = SolveTypeCanCarryNullness csenv ty nullness |> RaiseOperationResult + csenv.SolverState.PushPostInferenceCheck (preDefaults=false, check = canCarryNullnessCheck) + + let AddCxTypeMustSupportComparison denv css m trace ty = let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv PostponeOnFailedMemberConstraintResolution csenv trace @@ -3581,46 +4069,53 @@ let CreateCodegenState tcVal g amap = ExtraCxs = HashMultiMap(10, HashIdentity.Structural) InfoReader = InfoReader(g, amap) PostInferenceChecksPreDefaults = ResizeArray() - PostInferenceChecksFinal = ResizeArray() } + PostInferenceChecksFinal = ResizeArray() + WarnWhenUsingWithoutNullOnAWithNullTarget = None} /// Determine if a codegen witness for a trait will require witness args to be available, e.g. in generic code -let CodegenWitnessExprForTraitConstraintWillRequireWitnessArgs tcVal g amap m (traitInfo:TraitConstraintInfo) = trackErrors { - let css = CreateCodegenState tcVal g amap - let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g) - let! _res = SolveMemberConstraint csenv true PermitWeakResolution.Yes 0 m NoTrace traitInfo - let res = - match traitInfo.Solution with - | None - | Some BuiltInSln -> true - | _ -> false - return res - } +let CodegenWitnessExprForTraitConstraintWillRequireWitnessArgs tcVal g amap m (traitInfo:TraitConstraintInfo) = + trackErrors { + let css = CreateCodegenState tcVal g amap + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g) + + let! _res = SolveMemberConstraint csenv true PermitWeakResolution.Yes 0 m NoTrace traitInfo + + let res = + match traitInfo.Solution with + | None + | Some BuiltInSln -> true + | _ -> false + return res + } /// Generate a witness expression if none is otherwise available, e.g. in legacy non-witness-passing code -let CodegenWitnessExprForTraitConstraint tcVal g amap m (traitInfo:TraitConstraintInfo) argExprs = trackErrors { - let css = CreateCodegenState tcVal g amap - let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g) - let! _res = SolveMemberConstraint csenv true PermitWeakResolution.Yes 0 m NoTrace traitInfo - return GenWitnessExpr amap g m traitInfo argExprs - } +let CodegenWitnessExprForTraitConstraint tcVal g amap m (traitInfo:TraitConstraintInfo) argExprs = + trackErrors { + let css = CreateCodegenState tcVal g amap + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g) + let! _res = SolveMemberConstraint csenv true PermitWeakResolution.Yes 0 m NoTrace traitInfo + return GenWitnessExpr amap g m traitInfo argExprs + } /// Generate the lambda argument passed for a use of a generic construct that accepts trait witnesses -let CodegenWitnessesForTyparInst tcVal g amap m typars tyargs = trackErrors { - let css = CreateCodegenState tcVal g amap - let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g) - let ftps, _renaming, tinst = FreshenTypeInst g m typars - let traitInfos = GetTraitConstraintInfosOfTypars g ftps - do! SolveTyparsEqualTypes csenv 0 m NoTrace tinst tyargs - return GenWitnessArgs amap g m traitInfos - } +let CodegenWitnessesForTyparInst tcVal g amap m typars tyargs = + trackErrors { + let css = CreateCodegenState tcVal g amap + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g) + let ftps, _renaming, tinst = FreshenTypeInst g m typars + let traitInfos = GetTraitConstraintInfosOfTypars g ftps + let! _res = SolveTyparsEqualTypes csenv 0 m NoTrace tinst tyargs + return GenWitnessArgs amap g m traitInfos + } /// Generate the lambda argument passed for a use of a generic construct that accepts trait witnesses -let CodegenWitnessArgForTraitConstraint tcVal g amap m traitInfo = trackErrors { - let css = CreateCodegenState tcVal g amap - let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g) - let! _res = SolveMemberConstraint csenv true PermitWeakResolution.Yes 0 m NoTrace traitInfo - return GenWitnessExprLambda amap g m traitInfo - } +let CodegenWitnessArgForTraitConstraint tcVal g amap m traitInfo = + trackErrors { + let css = CreateCodegenState tcVal g amap + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g) + let! _res = SolveMemberConstraint csenv true PermitWeakResolution.Yes 0 m NoTrace traitInfo + return GenWitnessExprLambda amap g m traitInfo + } /// For some code like "let f() = ([] = [])", a free choice is made for a type parameter /// for an interior type variable. This chooses a solution for a type parameter subject @@ -3670,7 +4165,8 @@ let IsApplicableMethApprox g amap m (minfo: MethInfo) availObjTy = ExtraCxs = HashMultiMap(10, HashIdentity.Structural) InfoReader = InfoReader(g, amap) PostInferenceChecksPreDefaults = ResizeArray() - PostInferenceChecksFinal = ResizeArray() } + PostInferenceChecksFinal = ResizeArray() + WarnWhenUsingWithoutNullOnAWithNullTarget = None} let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g) let minst = FreshenMethInfo m minfo match minfo.GetObjArgTypes(amap, m, minst) with @@ -3685,4 +4181,4 @@ let IsApplicableMethApprox g amap m (minfo: MethInfo) availObjTy = |> CommitOperationResult | _ -> true else - true + true \ No newline at end of file diff --git a/src/Compiler/Checking/ConstraintSolver.fsi b/src/Compiler/Checking/ConstraintSolver.fsi index aab7c04dfec..4c29d684c31 100644 --- a/src/Compiler/Checking/ConstraintSolver.fsi +++ b/src/Compiler/Checking/ConstraintSolver.fsi @@ -119,6 +119,28 @@ exception ConstraintSolverTypesNotInSubsumptionRelation of exception ConstraintSolverMissingConstraint of displayEnv: DisplayEnv * Typar * TyparConstraint * range * range +exception ConstraintSolverNullnessWarningEquivWithTypes of + DisplayEnv * + TType * + TType * + NullnessInfo * + NullnessInfo * + range * + range + +exception ConstraintSolverNullnessWarningWithTypes of + DisplayEnv * + TType * + TType * + NullnessInfo * + NullnessInfo * + range * + range + +exception ConstraintSolverNullnessWarningWithType of DisplayEnv * TType * NullnessInfo * range * range + +exception ConstraintSolverNullnessWarning of string * range * range + exception ConstraintSolverError of string * range * range exception ErrorFromApplyingDefault of @@ -166,8 +188,32 @@ exception ArgDoesNotMatchError of /// A function that denotes captured tcVal, Used in constraint solver and elsewhere to get appropriate expressions for a ValRef. type TcValF = ValRef -> ValUseFlag -> TType list -> range -> Expr * TType -[] type ConstraintSolverState = + { + g: TcGlobals + + amap: ImportMap + + InfoReader: InfoReader + + /// The function used to freshen values we encounter during trait constraint solving + TcVal: TcValF + + /// This table stores all unsolved, ungeneralized trait constraints, indexed by free type variable. + /// That is, there will be one entry in this table for each free type variable in + /// each outstanding, unsolved, ungeneralized trait constraint. Constraints are removed from the table and resolved + /// each time a solution to an index variable is found. + mutable ExtraCxs: Internal.Utilities.Collections.HashMultiMap + + /// Checks to run after all inference is complete, but before defaults are applied and internal unknowns solved + PostInferenceChecksPreDefaults: ResizeArray unit> + + /// Checks to run after all inference is complete. + PostInferenceChecksFinal: ResizeArray unit> + + WarnWhenUsingWithoutNullOnAWithNullTarget: string option + } + static member New: TcGlobals * ImportMap * InfoReader * TcValF -> ConstraintSolverState /// Add a post-inference check to run at the end of inference @@ -241,8 +287,12 @@ val AddCxTypeMustSubsumeTypeMatchingOnlyUndoIfFailed: val AddCxMethodConstraint: DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TraitConstraintInfo -> unit +val AddCxTypeDefnNotSupportsNull: DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit + val AddCxTypeUseSupportsNull: DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit +val AddCxTypeCanCarryNullnessInfo: DisplayEnv -> ConstraintSolverState -> range -> TType -> Nullness -> unit + val AddCxTypeMustSupportComparison: DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit val AddCxTypeMustSupportEquality: DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit diff --git a/src/Compiler/Checking/InfoReader.fs b/src/Compiler/Checking/InfoReader.fs index 3a36122e89e..1d085c195da 100644 --- a/src/Compiler/Checking/InfoReader.fs +++ b/src/Compiler/Checking/InfoReader.fs @@ -650,6 +650,11 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) as this = MethInfosEquivByNameAndSig EraseNone true g amap m, (fun minfo -> minfo.LogicalName)) + static let PropsGetterSetterEquiv innerEquality (p1:PropInfo) (p2:PropInfo) : bool = + p1.HasGetter = p2.HasGetter && + p1.HasSetter = p2.HasSetter && + innerEquality p1 p2 + /// Filter the overrides of properties, either keeping the overrides or keeping the dispatch slots. static let FilterOverridesOfPropInfos findFlag g amap m props = props @@ -658,7 +663,7 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) as this = (fun pinfo -> pinfo.IsNewSlot), (fun pinfo -> pinfo.IsDefiniteFSharpOverride), (fun _ -> false), - PropInfosEquivByNameAndSig EraseNone g amap m, + PropsGetterSetterEquiv (PropInfosEquivByNameAndSig EraseNone g amap m), (fun pinfo -> pinfo.PropertyName)) //type A() = @@ -714,7 +719,7 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) as this = /// Exclude properties from super types which have the same name as a property in a more specific type. static let ExcludeHiddenOfPropInfosImpl g amap m pinfos = pinfos - |> ExcludeItemsInSuperTypesBasedOnEquivTestWithItemsInSubTypes (fun (pinfo: PropInfo) -> pinfo.PropertyName) (PropInfosEquivByNameAndPartialSig EraseNone g amap m) + |> ExcludeItemsInSuperTypesBasedOnEquivTestWithItemsInSubTypes (fun (pinfo: PropInfo) -> pinfo.PropertyName) (PropsGetterSetterEquiv (PropInfosEquivByNameAndPartialSig EraseNone g amap m)) |> List.concat /// Make a cache for function 'f' keyed by type (plus some additional 'flags') that only @@ -728,7 +733,7 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) as this = // a decent hash function for these. canMemoize=(fun (_flags, _: range, ty) -> match stripTyEqns g ty with - | TType_app(tcref, [], _) -> tcref.TypeContents.tcaug_closed + | TType_app(tcref, [], _) -> tcref.TypeContents.tcaug_closed // TODO NULLNESS: consider whether ignoring _nullness is valid here | _ -> false), keyComparer= @@ -737,13 +742,13 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) as this = // Ignoring the ranges - that's OK. flagsEq.Equals(flags1, flags2) && match stripTyEqns g ty1, stripTyEqns g ty2 with - | TType_app(tcref1, [], _), TType_app(tcref2, [], _) -> tyconRefEq g tcref1 tcref2 + | TType_app(tcref1, [], _),TType_app(tcref2, [], _) -> tyconRefEq g tcref1 tcref2 // TODO NULLNESS: consider whether ignoring _nullness is valid here | _ -> false member _.GetHashCode((flags, _, ty)) = // Ignoring the ranges - that's OK. flagsEq.GetHashCode flags + (match stripTyEqns g ty with - | TType_app(tcref, [], _) -> hash tcref.LogicalName + | TType_app(tcref, [], _) -> hash tcref.LogicalName // TODO NULLNESS: consider whether ignoring _nullness is valid here | _ -> 0) }) let FindImplicitConversionsUncached (ad, m, ty) = @@ -1125,7 +1130,7 @@ let TryFindMetadataInfoOfExternalEntityRef (infoReader: InfoReader) m eref = // Generalize to get a formal signature let formalTypars = eref.Typars m let formalTypeInst = generalizeTypars formalTypars - let ty = TType_app(eref, formalTypeInst, 0uy) + let ty = TType_app(eref, formalTypeInst, KnownAmbivalentToNull) if isILAppTy g ty then let formalTypeInfo = ILTypeInfo.FromType g ty Some(nlref.Ccu.FileName, formalTypars, formalTypeInfo) @@ -1196,7 +1201,7 @@ let GetXmlDocSigOfMethInfo (infoReader: InfoReader) m (minfo: MethInfo) = match TryFindMetadataInfoOfExternalEntityRef infoReader m ilminfo.DeclaringTyconRef with | None -> None | Some (ccuFileName, formalTypars, formalTypeInfo) -> - let filminfo = ILMethInfo(g, formalTypeInfo.ToType, None, ilminfo.RawMetadata, fmtps) + let filminfo = ILMethInfo(g, IlType formalTypeInfo, ilminfo.RawMetadata, fmtps) let args = if ilminfo.IsILExtensionMethod then filminfo.GetRawArgTypes(amap, m, minfo.FormalMethodInst) diff --git a/src/Compiler/Checking/MethodCalls.fs b/src/Compiler/Checking/MethodCalls.fs index 46f32c53431..25f9d420f2e 100644 --- a/src/Compiler/Checking/MethodCalls.fs +++ b/src/Compiler/Checking/MethodCalls.fs @@ -480,7 +480,7 @@ let MakeCalledArgs amap m (minfo: MethInfo) minst = IsOutArg=isOutArg ReflArgInfo=reflArgInfo NameOpt=nmOpt - CalledArgumentType=calledArgTy }) + CalledArgumentType= changeWithNullReqTyToVariable amap.g calledArgTy}) /// /// Represents the syntactic matching between a caller of a method and the called method. @@ -1183,8 +1183,17 @@ let BuildMethodCall tcVal g amap isMutable m isProp minfo valUseFlags minst objA // Build a 'call' to a struct default constructor | DefaultStructCtor (g, ty) -> - if not (TypeHasDefaultValue g m ty) then - errorR(Error(FSComp.SR.tcDefaultStructConstructorCall(), m)) + if g.langFeatureNullness && g.checkNullness then + if not (TypeHasDefaultValueNew g m ty) then + // If the condition is detected because of a variation in logic introduced because + // of nullness checking, then only a warning is emitted. + if not (TypeHasDefaultValue g m ty) then + errorR(Error(FSComp.SR.tcDefaultStructConstructorCall(), m)) + else + warning(Error(FSComp.SR.tcDefaultStructConstructorCall(), m)) + else + if not (TypeHasDefaultValue g m ty) then + errorR(Error(FSComp.SR.tcDefaultStructConstructorCall(), m)) mkDefault (m, ty), ty) let ILFieldStaticChecks g amap infoReader ad m (finfo : ILFieldInfo) = @@ -1244,7 +1253,7 @@ let MethInfoChecks g amap isInstance tyargsOpt objArgs ad m (minfo: MethInfo) = /// Build a call to the System.Object constructor taking no arguments, let BuildObjCtorCall (g: TcGlobals) m = let ilMethRef = (mkILCtorMethSpecForTy(g.ilg.typ_Object, [])).MethodRef - Expr.Op (TOp.ILCall (false, false, false, false, CtorValUsedAsSuperInit, false, true, ilMethRef, [], [], [g.obj_ty]), [], [], m) + Expr.Op (TOp.ILCall (false, false, false, false, CtorValUsedAsSuperInit, false, true, ilMethRef, [], [], [g.obj_ty_noNulls]), [], [], m) /// Implements the elaborated form of adhoc conversions from functions to delegates at member callsites let BuildNewDelegateExpr (eventInfoOpt: EventInfo option, g, amap, delegateTy, delInvokeMeth: MethInfo, delArgTys, delFuncExpr, delFuncTy, m) = @@ -1425,7 +1434,7 @@ let rec GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g (calledArg: C | Some tref -> let ty = mkILNonGenericBoxedTy tref let mref = mkILCtorMethSpecForTy(ty, [g.ilg.typ_Object]).MethodRef - let expr = Expr.Op (TOp.ILCall (false, false, false, true, NormalValUse, false, false, mref, [], [], [g.obj_ty]), [], [mkDefault(mMethExpr, currCalledArgTy)], mMethExpr) + let expr = Expr.Op (TOp.ILCall (false, false, false, true, NormalValUse, false, false, mref, [], [], [g.obj_ty_noNulls]), [], [mkDefault(mMethExpr, currCalledArgTy)], mMethExpr) emptyPreBinder, expr | WrapperForIUnknown -> @@ -1434,7 +1443,7 @@ let rec GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g (calledArg: C | Some tref -> let ty = mkILNonGenericBoxedTy tref let mref = mkILCtorMethSpecForTy(ty, [g.ilg.typ_Object]).MethodRef - let expr = Expr.Op (TOp.ILCall (false, false, false, true, NormalValUse, false, false, mref, [], [], [g.obj_ty]), [], [mkDefault(mMethExpr, currCalledArgTy)], mMethExpr) + let expr = Expr.Op (TOp.ILCall (false, false, false, true, NormalValUse, false, false, mref, [], [], [g.obj_ty_noNulls]), [], [mkDefault(mMethExpr, currCalledArgTy)], mMethExpr) emptyPreBinder, expr | PassByRef (ty, dfltVal2) -> diff --git a/src/Compiler/Checking/MethodOverrides.fs b/src/Compiler/Checking/MethodOverrides.fs index 7e36d12ed9c..8d292666eeb 100644 --- a/src/Compiler/Checking/MethodOverrides.fs +++ b/src/Compiler/Checking/MethodOverrides.fs @@ -893,7 +893,7 @@ let FinalTypeDefinitionChecksAtEndOfInferenceScope (infoReader: InfoReader, nenv #endif Option.isNone tycon.GeneratedCompareToValues && tycon.HasInterface g g.mk_IComparable_ty && - not (tycon.HasOverride g "Equals" [g.obj_ty]) && + not (tycon.HasOverride g "Equals" [g.obj_ty_ambivalent]) && not tycon.IsFSharpInterfaceTycon then (* Warn when we're doing this for class types *) @@ -912,7 +912,7 @@ let FinalTypeDefinitionChecksAtEndOfInferenceScope (infoReader: InfoReader, nenv let tcaug = tycon.TypeContents let m = tycon.Range let hasExplicitObjectGetHashCode = tycon.HasOverride g "GetHashCode" [] - let hasExplicitObjectEqualsOverride = tycon.HasOverride g "Equals" [g.obj_ty] + let hasExplicitObjectEqualsOverride = tycon.HasOverride g "Equals" [g.obj_ty_ambivalent] if (Option.isSome tycon.GeneratedHashAndEqualsWithComparerValues) && (hasExplicitObjectGetHashCode || hasExplicitObjectEqualsOverride) then diff --git a/src/Compiler/Checking/NameResolution.fs b/src/Compiler/Checking/NameResolution.fs index 6605ae861f2..ba45fc52411 100644 --- a/src/Compiler/Checking/NameResolution.fs +++ b/src/Compiler/Checking/NameResolution.fs @@ -1110,7 +1110,7 @@ let GetNestedTyconRefsOfType (infoReader: InfoReader) (amap: Import.ImportMap) ( let MakeNestedType (ncenv: NameResolver) (tinst: TType list) m (tcrefNested: TyconRef) = let tps = match tcrefNested.Typars m with [] -> [] | l -> l[tinst.Length..] let tinstNested = ncenv.InstantiationGenerator m tps - mkAppTy tcrefNested (tinst @ tinstNested) + mkWoNullAppTy tcrefNested (tinst @ tinstNested) /// Get all the accessible nested types of an existing type. let GetNestedTypesOfType (ad, ncenv: NameResolver, optFilter, staticResInfo, checkForGenerated, m) ty = @@ -1528,7 +1528,7 @@ let AddDeclaredTyparsToNameEnv check nenv typars = /// a fresh set of inference type variables for the type parameters. let FreshenTycon (ncenv: NameResolver) m (tcref: TyconRef) = let tinst = ncenv.InstantiationGenerator m (tcref.Typars m) - let improvedTy = ncenv.g.decompileType tcref tinst + let improvedTy = ncenv.g.decompileType tcref tinst ncenv.g.knownWithoutNull improvedTy /// Convert a reference to a named type into a type that includes @@ -1536,7 +1536,7 @@ let FreshenTycon (ncenv: NameResolver) m (tcref: TyconRef) = let FreshenTyconWithEnclosingTypeInst (ncenv: NameResolver) m (tinstEnclosing: TypeInst) (tcref: TyconRef) = let tps = ncenv.InstantiationGenerator m (tcref.Typars m) let tinst = List.skip tinstEnclosing.Length tps - let improvedTy = ncenv.g.decompileType tcref (tinstEnclosing @ tinst) + let improvedTy = ncenv.g.decompileType tcref (tinstEnclosing @ tinst) ncenv.g.knownWithoutNull improvedTy /// Convert a reference to a union case into a UnionCaseInfo that includes @@ -3403,7 +3403,7 @@ let rec ResolvePatternLongIdentPrim sink (ncenv: NameResolver) fullyQualified wa | tcref :: _ when tcref.IsUnionTycon -> let res = ResolutionInfo.Empty.AddEntity (id.idRange, tcref) ResolutionInfo.SendEntityPathToSink (sink, ncenv, nenv, ItemOccurence.Pattern, ad, res, ResultTyparChecker(fun () -> true)) - Item.Types (id.idText, [ mkAppTy tcref [] ]) + Item.Types (id.idText, [ mkWoNullAppTy tcref [] ]) | _ -> match ResolveLongIdentAsModuleOrNamespace sink ncenv.amap id.idRange true fullyQualified nenv ad id [] false ShouldNotifySink.Yes with | Result ((_, mref, _) :: _) -> @@ -4020,7 +4020,7 @@ let ResolveNestedField sink (ncenv: NameResolver) nenv ad recdTy lid = match item with | Item.RecdField info -> info.FieldType | Item.AnonRecdField (_, tys, index, _) -> tys[index] - | _ -> g.obj_ty + | _ -> g.obj_ty_ambivalent idsBeforeField, (fieldId, item) :: (nestedFieldSearch [] fieldTy rest) diff --git a/src/Compiler/Checking/NicePrint.fs b/src/Compiler/Checking/NicePrint.fs index cec9d12f6ac..265f0570d7e 100644 --- a/src/Compiler/Checking/NicePrint.fs +++ b/src/Compiler/Checking/NicePrint.fs @@ -333,6 +333,13 @@ module internal PrintUtilities = | Some w -> Display.squashTo w layout | None -> layout + // When showing types in diagnostics, we don't show nullness annotations by default + // unless the diagnostic is specifically about nullness. + let suppressNullnessAnnotations denv = + match denv.showNullnessAnnotations with + | None -> { denv with showNullnessAnnotations = Some false } + | _ -> denv + module PrintIL = let fullySplitILTypeRef (tref: ILTypeRef) = @@ -790,6 +797,9 @@ module PrintTypes = | TyparConstraint.SupportsNull _ -> [wordL (tagKeyword "null") |> longConstraintPrefix] + | TyparConstraint.NotSupportsNull _ -> + [(wordL (tagKeyword "not null") (* ^^ wordL(tagKeyword "null") *) ) |> longConstraintPrefix] + | TyparConstraint.IsNonNullableStruct _ -> if denv.shortConstraints then [wordL (tagText "value type")] @@ -895,6 +905,16 @@ module PrintTypes = | [] -> tcL | [arg] -> layoutTypeWithInfoAndPrec denv env 2 arg ^^ tcL | args -> bracketIfL (prec <= 1) (bracketL (layoutTypesWithInfoAndPrec denv env 2 SepL.comma args) --- tcL) + + and layoutNullness (denv: DisplayEnv) part2 (nullness: Nullness) = + // Show nullness annotations unless explicitly turned off + if denv.showNullnessAnnotations <> Some false then + match nullness.Evaluate() with + | NullnessInfo.WithNull -> part2 ^^ wordL (tagText "| null") + | NullnessInfo.WithoutNull -> part2 + | NullnessInfo.AmbivalentToNull -> part2 //^^ wordL (tagText "__maybenull") + else + part2 /// Layout a type, taking precedence into account to insert brackets where needed and layoutTypeWithInfoAndPrec denv env prec ty = @@ -915,46 +935,52 @@ module PrintTypes = // Always prefer 'float' to 'float<1>' | TType_app (tc, args, _) when tc.IsMeasureableReprTycon && List.forall (isDimensionless g) args -> - layoutTypeWithInfoAndPrec denv env prec (reduceTyconRefMeasureableOrProvided g tc args) + layoutTypeWithInfoAndPrec denv env prec (reduceTyconRefMeasureableOrProvided g tc args) // Layout a type application - | TType_ucase (UnionCaseRef(tc, _), args) - | TType_app (tc, args, _) -> - let prefix = usePrefix denv tc - let demangledCompilationPathOpt, args = - if not denv.includeStaticParametersInTypeNames then - None, args - else - let regex = System.Text.RegularExpressions.Regex(@"\`\d+") - let path, skip = - (0, tc.CompilationPath.DemangledPath) - ||> List.mapFold (fun skip path -> - // Verify the path does not contain a generic parameter count. - // For example Foo`3 indicates that there are three parameters in args that belong to this path. - let m = regex.Match(path) - if not m.Success then - path, skip - else - let take = m.Value.Replace("`", "") |> int - let genericArgs = - List.skip skip args - |> List.take take - |> List.map (layoutTypeWithInfoAndPrec denv env prec >> showL) - |> String.concat "," - |> sprintf "<%s>" - String.Concat(path.Substring(0, m.Index), genericArgs), (skip + take) - ) - - Some path, List.skip skip args - - layoutTypeAppWithInfoAndPrec - denv - env - (layoutTyconRefImpl false denv tc demangledCompilationPathOpt) - prec - prefix - args + | TType_ucase (UnionCaseRef(tc, _), args) -> + let prefix = usePrefix denv tc + layoutTypeAppWithInfoAndPrec denv env (layoutTyconRefImpl false denv tc None) prec prefix args + | TType_app (tc, args, nullness) -> + let prefix = usePrefix denv tc + let demangledCompilationPathOpt, args = + if not denv.includeStaticParametersInTypeNames then + None, args + else + let regex = System.Text.RegularExpressions.Regex(@"\`\d+") + let path, skip = + (0, tc.CompilationPath.DemangledPath) + ||> List.mapFold (fun skip path -> + // Verify the path does not contain a generic parameter count. + // For example Foo`3 indicates that there are three parameters in args that belong to this path. + let m = regex.Match(path) + if not m.Success then + path, skip + else + let take = m.Value.Replace("`", "") |> int + let genericArgs = + List.skip skip args + |> List.take take + |> List.map (layoutTypeWithInfoAndPrec denv env prec >> showL) + |> String.concat "," + |> sprintf "<%s>" + String.Concat(path.Substring(0, m.Index), genericArgs), (skip + take) + ) + + Some path, List.skip skip args + + let part1 = + layoutTypeAppWithInfoAndPrec + denv + env + (layoutTyconRefImpl false denv tc demangledCompilationPathOpt) + prec + prefix + args + let part2 = layoutNullness denv part1 nullness + + part2 // Layout a tuple type | TType_anon (anonInfo, tys) -> let core = sepListL RightL.semicolon (List.map2 (fun nm ty -> wordL (tagField nm) ^^ RightL.colon ^^ layoutTypeWithInfoAndPrec denv env prec ty) (Array.toList anonInfo.SortedNames) tys) @@ -979,16 +1005,20 @@ module PrintTypes = | [h] -> layoutTyparRefWithInfo denv env h ^^ rightL dot --- tauL | h :: t -> spaceListL (List.map (layoutTyparRefWithInfo denv env) (h :: t)) ^^ rightL dot --- tauL - | TType_fun _ -> + | TType_fun (_, _, nullness) -> let argTys, retTy = stripFunTy g ty let retTyL = layoutTypeWithInfoAndPrec denv env 5 retTy let argTysL = argTys |> List.map (layoutTypeWithInfoAndPrec denv env 4) let funcTyL = curriedLayoutsL arrow argTysL retTyL - bracketIfL (prec <= 4) funcTyL + let part1 = bracketIfL (prec <= 4) funcTyL + let part2 = layoutNullness denv part1 nullness + part2 // Layout a type variable . - | TType_var (r, _) -> - layoutTyparRefWithInfo denv env r + | TType_var (r, nullness) -> + let part1 = layoutTyparRefWithInfo denv env r + let part2 = layoutNullness denv part1 nullness + part2 | TType_measure unt -> layoutMeasure denv unt @@ -1285,6 +1315,7 @@ module PrintTastMemberOrVals = nameL let prettyLayoutOfMemberShortOption denv typarInst (v: Val) short = + let denv = suppressNullnessAnnotations denv let vref = mkLocalValRef v let membInfo = Option.get vref.MemberInfo let stat = layoutMemberFlags membInfo.MemberFlags @@ -1615,14 +1646,14 @@ module InfoMemberPrinting = // Prettify an ILMethInfo let prettifyILMethInfo (amap: Import.ImportMap) m (minfo: MethInfo) typarInst ilMethInfo = - let (ILMethInfo(_, apparentTy, dty, mdef, _)) = ilMethInfo - let (prettyTyparInst, prettyTys), _ = PrettyTypes.PrettifyInstAndTypes amap.g (typarInst, (apparentTy :: minfo.FormalMethodInst)) + let (ILMethInfo(_, methodsType, mdef, _)) = ilMethInfo + let (prettyTyparInst, prettyTys), _ = PrettyTypes.PrettifyInstAndTypes amap.g (typarInst, (methodsType.ToType :: minfo.FormalMethodInst)) match prettyTys with | prettyApparentTy :: prettyFormalMethInst -> let prettyMethInfo = - match dty with - | None -> MethInfo.CreateILMeth (amap, m, prettyApparentTy, mdef) - | Some declaringTyconRef -> MethInfo.CreateILExtensionMeth(amap, m, prettyApparentTy, declaringTyconRef, minfo.ExtensionMemberPriorityOption, mdef) + match methodsType with + | IlType _ -> MethInfo.CreateILMeth (amap, m, prettyApparentTy, mdef) + | CSharpStyleExtension(declaring=declaringTyconRef) -> MethInfo.CreateILExtensionMeth(amap, m, prettyApparentTy, declaringTyconRef, minfo.ExtensionMemberPriorityOption, mdef) prettyTyparInst, prettyMethInfo, prettyFormalMethInst | _ -> failwith "prettifyILMethInfo - prettyTys empty" @@ -2747,6 +2778,8 @@ let prettyLayoutOfInstAndSig denv x = PrintTypes.prettyLayoutOfInstAndSig denv x let minimalStringsOfTwoTypes denv ty1 ty2 = let (ty1, ty2), tpcs = PrettyTypes.PrettifyTypePair denv.g (ty1, ty2) + let denv = suppressNullnessAnnotations denv + // try denv + no type annotations let attempt1 = let denv = { denv with showInferenceTyparAnnotations=false; showStaticallyResolvedTyparAnnotations=false } @@ -2769,6 +2802,7 @@ let minimalStringsOfTwoTypes denv ty1 ty2 = | Some res -> res | None -> + // try denv let attempt3 = let min1 = stringOfTy denv ty1 let min2 = stringOfTy denv ty2 @@ -2794,13 +2828,14 @@ let minimalStringsOfTwoTypes denv ty1 ty2 = let denv = denv.SetOpenPaths [] let denv = { denv with includeStaticParametersInTypeNames=true } let makeName t = - let assemblyName = PrintTypes.layoutAssemblyName denv t |> fun name -> if String.IsNullOrEmpty(name) then "" else sprintf " (%s)" name + let assemblyName = PrintTypes.layoutAssemblyName denv t |> function null | "" -> "" | name -> sprintf " (%s)" name sprintf "%s%s" (stringOfTy denv t) assemblyName (makeName ty1, makeName ty2, stringOfTyparConstraints denv tpcs) // Note: Always show imperative annotations when comparing value signatures let minimalStringsOfTwoValues denv infoReader vref1 vref2 = + let denv = suppressNullnessAnnotations denv let denvMin = { denv with showInferenceTyparAnnotations=true; showStaticallyResolvedTyparAnnotations=false } let min1 = buildString (fun buf -> outputQualifiedValOrMember denvMin infoReader buf vref1) let min2 = buildString (fun buf -> outputQualifiedValOrMember denvMin infoReader buf vref2) @@ -2814,5 +2849,6 @@ let minimalStringsOfTwoValues denv infoReader vref1 vref2 = let minimalStringOfType denv ty = let ty, _cxs = PrettyTypes.PrettifyType denv.g ty + let denv = suppressNullnessAnnotations denv let denvMin = { denv with showInferenceTyparAnnotations=false; showStaticallyResolvedTyparAnnotations=false } showL (PrintTypes.layoutTypeWithInfoAndPrec denvMin SimplifyTypes.typeSimplificationInfo0 2 ty) diff --git a/src/Compiler/Checking/PatternMatchCompilation.fs b/src/Compiler/Checking/PatternMatchCompilation.fs index a1e9009798d..4855925bff1 100644 --- a/src/Compiler/Checking/PatternMatchCompilation.fs +++ b/src/Compiler/Checking/PatternMatchCompilation.fs @@ -611,7 +611,7 @@ let getDiscrimOfPattern (g: TcGlobals) tpinst t = | TPat_isinst (srcTy, tgtTy, _, _m) -> Some(DecisionTreeTest.IsInst (instType tpinst srcTy, instType tpinst tgtTy)) | TPat_exnconstr(tcref, _, _m) -> - Some(DecisionTreeTest.IsInst (g.exn_ty, mkAppTy tcref [])) + Some(DecisionTreeTest.IsInst (g.exn_ty, mkWoNullAppTy tcref [])) | TPat_const (c, _m) -> Some(DecisionTreeTest.Const c) | TPat_unioncase (c, tyargs', _, _m) -> @@ -1467,7 +1467,7 @@ let CompilePatternBasic | TPat_exnconstr (ecref, argpats, _) -> let srcTy1 = g.exn_ty - let tgtTy1 = mkAppTy ecref [] + let tgtTy1 = mkWoNullAppTy ecref [] if taken |> List.exists (discrimsEq g (DecisionTreeTest.IsInst (srcTy1, tgtTy1))) then [] else match discrim with diff --git a/src/Compiler/Checking/PostInferenceChecks.fs b/src/Compiler/Checking/PostInferenceChecks.fs index c7090709cca..878a70939d0 100644 --- a/src/Compiler/Checking/PostInferenceChecks.fs +++ b/src/Compiler/Checking/PostInferenceChecks.fs @@ -427,6 +427,7 @@ and CheckTypeConstraintDeep cenv f g env x = | TyparConstraint.SupportsComparison _ | TyparConstraint.SupportsEquality _ | TyparConstraint.SupportsNull _ + | TyparConstraint.NotSupportsNull _ | TyparConstraint.IsNonNullableStruct _ | TyparConstraint.IsUnmanaged _ | TyparConstraint.IsReferenceType _ @@ -2532,13 +2533,30 @@ let CheckEntityDefn cenv env (tycon: Entity) = // Check fields. We check these late because we have to have first checked that the structs are // free of cycles - if tycon.IsStructOrEnumTycon then + if g.langFeatureNullness && g.checkNullness then for f in tycon.AllInstanceFieldsAsList do + let m = f.Range // Check if it's marked unsafe let zeroInitUnsafe = TryFindFSharpBoolAttribute g g.attrib_DefaultValueAttribute f.FieldAttribs if zeroInitUnsafe = Some true then - if not (TypeHasDefaultValue g m ty) then - errorR(Error(FSComp.SR.chkValueWithDefaultValueMustHaveDefaultValue(), m)) + let ty = f.FormalType + // If the condition is detected because of a variation in logic introduced because + // of nullness checking, then only a warning is emitted. + if not (TypeHasDefaultValueNew g m ty) then + if not (TypeHasDefaultValue g m ty) then + errorR(Error(FSComp.SR.chkValueWithDefaultValueMustHaveDefaultValue(), m)) + else + warning(Error(FSComp.SR.chkValueWithDefaultValueMustHaveDefaultValue(), m)) + + // These are the old rules (not g.langFeatureNullness or not g.checkNullness), mistakenly only applied to structs + elif tycon.IsStructOrEnumTycon then + for f in tycon.AllInstanceFieldsAsList do + let m = f.Range + // Check if it's marked unsafe + let zeroInitUnsafe = TryFindFSharpBoolAttribute g g.attrib_DefaultValueAttribute f.FieldAttribs + if zeroInitUnsafe = Some true then + if not (TypeHasDefaultValue g m f.FormalType) then + errorR(Error(FSComp.SR.chkValueWithDefaultValueMustHaveDefaultValue(), m)) // Check type abbreviations match tycon.TypeAbbrev with diff --git a/src/Compiler/Checking/QuotationTranslator.fs b/src/Compiler/Checking/QuotationTranslator.fs index 8173c13755f..1ee9fb9fbd3 100644 --- a/src/Compiler/Checking/QuotationTranslator.fs +++ b/src/Compiler/Checking/QuotationTranslator.fs @@ -584,7 +584,7 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP. | TOp.ExnConstr tcref, _, args -> let _rgtypR = ConvTyconRef cenv tcref m - let _typ = mkAppTy tcref [] + let _typ = mkWoNullAppTy tcref [] let parentTyconR = ConvTyconRef cenv tcref m let argTys = tcref |> recdFieldsOfExnDefRef |> List.map (fun rfld -> rfld.FormalType) let methArgTypesR = ConvTypes cenv env m argTys @@ -1223,7 +1223,7 @@ and ConvILType cenv env m ty = and TryElimErasableTyconRef cenv m (tcref: TyconRef) = match tcref.TypeReprInfo with // Get the base type - | TProvidedTypeRepr info when info.IsErased -> Some (info.BaseTypeForErased (m, cenv.g.obj_ty)) + | TProvidedTypeRepr info when info.IsErased -> Some (info.BaseTypeForErased (m, cenv.g.obj_ty_withNulls)) | _ -> None #endif diff --git a/src/Compiler/Checking/SignatureConformance.fs b/src/Compiler/Checking/SignatureConformance.fs index 08a3be709b4..8e8dc84eb2b 100644 --- a/src/Compiler/Checking/SignatureConformance.fs +++ b/src/Compiler/Checking/SignatureConformance.fs @@ -239,7 +239,7 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = else let aNull2 = TypeNullIsExtraValue g m (generalizedTyconRef g (mkLocalTyconRef implTycon)) - let fNull2 = TypeNullIsExtraValue g m (generalizedTyconRef g (mkLocalTyconRef implTycon)) + let fNull2 = TypeNullIsExtraValue g m (generalizedTyconRef g (mkLocalTyconRef implTycon)) // TODO: should be sigTycon, raises extra errors if aNull2 && not fNull2 then errorR(Error(FSComp.SR.DefinitionsInSigAndImplNotCompatibleImplementationSaysNull2(implTycon.TypeOrMeasureKind.ToString(), implTycon.DisplayName), m)) false diff --git a/src/Compiler/Checking/SignatureHash.fs b/src/Compiler/Checking/SignatureHash.fs index 4acd53e0fad..e04a26aa393 100644 --- a/src/Compiler/Checking/SignatureHash.fs +++ b/src/Compiler/Checking/SignatureHash.fs @@ -164,6 +164,7 @@ module rec HashTypes = | TyparConstraint.IsReferenceType _ -> tpHash @@ 11 | TyparConstraint.SimpleChoice(tys, _) -> tpHash @@ 12 @@ (tys |> hashListOrderIndependent (hashTType g)) | TyparConstraint.RequiresDefaultConstructor _ -> tpHash @@ 13 + | TyparConstraint.NotSupportsNull(_) -> tpHash @@ 14 /// Hash type parameter constraints let private hashConstraints (g: TcGlobals) cxs = diff --git a/src/Compiler/Checking/TypeHierarchy.fs b/src/Compiler/Checking/TypeHierarchy.fs index a778b516d99..1ab418c276a 100644 --- a/src/Compiler/Checking/TypeHierarchy.fs +++ b/src/Compiler/Checking/TypeHierarchy.fs @@ -9,6 +9,7 @@ open FSharp.Compiler open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.DiagnosticsLogger open FSharp.Compiler.Import +open FSharp.Compiler.Import.Nullness open FSharp.Compiler.Features open FSharp.Compiler.Syntax open FSharp.Compiler.SyntaxTreeOps @@ -46,7 +47,7 @@ let GetSuperTypeOfType g amap m ty = #if !NO_TYPEPROVIDERS | ProvidedTypeMetadata info -> let st = info.ProvidedType - let superOpt = st.PApplyOption((fun st -> match st.BaseType with null -> None | t -> Some t), m) + let superOpt = st.PApplyOption((fun st -> match st.BaseType with null -> None | t -> Some (nonNull t)), m) match superOpt with | None -> None | Some super -> Some(ImportProvidedType amap m super) @@ -55,7 +56,10 @@ let GetSuperTypeOfType g amap m ty = let tinst = argsOfAppTy g ty match tdef.Extends with | None -> None - | Some ilTy -> Some (RescopeAndImportILType scoref amap m tinst ilTy) + | Some ilTy -> // 'inherit' can refer to a type which has nullable type arguments (e.g. List) + let typeAttrs = AttributesFromIL(tdef.MetadataIndex,tdef.CustomAttrsStored) + let nullness = {DirectAttributes = typeAttrs; Fallback = FromClass typeAttrs} + Some (RescopeAndImportILType scoref amap m tinst nullness ilTy) | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> if isFSharpObjModelTy g ty || isFSharpExceptionTy g ty then @@ -64,7 +68,7 @@ let GetSuperTypeOfType g amap m ty = elif isArrayTy g ty then Some g.system_Array_ty elif isRefTy g ty && not (isObjTy g ty) then - Some g.obj_ty + Some g.obj_ty_noNulls elif isStructTupleTy g ty then Some g.system_Value_ty elif isFSharpStructOrEnumTy g ty then @@ -75,13 +79,19 @@ let GetSuperTypeOfType g amap m ty = elif isStructAnonRecdTy g ty then Some g.system_Value_ty elif isAnonRecdTy g ty then - Some g.obj_ty + Some g.obj_ty_noNulls elif isRecdTy g ty || isUnionTy g ty then - Some g.obj_ty + Some g.obj_ty_noNulls else None - resBeforeNull + match resBeforeNull with + | Some superTy -> + let nullness = nullnessOfTy g ty + let superTyWithNull = addNullnessToTy nullness superTy + Some superTyWithNull + | None -> + None /// Make a type for System.Collections.Generic.IList let mkSystemCollectionsGenericIListTy (g: TcGlobals) ty = @@ -107,9 +117,17 @@ let GetImmediateInterfacesOfMetadataType g amap m skipUnref ty (tcref: TyconRef) // succeeded with more reported. There are pathological corner cases where this // doesn't apply: e.g. for mscorlib interfaces like IComparable, but we can always // assume those are present. - for intfTy in tdef.Implements do - if skipUnref = SkipUnrefInterfaces.No || CanRescopeAndImportILType scoref amap m intfTy then - RescopeAndImportILType scoref amap m tinst intfTy + match tdef.ImplementsCustomAttrs with + | Some attrsList when g.langFeatureNullness && g.checkNullness -> + for (attrs,attrsIdx),intfTy in tdef.Implements |> List.zip attrsList do + if skipUnref = SkipUnrefInterfaces.No || CanRescopeAndImportILType scoref amap m intfTy then + let typeAttrs = AttributesFromIL(attrsIdx,attrs) + let nullness = {DirectAttributes = typeAttrs; Fallback = FromClass typeAttrs} + RescopeAndImportILType scoref amap m tinst nullness intfTy + | _ -> + for intfTy in tdef.Implements do + if skipUnref = SkipUnrefInterfaces.No || CanRescopeAndImportILType scoref amap m intfTy then + RescopeAndImportILTypeSkipNullness scoref amap m tinst intfTy | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> for intfTy in tcref.ImmediateInterfaceTypesOfFSharpTycon do instType (mkInstForAppTy g ty) intfTy ] @@ -183,10 +201,10 @@ and GetImmediateInterfacesOfMeasureAnnotatedType skipUnref g amap m ty reprTy = // However since F# 2.0 we have always reported these interfaces for all measure-annotated types. //if ExistsInInterfaceHierarchy (typeEquiv g (mkAppTy g.system_GenericIComparable_tcref [reprTy])) skipUnref g amap m ty then - mkAppTy g.system_GenericIComparable_tcref [ty] + mkWoNullAppTy g.system_GenericIComparable_tcref [ty] //if ExistsInInterfaceHierarchy (typeEquiv g (mkAppTy g.system_GenericIEquatable_tcref [reprTy])) skipUnref g amap m ty then - mkAppTy g.system_GenericIEquatable_tcref [ty] + mkWoNullAppTy g.system_GenericIEquatable_tcref [ty] ] // Check for any System.Numerics type in the interface hierarchy @@ -249,11 +267,11 @@ let FoldHierarchyOfTypeAux followInterfaces allowMultiIntfInst skipUnref visitor List.foldBack (loop (ndeep+1)) (GetImmediateInterfacesOfType skipUnref g amap m ty) - (loop ndeep g.obj_ty state) + (loop ndeep g.obj_ty_noNulls state) else match tryDestTyparTy g ty with | ValueSome tp -> - let state = loop (ndeep+1) g.obj_ty state + let state = loop (ndeep+1) g.obj_ty_noNulls state List.foldBack (fun x vacc -> match x with @@ -264,6 +282,7 @@ let FoldHierarchyOfTypeAux followInterfaces allowMultiIntfInst skipUnref visitor | TyparConstraint.IsEnum _ | TyparConstraint.IsDelegate _ | TyparConstraint.SupportsNull _ + | TyparConstraint.NotSupportsNull _ | TyparConstraint.IsNonNullableStruct _ | TyparConstraint.IsUnmanaged _ | TyparConstraint.IsReferenceType _ @@ -349,33 +368,38 @@ let ExistsHeadTypeInEntireHierarchy g amap m typeToSearchFrom tcrefToLookFor = ExistsInEntireHierarchyOfType (HasHeadType g tcrefToLookFor) g amap m AllowMultiIntfInstantiations.Yes typeToSearchFrom /// Read an Abstract IL type from metadata and convert to an F# type. -let ImportILTypeFromMetadata amap m scoref tinst minst ilTy = - RescopeAndImportILType scoref amap m (tinst@minst) ilTy +let ImportILTypeFromMetadata amap m scoref tinst minst nullnessSource ilTy = + RescopeAndImportILType scoref amap m (tinst@minst) nullnessSource ilTy + +/// Read an Abstract IL type from metadata and convert to an F# type, ignoring nullness checking. +let ImportILTypeFromMetadataSkipNullness amap m scoref tinst minst ilTy = + RescopeAndImportILTypeSkipNullness scoref amap m (tinst@minst) ilTy /// Read an Abstract IL type from metadata, including any attributes that may affect the type itself, and convert to an F# type. -let ImportILTypeFromMetadataWithAttributes amap m scoref tinst minst ilTy getCattrs = - let ty = RescopeAndImportILType scoref amap m (tinst@minst) ilTy +let ImportILTypeFromMetadataWithAttributes amap m scoref tinst minst nullnessSource ilTy = + let ty = RescopeAndImportILType scoref amap m (tinst@minst) nullnessSource ilTy + // If the type is a byref and one of attributes from a return or parameter has // - a `IsReadOnlyAttribute` - it's an inref // - a `RequiresLocationAttribute` (in which case it's a `ref readonly`) which we treat as inref, // latter is an ad-hoc fix for https://github.com/dotnet/runtime/issues/94317. if isByrefTy amap.g ty - && (TryFindILAttribute amap.g.attrib_IsReadOnlyAttribute (getCattrs ()) - || TryFindILAttribute amap.g.attrib_RequiresLocationAttribute (getCattrs ())) then + && (TryFindILAttribute amap.g.attrib_IsReadOnlyAttribute (nullnessSource.DirectAttributes.Read()) + || TryFindILAttribute amap.g.attrib_RequiresLocationAttribute (nullnessSource.DirectAttributes.Read())) then mkInByrefTy amap.g (destByrefTy amap.g ty) else ty /// Get the parameter type of an IL method. -let ImportParameterTypeFromMetadata amap m ilTy getCattrs scoref tinst mist = - ImportILTypeFromMetadataWithAttributes amap m scoref tinst mist ilTy getCattrs +let ImportParameterTypeFromMetadata amap m nullnessSource ilTy scoref tinst mist = + ImportILTypeFromMetadataWithAttributes amap m scoref tinst mist nullnessSource ilTy /// Get the return type of an IL method, taking into account instantiations for type, return attributes and method generic parameters, and /// translating 'void' to 'None'. -let ImportReturnTypeFromMetadata amap m ilTy getCattrs scoref tinst minst = +let ImportReturnTypeFromMetadata amap m nullnessSource ilTy scoref tinst minst = match ilTy with | ILType.Void -> None - | retTy -> Some(ImportILTypeFromMetadataWithAttributes amap m scoref tinst minst retTy getCattrs) + | retTy -> Some(ImportILTypeFromMetadataWithAttributes amap m scoref tinst minst nullnessSource retTy ) /// Copy constraints. If the constraint comes from a type parameter associated @@ -400,6 +424,8 @@ let CopyTyparConstraints m tprefInst (tporig: Typar) = TyparConstraint.IsEnum (instType tprefInst underlyingTy, m) | TyparConstraint.SupportsComparison _ -> TyparConstraint.SupportsComparison m + | TyparConstraint.NotSupportsNull _ -> + TyparConstraint.NotSupportsNull m | TyparConstraint.SupportsEquality _ -> TyparConstraint.SupportsEquality m | TyparConstraint.IsDelegate(argTys, retTy, _) -> diff --git a/src/Compiler/Checking/TypeHierarchy.fsi b/src/Compiler/Checking/TypeHierarchy.fsi index 225e6187477..8633f9827f9 100644 --- a/src/Compiler/Checking/TypeHierarchy.fsi +++ b/src/Compiler/Checking/TypeHierarchy.fsi @@ -117,6 +117,17 @@ val ExistsHeadTypeInEntireHierarchy: /// Read an Abstract IL type from metadata and convert to an F# type. val ImportILTypeFromMetadata: + amap: ImportMap -> + m: range -> + scoref: ILScopeRef -> + tinst: TType list -> + minst: TType list -> + nullnessSource: Nullness.NullableAttributesSource -> + ilTy: ILType -> + TType + +/// Read an Abstract IL type from metadata and convert to an F# type, ignoring nullness checking. +val ImportILTypeFromMetadataSkipNullness: amap: ImportMap -> m: range -> scoref: ILScopeRef -> tinst: TType list -> minst: TType list -> ilTy: ILType -> TType /// Read an Abstract IL type from metadata, including any attributes that may affect the type itself, and convert to an F# type. @@ -126,16 +137,16 @@ val ImportILTypeFromMetadataWithAttributes: scoref: ILScopeRef -> tinst: TType list -> minst: TType list -> + nullnessSource: Nullness.NullableAttributesSource -> ilTy: ILType -> - getCattrs: (unit -> ILAttributes) -> TType /// Get the parameter type of an IL method. val ImportParameterTypeFromMetadata: amap: ImportMap -> m: range -> + nullnessSource: Nullness.NullableAttributesSource -> ilTy: ILType -> - getCattrs: (unit -> ILAttributes) -> scoref: ILScopeRef -> tinst: TType list -> mist: TType list -> @@ -146,8 +157,8 @@ val ImportParameterTypeFromMetadata: val ImportReturnTypeFromMetadata: amap: ImportMap -> m: range -> + nullnessSource: Nullness.NullableAttributesSource -> ilTy: ILType -> - getCattrs: (unit -> ILAttributes) -> scoref: ILScopeRef -> tinst: TType list -> minst: TType list -> diff --git a/src/Compiler/Checking/TypeRelations.fs b/src/Compiler/Checking/TypeRelations.fs index 49afd4825b6..16ed5e9f9d3 100644 --- a/src/Compiler/Checking/TypeRelations.fs +++ b/src/Compiler/Checking/TypeRelations.fs @@ -31,7 +31,7 @@ let rec TypeDefinitelySubsumesTypeNoCoercion ndeep g amap m ty1 ty2 = let ty1 = stripTyEqns g ty1 let ty2 = stripTyEqns g ty2 // F# reference types are subtypes of type 'obj' - (typeEquiv g ty1 g.obj_ty && isRefTy g ty2) || + (typeEquiv g ty1 g.obj_ty_ambivalent && isRefTy g ty2) || // Follow the supertype chain (isAppTy g ty2 && isRefTy g ty2 && @@ -138,7 +138,7 @@ let ChooseTyparSolutionAndRange (g: TcGlobals) amap (tp:Typar) = let (maxTy, isRefined), m = let initialTy = match tp.Kind with - | TyparKind.Type -> g.obj_ty + | TyparKind.Type -> g.obj_ty_noNulls | TyparKind.Measure -> TType_measure Measure.One // Loop through the constraints computing the lub (((initialTy, false), m), tp.Constraints) ||> List.fold (fun ((maxTy, isRefined), _) tpc -> @@ -157,7 +157,9 @@ let ChooseTyparSolutionAndRange (g: TcGlobals) amap (tp:Typar) = errorR(Error(FSComp.SR.typrelCannotResolveAmbiguityInPrintf(), m)) (maxTy, isRefined), m | TyparConstraint.SupportsNull m -> - (maxTy, isRefined), m + ((addNullnessToTy KnownWithNull maxTy), isRefined), m + | TyparConstraint.NotSupportsNull m -> + (maxTy, isRefined), m // NOTE: this doesn't "force" non-nullness, since it is the default choice in 'obj' or 'int' | TyparConstraint.SupportsComparison m -> join m g.mk_IComparable_ty, m | TyparConstraint.SupportsEquality m -> diff --git a/src/Compiler/Checking/import.fs b/src/Compiler/Checking/import.fs index 70e07fb26ec..4fbb7312584 100644 --- a/src/Compiler/Checking/import.fs +++ b/src/Compiler/Checking/import.fs @@ -163,8 +163,124 @@ let CanImportILTypeRef (env: ImportMap) m (tref: ILTypeRef) = /// /// Prefer the F# abbreviation for some built-in types, e.g. 'string' rather than /// 'System.String', since we prefer the F# abbreviation to the .NET equivalents. -let ImportTyconRefApp (env: ImportMap) tcref tyargs = - env.g.improveType tcref tyargs +let ImportTyconRefApp (env: ImportMap) tcref tyargs nullness = + env.g.improveType tcref tyargs nullness + + +module Nullness = + + open FSharp.Compiler.AbstractIL.Diagnostics + + let arrayWithByte0 = [|0uy|] + let arrayWithByte1 = [|1uy|] + let arrayWithByte2 = [|2uy|] + + let knownAmbivalent = NullnessInfo.AmbivalentToNull |> Nullness.Known + let knownWithoutNull = NullnessInfo.WithoutNull |> Nullness.Known + let knownNullable = NullnessInfo.WithNull |> Nullness.Known + + let mapping byteValue = + match byteValue with + | 0uy -> knownAmbivalent + | 1uy -> knownWithoutNull + | 2uy -> knownNullable + | _ -> + dprintfn "%i was passed to Nullness mapping, this is not a valid value" byteValue + knownAmbivalent + + let isByte (g:TcGlobals) (ilgType:ILType) = + g.ilg.typ_Byte.BasicQualifiedName = ilgType.BasicQualifiedName + + let tryParseAttributeDataToNullableByteFlags (g:TcGlobals) attrData = + match attrData with + | None -> ValueNone + | Some ([ILAttribElem.Byte 0uy],_) -> ValueSome arrayWithByte0 + | Some ([ILAttribElem.Byte 1uy],_) -> ValueSome arrayWithByte1 + | Some ([ILAttribElem.Byte 2uy],_) -> ValueSome arrayWithByte2 + | Some ([ILAttribElem.Array(byteType,listOfBytes)],_) when isByte g byteType -> + listOfBytes + |> Array.ofList + |> Array.choose(function | ILAttribElem.Byte b -> Some b | _ -> None) + |> ValueSome + + | _ -> ValueNone + + [] + type AttributesFromIL = AttributesFromIL of metadataIndex:int * attrs:ILAttributesStored + with + member this.Read() = match this with| AttributesFromIL(idx,attrs) -> attrs.GetCustomAttrs(idx) + member this.GetNullable(g:TcGlobals) = + match g.attrib_NullableAttribute_opt with + | None -> ValueNone + | Some n -> + TryDecodeILAttribute n.TypeRef (this.Read()) + |> tryParseAttributeDataToNullableByteFlags g + + member this.GetNullableContext(g:TcGlobals) = + match g.attrib_NullableContextAttribute_opt with + | None -> ValueNone + | Some n -> + TryDecodeILAttribute n.TypeRef (this.Read()) + |> tryParseAttributeDataToNullableByteFlags g + + [] + type NullableContextSource = + | FromClass of AttributesFromIL + | FromMethodAndClass of methodAttrs:AttributesFromIL * classAttrs:AttributesFromIL + + [] + type NullableAttributesSource = + { DirectAttributes: AttributesFromIL + Fallback : NullableContextSource} + with + member this.GetFlags(g:TcGlobals) = + let fallback = this.Fallback + this.DirectAttributes.GetNullable(g) + |> ValueOption.orElseWith(fun () -> + match fallback with + | FromClass attrs -> attrs.GetNullableContext(g) + | FromMethodAndClass(methodCtx,classCtx) -> + methodCtx.GetNullableContext(g) + |> ValueOption.orElseWith (fun () -> classCtx.GetNullableContext(g))) + |> ValueOption.defaultValue arrayWithByte0 + static member Empty = + let emptyFromIL = AttributesFromIL(0,Given(ILAttributes.Empty)) + {DirectAttributes = emptyFromIL; Fallback = FromClass(emptyFromIL)} + + [] + type NullableFlags = {Data : byte[]; Idx : int } +(* Nullness logic for generic arguments: +The data which comes from NullableAttribute back might be a flat array, or a scalar (which represents a virtual array of unknown size) +The array is passed trough all generic typars depth first , e.g. List,Uri>> + -- see here how the array indexes map to types above: [| 0 1 2 3 4 5 |] +For value types, a value is passed even though it is always 0 +*) + with + member this.GetNullness() = + match this.Data.Length with + // No nullable data nor parent context -> we cannot tell + | 0 -> knownAmbivalent + // A scalar value from attributes, cover type and all it's potential typars + | 1 -> this.Data[0] |> mapping + // We have a bigger array, indexes map to typars in a depth-first fashion + | n when n > this.Idx -> this.Data[this.Idx] |> mapping + // This is an errornous case, we need more nullnessinfo then the metadata contains + | _ -> + // TODO nullness - once being confident that our bugs are solved and what remains are incoming metadata bugs, remove failwith and replace with dprintfn + // Testing with .NET compilers other then Roslyn producing nullness metadata? + failwithf "Length of Nullable metadata and needs of its processing do not match: %A" this + knownAmbivalent + + member this.Advance() = {Data = this.Data; Idx = this.Idx + 1} + + let inline evaluateFirstOrderNullnessAndAdvance (ilt:ILType) (flags:NullableFlags) = + match ilt with + | ILType.Value tspec when tspec.GenericArgs.IsEmpty -> KnownWithoutNull, flags + // System.Nullable is special-cased in C# spec for nullnes metadata. + // You CAN assign 'null' to it, and when boxed, it CAN be boxed to 'null'. + | ILType.Value tspec when tspec.Name = "Nullable`1" && tspec.Enclosing = ["System"] -> KnownWithoutNull, flags + | ILType.Value _ -> KnownWithoutNull, flags.Advance() + | _ -> flags.GetNullness(), flags.Advance() /// Import an IL type as an F# type. let rec ImportILType (env: ImportMap) m tinst ty = @@ -174,24 +290,20 @@ let rec ImportILType (env: ImportMap) m tinst ty = | ILType.Array(bounds, ty) -> let n = bounds.Rank - let elemTy = ImportILType env m tinst ty - mkArrayTy env.g n elemTy m + let elemTy = ImportILType env m tinst ty + mkArrayTy env.g n Nullness.knownAmbivalent elemTy m | ILType.Boxed tspec | ILType.Value tspec -> let tcref = ImportILTypeRef env m tspec.TypeRef - let inst = tspec.GenericArgs |> List.map (ImportILType env m tinst) - ImportTyconRefApp env tcref inst + let inst = tspec.GenericArgs |> List.map (ImportILType env m tinst) + ImportTyconRefApp env tcref inst Nullness.knownAmbivalent | ILType.Byref ty -> mkByrefTy env.g (ImportILType env m tinst ty) - | ILType.Ptr ILType.Void when env.g.voidptr_tcr.CanDeref -> mkVoidPtrTy env.g - | ILType.Ptr ty -> mkNativePtrTy env.g (ImportILType env m tinst ty) - | ILType.FunctionPointer _ -> env.g.nativeint_ty (* failwith "cannot import this kind of type (ptr, fptr)" *) - | ILType.Modified(_, _, ty) -> - // All custom modifiers are ignored + // All custom modifiers are ignored ImportILType env m tinst ty | ILType.TypeVar u16 -> @@ -200,28 +312,69 @@ let rec ImportILType (env: ImportMap) m tinst ty = List.item (int u16) tinst with _ -> error(Error(FSComp.SR.impNotEnoughTypeParamsInScopeWhileImporting(), m)) - ty + + let tyWithNullness = addNullnessToTy Nullness.knownAmbivalent ty + tyWithNullness + +/// Import an IL type as an F# type. +let rec ImportILTypeWithNullness (env: ImportMap) m tinst (nf:Nullness.NullableFlags) ty : struct(TType*Nullness.NullableFlags) = + match ty with + | ILType.Void -> + env.g.unit_ty,nf + + | ILType.Array(bounds, innerTy) -> + let n = bounds.Rank + let (arrayNullness,nf) = Nullness.evaluateFirstOrderNullnessAndAdvance ty nf + let struct(elemTy,nf) = ImportILTypeWithNullness env m tinst nf innerTy + mkArrayTy env.g n arrayNullness elemTy m, nf + + | ILType.Boxed tspec | ILType.Value tspec -> + let tcref = ImportILTypeRef env m tspec.TypeRef + let (typeRefNullness,nf) = Nullness.evaluateFirstOrderNullnessAndAdvance ty nf + let struct(inst,nullableFlagsLeft) = (nf,tspec.GenericArgs) ||> List.vMapFold (fun nf current -> ImportILTypeWithNullness env m tinst nf current ) + + ImportTyconRefApp env tcref inst typeRefNullness, nullableFlagsLeft + + | ILType.Byref ty -> + let struct(ttype,nf) = ImportILTypeWithNullness env m tinst nf ty + mkByrefTy env.g ttype, nf + + | ILType.Ptr ILType.Void when env.g.voidptr_tcr.CanDeref -> mkVoidPtrTy env.g, nf + + | ILType.Ptr ty -> + let struct(ttype,nf) = ImportILTypeWithNullness env m tinst nf ty + mkNativePtrTy env.g ttype, nf + + | ILType.FunctionPointer _ -> env.g.nativeint_ty, nf (* failwith "cannot import this kind of type (ptr, fptr)" *) + + | ILType.Modified(_, _, ty) -> + // All custom modifiers are ignored + ImportILTypeWithNullness env m tinst nf ty + + | ILType.TypeVar u16 -> + let ttype = + try + List.item (int u16) tinst + with _ -> + error(Error(FSComp.SR.impNotEnoughTypeParamsInScopeWhileImporting(), m)) + + let (typeVarNullness,nf) = Nullness.evaluateFirstOrderNullnessAndAdvance ty nf + addNullnessToTy typeVarNullness ttype, nf /// Determines if an IL type can be imported as an F# type let rec CanImportILType (env: ImportMap) m ty = match ty with | ILType.Void -> true - | ILType.Array(_bounds, ety) -> CanImportILType env m ety - | ILType.Boxed tspec | ILType.Value tspec -> CanImportILTypeRef env m tspec.TypeRef && tspec.GenericArgs |> List.forall (CanImportILType env m) | ILType.Byref ety -> CanImportILType env m ety - | ILType.Ptr ety -> CanImportILType env m ety - | ILType.FunctionPointer _ -> true - | ILType.Modified(_, _, ety) -> CanImportILType env m ety - | ILType.TypeVar _u16 -> true #if !NO_TYPEPROVIDERS @@ -286,7 +439,9 @@ let rec ImportProvidedType (env: ImportMap) (m: range) (* (tinst: TypeInst) *) ( let g = env.g if st.PUntaint((fun st -> st.IsArray), m) then let elemTy = ImportProvidedType env m (* tinst *) (st.PApply((fun st -> st.GetElementType()), m)) - mkArrayTy g (st.PUntaint((fun st -> st.GetArrayRank()), m)) elemTy m + // TODO Nullness - integration into type providers as a separate feature for later. + let nullness = Nullness.knownAmbivalent + mkArrayTy g (st.PUntaint((fun st -> st.GetArrayRank()), m)) nullness elemTy m elif st.PUntaint((fun st -> st.IsByRef), m) then let elemTy = ImportProvidedType env m (* tinst *) (st.PApply((fun st -> st.GetElementType()), m)) mkByrefTy g elemTy @@ -358,7 +513,10 @@ let rec ImportProvidedType (env: ImportMap) (m: range) (* (tinst: TypeInst) *) ( else genericArg) - ImportTyconRefApp env tcref genericArgs + // TODO Nullness - integration into type providers as a separate feature for later. + let nullness = Nullness.knownAmbivalent + + ImportTyconRefApp env tcref genericArgs nullness /// Import a provided method reference as an Abstract IL method reference let ImportProvidedMethodBaseAsILMethodRef (env: ImportMap) (m: range) (mbase: Tainted) = @@ -409,6 +567,7 @@ let ImportProvidedMethodBaseAsILMethodRef (env: ImportMap) (m: range) (mbase: Ta let formalParamTysAfterInst = [ for p in ctor.PApplyArray((fun x -> x.GetParameters()), "GetParameters", m) do let ilFormalTy = ImportProvidedTypeAsILType env m (p.PApply((fun p -> p.ParameterType), m)) + // TODO Nullness - integration into type providers as a separate feature for later. yield ImportILType env m actualGenericArgs ilFormalTy ] (formalParamTysAfterInst, actualParamTys) ||> List.lengthsEqAndForall2 (typeEquiv env.g)) @@ -455,7 +614,7 @@ let ImportProvidedMethodBaseAsILMethodRef (env: ImportMap) (m: range) (mbase: Ta /// /// Fixup the constraints so that any references to the generic parameters /// in the constraints now refer to the new generic parameters. -let ImportILGenericParameters amap m scoref tinst (gps: ILGenericParameterDefs) = +let ImportILGenericParameters amap m scoref tinst (nullableFallback:Nullness.NullableContextSource) (gps: ILGenericParameterDefs) = match gps with | [] -> [] | _ -> @@ -465,8 +624,22 @@ let ImportILGenericParameters amap m scoref tinst (gps: ILGenericParameterDefs) let tptys = tps |> List.map mkTyparTy let importInst = tinst@tptys (tps, gps) ||> List.iter2 (fun tp gp -> + if gp.Variance = ILGenericVariance.ContraVariant then + tp.MarkAsContravariant() let constraints = - [ if gp.CustomAttrs |> TryFindILAttribute amap.g.attrib_IsUnmanagedAttribute then + [ + if amap.g.langFeatureNullness && amap.g.checkNullness then + let nullness = + { Nullness.DirectAttributes = Nullness.AttributesFromIL(gp.MetadataIndex,gp.CustomAttrsStored) + Nullness.Fallback = nullableFallback } + + match nullness.GetFlags(amap.g) with + | [|1uy|] -> TyparConstraint.NotSupportsNull(m) + // In F#, 'SupportsNull' has the meaning of "must support null as a value". In C#, Nullable(2) is an allowance, not a requirement. + //| [|2uy|] -> TyparConstraint.SupportsNull(m) + | _ -> () + + if gp.CustomAttrs |> TryFindILAttribute amap.g.attrib_IsUnmanagedAttribute then TyparConstraint.IsUnmanaged(m) if gp.HasDefaultConstructorConstraint then TyparConstraint.RequiresDefaultConstructor(m) @@ -517,13 +690,15 @@ let rec ImportILTypeDef amap m scoref (cpath: CompilationPath) enc nm (tdef: ILT ImportILTypeDefs amap m scoref cpath (enc@[tdef]) tdef.NestedTypes ) + let nullableFallback = Nullness.FromClass(Nullness.AttributesFromIL(tdef.MetadataIndex,tdef.CustomAttrsStored)) + // Add the type itself. Construct.NewILTycon (Some cpath) (nm, m) // The read of the type parameters may fail to resolve types. We pick up a new range from the point where that read is forced // Make sure we reraise the original exception one occurs - see findOriginalException. - (LazyWithContext.Create((fun m -> ImportILGenericParameters amap m scoref [] tdef.GenericParams), findOriginalException)) + (LazyWithContext.Create((fun m -> ImportILGenericParameters amap m scoref [] nullableFallback tdef.GenericParams), findOriginalException)) (scoref, enc, tdef) (MaybeLazy.Lazy lazyModuleOrNamespaceTypeForNestedTypes) @@ -701,13 +876,25 @@ let ImportILAssembly(amap: unit -> ImportMap, m, auxModuleLoader, xmlDocInfoLoad CcuThunk.Create(nm, ccuData) //------------------------------------------------------------------------- -// From IL types to F# types +// From IL types to F# typess //------------------------------------------------------------------------- /// Import an IL type as an F# type. importInst gives the context for interpreting type variables. -let RescopeAndImportILType scoref amap m importInst ilTy = +let RescopeAndImportILTypeSkipNullness scoref amap m importInst ilTy = ilTy |> rescopeILType scoref |> ImportILType amap m importInst +let RescopeAndImportILType scoref (amap:ImportMap) m importInst (nullnessSource:Nullness.NullableAttributesSource) ilTy = + let g = amap.g + if g.langFeatureNullness && g.checkNullness then + let flags = nullnessSource.GetFlags(g) + let flags = {Nullness.NullableFlags.Data = flags; Nullness.NullableFlags.Idx = 0} + let struct(ty,_) = ilTy |> rescopeILType scoref |> ImportILTypeWithNullness amap m importInst flags + ty + else + RescopeAndImportILTypeSkipNullness scoref amap m importInst ilTy + + + let CanRescopeAndImportILType scoref amap m ilTy = ilTy |> rescopeILType scoref |> CanImportILType amap m diff --git a/src/Compiler/Checking/import.fsi b/src/Compiler/Checking/import.fsi index 830fd81b12d..fb1f191effc 100644 --- a/src/Compiler/Checking/import.fsi +++ b/src/Compiler/Checking/import.fsi @@ -51,6 +51,26 @@ type ImportMap = /// The TcGlobals for the import context member g: TcGlobals +module Nullness = + + [] + type AttributesFromIL = + | AttributesFromIL of metadataIndex: int * attrs: ILAttributesStored + + member Read: unit -> ILAttributes + + [] + type NullableContextSource = + | FromClass of AttributesFromIL + | FromMethodAndClass of methodAttrs: AttributesFromIL * classAttrs: AttributesFromIL + + [] + type NullableAttributesSource = + { DirectAttributes: AttributesFromIL + Fallback: NullableContextSource } + + static member Empty: NullableAttributesSource + /// Import a reference to a type definition, given an AbstractIL ILTypeRef, with caching val internal ImportILTypeRef: ImportMap -> range -> ILTypeRef -> TyconRef @@ -79,7 +99,13 @@ val internal ImportProvidedMethodBaseAsILMethodRef: ImportMap -> range -> Tainte /// Import a set of Abstract IL generic parameter specifications as a list of new F# generic parameters. val internal ImportILGenericParameters: - (unit -> ImportMap) -> range -> ILScopeRef -> TType list -> ILGenericParameterDef list -> Typar list + (unit -> ImportMap) -> + range -> + ILScopeRef -> + TType list -> + Nullness.NullableContextSource -> + ILGenericParameterDef list -> + Typar list /// Import an IL assembly as a new TAST CCU val internal ImportILAssembly: @@ -100,7 +126,19 @@ val internal ImportILAssemblyTypeForwarders: /// Import an IL type as an F# type, first rescoping to view the metadata from the current assembly /// being compiled. importInst gives the context for interpreting type variables. -val RescopeAndImportILType: +/// This function fully skips the 'nullness checking' metadata flags. +val RescopeAndImportILTypeSkipNullness: scoref: ILScopeRef -> amap: ImportMap -> m: range -> importInst: TType list -> ilTy: ILType -> TType +/// Import an IL type as an F# type, first rescoping to view the metadata from the current assembly +/// being compiled. importInst gives the context for interpreting type variables. +val RescopeAndImportILType: + scoref: ILScopeRef -> + amap: ImportMap -> + m: range -> + importInst: TType list -> + nullnessSource: Nullness.NullableAttributesSource -> + ilTy: ILType -> + TType + val CanRescopeAndImportILType: scoref: ILScopeRef -> amap: ImportMap -> m: range -> ilTy: ILType -> bool diff --git a/src/Compiler/Checking/infos.fs b/src/Compiler/Checking/infos.fs index c90d49f3dcc..6ab2bed3931 100644 --- a/src/Compiler/Checking/infos.fs +++ b/src/Compiler/Checking/infos.fs @@ -9,6 +9,7 @@ open FSharp.Compiler open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.DiagnosticsLogger open FSharp.Compiler.Import +open FSharp.Compiler.Import.Nullness open FSharp.Compiler.Syntax open FSharp.Compiler.SyntaxTreeOps open FSharp.Compiler.TcGlobals @@ -216,7 +217,8 @@ type OptionalArgInfo = else MissingValue else DefaultValue - CallerSide (analyze (ImportILTypeFromMetadata amap m ilScope ilTypeInst [] ilParam.Type)) + // See above - the typpe is imported only in order to be analyzed for optional default value, nullness is irrelevant here. + CallerSide (analyze (ImportILTypeFromMetadataSkipNullness amap m ilScope ilTypeInst [] ilParam.Type)) | Some v -> CallerSide (Constant v) else @@ -394,8 +396,8 @@ let OptionalArgInfoOfProvidedParameter (amap: ImportMap) m (provParam : Tainted< /// Compute the ILFieldInit for the given provided constant value for a provided enum type. let GetAndSanityCheckProviderMethod m (mi: Tainted<'T :> ProvidedMemberInfo>) (get : 'T -> ProvidedMethodInfo MaybeNull) err = match mi.PApply((fun mi -> (get mi :> ProvidedMethodBase MaybeNull)),m) with - | Tainted.Null -> error(Error(err(mi.PUntaint((fun mi -> mi.Name),m),mi.PUntaint((fun mi -> (nonNull mi.DeclaringType).Name), m)), m)) // TODO NULLNESS: type isntantiation should not be needed - | meth -> meth + | Tainted.Null -> error(Error(err(mi.PUntaint((fun mi -> mi.Name),m),mi.PUntaint((fun mi -> (nonNull mi.DeclaringType).Name), m)), m)) + | Tainted.NonNull meth -> meth /// Try to get an arbitrary ProvidedMethodInfo associated with a property. let ArbitraryMethodInfoOfPropertyInfo (pi: Tainted) m = @@ -447,6 +449,10 @@ type ILTypeInfo = let (ILTypeInfo(g, ty, tref, tdef)) = x ILTypeInfo(g, instType inst ty, tref, tdef) + member x.NullableAttributes = AttributesFromIL(x.RawMetadata.MetadataIndex,x.RawMetadata.CustomAttrsStored) + + member x.NullableClassSource = FromClass(x.NullableAttributes) + static member FromType g ty = if isAnyTupleTy g ty then // When getting .NET metadata for the properties and methods @@ -463,7 +469,17 @@ type ILTypeInfo = let tref = mkRefForNestedILTypeDef scoref (enc, tdef) ILTypeInfo(g, ty, tref, tdef) else - failwith "ILTypeInfo.FromType - no IL metadata for type" + failwith ("ILTypeInfo.FromType - no IL metadata for type" + System.Environment.StackTrace) + +[] +type ILMethParentTypeInfo = + | IlType of ILTypeInfo + | CSharpStyleExtension of declaring:TyconRef * apparent:TType + + member x.ToType = + match x with + | IlType x -> x.ToType + | CSharpStyleExtension(apparent=x) -> x /// Describes an F# use of an IL method. [] @@ -472,32 +488,38 @@ type ILMethInfo = /// /// If ilDeclaringTyconRefOpt is 'Some' then this is an F# use of an C#-style extension method. /// If ilDeclaringTyconRefOpt is 'None' then ilApparentType is an IL type definition. - | ILMethInfo of g: TcGlobals * ilApparentType: TType * ilDeclaringTyconRefOpt: TyconRef option * ilMethodDef: ILMethodDef * ilGenericMethodTyArgs: Typars + | ILMethInfo of g: TcGlobals * ilType:ILMethParentTypeInfo * ilMethodDef: ILMethodDef * ilGenericMethodTyArgs: Typars - member x.TcGlobals = match x with ILMethInfo(g, _, _, _, _) -> g + member x.TcGlobals = match x with ILMethInfo(g, _, _, _) -> g /// Get the apparent declaring type of the method as an F# type. /// If this is a C#-style extension method then this is the type which the method /// appears to extend. This may be a variable type. - member x.ApparentEnclosingType = match x with ILMethInfo(_, ty, _, _, _) -> ty + member x.ApparentEnclosingType = match x with ILMethInfo(_, ty, _, _) -> ty.ToType /// Like ApparentEnclosingType but use the compiled nominal type if this is a method on a tuple type member x.ApparentEnclosingAppType = convertToTypeWithMetadataIfPossible x.TcGlobals x.ApparentEnclosingType /// Get the declaring type associated with an extension member, if any. - member x.ILExtensionMethodDeclaringTyconRef = match x with ILMethInfo(_, _, tcrefOpt, _, _) -> tcrefOpt + member x.ILExtensionMethodDeclaringTyconRef = + match x with + | ILMethInfo(ilType=CSharpStyleExtension(declaring= x)) -> Some x + | _ -> None /// Get the Abstract IL metadata associated with the method. - member x.RawMetadata = match x with ILMethInfo(_, _, _, md, _) -> md + member x.RawMetadata = match x with ILMethInfo(_, _, md, _) -> md /// Get the formal method type parameters associated with a method. - member x.FormalMethodTypars = match x with ILMethInfo(_, _, _, _, fmtps) -> fmtps + member x.FormalMethodTypars = match x with ILMethInfo(_, _, _, fmtps) -> fmtps /// Get the IL name of the method member x.ILName = x.RawMetadata.Name /// Indicates if the method is an extension method - member x.IsILExtensionMethod = x.ILExtensionMethodDeclaringTyconRef.IsSome + member x.IsILExtensionMethod = + match x with + | ILMethInfo(ilType=CSharpStyleExtension _) -> true + | _ -> false /// Get the declaring type of the method. If this is an C#-style extension method then this is the IL type /// holding the static member that is the extension method. @@ -558,15 +580,28 @@ type ILMethInfo = /// Does it appear to the user as an instance method? member x.IsInstance = not x.IsConstructor && not x.IsStatic + member x.NullableFallback = + let raw = x.RawMetadata + let classAttrs = + match x with + | ILMethInfo(ilType=CSharpStyleExtension(declaring= t)) when t.IsILTycon -> AttributesFromIL(t.ILTyconRawMetadata.MetadataIndex,t.ILTyconRawMetadata.CustomAttrsStored) + // C#-style extension defined in F# -> we do not support manually adding NullableContextAttribute by F# users. + | ILMethInfo(ilType=CSharpStyleExtension _) -> AttributesFromIL(0,Given(ILAttributes.Empty)) + | ILMethInfo(ilType=IlType(t)) -> t.NullableAttributes + + FromMethodAndClass(AttributesFromIL(raw.MetadataIndex,raw.CustomAttrsStored),classAttrs) + + member x.GetNullness(p:ILParameter) = {DirectAttributes = AttributesFromIL(p.MetadataIndex,p.CustomAttrsStored); Fallback = x.NullableFallback} + /// Get the argument types of the the IL method. If this is an C#-style extension method /// then drop the object argument. member x.GetParamTypes(amap, m, minst) = - x.ParamMetadata |> List.map (fun p -> ImportParameterTypeFromMetadata amap m p.Type (fun _ -> p.CustomAttrs) x.MetadataScope x.DeclaringTypeInst minst) + x.ParamMetadata |> List.map (fun p -> ImportParameterTypeFromMetadata amap m (x.GetNullness(p)) p.Type x.MetadataScope x.DeclaringTypeInst minst) /// Get all the argument types of the IL method. Include the object argument even if this is /// an C#-style extension method. member x.GetRawArgTypes(amap, m, minst) = - x.RawMetadata.Parameters |> List.map (fun p -> ImportParameterTypeFromMetadata amap m p.Type (fun _ -> p.CustomAttrs) x.MetadataScope x.DeclaringTypeInst minst) + x.RawMetadata.Parameters |> List.map (fun p -> ImportParameterTypeFromMetadata amap m (x.GetNullness(p)) p.Type x.MetadataScope x.DeclaringTypeInst minst) /// Get info about the arguments of the IL method. If this is an C#-style extension method then /// drop the object argument. @@ -575,7 +610,7 @@ type ILMethInfo = member x.GetParamNamesAndTypes(amap, m, minst) = let scope = x.MetadataScope let tinst = x.DeclaringTypeInst - x.ParamMetadata |> List.map (fun p -> ParamNameAndType(Option.map (mkSynId m) p.Name, ImportParameterTypeFromMetadata amap m p.Type (fun _ -> p.CustomAttrs) scope tinst minst) ) + x.ParamMetadata |> List.map (fun p -> ParamNameAndType(Option.map (mkSynId m) p.Name, ImportParameterTypeFromMetadata amap m (x.GetNullness(p)) p.Type scope tinst minst) ) /// Get a reference to the method (dropping all generic instantiations), as an Abstract IL ILMethodRef. member x.ILMethodRef = @@ -599,12 +634,13 @@ type ILMethInfo = /// Get the (zero or one) 'self'/'this'/'object' arguments associated with an IL method. /// An instance extension method returns one object argument. - member x.GetObjArgTypes(amap, m, minst) = + member x.GetObjArgTypes(amap, m, minst) = // All C#-style extension methods are instance. We have to re-read the 'obj' type w.r.t. the // method instantiation. if x.IsILExtensionMethod then let p = x.RawMetadata.Parameters.Head - [ ImportParameterTypeFromMetadata amap m p.Type (fun _ -> p.CustomAttrs) x.MetadataScope x.DeclaringTypeInst minst ] + let nullableSource = {DirectAttributes = AttributesFromIL(p.MetadataIndex,p.CustomAttrsStored); Fallback = x.NullableFallback} + [ ImportParameterTypeFromMetadata amap m nullableSource p.Type x.MetadataScope x.DeclaringTypeInst minst ] else if x.IsInstance then [ x.ApparentEnclosingType ] else @@ -612,10 +648,12 @@ type ILMethInfo = /// Get the compiled return type of the method, where 'void' is None. member x.GetCompiledReturnType (amap, m, minst) = - ImportReturnTypeFromMetadata amap m x.RawMetadata.Return.Type (fun _ -> x.RawMetadata.Return.CustomAttrs) x.MetadataScope x.DeclaringTypeInst minst + let ilReturn = x.RawMetadata.Return + let nullableSource = {DirectAttributes = AttributesFromIL(ilReturn.MetadataIndex,ilReturn.CustomAttrsStored); Fallback = x.NullableFallback} + ImportReturnTypeFromMetadata amap m nullableSource ilReturn.Type x.MetadataScope x.DeclaringTypeInst minst /// Get the F# view of the return type of the method, where 'void' is 'unit'. - member x.GetFSharpReturnType (amap, m, minst) = + member x.GetFSharpReturnType (amap, m, minst) = x.GetCompiledReturnType(amap, m, minst) |> GetFSharpViewOfReturnType amap.g @@ -1040,14 +1078,19 @@ type MethInfo = /// Build IL method infos. static member CreateILMeth (amap: ImportMap, m, ty: TType, md: ILMethodDef) = let tinfo = ILTypeInfo.FromType amap.g ty - let mtps = ImportILGenericParameters (fun () -> amap) m tinfo.ILScopeRef tinfo.TypeInstOfRawMetadata md.GenericParams - ILMeth (amap.g, ILMethInfo(amap.g, ty, None, md, mtps), None) + let nullableFallback = FromMethodAndClass(AttributesFromIL(md.MetadataIndex,md.CustomAttrsStored),tinfo.NullableAttributes) + let mtps = ImportILGenericParameters (fun () -> amap) m tinfo.ILScopeRef tinfo.TypeInstOfRawMetadata nullableFallback md.GenericParams + ILMeth (amap.g, ILMethInfo(amap.g, IlType tinfo, md, mtps), None) /// Build IL method infos for a C#-style extension method - static member CreateILExtensionMeth (amap, m, apparentTy: TType, declaringTyconRef: TyconRef, extMethPri, md: ILMethodDef) = + static member CreateILExtensionMeth (amap:ImportMap, m, apparentTy: TType, declaringTyconRef: TyconRef, extMethPri, md: ILMethodDef) = let scoref = declaringTyconRef.CompiledRepresentationForNamedType.Scope - let mtps = ImportILGenericParameters (fun () -> amap) m scoref [] md.GenericParams - ILMeth (amap.g, ILMethInfo(amap.g, apparentTy, Some declaringTyconRef, md, mtps), extMethPri) + let typeInfo = CSharpStyleExtension(declaringTyconRef,apparentTy) + let declaringMetadata = declaringTyconRef.ILTyconRawMetadata + let declaringAttributes = AttributesFromIL(declaringMetadata.MetadataIndex,declaringMetadata.CustomAttrsStored) + let nullableFallback = FromMethodAndClass(AttributesFromIL(md.MetadataIndex,md.CustomAttrsStored),declaringAttributes) + let mtps = ImportILGenericParameters (fun () -> amap) m scoref [] nullableFallback md.GenericParams + ILMeth (amap.g, ILMethInfo(amap.g, typeInfo, md, mtps), extMethPri) /// Tests whether two method infos have the same underlying definition. /// Used to merge operator overloads collected from left and right of an operator constraint. @@ -1078,8 +1121,8 @@ type MethInfo = match x with | ILMeth(_g, ilminfo, pri) -> match ilminfo with - | ILMethInfo(_, ty, None, md, _) -> MethInfo.CreateILMeth(amap, m, instType inst ty, md) - | ILMethInfo(_, ty, Some declaringTyconRef, md, _) -> MethInfo.CreateILExtensionMeth(amap, m, instType inst ty, declaringTyconRef, pri, md) + | ILMethInfo(_, IlType ty, md, _) -> MethInfo.CreateILMeth(amap, m, instType inst ty.ToType, md) + | ILMethInfo(_, CSharpStyleExtension(declaringTyconRef,ty), md, _) -> MethInfo.CreateILExtensionMeth(amap, m, instType inst ty, declaringTyconRef, pri, md) | FSMeth(g, ty, vref, pri) -> FSMeth(g, instType inst ty, vref, pri) | DefaultStructCtor(g, ty) -> DefaultStructCtor(g, instType inst ty) #if !NO_TYPEPROVIDERS @@ -1269,12 +1312,17 @@ type MethInfo = let formalRetTy, formalParams = match x with - | ILMeth(_, ilminfo, _) -> + | ILMeth(_, ilminfo, _) -> let ftinfo = ILTypeInfo.FromType g (TType_app(tcref, formalEnclosingTyparTys, g.knownWithoutNull)) - let formalRetTy = ImportReturnTypeFromMetadata amap m ilminfo.RawMetadata.Return.Type (fun _ -> ilminfo.RawMetadata.Return.CustomAttrs) ftinfo.ILScopeRef ftinfo.TypeInstOfRawMetadata formalMethTyparTys + + let ilReturn = ilminfo.RawMetadata.Return + let nullableSource = {DirectAttributes = AttributesFromIL(ilReturn.MetadataIndex,ilReturn.CustomAttrsStored); Fallback = ilminfo.NullableFallback} + + let formalRetTy = ImportReturnTypeFromMetadata amap m nullableSource ilReturn.Type ftinfo.ILScopeRef ftinfo.TypeInstOfRawMetadata formalMethTyparTys let formalParams = [ [ for p in ilminfo.RawMetadata.Parameters do - let paramTy = ImportILTypeFromMetadataWithAttributes amap m ftinfo.ILScopeRef ftinfo.TypeInstOfRawMetadata formalMethTyparTys p.Type (fun _ -> p.CustomAttrs) + let nullableSource = {nullableSource with DirectAttributes = AttributesFromIL(p.MetadataIndex,p.CustomAttrsStored)} + let paramTy = ImportILTypeFromMetadataWithAttributes amap m ftinfo.ILScopeRef ftinfo.TypeInstOfRawMetadata formalMethTyparTys nullableSource p.Type yield TSlotParam(p.Name, paramTy, p.IsIn, p.IsOut, p.IsOptional, []) ] ] formalRetTy, formalParams #if !NO_TYPEPROVIDERS @@ -1286,7 +1334,7 @@ type MethInfo = // For non-generic type providers there is no difference let formalParams = [ [ for p in mi.PApplyArray((fun mi -> mi.GetParameters()), "GetParameters", m) do - let paramName = p.PUntaint((fun p -> match p.Name with null -> None | s -> Some s), m) + let paramName = p.PUntaint((fun p -> match p.Name with "" -> None | s -> Some s), m) let paramTy = ImportProvidedType amap m (p.PApply((fun p -> p.ParameterType), m)) let isIn, isOut, isOptional = p.PUntaint((fun p -> p.IsIn, p.IsOut, p.IsOptional), m) yield TSlotParam(paramName, paramTy, isIn, isOut, isOptional, []) ] ] @@ -1315,7 +1363,7 @@ type MethInfo = [ [for p in mi.PApplyArray((fun mi -> mi.GetParameters()), "GetParameters", m) do let paramName = match p.PUntaint((fun p -> p.Name), m) with - | null -> None + | "" -> None | name -> Some (mkSynId m name) let paramTy = match p.PApply((fun p -> p.ParameterType), m) with @@ -1472,8 +1520,10 @@ type ILFieldInfo = /// Get the type of the field as an F# type member x.FieldType(amap, m) = - match x with - | ILFieldInfo (tinfo, fdef) -> ImportILTypeFromMetadata amap m tinfo.ILScopeRef tinfo.TypeInstOfRawMetadata [] fdef.FieldType + match x with + | ILFieldInfo (tinfo, fdef) -> + let nullness = {DirectAttributes = AttributesFromIL(fdef.MetadataIndex,fdef.CustomAttrsStored); Fallback = tinfo.NullableClassSource} + ImportILTypeFromMetadata amap m tinfo.ILScopeRef tinfo.TypeInstOfRawMetadata [] nullness fdef.FieldType #if !NO_TYPEPROVIDERS | ProvidedField(amap, fi, m) -> ImportProvidedType amap m (fi.PApply((fun fi -> fi.FieldType), m)) #endif @@ -1533,7 +1583,7 @@ type RecdFieldInfo = member x.FieldType = actualTyOfRecdFieldRef x.RecdFieldRef x.TypeInst /// Get the enclosing (declaring) type of the field in an F#-declared record, class or struct type - member x.DeclaringType = TType_app (x.RecdFieldRef.TyconRef, x.TypeInst, 0uy) + member x.DeclaringType = TType_app (x.RecdFieldRef.TyconRef, x.TypeInst, KnownWithoutNull) // TODO NULLNESS - qualify this override x.ToString() = x.TyconRef.ToString() + "::" + x.LogicalName @@ -1608,13 +1658,13 @@ type ILPropInfo = member x.GetterMethod = assert x.HasGetter let mdef = resolveILMethodRef x.ILTypeInfo.RawMetadata x.RawMetadata.GetMethod.Value - ILMethInfo(x.TcGlobals, x.ILTypeInfo.ToType, None, mdef, []) + ILMethInfo(x.TcGlobals, IlType x.ILTypeInfo, mdef, []) /// Gets the ILMethInfo of the 'set' method for the IL property member x.SetterMethod = assert x.HasSetter let mdef = resolveILMethodRef x.ILTypeInfo.RawMetadata x.RawMetadata.SetMethod.Value - ILMethInfo(x.TcGlobals, x.ILTypeInfo.ToType, None, mdef, []) + ILMethInfo(x.TcGlobals, IlType x.ILTypeInfo, mdef, []) /// Indicates if the IL property has a 'get' method member x.HasGetter = Option.isSome x.RawMetadata.GetMethod @@ -1647,21 +1697,34 @@ type ILPropInfo = /// Any type parameters of the enclosing type are instantiated in the type returned. member x.GetParamNamesAndTypes(amap, m) = let (ILPropInfo (tinfo, pdef)) = x - pdef.Args |> List.map (fun ty -> ParamNameAndType(None, ImportILTypeFromMetadata amap m tinfo.ILScopeRef tinfo.TypeInstOfRawMetadata [] ty) ) + if x.HasGetter then + x.GetterMethod.GetParamNamesAndTypes(amap,m,tinfo.TypeInstOfRawMetadata) + else if x.HasSetter then + x.SetterMethod.GetParamNamesAndTypes(amap,m,tinfo.TypeInstOfRawMetadata) + else + // Fallback-only for invalid properties + pdef.Args |> List.map (fun ty -> ParamNameAndType(None, ImportILTypeFromMetadataSkipNullness amap m tinfo.ILScopeRef tinfo.TypeInstOfRawMetadata [] ty) ) /// Get the types of the indexer arguments associated with the IL property. /// /// Any type parameters of the enclosing type are instantiated in the type returned. member x.GetParamTypes(amap, m) = let (ILPropInfo (tinfo, pdef)) = x - pdef.Args |> List.map (fun ty -> ImportILTypeFromMetadata amap m tinfo.ILScopeRef tinfo.TypeInstOfRawMetadata [] ty) + if x.HasGetter then + x.GetterMethod.GetParamTypes(amap,m,tinfo.TypeInstOfRawMetadata) + else if x.HasSetter then + x.SetterMethod.GetParamTypes(amap,m,tinfo.TypeInstOfRawMetadata) + else + // Fallback-only for invalid properties + pdef.Args |> List.map (fun ty -> ImportILTypeFromMetadataSkipNullness amap m tinfo.ILScopeRef tinfo.TypeInstOfRawMetadata [] ty) /// Get the return type of the IL property. /// /// Any type parameters of the enclosing type are instantiated in the type returned. member x.GetPropertyType (amap, m) = let (ILPropInfo (tinfo, pdef)) = x - ImportILTypeFromMetadata amap m tinfo.ILScopeRef tinfo.TypeInstOfRawMetadata [] pdef.PropertyType + let nullness = {DirectAttributes = AttributesFromIL(pdef.MetadataIndex,pdef.CustomAttrsStored); Fallback = tinfo.NullableClassSource} + ImportILTypeFromMetadata amap m tinfo.ILScopeRef tinfo.TypeInstOfRawMetadata [] nullness pdef.PropertyType override x.ToString() = x.ILTypeInfo.ToString() + "::" + x.PropertyName @@ -1939,7 +2002,7 @@ type PropInfo = /// Get the result type of the property member x.GetPropertyType (amap, m) = - match x with + match x with | ILProp ilpinfo -> ilpinfo.GetPropertyType (amap, m) | FSProp (g, _, Some vref, _) | FSProp (g, _, _, Some vref) -> @@ -1957,7 +2020,7 @@ type PropInfo = /// /// If the property is in a generic type, then the type parameters are instantiated in the types returned. member x.GetParamNamesAndTypes(amap, m) = - match x with + match x with | ILProp ilpinfo -> ilpinfo.GetParamNamesAndTypes(amap, m) | FSProp (g, ty, Some vref, _) | FSProp (g, ty, _, Some vref) -> @@ -1967,7 +2030,7 @@ type PropInfo = #if !NO_TYPEPROVIDERS | ProvidedProp (_, pi, m) -> [ for p in pi.PApplyArray((fun pi -> pi.GetIndexParameters()), "GetIndexParameters", m) do - let paramName = p.PUntaint((fun p -> match p.Name with null -> None | s -> Some (mkSynId m s)), m) + let paramName = p.PUntaint((fun p -> match p.Name with "" -> None | s -> Some (mkSynId m s)), m) let paramTy = ImportProvidedType amap m (p.PApply((fun p -> p.ParameterType), m)) yield ParamNameAndType(paramName, paramTy) ] #endif @@ -1978,7 +2041,7 @@ type PropInfo = |> List.map (fun (ParamNameAndType(nmOpt, paramTy)) -> ParamData(false, false, false, NotOptional, NoCallerInfo, nmOpt, ReflectedArgInfo.None, paramTy)) /// Get the types of the indexer parameters associated with the property - member x.GetParamTypes(amap, m) = + member x.GetParamTypes(amap, m) = x.GetParamNamesAndTypes(amap, m) |> List.map (fun (ParamNameAndType(_, ty)) -> ty) /// Get a MethInfo for the 'getter' method associated with the property @@ -2073,12 +2136,12 @@ type ILEventInfo = /// Get the ILMethInfo describing the 'add' method associated with the event member x.AddMethod = let mdef = resolveILMethodRef x.ILTypeInfo.RawMetadata x.RawMetadata.AddMethod - ILMethInfo(x.TcGlobals, x.ILTypeInfo.ToType, None, mdef, []) + ILMethInfo(x.TcGlobals, IlType x.ILTypeInfo, mdef, []) /// Get the ILMethInfo describing the 'remove' method associated with the event member x.RemoveMethod = let mdef = resolveILMethodRef x.ILTypeInfo.RawMetadata x.RawMetadata.RemoveMethod - ILMethInfo(x.TcGlobals, x.ILTypeInfo.ToType, None, mdef, []) + ILMethInfo(x.TcGlobals, IlType x.ILTypeInfo, mdef, []) /// Get the declaring type of the event as an ILTypeRef member x.TypeRef = x.ILTypeInfo.ILTypeRef @@ -2274,9 +2337,10 @@ type EventInfo = match x with | ILEvent(ILEventInfo(tinfo, edef)) -> // Get the delegate type associated with an IL event, taking into account the instantiation of the - // declaring type. + // declaring type if Option.isNone edef.EventType then error (nonStandardEventError x.EventName m) - ImportILTypeFromMetadata amap m tinfo.ILScopeRef tinfo.TypeInstOfRawMetadata [] edef.EventType.Value + let nullness = {DirectAttributes = AttributesFromIL(edef.MetadataIndex,edef.CustomAttrsStored); Fallback = tinfo.NullableClassSource} + ImportILTypeFromMetadata amap m tinfo.ILScopeRef tinfo.TypeInstOfRawMetadata [] nullness edef.EventType.Value | FSEvent(g, p, _, _) -> FindDelegateTypeOfPropertyEvent g amap x.EventName m (p.GetPropertyType(amap, m)) diff --git a/src/Compiler/Checking/infos.fsi b/src/Compiler/Checking/infos.fsi index a2b178d92ac..406919bfa37 100644 --- a/src/Compiler/Checking/infos.fsi +++ b/src/Compiler/Checking/infos.fsi @@ -178,13 +178,19 @@ type ILTypeInfo = member TypeInstOfRawMetadata: TypeInst +[] +type ILMethParentTypeInfo = + | IlType of ILTypeInfo + | CSharpStyleExtension of declaring: TyconRef * apparent: TType + + member ToType: TType + /// Describes an F# use of an IL method. [] type ILMethInfo = | ILMethInfo of g: TcGlobals * - ilApparentType: TType * - ilDeclaringTyconRefOpt: TyconRef option * + ilType: ILMethParentTypeInfo * ilMethodDef: ILMethodDef * ilGenericMethodTyArgs: Typars diff --git a/src/Compiler/CodeGen/EraseClosures.fs b/src/Compiler/CodeGen/EraseClosures.fs index 7eddfd9b820..fa117b60777 100644 --- a/src/Compiler/CodeGen/EraseClosures.fs +++ b/src/Compiler/CodeGen/EraseClosures.fs @@ -573,12 +573,13 @@ let rec convIlxClosureDef cenv encl (td: ILTypeDef) clo = genericParams = td.GenericParams, attributes = td.Attributes, implements = [], + implementsCustomAttrs = None, nestedTypes = emptyILTypeDefs, layout = ILTypeDefLayout.Auto, extends = Some cenv.mkILTyFuncTy, methods = mkILMethods (ctorMethodDef :: nowApplyMethDef :: nowMethods), fields = mkILFields (mkILCloFldDefs cenv nowFields @ td.Fields.AsList()), - customAttrs = emptyILCustomAttrsStored, + customAttrs = emptyILCustomAttrs, methodImpls = emptyILMethodImpls, properties = emptyILProperties, events = emptyILEvents, @@ -707,12 +708,13 @@ let rec convIlxClosureDef cenv encl (td: ILTypeDef) clo = genericParams = td.GenericParams, attributes = td.Attributes, implements = [], + implementsCustomAttrs = None, layout = ILTypeDefLayout.Auto, nestedTypes = emptyILTypeDefs, extends = Some nowEnvParentClass, methods = mkILMethods (ctorMethodDef :: nowApplyMethDef :: nowMethods), fields = mkILFields (mkILCloFldDefs cenv nowFields @ td.Fields.AsList()), - customAttrs = emptyILCustomAttrsStored, + customAttrs = emptyILCustomAttrs, methodImpls = emptyILMethodImpls, properties = emptyILProperties, events = emptyILEvents, diff --git a/src/Compiler/CodeGen/EraseUnions.fs b/src/Compiler/CodeGen/EraseUnions.fs index d5670ed3fdf..a42661855e6 100644 --- a/src/Compiler/CodeGen/EraseUnions.fs +++ b/src/Compiler/CodeGen/EraseUnions.fs @@ -8,6 +8,7 @@ open FSharp.Compiler.IlxGenSupport open System.Collections.Generic open System.Reflection open Internal.Utilities.Library +open FSharp.Compiler.TypedTreeOps open FSharp.Compiler.Features open FSharp.Compiler.TcGlobals open FSharp.Compiler.AbstractIL.IL @@ -666,6 +667,7 @@ let emitDataSwitch ilg (cg: ICodeGen<'Mark>) (avoidHelpers, cuspec, cases) = let mkMethodsAndPropertiesForFields (addMethodGeneratedAttrs, addPropertyGeneratedAttrs) + (g: TcGlobals) access attr imports @@ -705,15 +707,28 @@ let mkMethodsAndPropertiesForFields for field in fields do let fspec = mkILFieldSpecInTy (ilTy, field.LowerName, field.Type) + let ilReturn = mkILReturn field.Type + + let ilReturn = + if TryFindILAttribute g.attrib_NullableAttribute field.ILField.CustomAttrs then + let attrs = + field.ILField.CustomAttrs.AsArray() + |> Array.filter (IsILAttrib g.attrib_NullableAttribute) + + ilReturn.WithCustomAttrs(mkILCustomAttrsFromArray attrs) + else + ilReturn + yield mkILNonGenericInstanceMethod ( "get_" + adjustFieldName hasHelpers field.Name, access, [], - mkILReturn field.Type, + ilReturn, mkMethodBody (true, [], 2, nonBranchingInstrsToCode [ mkLdarg 0us; mkNormalLdfld fspec ], attr, imports) ) |> addMethodGeneratedAttrs + ] basicProps, basicMethods @@ -789,7 +804,19 @@ let convAlternativeDef mkMakerName cuspec altName, cud.HelpersAccessibility, fields - |> Array.map (fun fd -> mkILParamNamed (fd.LowerName, fd.Type)) + |> Array.map (fun fd -> + let plainParam = mkILParamNamed (fd.LowerName, fd.Type) + + if TryFindILAttribute g.attrib_NullableAttribute fd.ILField.CustomAttrs then + let attrs = + fd.ILField.CustomAttrs.AsArray() + |> Array.filter (IsILAttrib g.attrib_NullableAttribute) + + { plainParam with + CustomAttrsStored = storeILCustomAttrs (mkILCustomAttrsFromArray attrs) + } + else + plainParam) |> Array.toList, mkILReturn baseTy, mkMethodBody (true, locals, fields.Length + locals.Length, nonBranchingInstrsToCode ilInstrs, attr, imports) @@ -844,18 +871,39 @@ let convAlternativeDef | SpecialFSharpListHelpers -> let baseTesterMeths, baseTesterProps = - if - g.langVersion.SupportsFeature LanguageFeature.UnionIsPropertiesVisible - && cud.HasHelpers = AllHelpers - then - [], [] - elif cud.UnionCases.Length <= 1 then + if cud.UnionCases.Length <= 1 then [], [] elif repr.RepresentOneAlternativeAsNull info then [], [] else + let additionalAttributes = + if + g.checkNullness + && g.langFeatureNullness + && repr.RepresentAlternativeAsStructValue info + && not alt.IsNullary + then + let notnullfields = + alt.FieldDefs + // Fields that are nullable even from F# perspective has an [Nullable] attribute on them + // Non-nullable fields are implicit in F#, therefore not annotated separately + |> Array.filter (fun f -> TryFindILAttribute g.attrib_NullableAttribute f.ILField.CustomAttrs |> not) + + let fieldNames = + notnullfields + |> Array.map (fun f -> f.LowerName) + |> Array.append (notnullfields |> Array.map (fun f -> f.Name)) + + if fieldNames |> Array.isEmpty then + emptyILCustomAttrs + else + mkILCustomAttrsFromArray [| GetNotNullWhenTrueAttribute g fieldNames |] + + else + emptyILCustomAttrs + [ - mkILNonGenericInstanceMethod ( + (mkILNonGenericInstanceMethod ( "get_" + mkTesterName altName, cud.HelpersAccessibility, [], @@ -868,7 +916,8 @@ let convAlternativeDef attr, imports ) - ) + )) + .With(customAttrs = additionalAttributes) |> addMethodGeneratedAttrs ], [ @@ -891,7 +940,7 @@ let convAlternativeDef propertyType = g.ilg.typ_Bool, init = None, args = [], - customAttrs = emptyILCustomAttrs + customAttrs = additionalAttributes ) |> addPropertyGeneratedAttrs |> addPropertyNeverAttrs @@ -900,13 +949,24 @@ let convAlternativeDef let baseMakerMeths, baseMakerProps = if alt.IsNullary then + let attributes = + if + g.checkNullness + && g.langFeatureNullness + && repr.RepresentAlternativeAsNull(info, alt) + then + GetNullableAttribute g [ FSharp.Compiler.TypedTree.NullnessInfo.WithNull ] + |> Array.singleton + |> mkILCustomAttrsFromArray + else + emptyILCustomAttrs let nullaryMeth = mkILNonGenericStaticMethod ( "get_" + altName, cud.HelpersAccessibility, [], - mkILReturn baseTy, + (mkILReturn baseTy).WithCustomAttrs attributes, mkMethodBody ( true, [], @@ -930,7 +990,7 @@ let convAlternativeDef propertyType = baseTy, init = None, args = [], - customAttrs = emptyILCustomAttrs + customAttrs = attributes ) |> addPropertyGeneratedAttrs |> addPropertyNeverAttrs @@ -1103,6 +1163,7 @@ let convAlternativeDef let basicProps, basicMethods = mkMethodsAndPropertiesForFields (addMethodGeneratedAttrs, addPropertyGeneratedAttrs) + g cud.UnionCasesAccessibility attr imports @@ -1136,6 +1197,12 @@ let convAlternativeDef .With(customAttrs = mkILCustomAttrs [ GetDynamicDependencyAttribute g 0x660 baseTy ]) |> addMethodGeneratedAttrs + let attrs = + if g.checkNullness && g.langFeatureNullness then + GetNullableContextAttribute g :: debugAttrs + else + debugAttrs + let altTypeDef = mkILGenericClass ( altTy.TypeSpec.Name, @@ -1154,7 +1221,7 @@ let convAlternativeDef emptyILTypeDefs, mkILProperties basicProps, emptyILEvents, - mkILCustomAttrs debugAttrs, + mkILCustomAttrs attrs, ILTypeInit.BeforeField ) @@ -1276,8 +1343,60 @@ let mkClassUnionDef |> addMethodGeneratedAttrs ] + let fieldDefs = + // Since structs are flattened out for all cases together, all boxed fields are potentially nullable + if + isStruct + && cud.UnionCases.Length > 1 + && g.checkNullness + && g.langFeatureNullness + then + alt.FieldDefs + |> Array.map (fun field -> + if field.Type.IsNominal && field.Type.Boxity = AsValue then + field + else + let attrs = + let existingAttrs = field.ILField.CustomAttrs.AsArray() + + let nullableIdx = + existingAttrs |> Array.tryFindIndex (IsILAttrib g.attrib_NullableAttribute) + + match nullableIdx with + | None -> + existingAttrs + |> Array.append + [| GetNullableAttribute g [ FSharp.Compiler.TypedTree.NullnessInfo.WithNull ] |] + | Some idx -> + let replacementAttr = + match existingAttrs[idx] with + (* + The attribute carries either a single byte, or a list of bytes for the fields itself and all its generic type arguments + The way we lay out DUs does not affect nullability of the typars of a field, therefore we just change the very first byte + If the field was already declared as nullable (value = 2uy) or ambivalent(value = 0uy), we can keep it that way + If it was marked as non-nullable within that UnionCase, we have to convert it to WithNull (2uy) due to other cases being possible + *) + | Encoded(method, _data, [ ILAttribElem.Byte 1uy ]) -> + mkILCustomAttribMethRef (method, [ ILAttribElem.Byte 2uy ], []) + | Encoded(method, + _data, + [ ILAttribElem.Array(elemType, (ILAttribElem.Byte 1uy) :: otherElems) ]) -> + mkILCustomAttribMethRef ( + method, + [ ILAttribElem.Array(elemType, (ILAttribElem.Byte 2uy) :: otherElems) ], + [] + ) + | attrAsBefore -> attrAsBefore + + existingAttrs |> Array.replace idx replacementAttr + + field.ILField.With(customAttrs = mkILCustomAttrsFromArray attrs) + |> IlxUnionCaseField) + else + alt.FieldDefs + let fieldsToBeAddedIntoType = - alt.FieldDefs + fieldDefs |> Array.filter (fun f -> fieldsEmitted.Add(struct (f.LowerName, f.Type))) let fields = fieldsToBeAddedIntoType |> Array.map mkUnionCaseFieldId |> Array.toList @@ -1285,6 +1404,7 @@ let mkClassUnionDef let props, meths = mkMethodsAndPropertiesForFields (addMethodGeneratedAttrs, addPropertyGeneratedAttrs) + g cud.UnionCasesAccessibility cud.DebugPoint cud.DebugImports @@ -1445,6 +1565,7 @@ let mkClassUnionDef attributes = enum 0, layout = ILTypeDefLayout.Auto, implements = [], + implementsCustomAttrs = None, extends = Some g.ilg.typ_Object, methods = emptyILMethods, securityDecls = emptyILSecurityDecls, @@ -1453,7 +1574,7 @@ let mkClassUnionDef events = emptyILEvents, properties = emptyILProperties, additionalFlags = ILTypeDefAdditionalFlags.None, - customAttrs = emptyILCustomAttrsStored + customAttrs = emptyILCustomAttrs ) .WithNestedAccess(cud.UnionCasesAccessibility) .WithAbstract(true) @@ -1494,7 +1615,14 @@ let mkClassUnionDef @ List.map (fun (_, _, _, _, fdef, _) -> fdef) altNullaryFields @ td.Fields.AsList() ), - properties = mkILProperties (tagProps @ basePropsFromAlt @ selfProps @ existingProps) + properties = mkILProperties (tagProps @ basePropsFromAlt @ selfProps @ existingProps), + customAttrs = + if cud.IsNullPermitted && g.checkNullness && g.langFeatureNullness then + td.CustomAttrs.AsArray() + |> Array.append [| GetNullableAttribute g [ FSharp.Compiler.TypedTree.NullnessInfo.WithNull ] |] + |> mkILCustomAttrsFromArray + else + td.CustomAttrs ) // The .cctor goes on the Cases type since that's where the constant fields for nullary constructors live |> addConstFieldInit diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs index c152a0f239a..4c12b687a08 100644 --- a/src/Compiler/CodeGen/IlxGen.fs +++ b/src/Compiler/CodeGen/IlxGen.fs @@ -642,7 +642,8 @@ and GenNamedTyAppAux (cenv: cenv) m (tyenv: TypeReprEnv) ptrsOK tcref tinst = #if !NO_TYPEPROVIDERS match tcref.TypeReprInfo with // Generate the base type, because that is always the representation of the erased type, unless the assembly is being injected - | TProvidedTypeRepr info when info.IsErased -> GenTypeAux cenv m tyenv VoidNotOK ptrsOK (info.BaseTypeForErased(m, g.obj_ty)) + | TProvidedTypeRepr info when info.IsErased -> + GenTypeAux cenv m tyenv VoidNotOK ptrsOK (info.BaseTypeForErased(m, g.obj_ty_withNulls)) | _ -> #endif GenTyAppAux cenv m tyenv (GenTyconRef tcref) tinst @@ -701,15 +702,11 @@ and GenUnionCaseRef (cenv: cenv) m tyenv i (fspecs: RecdField[]) = let ilFieldDef = mkILInstanceField (fspec.LogicalName, GenType cenv m tyenv fspec.FormalType, None, ILMemberAccess.Public) // These properties on the "field" of an alternative end up going on a property generated by cu_erase.fs - IlxUnionCaseField( - ilFieldDef.With( - customAttrs = - mkILCustomAttrs - [ - (mkCompilationMappingAttrWithVariantNumAndSeqNum g (int SourceConstructFlags.Field) i j) - ] - ) - )) + let attrs = + (mkCompilationMappingAttrWithVariantNumAndSeqNum g (int SourceConstructFlags.Field) i j) + :: GenAdditionalAttributesForTy g fspec.FormalType + + IlxUnionCaseField(ilFieldDef.With(customAttrs = mkILCustomAttrs attrs))) and GenUnionRef (cenv: cenv) m (tcref: TyconRef) = let g = cenv.g @@ -1386,7 +1383,7 @@ let GetMethodSpecForMemberVal cenv (memberInfo: ValMemberInfo) (vref: ValRef) = if isCtor || cctor then ILType.Void else ilRetTy let ilTy = - GenType cenv m tyenvUnderTypars (mkAppTy parentTcref (List.map mkTyparTy ctps)) + GenType cenv m tyenvUnderTypars (mkWoNullAppTy parentTcref (List.map mkTyparTy ctps)) let nm = vref.CompiledName g.CompilerGlobalState @@ -1904,13 +1901,30 @@ type TypeDefBuilder(tdef: ILTypeDef, tdefDiscards) = let gevents = ResizeArray(tdef.Events.AsList()) let gnested = TypeDefsBuilder() - member _.Close() = + member _.Close(g: TcGlobals) = + + let attrs = + if g.checkNullness && g.langFeatureNullness then + let attrsBefore = tdef.CustomAttrs + + [| + yield! attrsBefore.AsArray() + if attrsBefore |> TryFindILAttribute g.attrib_AllowNullLiteralAttribute then + yield GetNullableAttribute g [ NullnessInfo.WithNull ] + if (gmethods.Count + gfields.Count + gproperties.Count) > 0 then + yield GetNullableContextAttribute g + |] + |> mkILCustomAttrsFromArray + else + tdef.CustomAttrs + tdef.With( methods = mkILMethods (ResizeArray.toList gmethods), fields = mkILFields (ResizeArray.toList gfields), properties = mkILProperties (tdef.Properties.AsList() @ HashRangeSorted gproperties), events = mkILEvents (ResizeArray.toList gevents), - nestedTypes = mkILTypeDefs (tdef.NestedTypes.AsList() @ gnested.Close()) + nestedTypes = mkILTypeDefs (tdef.NestedTypes.AsList() @ gnested.Close(g)), + customAttrs = attrs ) member _.AddEventDef edef = gevents.Add edef @@ -1971,14 +1985,14 @@ and TypeDefsBuilder() = let mutable countDown = System.Int32.MaxValue let mutable countUp = -1 - member b.Close() = + member b.Close(g: TcGlobals) = //The order we emit type definitions is not deterministic since it is using the reverse of a range from a hash table. We should use an approximation of source order. // Ideally it shouldn't matter which order we use. // However, for some tests FSI generated code appears sensitive to the order, especially for nested types. [ for _, (b, eliminateIfEmpty) in tdefs.Values |> Seq.collect id |> Seq.sortBy fst do - let tdef = b.Close() + let tdef = b.Close(g) // Skip the type if it is empty if not eliminateIfEmpty @@ -2182,9 +2196,9 @@ type AnonTypeGenerationTable() = [ (g.mk_IStructuralComparable_ty, true, m) (g.mk_IComparable_ty, true, m) - (mkAppTy g.system_GenericIComparable_tcref [ ty ], true, m) + (mkWoNullAppTy g.system_GenericIComparable_tcref [ ty ], true, m) (g.mk_IStructuralEquatable_ty, true, m) - (mkAppTy g.system_GenericIEquatable_tcref [ ty ], true, m) + (mkWoNullAppTy g.system_GenericIEquatable_tcref [ ty ], true, m) ] let vspec1, vspec2 = AugmentTypeDefinitions.MakeValsForEqualsAugmentation g tcref @@ -2426,7 +2440,7 @@ and AssemblyBuilder(cenv: cenv, anonTypeTable: AnonTypeGenerationTable) as mgbuf |> List.sortBy (fst >> (~-)) // invert the result to get 'order-by-descending' behavior (items in list are 0..* so we don't need to worry about int.MinValue) |> List.map snd - gtdefs.Close(), orderedReflectedDefinitions + gtdefs.Close(g), orderedReflectedDefinitions member _.cenv = cenv @@ -5444,7 +5458,7 @@ and CommitCallSequel cenv eenv m cloc cgbuf mustGenerateUnitAfterCall sequel = and MakeNotSupportedExnExpr cenv eenv (argExpr, m) = let g = cenv.g - let ety = mkAppTy (g.FindSysTyconRef [ "System" ] "NotSupportedException") [] + let ety = mkWoNullAppTy (g.FindSysTyconRef [ "System" ] "NotSupportedException") [] let ilTy = GenType cenv m eenv.tyenv ety let mref = mkILCtorMethSpecForTy(ilTy, [ g.ilg.typ_String ]).MethodRef Expr.Op(TOp.ILCall(false, false, false, true, NormalValUse, false, false, mref, [], [], [ ety ]), [], [ argExpr ], m) @@ -5634,6 +5648,30 @@ and GenGenericParam cenv eenv (tp: Typar) = | TyparConstraint.IsNonNullableStruct _ -> true | _ -> false) + let nullnessOfTypar = + if g.langFeatureNullness && g.checkNullness then + let hasNotSupportsNull = + tp.Constraints + |> List.exists (function + | TyparConstraint.NotSupportsNull _ -> true + | _ -> false) + + let hasSupportsNull () = + tp.Constraints + |> List.exists (function + | TyparConstraint.SupportsNull _ -> true + | _ -> false) + + if hasNotSupportsNull || notNullableValueTypeConstraint then + NullnessInfo.WithoutNull + elif refTypeConstraint || hasSupportsNull () then + NullnessInfo.WithNull + else + NullnessInfo.AmbivalentToNull + |> Some + else + None + let defaultConstructorConstraint = tp.Constraints |> List.exists (function @@ -5675,12 +5713,14 @@ and GenGenericParam cenv eenv (tp: Typar) = nm let attributeList = - let defined = GenAttrs cenv eenv tp.Attribs - - if emitUnmanagedInIlOutput then - (GetIsUnmanagedAttribute g) :: defined - else - defined + [ + yield! GenAttrs cenv eenv tp.Attribs + if emitUnmanagedInIlOutput then + yield (GetIsUnmanagedAttribute g) + match nullnessOfTypar with + | Some nullInfo -> yield GetNullableAttribute g [ nullInfo ] + | _ -> () + ] let tpAttrs = mkILCustomAttrs (attributeList) @@ -5715,11 +5755,7 @@ and GenSlotParam m cenv eenv slotParam : ILParameter = GenParamAttribs cenv ty attribs let ilAttribs = GenAttrs cenv eenv attribs - - let ilAttribs = - match GenReadOnlyAttributeIfNecessary cenv.g ty with - | Some attr -> ilAttribs @ [ attr ] - | None -> ilAttribs + let ilAttribs = ilAttribs @ GenAdditionalAttributesForTy cenv.g ty { Name = nm @@ -5775,9 +5811,9 @@ and GenFormalReturnType m cenv eenvFormal returnTy : ILReturn = match returnTy with | None -> ilRet | Some ty -> - match GenReadOnlyAttributeIfNecessary cenv.g ty with - | Some attr -> ilRet.WithCustomAttrs(mkILCustomAttrs (ilRet.CustomAttrs.AsList() @ [ attr ])) - | None -> ilRet + match GenAdditionalAttributesForTy cenv.g ty with + | [] -> ilRet + | attrs -> ilRet.WithCustomAttrs(mkILCustomAttrs (ilRet.CustomAttrs.AsList() @ attrs)) and instSlotParam inst (TSlotParam(nm, ty, inFlag, fl2, fl3, attrs)) = TSlotParam(nm, instType inst ty, inFlag, fl2, fl3, attrs) @@ -6208,7 +6244,6 @@ and GenStructStateMachine cenv cgbuf eenvouter (res: LoweredStateMachine) sequel mkCompilationMappingAttr g (int SourceConstructFlags.Closure) ] |> mkILCustomAttrs - |> storeILCustomAttrs let cloTypeDef = ILTypeDef( @@ -6224,6 +6259,7 @@ and GenStructStateMachine cenv cgbuf eenvouter (res: LoweredStateMachine) sequel methodImpls = mkILMethodImpls mimpls, nestedTypes = emptyILTypeDefs, implements = ilInterfaceTys, + implementsCustomAttrs = None, extends = Some super, additionalFlags = ILTypeDefAdditionalFlags.None, securityDecls = emptyILSecurityDecls @@ -6641,7 +6677,6 @@ and GenClosureTypeDefs let customAttrs = attrs @ [ mkCompilationMappingAttr g (int SourceConstructFlags.Closure) ] |> mkILCustomAttrs - |> storeILCustomAttrs let tdef = ILTypeDef( @@ -6657,6 +6692,7 @@ and GenClosureTypeDefs methodImpls = mkILMethodImpls mimpls, nestedTypes = emptyILTypeDefs, implements = ilIntfTys, + implementsCustomAttrs = None, extends = Some ext, additionalFlags = ILTypeDefAdditionalFlags.None, securityDecls = emptyILSecurityDecls @@ -8473,7 +8509,7 @@ and GenBindingAfterDebugPoint cenv cgbuf eenv bind isStateVar startMarkOpt = propertyType = ilTy, init = None, args = [], - customAttrs = mkILCustomAttrs ilAttribs + customAttrs = mkILCustomAttrs (GenAdditionalAttributesForTy g vspec.Type @ ilAttribs) ) cgbuf.mgbuf.AddOrMergePropertyDef(ilGetterMethSpec.MethodRef.DeclaringTypeRef, ilPropDef, m) @@ -8550,6 +8586,8 @@ and GenBindingAfterDebugPoint cenv cgbuf eenv bind isStateVar startMarkOpt = else GenAttrs cenv eenv vspec.Attribs // literals have no property, so preserve all the attributes on the field itself + let ilAttribs = GenAdditionalAttributesForTy g vspec.Type @ ilAttribs + let ilFieldDef = ilFieldDef.With(customAttrs = mkILCustomAttrs (ilAttribs @ [ g.DebuggerBrowsableNeverAttribute ])) @@ -8571,6 +8609,7 @@ and GenBindingAfterDebugPoint cenv cgbuf eenv bind isStateVar startMarkOpt = vspec.Attribs |> List.filter (fun (Attrib(_, _, _, _, _, targets, _)) -> canTarget (targets, System.AttributeTargets.Property)) |> GenAttrs cenv eenv // property only gets attributes that target properties + |> List.append (GenAdditionalAttributesForTy g vspec.Type) let ilPropDef = ILPropertyDef( @@ -8877,11 +8916,7 @@ and GenParams | None -> None, takenNames let ilAttribs = GenAttrs cenv eenv attribs - - let ilAttribs = - match GenReadOnlyAttributeIfNecessary cenv.g methodArgTy with - | Some attr -> ilAttribs @ [ attr ] - | None -> ilAttribs + let ilAttribs = ilAttribs @ GenAdditionalAttributesForTy cenv.g methodArgTy let param: ILParameter = { @@ -8907,10 +8942,7 @@ and GenReturnInfo cenv eenv returnTy ilRetTy (retInfo: ArgReprInfo) : ILReturn = let ilAttribs = match returnTy with - | Some retTy -> - match GenReadOnlyAttributeIfNecessary cenv.g retTy with - | Some attr -> ilAttribs @ [ attr ] - | None -> ilAttribs + | Some retTy -> ilAttribs @ GenAdditionalAttributesForTy cenv.g retTy | _ -> ilAttribs let ilAttrs = mkILCustomAttrs ilAttribs @@ -9245,9 +9277,7 @@ and GenMethodForBinding || memberInfo.MemberFlags.MemberKind = SynMemberKind.PropertySet || memberInfo.MemberFlags.MemberKind = SynMemberKind.PropertyGetSet -> - match GenReadOnlyAttributeIfNecessary cenv.g returnTy with - | Some ilAttr -> ilAttr - | _ -> () + yield! GenAdditionalAttributesForTy cenv.g returnTy | _ -> () ] @@ -10536,6 +10566,8 @@ and GenWitnessParams cenv eenv m (witnessInfos: TraitWitnessInfos) = let nm = String.uncapitalize witnessInfo.MemberName let nm = if used.Contains nm then nm + string i else nm + let attribs = GenAdditionalAttributesForTy cenv.g ty + let ilParam: ILParameter = { Name = Some nm @@ -10545,7 +10577,7 @@ and GenWitnessParams cenv eenv m (witnessInfos: TraitWitnessInfos) = IsIn = false IsOut = false IsOptional = false - CustomAttrsStored = storeILCustomAttrs (mkILCustomAttrs []) + CustomAttrsStored = storeILCustomAttrs (mkILCustomAttrs attribs) MetadataIndex = NoMetadataIdx } @@ -10577,9 +10609,7 @@ and GenAbstractBinding cenv eenv tref (vref: ValRef) = || memberInfo.MemberFlags.MemberKind = SynMemberKind.PropertySet || memberInfo.MemberFlags.MemberKind = SynMemberKind.PropertyGetSet -> - match GenReadOnlyAttributeIfNecessary cenv.g returnTy with - | Some ilAttr -> ilAttr - | _ -> () + yield! GenAdditionalAttributesForTy cenv.g returnTy | _ -> () ] @@ -10748,6 +10778,19 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option tycon.ImmediateInterfaceTypesOfFSharpTycon |> List.map (GenType cenv m eenvinner.tyenv) + let ilIntCustomAttrs = + if g.langFeatureNullness && g.checkNullness && not (isNil ilIntfTys) then + tycon.ImmediateInterfaceTypesOfFSharpTycon + |> List.map ( + GenAdditionalAttributesForTy g + >> mkILCustomAttrs + >> ILAttributesStored.Given + >> (fun x -> x, 0) + ) + |> Some + else + None + let ilTypeName = tref.Name let hidden = IsHiddenTycon eenv.sigToImplRemapInfo tycon @@ -10777,7 +10820,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option Option.isNone tycon.GeneratedCompareToValues && Option.isNone tycon.GeneratedHashAndEqualsValues && tycon.HasInterface g g.mk_IComparable_ty - && not (tycon.HasOverride g "Equals" [ g.obj_ty ]) + && not (tycon.HasOverride g "Equals" [ g.obj_ty_ambivalent ]) && not tycon.IsFSharpInterfaceTycon then [ GenEqualsOverrideCallingIComparable cenv (tcref, ilThisTy, ilThisTy) ] @@ -10920,6 +10963,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option else ILTypeDefKind.Class | TFSharpClass -> ILTypeDefKind.Class + | TFSharpStruct -> ILTypeDefKind.ValueType | TFSharpInterface -> ILTypeDefKind.Interface | TFSharpEnum -> ILTypeDefKind.Enum @@ -11042,7 +11086,12 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option literalValue = None, offset = ilFieldOffset, marshal = None, - customAttrs = mkILCustomAttrs (GenAttrs cenv eenv fattribs @ extraAttribs) + customAttrs = + mkILCustomAttrs ( + GenAttrs cenv eenv fattribs + @ extraAttribs + @ GenAdditionalAttributesForTy g fspec.FormalType + ) ) .WithAccess(access) .WithStatic(isStatic) @@ -11334,7 +11383,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option | TILObjectRepr _ -> let tdef = tycon.ILTyconRawMetadata.WithAccess tyconAccess - let customAttrs = ilCustomAttrs |> mkILCustomAttrs |> storeILCustomAttrs + let customAttrs = ilCustomAttrs |> mkILCustomAttrs let tdef = tdef.With(customAttrs = customAttrs, genericParams = ilGenParams) @@ -11357,16 +11406,20 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option let ilAttrs = ilCustomAttrs @ [ - mkCompilationMappingAttr - g - (int ( - if isObjectType then - SourceConstructFlags.ObjectType - elif hiddenRepr then - SourceConstructFlags.RecordType ||| SourceConstructFlags.NonPublicRepresentation - else - SourceConstructFlags.RecordType - )) + yield + mkCompilationMappingAttr + g + (int ( + if isObjectType then + SourceConstructFlags.ObjectType + elif hiddenRepr then + SourceConstructFlags.RecordType ||| SourceConstructFlags.NonPublicRepresentation + else + SourceConstructFlags.RecordType + )) + + if not (ilBaseTy.GenericArgs.IsEmpty) then + yield! GenAdditionalAttributesForTy g super ] let isKnownToBeAttribute = @@ -11403,7 +11456,11 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option .WithSerializable(isSerializable) .WithAbstract(isAbstract) .WithImport(isComInteropTy g thisTy) - .With(methodImpls = mkILMethodImpls methodImpls, newAdditionalFlags = additionalFlags) + .With( + methodImpls = mkILMethodImpls methodImpls, + newAdditionalFlags = additionalFlags, + implementsCustomAttrs = ilIntCustomAttrs + ) let tdLayout, tdEncoding = match TryFindFSharpAttribute g g.attrib_StructLayoutAttribute tycon.Attribs with @@ -11550,7 +11607,6 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option )) ] |> mkILCustomAttrs - |> storeILCustomAttrs let tdef = ILTypeDef( @@ -11566,6 +11622,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option methodImpls = mkILMethodImpls methodImpls, nestedTypes = emptyILTypeDefs, implements = ilIntfTys, + implementsCustomAttrs = None, extends = Some( if tycon.IsStructOrEnumTycon then @@ -11608,19 +11665,24 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option // private static field for lists etc. // // Also discard the F#-compiler supplied implementation of the Empty, IsEmpty, Value and None properties. + let tdefDiscards = Some( (fun (md: ILMethodDef) -> (cuinfo.HasHelpers = SpecialFSharpListHelpers && (md.Name = "get_Empty" || md.Name = "Cons" || md.Name = "get_IsEmpty")) || (cuinfo.HasHelpers = SpecialFSharpOptionHelpers - && (md.Name = "get_Value" || md.Name = "get_None" || md.Name = "Some"))), + && (md.Name = "get_Value" || md.Name = "get_None" || md.Name = "Some")) + || (cuinfo.HasHelpers = AllHelpers + && (md.Name.StartsWith("get_Is") && not (tdef2.Methods.FindByName(md.Name).IsEmpty)))), (fun (pd: ILPropertyDef) -> (cuinfo.HasHelpers = SpecialFSharpListHelpers && (pd.Name = "Empty" || pd.Name = "IsEmpty")) || (cuinfo.HasHelpers = SpecialFSharpOptionHelpers - && (pd.Name = "Value" || pd.Name = "None"))) + && (pd.Name = "Value" || pd.Name = "None")) + || (cuinfo.HasHelpers = AllHelpers + && (pd.Name.StartsWith("Is") && not (tdef2.Properties.LookupByName(pd.Name).IsEmpty)))) ) tdef2, tdefDiscards diff --git a/src/Compiler/CodeGen/IlxGenSupport.fs b/src/Compiler/CodeGen/IlxGenSupport.fs index a0fa11a4a31..4be01ced411 100644 --- a/src/Compiler/CodeGen/IlxGenSupport.fs +++ b/src/Compiler/CodeGen/IlxGenSupport.fs @@ -8,6 +8,7 @@ open Internal.Utilities.Library open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.TcGlobals open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.TypedTree /// Make a method that simply loads a field let mkLdfldMethodDef (ilMethName, iLAccess, isStatic, ilTy, ilFieldName, ilPropType, customAttrs) = @@ -68,7 +69,22 @@ let mkILNonGenericInstanceProperty (name, ilType, propertyAttribute, customAttri customAttrs = customAttributes ) -let mkLocalPrivateAttributeWithPropertyConstructors (g: TcGlobals, name: string, attrProperties: (string * ILType) list option) = +type AttrDataGenerationStyle = + | PublicFields + | EncapsulatedProperties + +let getFieldMemberAccess = + function + | PublicFields -> ILMemberAccess.Public + | EncapsulatedProperties -> ILMemberAccess.Private + +let mkLocalPrivateAttributeWithPropertyConstructors + ( + g: TcGlobals, + name: string, + attrProperties: (string * ILType) list option, + codegenStyle: AttrDataGenerationStyle + ) = let ilTypeRef = mkILTyRef (ILScopeRef.Local, name) let ilTy = mkILFormalNamedTy ILBoxity.AsObject ilTypeRef [] @@ -76,21 +92,34 @@ let mkLocalPrivateAttributeWithPropertyConstructors (g: TcGlobals, name: string, attrProperties |> Option.defaultValue [] |> List.map (fun (name, ilType) -> - let fieldName = name + "@" - - (g.AddFieldGeneratedAttributes(mkILInstanceField (fieldName, ilType, None, ILMemberAccess.Private))), - (g.AddMethodGeneratedAttributes(mkLdfldMethodDef ($"get_{name}", ILMemberAccess.Public, false, ilTy, fieldName, ilType, []))), - (g.AddPropertyGeneratedAttributes( - mkILNonGenericInstanceProperty ( - name, - ilType, - PropertyAttributes.None, - emptyILCustomAttrs, - Some(mkILMethRef (ilTypeRef, ILCallingConv.Instance, "get_" + name, 0, [], ilType)), - None - ) - )), - (name, fieldName, ilType)) + match codegenStyle with + | PublicFields -> + (g.AddFieldGeneratedAttributes(mkILInstanceField (name, ilType, None, getFieldMemberAccess codegenStyle))), + [], + [], + (name, name, ilType) + | EncapsulatedProperties -> + let fieldName = name + "@" + + (g.AddFieldGeneratedAttributes(mkILInstanceField (fieldName, ilType, None, getFieldMemberAccess codegenStyle))), + [ + g.AddMethodGeneratedAttributes( + mkLdfldMethodDef ($"get_{name}", ILMemberAccess.Public, false, ilTy, fieldName, ilType, []) + ) + ], + [ + g.AddPropertyGeneratedAttributes( + mkILNonGenericInstanceProperty ( + name, + ilType, + PropertyAttributes.None, + emptyILCustomAttrs, + Some(mkILMethRef (ilTypeRef, ILCallingConv.Instance, "get_" + name, 0, [], ilType)), + None + ) + ) + ], + (name, fieldName, ilType)) // Generate constructor with required arguments let ilCtorDef = @@ -106,8 +135,6 @@ let mkLocalPrivateAttributeWithPropertyConstructors (g: TcGlobals, name: string, ) ) - let ilCustomAttrs = mkILCustomAttrsFromArray [| g.CompilerGeneratedAttribute |] - mkILGenericClass ( name, ILTypeDefAccess.Private, @@ -116,13 +143,75 @@ let mkLocalPrivateAttributeWithPropertyConstructors (g: TcGlobals, name: string, ILTypes.Empty, mkILMethods ( ilCtorDef - :: (ilElements |> List.fold (fun acc (_, getter, _, _) -> getter :: acc) []) + :: (ilElements |> List.fold (fun acc (_, getter, _, _) -> getter @ acc) []) ), mkILFields (ilElements |> List.map (fun (field, _, _, _) -> field)), emptyILTypeDefs, - mkILProperties (ilElements |> List.map (fun (_, _, property, _) -> property)), + mkILProperties (ilElements |> List.collect (fun (_, _, props, _) -> props)), emptyILEvents, - ilCustomAttrs, + mkILCustomAttrsFromArray [| g.CompilerGeneratedAttribute |], + ILTypeInit.BeforeField + ) + +let mkLocalPrivateAttributeWithByteAndByteArrayConstructors (g: TcGlobals, name: string, bytePropertyName: string) = + let ilTypeRef = mkILTyRef (ILScopeRef.Local, name) + let ilTy = mkILFormalNamedTy ILBoxity.AsObject ilTypeRef [] + + let fieldName = bytePropertyName + let fieldType = g.ilg.typ_ByteArray + + let fieldDef = + g.AddFieldGeneratedAttributes(mkILInstanceField (fieldName, fieldType, None, ILMemberAccess.Public)) + + // Constructor taking an array + let ilArrayCtorDef = + g.AddMethodGeneratedAttributes( + mkILSimpleStorageCtorWithParamNames ( + Some g.ilg.typ_Attribute.TypeSpec, + ilTy, + [], + [ (fieldName, fieldName, fieldType) ], + ILMemberAccess.Public, + None, + None + ) + ) + + let ilScalarCtorDef = + let scalarValueIlType = g.ilg.typ_Byte + + g.AddMethodGeneratedAttributes( + let code = + [ + mkLdarg0 + mkNormalCall (mkILCtorMethSpecForTy (mkILBoxedType g.ilg.typ_Attribute.TypeSpec, [])) // Base class .ctor + + mkLdarg0 // Prepare 'this' to be on bottom of the stack + mkLdcInt32 1 + I_newarr(ILArrayShape.SingleDimensional, scalarValueIlType) // new byte[1] + AI_dup // Duplicate the array pointer in stack, 1 for stelem and 1 for stfld + mkLdcInt32 0 + mkLdarg 1us + I_stelem DT_I1 // array[0] = argument from .ctor + mkNormalStfld (mkILFieldSpecInTy (ilTy, fieldName, fieldType)) + ] + + let body = mkMethodBody (false, [], 8, nonBranchingInstrsToCode code, None, None) + mkILCtor (ILMemberAccess.Public, [ mkILParamNamed ("scalarByteValue", scalarValueIlType) ], body) + ) + + mkILGenericClass ( + name, + ILTypeDefAccess.Private, + ILGenericParameterDefs.Empty, + g.ilg.typ_Attribute, + ILTypes.Empty, + mkILMethods ([ ilScalarCtorDef; ilArrayCtorDef ]), + mkILFields [ fieldDef ], + emptyILTypeDefs, + emptyILProperties, + emptyILEvents, + mkILCustomAttrsFromArray [| g.CompilerGeneratedAttribute |], ILTypeInit.BeforeField ) @@ -170,13 +259,6 @@ let GetReadOnlyAttribute (g: TcGlobals) = let GetIsUnmanagedAttribute (g: TcGlobals) = getPotentiallyEmbedableAttribute g g.attrib_IsUnmanagedAttribute -let GenReadOnlyAttributeIfNecessary g ty = - if isInByrefTy g ty then - let attr = GetReadOnlyAttribute g - Some attr - else - None - let GetDynamicallyAccessedMemberTypes (g: TcGlobals) = let tref = g.enum_DynamicallyAccessedMemberTypes.TypeRef @@ -220,7 +302,7 @@ let GetDynamicDependencyAttribute (g: TcGlobals) memberTypes (ilType: ILType) = let properties = Some [ "MemberType", GetDynamicallyAccessedMemberTypes g; "Type", g.ilg.typ_Type ] - mkLocalPrivateAttributeWithPropertyConstructors (g, tref.Name, properties)) + mkLocalPrivateAttributeWithPropertyConstructors (g, tref.Name, properties, EncapsulatedProperties)) ) let typIlMemberTypes = @@ -233,6 +315,163 @@ let GetDynamicDependencyAttribute (g: TcGlobals) memberTypes (ilType: ILType) = [] ) +/// Generates NullableContextAttribute[1], which has the meaning of: +/// Nested items not being annotated with Nullable attribute themselves are interpreted as being withoutnull +/// Doing it that way is a heuristical decision supporting limited usage of (| null) annotations and not allowing nulls in >50% of F# code +/// (if majority of fields/parameters/return values would be nullable, this heuristic would lead to bloat of generated metadata) +let GetNullableContextAttribute (g: TcGlobals) = + let tref = g.attrib_NullableContextAttribute.TypeRef + + g.TryEmbedILType( + tref, + (fun () -> + let fields = Some [ "Flag", g.ilg.typ_Byte ] + mkLocalPrivateAttributeWithPropertyConstructors (g, tref.Name, fields, PublicFields)) + ) + + mkILCustomAttribute (tref, [ g.ilg.typ_Byte ], [ ILAttribElem.Byte 1uy ], []) + +let GetNotNullWhenTrueAttribute (g: TcGlobals) (propNames: string array) = + let tref = g.attrib_MemberNotNullWhenAttribute.TypeRef + + g.TryEmbedILType( + tref, + (fun () -> + let fields = + Some [ "ReturnValue", g.ilg.typ_Bool; "Members", g.ilg.typ_StringArray ] + + mkLocalPrivateAttributeWithPropertyConstructors (g, tref.Name, fields, EncapsulatedProperties)) + ) + + let stringArgs = + propNames |> Array.map (Some >> ILAttribElem.String) |> List.ofArray + + mkILCustomAttribute ( + tref, + [ g.ilg.typ_Bool; g.ilg.typ_StringArray ], + [ ILAttribElem.Bool true; ILAttribElem.Array(g.ilg.typ_String, stringArgs) ], + [] + ) + +let GetNullableAttribute (g: TcGlobals) (nullnessInfos: TypedTree.NullnessInfo list) = + let tref = g.attrib_NullableAttribute.TypeRef + + g.TryEmbedILType(tref, (fun () -> mkLocalPrivateAttributeWithByteAndByteArrayConstructors (g, tref.Name, "NullableFlags"))) + + let byteValue ni = + match ni with + | NullnessInfo.WithNull -> 2uy + | NullnessInfo.AmbivalentToNull -> 0uy + | NullnessInfo.WithoutNull -> 1uy + + let bytes = nullnessInfos |> List.map (fun ni -> byteValue ni |> ILAttribElem.Byte) + + match bytes with + | [ singleByte ] -> mkILCustomAttribute (tref, [ g.ilg.typ_Byte ], [ singleByte ], []) + | listOfBytes -> mkILCustomAttribute (tref, [ g.ilg.typ_ByteArray ], [ ILAttribElem.Array(g.ilg.typ_Byte, listOfBytes) ], []) + +let GenReadOnlyIfNecessary g ty = + if isInByrefTy g ty then + let attr = GetReadOnlyAttribute g + Some attr + else + None + +(* Nullness metadata format in C#: https://github.com/dotnet/roslyn/blob/main/docs/features/nullable-metadata.md +Each type reference in metadata may have an associated NullableAttribute with a byte[] where each byte represents nullability: 0 for oblivious, 1 for not annotated, and 2 for annotated. + +The byte[] is constructed as follows: + +Reference type: the nullability (0, 1, or 2), followed by the representation of the type arguments in order including containing types +Nullable value type: the representation of the type argument only +Non-generic value type: skipped +Generic value type: 0, followed by the representation of the type arguments in order including containing types +Array: the nullability (0, 1, or 2), followed by the representation of the element type +Tuple: the representation of the underlying constructed type +Type parameter reference: the nullability (0, 1, or 2, with 0 for unconstrained type parameter) +*) +let rec GetNullnessFromTType (g: TcGlobals) ty = + match ty |> stripTyEqns g with + | TType_app(tcref, tinst, nullness) -> + let isValueType = tcref.IsStructOrEnumTycon + let isNonGeneric = tinst.IsEmpty + + if isNonGeneric && isValueType then + // Non-generic value type: skipped + [] + else + [ + if tyconRefEq g g.system_Nullable_tcref tcref then + // Nullable value type: the representation of the type argument only + () + else if isValueType then + // Generic value type: 0, followed by the representation of the type arguments in order including containing types + yield NullnessInfo.AmbivalentToNull + else + // Reference type: the nullability (0, 1, or 2), followed by the representation of the type arguments in order including containing types + yield nullness.Evaluate() + + for tt in tinst do + yield! GetNullnessFromTType g tt + ] + + | TType_fun(domainTy, retTy, nullness) -> + // FsharpFunc + [ + yield nullness.Evaluate() + yield! GetNullnessFromTType g domainTy + yield! GetNullnessFromTType g retTy + ] + + | TType_tuple(tupInfo, elementTypes) -> + // Tuple: the representation of the underlying constructed type + [ + if evalTupInfoIsStruct tupInfo then + yield NullnessInfo.AmbivalentToNull + else + yield NullnessInfo.WithoutNull + for t in elementTypes do + yield! GetNullnessFromTType g t + ] + + | TType_anon(anonInfo, tys) -> + // It is unlikely for an anon type to be used from C# due to the mangled name, but can still carry the nullability info about it's generic type arguments == the types of the fields + [ + if evalAnonInfoIsStruct anonInfo then + yield NullnessInfo.AmbivalentToNull + else + yield NullnessInfo.WithoutNull + for t in tys do + yield! GetNullnessFromTType g t + ] + | TType_forall _ + | TType_ucase _ + | TType_measure _ -> [] + | TType_var(nullness = nullness) -> [ nullness.Evaluate() ] + +let GenNullnessIfNecessary (g: TcGlobals) ty = + if g.langFeatureNullness && g.checkNullness then + let nullnessList = GetNullnessFromTType g ty + + match nullnessList with + // Optimizations as done in C# :: If the byte[] is empty, the NullableAttribute is omitted. + | [] -> None + // Optimizations as done in C# :: If all values in the byte[] are the same, the NullableAttribute is constructed with that single byte value. + | head :: tail when tail |> List.forall ((=) head) -> + match head with + // For F# code, each type has an automatically generated NullableContextAttribute(1) + // That means an implicit (hidden, not generated) Nullable(1) attribute + | NullnessInfo.WithoutNull -> None + | _ -> GetNullableAttribute g [ head ] |> Some + | nonUniformList -> GetNullableAttribute g nonUniformList |> Some + else + None + +let GenAdditionalAttributesForTy g ty = + let readOnly = GenReadOnlyIfNecessary g ty |> Option.toList + let nullable = GenNullnessIfNecessary g ty |> Option.toList + readOnly @ nullable + /// Generate "modreq([mscorlib]System.Runtime.InteropServices.InAttribute)" on inref types. let GenReadOnlyModReqIfNecessary (g: TcGlobals) ty ilTy = let add = isInByrefTy g ty && g.attrib_InAttribute.TyconRef.CanDeref diff --git a/src/Compiler/CodeGen/IlxGenSupport.fsi b/src/Compiler/CodeGen/IlxGenSupport.fsi index 24968a25ec6..6bd3723e886 100644 --- a/src/Compiler/CodeGen/IlxGenSupport.fsi +++ b/src/Compiler/CodeGen/IlxGenSupport.fsi @@ -19,6 +19,9 @@ val mkLdfldMethodDef: val GetDynamicDependencyAttribute: g: TcGlobals -> memberTypes: int32 -> ilType: ILType -> ILAttribute val GenReadOnlyModReqIfNecessary: g: TcGlobals -> ty: TypedTree.TType -> ilTy: ILType -> ILType -val GenReadOnlyAttributeIfNecessary: g: TcGlobals -> ty: TypedTree.TType -> ILAttribute option +val GenAdditionalAttributesForTy: g: TcGlobals -> ty: TypedTree.TType -> ILAttribute list val GetReadOnlyAttribute: g: TcGlobals -> ILAttribute val GetIsUnmanagedAttribute: g: TcGlobals -> ILAttribute +val GetNullableAttribute: g: TcGlobals -> nullnessInfos: TypedTree.NullnessInfo list -> ILAttribute +val GetNullableContextAttribute: g: TcGlobals -> ILAttribute +val GetNotNullWhenTrueAttribute: g: TcGlobals -> string array -> ILAttribute diff --git a/src/Compiler/DependencyManager/DependencyProvider.fs b/src/Compiler/DependencyManager/DependencyProvider.fs index 858cf84fc1a..0fb7be23b6c 100644 --- a/src/Compiler/DependencyManager/DependencyProvider.fs +++ b/src/Compiler/DependencyManager/DependencyProvider.fs @@ -124,7 +124,9 @@ type IResolveDependenciesResult = /// #I @"c:\somepath\to\packages\1.1.1\ResolvedPackage" abstract Roots: seq +#if NO_CHECKNULLS [] +#endif type IDependencyManagerProvider = abstract Name: string abstract Key: string diff --git a/src/Compiler/DependencyManager/DependencyProvider.fsi b/src/Compiler/DependencyManager/DependencyProvider.fsi index a4c76e67b92..7618f353141 100644 --- a/src/Compiler/DependencyManager/DependencyProvider.fsi +++ b/src/Compiler/DependencyManager/DependencyProvider.fsi @@ -39,7 +39,9 @@ type IResolveDependenciesResult = abstract Roots: seq /// Wraps access to a DependencyManager implementation +#if NO_CHECKNULLS [] +#endif type IDependencyManagerProvider = /// Name of the dependency manager diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs index ba16b854298..4a1d0d18c74 100644 --- a/src/Compiler/Driver/CompilerConfig.fs +++ b/src/Compiler/Driver/CompilerConfig.fs @@ -197,11 +197,14 @@ type IRawFSharpAssemblyData = abstract TryGetILModuleDef: unit -> ILModuleDef option /// The raw F# signature data in the assembly, if any - abstract GetRawFSharpSignatureData: range * ilShortAssemName: string * fileName: string -> (string * (unit -> ReadOnlyByteMemory)) list + abstract GetRawFSharpSignatureData: + range * ilShortAssemName: string * fileName: string -> + (string * ((unit -> ReadOnlyByteMemory) * (unit -> ReadOnlyByteMemory) option)) list /// The raw F# optimization data in the assembly, if any abstract GetRawFSharpOptimizationData: - range * ilShortAssemName: string * fileName: string -> (string * (unit -> ReadOnlyByteMemory)) list + range * ilShortAssemName: string * fileName: string -> + (string * ((unit -> ReadOnlyByteMemory) * (unit -> ReadOnlyByteMemory) option)) list /// The table of type forwarders in the assembly abstract GetRawTypeForwarders: unit -> ILExportedTypesAndForwarders @@ -443,6 +446,7 @@ type TcConfigBuilder = mutable embedResources: string list mutable diagnosticsOptions: FSharpDiagnosticOptions mutable mlCompatibility: bool + mutable checkNullness: bool mutable checkOverflow: bool mutable showReferenceResolutions: bool mutable outputDir: string option @@ -681,6 +685,7 @@ type TcConfigBuilder = subsystemVersion = 4, 0 // per spec for 357994 useHighEntropyVA = false mlCompatibility = false + checkNullness = false checkOverflow = false showReferenceResolutions = false outputDir = None @@ -1257,6 +1262,7 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) = member _.embedResources = data.embedResources member _.diagnosticsOptions = data.diagnosticsOptions member _.mlCompatibility = data.mlCompatibility + member _.checkNullness = data.checkNullness member _.checkOverflow = data.checkOverflow member _.showReferenceResolutions = data.showReferenceResolutions member _.outputDir = data.outputDir diff --git a/src/Compiler/Driver/CompilerConfig.fsi b/src/Compiler/Driver/CompilerConfig.fsi index 89e0039610b..f21ae429029 100644 --- a/src/Compiler/Driver/CompilerConfig.fsi +++ b/src/Compiler/Driver/CompilerConfig.fsi @@ -46,11 +46,13 @@ type IRawFSharpAssemblyData = /// Get the raw F# signature data in the assembly, if any abstract GetRawFSharpSignatureData: - m: range * ilShortAssemName: string * fileName: string -> (string * (unit -> ReadOnlyByteMemory)) list + m: range * ilShortAssemName: string * fileName: string -> + (string * ((unit -> ReadOnlyByteMemory) * (unit -> ReadOnlyByteMemory) option)) list /// Get the raw F# optimization data in the assembly, if any abstract GetRawFSharpOptimizationData: - m: range * ilShortAssemName: string * fileName: string -> (string * (unit -> ReadOnlyByteMemory)) list + m: range * ilShortAssemName: string * fileName: string -> + (string * ((unit -> ReadOnlyByteMemory) * (unit -> ReadOnlyByteMemory) option)) list /// Get the table of type forwarders in the assembly abstract GetRawTypeForwarders: unit -> ILExportedTypesAndForwarders @@ -288,6 +290,8 @@ type TcConfigBuilder = mutable mlCompatibility: bool + mutable checkNullness: bool + mutable checkOverflow: bool mutable showReferenceResolutions: bool @@ -626,6 +630,8 @@ type TcConfig = member mlCompatibility: bool + member checkNullness: bool + member checkOverflow: bool member showReferenceResolutions: bool diff --git a/src/Compiler/Driver/CompilerDiagnostics.fs b/src/Compiler/Driver/CompilerDiagnostics.fs index 823eb4ccbf1..5ac8f448448 100644 --- a/src/Compiler/Driver/CompilerDiagnostics.fs +++ b/src/Compiler/Driver/CompilerDiagnostics.fs @@ -177,6 +177,10 @@ type Exception with | ConstraintSolverTupleDiffLengths(_, _, _, _, m, _) | ConstraintSolverInfiniteTypes(_, _, _, _, m, _) | ConstraintSolverMissingConstraint(_, _, _, m, _) + | ConstraintSolverNullnessWarningEquivWithTypes(_, _, _, _, _, m, _) + | ConstraintSolverNullnessWarningWithTypes(_, _, _, _, _, m, _) + | ConstraintSolverNullnessWarningWithType(_, _, _, m, _) + | ConstraintSolverNullnessWarning(_, m, _) | ConstraintSolverTypesNotInEqualityRelation(_, _, _, m, _, _) | ConstraintSolverError(_, m, _) | ConstraintSolverTypesNotInSubsumptionRelation(_, _, _, m, _) @@ -345,6 +349,10 @@ type Exception with #endif | ErrorsFromAddingSubsumptionConstraint(_, _, _, _, _, ContextInfo.DowncastUsedInsteadOfUpcast _, _) -> fst (FSComp.SR.considerUpcast ("", "")) + | ConstraintSolverNullnessWarningEquivWithTypes _ -> 3261 + | ConstraintSolverNullnessWarningWithTypes _ -> 3261 + | ConstraintSolverNullnessWarningWithType _ -> 3261 + | ConstraintSolverNullnessWarning _ -> 3261 | _ -> 193 type PhasedDiagnostic with @@ -452,6 +460,10 @@ module OldStyleMessages = let ConstraintSolverTupleDiffLengthsE () = Message("ConstraintSolverTupleDiffLengths", "%d%d") let ConstraintSolverInfiniteTypesE () = Message("ConstraintSolverInfiniteTypes", "%s%s") let ConstraintSolverMissingConstraintE () = Message("ConstraintSolverMissingConstraint", "%s") + let ConstraintSolverNullnessWarningEquivWithTypesE () = Message("ConstraintSolverNullnessWarningEquivWithTypes", "%s%s") + let ConstraintSolverNullnessWarningWithTypesE () = Message("ConstraintSolverNullnessWarningWithTypes", "%s%s") + let ConstraintSolverNullnessWarningWithTypeE () = Message("ConstraintSolverNullnessWarningWithType", "%s") + let ConstraintSolverNullnessWarningE () = Message("ConstraintSolverNullnessWarning", "%s") let ConstraintSolverTypesNotInEqualityRelation1E () = Message("ConstraintSolverTypesNotInEqualityRelation1", "%s%s") let ConstraintSolverTypesNotInEqualityRelation2E () = Message("ConstraintSolverTypesNotInEqualityRelation2", "%s%s") let ConstraintSolverTypesNotInSubsumptionRelationE () = Message("ConstraintSolverTypesNotInSubsumptionRelation", "%s%s%s") @@ -678,6 +690,57 @@ type Exception with if m.StartLine <> m2.StartLine then os.AppendString(SeeAlsoE().Format(stringOfRange m)) + | ConstraintSolverNullnessWarningEquivWithTypes(denv, ty1, ty2, _nullness1, _nullness2, m, m2) -> + + // Turn on nullness annotations for messages about nullness + let denv = + { denv with + showNullnessAnnotations = Some true + } + + let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2 + + os.Append(ConstraintSolverNullnessWarningEquivWithTypesE().Format t1 t2) + |> ignore + + if m.StartLine <> m2.StartLine then + os.Append(SeeAlsoE().Format(stringOfRange m)) |> ignore + + | ConstraintSolverNullnessWarningWithTypes(denv, ty1, ty2, _nullness1, _nullness2, m, m2) -> + + // Turn on nullness annotations for messages about nullness + let denv = + { denv with + showNullnessAnnotations = Some true + } + + let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2 + + os.Append(ConstraintSolverNullnessWarningWithTypesE().Format t1 t2) |> ignore + + if m.StartLine <> m2.StartLine then + os.Append(SeeAlsoE().Format(stringOfRange m)) |> ignore + + | ConstraintSolverNullnessWarningWithType(denv, ty, _, m, m2) -> + + // Turn on nullness annotations for messages about nullness + let denv = + { denv with + showNullnessAnnotations = Some true + } + + let t = NicePrint.minimalStringOfType denv ty + os.Append(ConstraintSolverNullnessWarningWithTypeE().Format(t)) |> ignore + + if m.StartLine <> m2.StartLine then + os.Append(SeeAlsoE().Format(stringOfRange m)) |> ignore + + | ConstraintSolverNullnessWarning(msg, m, m2) -> + os.Append(ConstraintSolverNullnessWarningE().Format(msg)) |> ignore + + if m.StartLine <> m2.StartLine then + os.AppendString(SeeAlsoE().Format(stringOfRange m2)) + | ConstraintSolverMissingConstraint(denv, tpr, tpc, m, m2) -> os.AppendString( ConstraintSolverMissingConstraintE() @@ -830,7 +893,8 @@ type Exception with let argsMessage, returnType, genericParametersMessage = let retTy = - knownReturnType |> Option.defaultValue (TType_var(Typar.NewUnlinked(), 0uy)) + knownReturnType + |> Option.defaultValue (TType.TType_var(Typar.NewUnlinked(), KnownAmbivalentToNull)) let argRepr = callerArgs.ArgumentNamesAndTypes @@ -1237,9 +1301,9 @@ type Exception with | Parser.TOKEN_INTERP_STRING_BEGIN_PART -> SR.GetString("Parser.TOKEN.INTERP.STRING.BEGIN.PART") | Parser.TOKEN_INTERP_STRING_PART -> SR.GetString("Parser.TOKEN.INTERP.STRING.PART") | Parser.TOKEN_INTERP_STRING_END -> SR.GetString("Parser.TOKEN.INTERP.STRING.END") + | Parser.TOKEN_BAR_JUST_BEFORE_NULL -> SR.GetString("Parser.TOKEN.BAR_JUST_BEFORE_NULL") | unknown -> - Debug.Assert(false, "unknown token tag") - let result = sprintf "%+A" unknown + let result = sprintf "unknown token tag %+A" unknown Debug.Assert(false, result) result @@ -2172,8 +2236,11 @@ type DiagnosticsLoggerFilteringByScopedPragmas (checkFile, scopedPragmas, diagnosticOptions: FSharpDiagnosticOptions, diagnosticsLogger: DiagnosticsLogger) = inherit DiagnosticsLogger("DiagnosticsLoggerFilteringByScopedPragmas") + let mutable realErrorPresent = false + override _.DiagnosticSink(diagnostic: PhasedDiagnostic, severity) = if severity = FSharpDiagnosticSeverity.Error then + realErrorPresent <- true diagnosticsLogger.DiagnosticSink(diagnostic, severity) else let report = @@ -2201,5 +2268,7 @@ type DiagnosticsLoggerFilteringByScopedPragmas override _.ErrorCount = diagnosticsLogger.ErrorCount + override _.CheckForRealErrorsIgnoringWarnings = realErrorPresent + let GetDiagnosticsLoggerFilteringByScopedPragmas (checkFile, scopedPragmas, diagnosticOptions, diagnosticsLogger) = DiagnosticsLoggerFilteringByScopedPragmas(checkFile, scopedPragmas, diagnosticOptions, diagnosticsLogger) :> DiagnosticsLogger diff --git a/src/Compiler/Driver/CompilerImports.fs b/src/Compiler/Driver/CompilerImports.fs index 76573599919..334a834db32 100644 --- a/src/Compiler/Driver/CompilerImports.fs +++ b/src/Compiler/Driver/CompilerImports.fs @@ -58,11 +58,19 @@ let IsSignatureDataResource (r: ILResource) = || r.Name.StartsWithOrdinal FSharpSignatureCompressedDataResourceName || r.Name.StartsWithOrdinal FSharpSignatureDataResourceName2 +let IsSignatureDataResourceB (r: ILResource) = + r.Name.StartsWithOrdinal FSharpSignatureDataResourceNameB + || r.Name.StartsWithOrdinal FSharpSignatureCompressedDataResourceNameB + let IsOptimizationDataResource (r: ILResource) = r.Name.StartsWithOrdinal FSharpOptimizationDataResourceName || r.Name.StartsWithOrdinal FSharpOptimizationCompressedDataResourceName || r.Name.StartsWithOrdinal FSharpOptimizationDataResourceName2 +let IsOptimizationDataResourceB (r: ILResource) = + r.Name.StartsWithOrdinal FSharpOptimizationDataResourceNameB + || r.Name.StartsWithOrdinal FSharpOptimizationCompressedDataResourceNameB + let decompressResource (r: ILResource) = use raw = r.GetBytes().AsStream() use decompressed = new MemoryStream() @@ -71,71 +79,130 @@ let decompressResource (r: ILResource) = deflator.Close() ByteStorage.FromByteArray(decompressed.ToArray()).GetByteMemory() -let GetResourceNameAndSignatureDataFunc (r: ILResource) = - let resourceType, ccuName = - if r.Name.StartsWithOrdinal FSharpSignatureDataResourceName then - FSharpSignatureDataResourceName, String.dropPrefix r.Name FSharpSignatureDataResourceName - elif r.Name.StartsWithOrdinal FSharpSignatureCompressedDataResourceName then - FSharpSignatureCompressedDataResourceName, String.dropPrefix r.Name FSharpSignatureCompressedDataResourceName - elif r.Name.StartsWithOrdinal FSharpSignatureDataResourceName2 then - FSharpSignatureDataResourceName2, String.dropPrefix r.Name FSharpSignatureDataResourceName2 - else - failwith "GetSignatureDataResourceName" - - if resourceType = FSharpSignatureCompressedDataResourceName then - ccuName, (fun () -> decompressResource (r)) +let GetSignatureDataResourceName (r: ILResource) = + if r.Name.StartsWithOrdinal FSharpSignatureDataResourceName then + (fun () -> r.GetBytes()), String.dropPrefix r.Name FSharpSignatureDataResourceName + elif r.Name.StartsWithOrdinal FSharpSignatureCompressedDataResourceName then + (fun () -> decompressResource r), String.dropPrefix r.Name FSharpSignatureCompressedDataResourceName + elif r.Name.StartsWithOrdinal FSharpSignatureDataResourceNameB then + (fun () -> r.GetBytes()), String.dropPrefix r.Name FSharpSignatureDataResourceNameB + elif r.Name.StartsWithOrdinal FSharpSignatureCompressedDataResourceNameB then + (fun () -> decompressResource r), String.dropPrefix r.Name FSharpSignatureCompressedDataResourceNameB + elif r.Name.StartsWithOrdinal FSharpSignatureDataResourceName2 then + (fun () -> r.GetBytes()), String.dropPrefix r.Name FSharpSignatureDataResourceName2 else - ccuName, (fun () -> r.GetBytes()) - -let GetResourceNameAndOptimizationDataFunc (r: ILResource) = - let resourceType, ccuName = - if r.Name.StartsWithOrdinal FSharpOptimizationDataResourceName then - FSharpOptimizationDataResourceName, String.dropPrefix r.Name FSharpOptimizationDataResourceName - elif r.Name.StartsWithOrdinal FSharpOptimizationCompressedDataResourceName then - FSharpOptimizationCompressedDataResourceName, String.dropPrefix r.Name FSharpOptimizationCompressedDataResourceName - elif r.Name.StartsWithOrdinal FSharpOptimizationDataResourceName2 then - FSharpOptimizationDataResourceName2, String.dropPrefix r.Name FSharpOptimizationDataResourceName2 - else - failwith "GetOptimizationDataResourceName" - - if resourceType = FSharpOptimizationCompressedDataResourceName then - ccuName, (fun () -> decompressResource (r)) + failwith "unreachable" + +let GetResourceNameAndSignatureDataFuncs (resources: ILResource list) = + [ for r in resources do + if IsSignatureDataResource r then + let readerA, ccuName = GetSignatureDataResourceName r + + let readerB = + resources |> List.tryPick (fun rB -> + if IsSignatureDataResourceB rB then + let readerB, ccuNameB = GetSignatureDataResourceName rB + if ccuName = ccuNameB then + Some readerB + else None + else None) + + ccuName, (readerA, readerB) ] + +let GetOptimizationDataResourceName (r: ILResource) = + if r.Name.StartsWithOrdinal FSharpOptimizationDataResourceName then + (fun () -> r.GetBytes()), String.dropPrefix r.Name FSharpOptimizationDataResourceName + elif r.Name.StartsWithOrdinal FSharpOptimizationCompressedDataResourceName then + (fun () -> decompressResource r), String.dropPrefix r.Name FSharpOptimizationCompressedDataResourceName + elif r.Name.StartsWithOrdinal FSharpOptimizationDataResourceNameB then + (fun () -> r.GetBytes()), String.dropPrefix r.Name FSharpOptimizationDataResourceNameB + elif r.Name.StartsWithOrdinal FSharpOptimizationCompressedDataResourceNameB then + (fun () -> decompressResource r), String.dropPrefix r.Name FSharpOptimizationCompressedDataResourceNameB + elif r.Name.StartsWithOrdinal FSharpOptimizationDataResourceName2 then + (fun () -> r.GetBytes()), String.dropPrefix r.Name FSharpOptimizationDataResourceName2 else - ccuName, (fun () -> r.GetBytes()) + failwith $"GetOptimizationDataResourceName - {r.Name}" + +let GetResourceNameAndOptimizationDataFuncs (resources: ILResource list) = + [ for r in resources do + if IsOptimizationDataResource r then + let readerA, ccuName = GetOptimizationDataResourceName r + + let readerB = + resources |> List.tryPick (fun rB -> + if IsOptimizationDataResourceB rB then + let readerB, ccuNameB = GetOptimizationDataResourceName rB + if ccuName = ccuNameB then + Some readerB + else None + else None) + ccuName, (readerA, readerB) ] let IsReflectedDefinitionsResource (r: ILResource) = r.Name.StartsWithOrdinal(QuotationPickler.SerializedReflectedDefinitionsResourceNameBase) -let PickleToResource inMem file (g: TcGlobals) compress scope rName p x = +let ByteBufferToBytes compress (bytes: ByteBuffer) = + if compress then + let raw = new MemoryStream(bytes.AsMemory().ToArray()) + let compressed = new MemoryStream() + use deflator = new DeflateStream(compressed, CompressionLevel.Optimal) + raw.CopyTo deflator + deflator.Close() + compressed.ToArray() + else + bytes.AsMemory().ToArray() + +let PickleToResource inMem file (g: TcGlobals) compress scope rName rNameB p x = let file = PathMap.apply g.pathMap file - let bytes = - use bytes = pickleObjWithDanglingCcus inMem file g scope p x + let bytes, bytesB = pickleObjWithDanglingCcus inMem file g scope p x + use bytes = bytes + use bytesB = bytesB + let bytes = ByteBufferToBytes compress bytes + let bytesB = ByteBufferToBytes compress bytesB + let byteStorage = ByteStorage.FromByteArray(bytes) - if compress then - let raw = new MemoryStream(bytes.AsMemory().ToArray()) - let compressed = new MemoryStream() - use deflator = new DeflateStream(compressed, CompressionLevel.Optimal) - raw.CopyTo deflator - deflator.Close() - compressed.ToArray() + let byteStorageB = + if inMem then + ByteStorage.FromMemoryAndCopy(bytesB.AsMemory(), useBackingMemoryMappedFile = true) else - bytes.AsMemory().ToArray() + ByteStorage.FromByteArray(bytesB.AsMemory().ToArray()) - let byteStorage = ByteStorage.FromByteArray(bytes) + let resource = + { + Name = rName + Location = ILResourceLocation.Local(byteStorage) + Access = ILResourceAccess.Public + CustomAttrsStored = storeILCustomAttrs emptyILCustomAttrs + MetadataIndex = NoMetadataIdx + } - { - Name = rName - Location = ILResourceLocation.Local(byteStorage) - Access = ILResourceAccess.Public - CustomAttrsStored = storeILCustomAttrs emptyILCustomAttrs - MetadataIndex = NoMetadataIdx - } + let resourceB = + if bytesB.AsMemory().Length > 0 then + Some + { + Name = rNameB + Location = ILResourceLocation.Local(byteStorageB) + Access = ILResourceAccess.Public + CustomAttrsStored = storeILCustomAttrs emptyILCustomAttrs + MetadataIndex = NoMetadataIdx + } + else + None + + resource, resourceB + +let GetSignatureData (file, ilScopeRef, ilModule, byteReaderA, byteReaderB) : PickledDataWithReferences = + let memA = byteReaderA () + + let memB = + (match byteReaderB with + | None -> ByteMemory.Empty.AsReadOnly() + | Some br -> br ()) -let GetSignatureData (file, ilScopeRef, ilModule, byteReader) : PickledDataWithReferences = - unpickleObjWithDanglingCcus file ilScopeRef ilModule unpickleCcuInfo (byteReader ()) + unpickleObjWithDanglingCcus file ilScopeRef ilModule unpickleCcuInfo memA memB -let WriteSignatureData (tcConfig: TcConfig, tcGlobals, exportRemapping, ccu: CcuThunk, fileName, inMem) : ILResource = +let WriteSignatureData (tcConfig: TcConfig, tcGlobals, exportRemapping, ccu: CcuThunk, fileName, inMem) = let mspec = ApplyExportRemappingToEntity tcGlobals exportRemapping ccu.Contents if tcConfig.dumpSignatureData then @@ -150,13 +217,19 @@ let WriteSignatureData (tcConfig: TcConfig, tcGlobals, exportRemapping, ccu: Ccu // For historical reasons, we use a different resource name for FSharp.Core, so older F# compilers // don't complain when they see the resource. - let rName, compress = + let rName = if tcConfig.compressMetadata then - FSharpSignatureCompressedDataResourceName, true + FSharpSignatureCompressedDataResourceName elif ccu.AssemblyName = getFSharpCoreLibraryName then - FSharpSignatureDataResourceName2, false + FSharpSignatureDataResourceName2 else - FSharpSignatureDataResourceName, false + FSharpSignatureDataResourceName + + let rNameB = + if tcConfig.compressMetadata then + FSharpSignatureCompressedDataResourceNameB + else + FSharpSignatureDataResourceNameB let includeDir = if String.IsNullOrEmpty tcConfig.implicitIncludeDir then @@ -170,9 +243,10 @@ let WriteSignatureData (tcConfig: TcConfig, tcGlobals, exportRemapping, ccu: Ccu inMem fileName tcGlobals - compress + tcConfig.compressMetadata ccu (rName + ccu.AssemblyName) + (rNameB + ccu.AssemblyName) pickleCcuInfo { mspec = mspec @@ -180,28 +254,56 @@ let WriteSignatureData (tcConfig: TcConfig, tcGlobals, exportRemapping, ccu: Ccu usesQuotations = ccu.UsesFSharp20PlusQuotations } -let GetOptimizationData (file, ilScopeRef, ilModule, byteReader) = - unpickleObjWithDanglingCcus file ilScopeRef ilModule Optimizer.u_CcuOptimizationInfo (byteReader ()) +let GetOptimizationData (file, ilScopeRef, ilModule, byteReaderA, byteReaderB) = + let memA = byteReaderA () + + let memB = + (match byteReaderB with + | None -> ByteMemory.Empty.AsReadOnly() + | Some br -> br ()) + + unpickleObjWithDanglingCcus file ilScopeRef ilModule Optimizer.u_CcuOptimizationInfo memA memB let WriteOptimizationData (tcConfig: TcConfig, tcGlobals, fileName, inMem, ccu: CcuThunk, modulInfo) = // For historical reasons, we use a different resource name for FSharp.Core, so older F# compilers // don't complain when they see the resource. - let rName, compress = + let rName = if tcConfig.compressMetadata then - FSharpOptimizationCompressedDataResourceName, true + FSharpOptimizationCompressedDataResourceName elif ccu.AssemblyName = getFSharpCoreLibraryName then - FSharpOptimizationDataResourceName2, false + FSharpOptimizationDataResourceName2 + else + FSharpOptimizationDataResourceName + + let rNameB = + if tcConfig.compressMetadata then + FSharpOptimizationCompressedDataResourceNameB else - FSharpOptimizationDataResourceName, false + FSharpOptimizationDataResourceNameB - PickleToResource inMem fileName tcGlobals compress ccu (rName + ccu.AssemblyName) Optimizer.p_CcuOptimizationInfo modulInfo + PickleToResource + inMem + fileName + tcGlobals + tcConfig.compressMetadata + ccu + (rName + ccu.AssemblyName) + (rNameB + ccu.AssemblyName) + Optimizer.p_CcuOptimizationInfo + modulInfo let EncodeSignatureData (tcConfig: TcConfig, tcGlobals, exportRemapping, generatedCcu, outfile, isIncrementalBuild) = if tcConfig.GenerateSignatureData then - let resource = + let resource1, resource2 = WriteSignatureData(tcConfig, tcGlobals, exportRemapping, generatedCcu, outfile, isIncrementalBuild) - let resources = [ resource ] + let resources = + [ + resource1 + match resource2 with + | None -> () + | Some r -> r + ] let sigAttr = mkSignatureDataVersionAttr tcGlobals (parseILVersion FSharpBinaryMetadataFormatRevision) @@ -220,7 +322,18 @@ let EncodeOptimizationData (tcGlobals, tcConfig: TcConfig, outfile, exportRemapp else data - [ WriteOptimizationData(tcConfig, tcGlobals, outfile, isIncrementalBuild, ccu, optData) ] + let r1, r2 = + WriteOptimizationData(tcConfig, tcGlobals, outfile, isIncrementalBuild, ccu, optData) + + let resources = + [ + r1 + match r2 with + | None -> () + | Some r -> r + ] + + resources else [] @@ -872,12 +985,7 @@ type RawFSharpAssemblyDataBackedByFileOnDisk(ilModule: ILModuleDef, ilAssemblyRe member _.GetRawFSharpSignatureData(m, ilShortAssemName, fileName) = let resources = ilModule.Resources.AsList() - let sigDataReaders = - [ - for r in resources do - if IsSignatureDataResource r then - GetResourceNameAndSignatureDataFunc r - ] + let sigDataReaders = GetResourceNameAndSignatureDataFuncs resources let sigDataReaders = if sigDataReaders.IsEmpty && List.contains ilShortAssemName externalSigAndOptData then @@ -886,27 +994,22 @@ type RawFSharpAssemblyDataBackedByFileOnDisk(ilModule: ILModuleDef, ilAssemblyRe if not (FileSystem.FileExistsShim sigFileName) then error (Error(FSComp.SR.buildExpectedSigdataFile (FileSystem.GetFullPathShim sigFileName), m)) - [ - (ilShortAssemName, - fun () -> - FileSystem - .OpenFileForReadShim(sigFileName, useMemoryMappedFile = true, shouldShadowCopy = true) - .AsByteMemory() - .AsReadOnly()) - ] + let readerA () = + FileSystem + .OpenFileForReadShim(sigFileName, useMemoryMappedFile = true, shouldShadowCopy = true) + .AsByteMemory() + .AsReadOnly() + + [ (ilShortAssemName, (readerA, None)) ] else sigDataReaders sigDataReaders member _.GetRawFSharpOptimizationData(m, ilShortAssemName, fileName) = - let optDataReaders = - ilModule.Resources.AsList() - |> List.choose (fun r -> - if IsOptimizationDataResource r then - Some(GetResourceNameAndOptimizationDataFunc r) - else - None) + let resources = ilModule.Resources.AsList() + + let optDataReaders = GetResourceNameAndOptimizationDataFuncs resources // Look for optimization data in a file let optDataReaders = @@ -914,17 +1017,17 @@ type RawFSharpAssemblyDataBackedByFileOnDisk(ilModule: ILModuleDef, ilAssemblyRe let optDataFile = Path.ChangeExtension(fileName, "optdata") if not (FileSystem.FileExistsShim optDataFile) then - let fullPath = FileSystem.GetFullPathShim optDataFile - error (Error(FSComp.SR.buildExpectedFileAlongSideFSharpCore (optDataFile, fullPath), m)) - - [ - (ilShortAssemName, - (fun () -> - FileSystem - .OpenFileForReadShim(optDataFile, useMemoryMappedFile = true, shouldShadowCopy = true) - .AsByteMemory() - .AsReadOnly())) - ] + error ( + Error(FSComp.SR.buildExpectedFileAlongSideFSharpCore (optDataFile, FileSystem.GetFullPathShim optDataFile), m) + ) + + let readerA () = + FileSystem + .OpenFileForReadShim(optDataFile, useMemoryMappedFile = true, shouldShadowCopy = true) + .AsByteMemory() + .AsReadOnly() + + [ (ilShortAssemName, (readerA, None)) ] else optDataReaders @@ -963,20 +1066,11 @@ type RawFSharpAssemblyData(ilModule: ILModuleDef, ilAssemblyRefs) = member _.GetRawFSharpSignatureData(_, _, _) = let resources = ilModule.Resources.AsList() - - [ - for r in resources do - if IsSignatureDataResource r then - GetResourceNameAndSignatureDataFunc r - ] + GetResourceNameAndSignatureDataFuncs resources member _.GetRawFSharpOptimizationData(_, _, _) = - ilModule.Resources.AsList() - |> List.choose (fun r -> - if IsOptimizationDataResource r then - Some(GetResourceNameAndOptimizationDataFunc r) - else - None) + let resources = ilModule.Resources.AsList() + GetResourceNameAndOptimizationDataFuncs resources member _.GetRawTypeForwarders() = match ilModule.Manifest with @@ -2020,9 +2114,9 @@ and [] TcImports let ccuRawDataAndInfos = ilModule.GetRawFSharpSignatureData(m, ilShortAssemName, fileName) - |> List.map (fun (ccuName, sigDataReader) -> + |> List.map (fun (ccuName, (sigDataReader, sigDataReaderB)) -> let data = - GetSignatureData(fileName, ilScopeRef, ilModule.TryGetILModuleDef(), sigDataReader) + GetSignatureData(fileName, ilScopeRef, ilModule.TryGetILModuleDef(), sigDataReader, sigDataReaderB) let optDatas = Map.ofList optDataReaders @@ -2073,9 +2167,9 @@ and [] TcImports InterruptibleLazy(fun _ -> match Map.tryFind ccuName optDatas with | None -> None - | Some info -> + | Some (readerA, readerB) -> let data = - GetOptimizationData(fileName, ilScopeRef, ilModule.TryGetILModuleDef(), info) + GetOptimizationData(fileName, ilScopeRef, ilModule.TryGetILModuleDef(), readerA, readerB) let fixupThunk () = data.OptionalFixup(fun nm -> availableToOptionalCcu (tcImports.FindCcu(ctok, m, nm, lookupOnly = false))) @@ -2513,6 +2607,7 @@ and [] TcImports tcConfig.implicitIncludeDir, tcConfig.mlCompatibility, tcConfig.isInteractive, + tcConfig.checkNullness, tcConfig.useReflectionFreeCodeGen, tryFindSysTypeCcu, tcConfig.emitDebugInfoInQuotations, diff --git a/src/Compiler/Driver/CompilerImports.fsi b/src/Compiler/Driver/CompilerImports.fsi index 9697e18968d..ed3a55a7d4e 100644 --- a/src/Compiler/Driver/CompilerImports.fsi +++ b/src/Compiler/Driver/CompilerImports.fsi @@ -37,13 +37,20 @@ exception MSBuildReferenceResolutionError of message: string * warningCode: stri /// Determine if an IL resource attached to an F# assembly is an F# signature data resource val IsSignatureDataResource: ILResource -> bool +/// Determine if an IL resource attached to an F# assembly is an F# signature data resource (data stream B) +val IsSignatureDataResourceB: ILResource -> bool + /// Determine if an IL resource attached to an F# assembly is an F# optimization data resource val IsOptimizationDataResource: ILResource -> bool +/// Determine if an IL resource attached to an F# assembly is an F# optimization data resource (data sream B) +val IsOptimizationDataResourceB: ILResource -> bool + /// Determine if an IL resource attached to an F# assembly is an F# quotation data resource for reflected definitions val IsReflectedDefinitionsResource: ILResource -> bool -val GetResourceNameAndSignatureDataFunc: ILResource -> string * (unit -> ReadOnlyByteMemory) +val GetResourceNameAndSignatureDataFuncs: + ILResource list -> (string * ((unit -> ReadOnlyByteMemory) * (unit -> ReadOnlyByteMemory) option)) list /// Encode the F# interface data into a set of IL attributes and resources val EncodeSignatureData: diff --git a/src/Compiler/Driver/CompilerOptions.fs b/src/Compiler/Driver/CompilerOptions.fs index e742a20e139..a43d686fb01 100644 --- a/src/Compiler/Driver/CompilerOptions.fs +++ b/src/Compiler/Driver/CompilerOptions.fs @@ -845,6 +845,14 @@ let errorsAndWarningsFlags (tcConfigB: TcConfigBuilder) = Some(FSComp.SR.optsWarnOn ()) ) + CompilerOption( + "checknulls", + tagNone, + OptionSwitch(fun switch -> tcConfigB.checkNullness <- switch = OptionSwitch.On), + None, + Some(FSComp.SR.optsCheckNulls ()) + ) + CompilerOption( "consolecolors", tagNone, diff --git a/src/Compiler/Driver/GraphChecking/FileContentMapping.fs b/src/Compiler/Driver/GraphChecking/FileContentMapping.fs index e64a64e2ace..271e927933a 100644 --- a/src/Compiler/Driver/GraphChecking/FileContentMapping.fs +++ b/src/Compiler/Driver/GraphChecking/FileContentMapping.fs @@ -250,6 +250,7 @@ let visitSynType (t: SynType) : FileContentEntry list = let continuations = List.map (snd >> visit) fields Continuation.concatenate continuations continuation | SynType.Array(elementType = elementType) -> visit elementType continuation + | SynType.WithNull(innerType = innerType) -> visit innerType continuation | SynType.Fun(argType, returnType, _, _) -> let continuations = List.map visit [ argType; returnType ] Continuation.concatenate continuations continuation @@ -260,6 +261,7 @@ let visitSynType (t: SynType) : FileContentEntry list = | SynType.HashConstraint(innerType, _) -> visit innerType continuation | SynType.MeasurePower(baseMeasure = baseMeasure) -> visit baseMeasure continuation | SynType.StaticConstant _ -> continuation [] + | SynType.StaticConstantNull _ -> continuation [] | SynType.StaticConstantExpr(expr, _) -> continuation (visitSynExpr expr) | SynType.StaticConstantNamed(ident, value, _) -> let continuations = List.map visit [ ident; value ] @@ -298,6 +300,7 @@ let visitSynTypeConstraint (tc: SynTypeConstraint) : FileContentEntry list = | SynTypeConstraint.WhereTyparIsReferenceType _ | SynTypeConstraint.WhereTyparIsUnmanaged _ | SynTypeConstraint.WhereTyparSupportsNull _ + | SynTypeConstraint.WhereTyparNotSupportsNull _ | SynTypeConstraint.WhereTyparIsComparable _ | SynTypeConstraint.WhereTyparIsEquatable _ -> [] | SynTypeConstraint.WhereTyparDefaultsToType(typeName = typeName) -> visitSynType typeName diff --git a/src/Compiler/Driver/StaticLinking.fs b/src/Compiler/Driver/StaticLinking.fs index 007c77c8e52..9481b4e1006 100644 --- a/src/Compiler/Driver/StaticLinking.fs +++ b/src/Compiler/Driver/StaticLinking.fs @@ -184,7 +184,8 @@ let StaticLinkILModules // Save only the interface/optimization attributes of generated data let intfDataResources, others = - allResources |> List.partition (snd >> IsSignatureDataResource) + allResources + |> List.partition (fun (_, r) -> IsSignatureDataResource r || IsSignatureDataResourceB r) let intfDataResources = [ @@ -194,7 +195,8 @@ let StaticLinkILModules ] let optDataResources, others = - others |> List.partition (snd >> IsOptimizationDataResource) + others + |> List.partition (fun (_, r) -> IsOptimizationDataResource r || IsOptimizationDataResourceB r) let optDataResources = [ diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 55484591abc..0b00fdf78ea 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1522,6 +1522,21 @@ notAFunctionButMaybeDeclaration,"This value is not a function and cannot be appl 3250,expressionHasNoName,"Expression does not have a name." 3251,chkNoFirstClassNameOf,"Using the 'nameof' operator as a first-class function value is not permitted." 3252,tcIllegalByrefsInOpenTypeDeclaration,"Byref types are not allowed in an open type declaration." +3260,tcTypeDoesNotHaveAnyNull,"The type '%s' does not support a nullness qualitification." +#3261 reserved for ConstraintSolverNullnessWarningEquivWithTypes +#3261 reserved for ConstraintSolverNullnessWarningWithTypes +#3261 reserved for ConstraintSolverNullnessWarningWithType +#3261 reserved for ConstraintSolverNullnessWarning +3262,tcPassingWithoutNullToANullableExpectingFunc,"Value known to be without null passed to a function meant for nullables: %s" +tcPassingWithoutNullToOptionOfObj,"You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value." +tcPassingWithoutNullToValueOptionOfObj,"You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value." +tcPassingWithoutNullToNonNullAP,"You can remove this |Null|NonNull| pattern usage." +tcPassingWithoutNullToNonNullQuickAP,"You can remove this |NonNullQuick| pattern usage." +tcPassingWithoutNullTononNullFunction,"You can remove this `nonNull` assertion." +3268,csNullNotNullConstraintInconsistent,"The constraints 'null' and 'not null' are inconsistent" +3271,tcNullnessCheckingNotEnabled,"The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored." +csTypeHasNullAsTrueValue,"The type '%s' uses 'null' as a representation value but a non-null type is expected" +csTypeHasNullAsExtraValue,"The type '%s' supports 'null' but a non-null type is expected" 3300,chkInvalidFunctionParameterType,"The parameter '%s' has an invalid type '%s'. This is not permitted by the rules of Common IL." 3301,chkInvalidFunctionReturnType,"The function or method has an invalid return type '%s'. This is not permitted by the rules of Common IL." 3302,packageManagementRequiresVFive,"The 'package management' feature requires language version 5.0 or above" @@ -1536,6 +1551,8 @@ notAFunctionButMaybeDeclaration,"This value is not a function and cannot be appl 3352,typrelInterfaceMemberNoMostSpecificImplementation,"Interface member '%s' does not have a most specific implementation." 3353,fsiInvalidDirective,"Invalid directive '#%s %s'" useSdkRefs,"Use reference assemblies for .NET framework references when available (Enabled by default)." +optsCheckNulls,"Enable nullness declarations and checks" +fSharpBannerVersion,"%s for F# %s" optsGetLangVersions,"Display the allowed values for language version." optsSetLangVersion,"Specify language version such as 'latest' or 'preview'." optsSupportedLangVersions,"Supported language versions:" @@ -1554,6 +1571,7 @@ featurePackageManagement,"package management" featureFromEndSlicing,"from-end slicing" featureFixedIndexSlice3d4d,"fixed-index slice 3d/4d" featureAndBang,"applicative computation expressions" +featureNullnessChecking,"nullness checking" featureResumableStateMachines,"resumable state machines" featureNullableOptionalInterop,"nullable optional interop" featureDefaultInterfaceMemberConsumption,"default interface member consumption" diff --git a/src/Compiler/FSStrings.resx b/src/Compiler/FSStrings.resx index 278d209991b..b25e2b098da 100644 --- a/src/Compiler/FSStrings.resx +++ b/src/Compiler/FSStrings.resx @@ -129,6 +129,18 @@ A type parameter is missing a constraint '{0}' + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + + Nullness warning: The type '{0}' does not support 'null'. + + + Nullness warning: {0}. + The unit of measure '{0}' does not match the unit of measure '{1}' @@ -414,6 +426,9 @@ symbol '|}' + + symbol '|' (directly before 'null') + symbol '>}' diff --git a/src/Compiler/FSharp.Compiler.Service.fsproj b/src/Compiler/FSharp.Compiler.Service.fsproj index 6fa9d392a4a..d7c2c590071 100644 --- a/src/Compiler/FSharp.Compiler.Service.fsproj +++ b/src/Compiler/FSharp.Compiler.Service.fsproj @@ -1,4 +1,4 @@ - + diff --git a/src/Compiler/Facilities/DiagnosticsLogger.fs b/src/Compiler/Facilities/DiagnosticsLogger.fs index 382a9574f97..8925022b5e1 100644 --- a/src/Compiler/Facilities/DiagnosticsLogger.fs +++ b/src/Compiler/Facilities/DiagnosticsLogger.fs @@ -351,6 +351,9 @@ type DiagnosticsLogger(nameForDebugging: string) = member x.CheckForErrors() = (x.ErrorCount > 0) + abstract CheckForRealErrorsIgnoringWarnings: bool + default x.CheckForRealErrorsIgnoringWarnings = x.CheckForErrors() + member _.DebugDisplay() = sprintf "DiagnosticsLogger(%s)" nameForDebugging diff --git a/src/Compiler/Facilities/DiagnosticsLogger.fsi b/src/Compiler/Facilities/DiagnosticsLogger.fsi index 048988e0cf9..481dbc87643 100644 --- a/src/Compiler/Facilities/DiagnosticsLogger.fsi +++ b/src/Compiler/Facilities/DiagnosticsLogger.fsi @@ -208,6 +208,9 @@ type DiagnosticsLogger = /// Checks if ErrorCount > 0 member CheckForErrors: unit -> bool + abstract CheckForRealErrorsIgnoringWarnings: bool + default CheckForRealErrorsIgnoringWarnings: bool + /// Represents a DiagnosticsLogger that discards diagnostics val DiscardErrorsLogger: DiagnosticsLogger diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs index f6baf0dcf3b..14b2c460cfe 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fs +++ b/src/Compiler/Facilities/LanguageFeatures.fs @@ -38,6 +38,7 @@ type LanguageFeature = | StringInterpolation | OverloadsForCustomOperations | ExpandedMeasurables + | NullnessChecking | StructActivePattern | PrintfBinaryFormat | IndexerNotationWithoutDot @@ -195,6 +196,7 @@ type LanguageVersion(versionText) = LanguageFeature.PreferStringGetPinnableReference, languageVersion80 // F# preview + LanguageFeature.NullnessChecking, previewVersion LanguageFeature.FromEndSlicing, previewVersion LanguageFeature.UnmanagedConstraintCsharpInterop, previewVersion LanguageFeature.ReuseSameFieldsInStructUnions, previewVersion @@ -291,6 +293,7 @@ type LanguageVersion(versionText) = | LanguageFeature.FromEndSlicing -> FSComp.SR.featureFromEndSlicing () | LanguageFeature.FixedIndexSlice3d4d -> FSComp.SR.featureFixedIndexSlice3d4d () | LanguageFeature.AndBang -> FSComp.SR.featureAndBang () + | LanguageFeature.NullnessChecking -> FSComp.SR.featureNullnessChecking () | LanguageFeature.ResumableStateMachines -> FSComp.SR.featureResumableStateMachines () | LanguageFeature.NullableOptionalInterop -> FSComp.SR.featureNullableOptionalInterop () | LanguageFeature.DefaultInterfaceMemberConsumption -> FSComp.SR.featureDefaultInterfaceMemberConsumption () diff --git a/src/Compiler/Facilities/LanguageFeatures.fsi b/src/Compiler/Facilities/LanguageFeatures.fsi index ff60b7442f7..56f09684370 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fsi +++ b/src/Compiler/Facilities/LanguageFeatures.fsi @@ -28,6 +28,7 @@ type LanguageFeature = | StringInterpolation | OverloadsForCustomOperations | ExpandedMeasurables + | NullnessChecking | StructActivePattern | PrintfBinaryFormat | IndexerNotationWithoutDot diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs index 1e560e70bdd..c27382e0963 100644 --- a/src/Compiler/Interactive/fsi.fs +++ b/src/Compiler/Interactive/fsi.fs @@ -1563,7 +1563,7 @@ let rec ConvReflectionTypeToILType (reflectionTy: Type) = if ctors.Length = 1 - && (not (isNull (ctors[0].GetCustomAttribute()))) + && not (isNull (box (ctors[0].GetCustomAttribute()))) && not ctors[0].IsPublic && IsCompilerGeneratedName reflectionTy.Name then @@ -3281,7 +3281,7 @@ type internal MagicAssemblyResolution() = fsiDynamicCompiler: FsiDynamicCompiler, fsiConsoleOutput: FsiConsoleOutput, fullAssemName: string - ) = + ) : Assembly MaybeNull = try // Grab the name of the assembly @@ -3437,7 +3437,7 @@ type internal MagicAssemblyResolution() = fsiDynamicCompiler: FsiDynamicCompiler, fsiConsoleOutput: FsiConsoleOutput, fullAssemName: string - ) = + ) : Assembly MaybeNull = //Eliminate recursive calls to Resolve which can happen via our callout to msbuild resolution if MagicAssemblyResolution.resolving then @@ -3526,14 +3526,14 @@ type FsiStdinLexerProvider | NonNull t -> fsiStdinSyphon.Add(t + "\n")) match inputOption with - | Some null + | Some Null | None -> if progress then fprintfn fsiConsoleOutput.Out "End of file from TextReader.ReadLine" 0 - | Some(input: string) -> - let input = input + "\n" + | Some(NonNull input) -> + let input = nonNull input + "\n" if input.Length > len then fprintf fsiConsoleOutput.Error "%s" (FSIstrings.SR.fsiLineTooLong ()) diff --git a/src/Compiler/Legacy/LegacyHostedCompilerForTesting.fs b/src/Compiler/Legacy/LegacyHostedCompilerForTesting.fs index 688b53643c3..0c907d0652e 100644 --- a/src/Compiler/Legacy/LegacyHostedCompilerForTesting.fs +++ b/src/Compiler/Legacy/LegacyHostedCompilerForTesting.fs @@ -208,11 +208,13 @@ type internal FscCompiler(legacyReferenceResolver) = // args.[0] is later discarded, assuming it is just the path to fsc. // compensate for this in case caller didn't know let args = - match args with - | [||] - | null -> [| "fsc" |] - | a when not <| fscExeArg a[0] -> Array.append [| "fsc" |] a - | _ -> args + match box args with + | Null -> [| "fsc" |] + | _ -> + match args with + | [||] -> [| "fsc" |] + | a when not <| fscExeArg a[0] -> Array.append [| "fsc" |] a + | _ -> args let errorRanges = args |> Seq.exists errorRangesArg let vsErrors = args |> Seq.exists vsErrorsArg diff --git a/src/Compiler/Optimize/LowerComputedCollections.fs b/src/Compiler/Optimize/LowerComputedCollections.fs index 2d2e02a9df3..e4b5eec6707 100644 --- a/src/Compiler/Optimize/LowerComputedCollections.fs +++ b/src/Compiler/Optimize/LowerComputedCollections.fs @@ -36,7 +36,7 @@ let BuildDisposableCleanup tcVal (g: TcGlobals) infoReader m (v: Val) = else let disposeObjVar, disposeObjExpr = mkCompGenLocal m "objectToDispose" g.system_IDisposable_ty let disposeExpr, _ = BuildMethodCall tcVal g infoReader.amap PossiblyMutates m false disposeMethod NormalValUse [] [disposeObjExpr] [] None - let inputExpr = mkCoerceExpr(exprForVal v.Range v, g.obj_ty, m, v.Type) + let inputExpr = mkCoerceExpr(exprForVal v.Range v, g.obj_ty_ambivalent, m, v.Type) mkIsInstConditional g m g.system_IDisposable_ty inputExpr disposeObjVar disposeExpr (mkUnit g m) let mkCallCollectorMethod tcVal (g: TcGlobals) infoReader m name collExpr args = diff --git a/src/Compiler/Optimize/Optimizer.fs b/src/Compiler/Optimize/Optimizer.fs index b2f5f654ce2..bc4c0829871 100644 --- a/src/Compiler/Optimize/Optimizer.fs +++ b/src/Compiler/Optimize/Optimizer.fs @@ -2245,7 +2245,7 @@ let TryDetectQueryQuoteAndRun cenv (expr: Expr) = | QuerySelect g (qTy, _, resultElemTy, _, _) | QueryYield g (qTy, resultElemTy, _) | QueryYieldFrom g (qTy, resultElemTy, _) - when typeEquiv g qTy (mkAppTy g.tcref_System_Collections_IEnumerable []) -> + when typeEquiv g qTy (mkWoNullAppTy g.tcref_System_Collections_IEnumerable []) -> match tryRewriteToSeqCombinators g e with | Some newSource -> @@ -3224,7 +3224,7 @@ and TryDevirtualizeApplication cenv env (f, tyargs, args, m) = // the target takes a tupled argument, so we need to reorder the arg expressions in the // arg list, and create a tuple of y & comp // push the comparer to the end and box the argument - let args2 = [x; mkRefTupledNoTypes g m [mkCoerceExpr(y, g.obj_ty, m, ty) ; comp]] + let args2 = [x; mkRefTupledNoTypes g m [mkCoerceExpr(y, g.obj_ty_ambivalent, m, ty) ; comp]] Some (DevirtualizeApplication cenv env vref ty tyargs args2 m) | _ -> None @@ -3249,7 +3249,7 @@ and TryDevirtualizeApplication cenv env (f, tyargs, args, m) = Some (DevirtualizeApplication cenv env withcEqualsExactVal ty tyargs args2 m) | Some (_, _, withcEqualsVal, _ ), [comp; x; y] -> // push the comparer to the end and box the argument - let args2 = [x; mkRefTupledNoTypes g m [mkCoerceExpr(y, g.obj_ty, m, ty) ; comp]] + let args2 = [x; mkRefTupledNoTypes g m [mkCoerceExpr(y, g.obj_ty_ambivalent, m, ty) ; comp]] Some (DevirtualizeApplication cenv env withcEqualsVal ty tyargs args2 m) | _ -> None @@ -3271,7 +3271,7 @@ and TryDevirtualizeApplication cenv env (f, tyargs, args, m) = let args2 = [x; mkRefTupledNoTypes g m [y; (mkCallGetGenericPEREqualityComparer g m)]] Some (DevirtualizeApplication cenv env equalsExact ty tyargs args2 m) | None -> - let args2 = [x; mkRefTupledNoTypes g m [mkCoerceExpr(y, g.obj_ty, m, ty); (mkCallGetGenericPEREqualityComparer g m)]] + let args2 = [x; mkRefTupledNoTypes g m [mkCoerceExpr(y, g.obj_ty_ambivalent, m, ty); (mkCallGetGenericPEREqualityComparer g m)]] Some (DevirtualizeApplication cenv env withcEqualsVal ty tyargs args2 m) | _ -> None diff --git a/src/Compiler/Service/FSharpCheckerResults.fs b/src/Compiler/Service/FSharpCheckerResults.fs index cab12da5cdf..6d9b9133c5b 100644 --- a/src/Compiler/Service/FSharpCheckerResults.fs +++ b/src/Compiler/Service/FSharpCheckerResults.fs @@ -1358,7 +1358,8 @@ type internal TypeCheckInfo match r.Item with | Item.Types(_, ty :: _) when equals r.Range typeNameRange && isAppTy g ty -> let superTy = - (tcrefOfAppTy g ty).TypeContents.tcaug_super |> Option.defaultValue g.obj_ty + (tcrefOfAppTy g ty).TypeContents.tcaug_super + |> Option.defaultValue g.obj_ty_noNulls Some(ty, superTy) | _ -> None) @@ -1368,7 +1369,7 @@ type internal TypeCheckInfo |> ResizeArray.tryPick (fun r -> match r.Item with | Item.Types(_, ty :: _) when equals r.Range typeNameRange && isAppTy g ty -> - let superTy = getTyFromTypeNamePos mTy.End |> Option.defaultValue g.obj_ty + let superTy = getTyFromTypeNamePos mTy.End |> Option.defaultValue g.obj_ty_noNulls Some(ty, superTy) | _ -> None) | MethodOverrideCompletionContext.ObjExpr m -> @@ -1376,7 +1377,7 @@ type internal TypeCheckInfo quals |> Array.tryFind (fun (_, _, _, r) -> posEq m.Start r.Start) - |> Option.map (fun (ty, _, _, _) -> ty, getTyFromTypeNamePos typeNameRange.End |> Option.defaultValue g.obj_ty) + |> Option.map (fun (ty, _, _, _) -> ty, getTyFromTypeNamePos typeNameRange.End |> Option.defaultValue g.obj_ty_noNulls) match ctx with | Some(ty, superTy) -> diff --git a/src/Compiler/Service/IncrementalBuild.fs b/src/Compiler/Service/IncrementalBuild.fs index 76056026c1d..43a7a9cde96 100644 --- a/src/Compiler/Service/IncrementalBuild.fs +++ b/src/Compiler/Service/IncrementalBuild.fs @@ -487,14 +487,14 @@ type BoundModel private ( /// Global service state type FrameworkImportsCacheKey = - | FrameworkImportsCacheKey of resolvedpath: string list * assemblyName: string * targetFrameworkDirectories: string list * fsharpBinaries: string * langVersion: decimal + | FrameworkImportsCacheKey of resolvedpath: string list * assemblyName: string * targetFrameworkDirectories: string list * fsharpBinaries: string * langVersion: decimal * checkNulls: bool interface ICacheKey with member this.GetKey() = - this |> function FrameworkImportsCacheKey(assemblyName=a) -> a + this |> function FrameworkImportsCacheKey(assemblyName=a;checkNulls=c) -> if c then a + "CheckNulls" else a member this.GetLabel() = - this |> function FrameworkImportsCacheKey(assemblyName=a) -> a + this |> function FrameworkImportsCacheKey(assemblyName=a;checkNulls=c) -> if c then a + "CheckNulls" else a member this.GetVersion() = this @@ -529,7 +529,8 @@ type FrameworkImportsCache(size) = tcConfig.primaryAssembly.Name, tcConfig.GetTargetFrameworkDirectories(), tcConfig.fsharpBinariesDir, - tcConfig.langVersion.SpecifiedVersion) + tcConfig.langVersion.SpecifiedVersion, + tcConfig.checkNullness) let node = lock gate (fun () -> @@ -609,9 +610,7 @@ type RawFSharpAssemblyDataBackedByLanguageService (tcConfig, tcGlobals, generate let sigData = let _sigDataAttributes, sigDataResources = EncodeSignatureData(tcConfig, tcGlobals, exportRemapping, generatedCcu, outfile, true) - [ for r in sigDataResources do - GetResourceNameAndSignatureDataFunc r - ] + GetResourceNameAndSignatureDataFuncs sigDataResources let autoOpenAttrs = topAttrs.assemblyAttrs |> List.choose (List.singleton >> TryFindFSharpStringAttribute tcGlobals tcGlobals.attrib_AutoOpenAttribute) diff --git a/src/Compiler/Service/IncrementalBuild.fsi b/src/Compiler/Service/IncrementalBuild.fsi index 0fd380631e4..21b2fb23404 100644 --- a/src/Compiler/Service/IncrementalBuild.fsi +++ b/src/Compiler/Service/IncrementalBuild.fsi @@ -30,7 +30,8 @@ type internal FrameworkImportsCacheKey = assemblyName: string * targetFrameworkDirectories: string list * fsharpBinaries: string * - langVersion: decimal + langVersion: decimal * + checkNulls: bool interface ICacheKey diff --git a/src/Compiler/Service/QuickParse.fs b/src/Compiler/Service/QuickParse.fs index 7738d74ad80..c3de9dc2c2e 100644 --- a/src/Compiler/Service/QuickParse.fs +++ b/src/Compiler/Service/QuickParse.fs @@ -79,7 +79,7 @@ module QuickParse = | _ -> false let GetCompleteIdentifierIslandImplAux (lineStr: string) (index: int) : (string * int * bool) option = - if index < 0 || isNull lineStr || index >= lineStr.Length then + if index < 0 || index >= lineStr.Length then None else let fixup = diff --git a/src/Compiler/Service/SemanticClassification.fs b/src/Compiler/Service/SemanticClassification.fs index 6ebbb3c8ae0..6053f996ece 100644 --- a/src/Compiler/Service/SemanticClassification.fs +++ b/src/Compiler/Service/SemanticClassification.fs @@ -58,7 +58,6 @@ type SemanticClassificationType = | TypeDef = 35 | Plaintext = 36 -[] [] type SemanticClassificationItem = val Range: range diff --git a/src/Compiler/Service/SemanticClassification.fsi b/src/Compiler/Service/SemanticClassification.fsi index ce5d6d88aeb..1fb4cf28df5 100644 --- a/src/Compiler/Service/SemanticClassification.fsi +++ b/src/Compiler/Service/SemanticClassification.fsi @@ -49,7 +49,6 @@ type SemanticClassificationType = | TypeDef = 35 | Plaintext = 36 -[] [] type SemanticClassificationItem = val Range: range diff --git a/src/Compiler/Service/ServiceDeclarationLists.fs b/src/Compiler/Service/ServiceDeclarationLists.fs index dd6727a5ba9..92729d789f8 100644 --- a/src/Compiler/Service/ServiceDeclarationLists.fs +++ b/src/Compiler/Service/ServiceDeclarationLists.fs @@ -671,7 +671,7 @@ module internal DescriptionListsImpl = |> Array.map (fun sp -> let ty = Import.ImportProvidedType amap m (sp.PApply((fun x -> x.ParameterType), m)) let spKind = NicePrint.prettyLayoutOfType denv ty - let spName = sp.PUntaint((fun sp -> sp.Name), m) + let spName = sp.PUntaint((fun sp -> nonNull sp.Name), m) let spOpt = sp.PUntaint((fun sp -> sp.IsOptional), m) let display = (if spOpt then SepL.questionMark else emptyL) ^^ wordL (tagParameter spName) ^^ RightL.colon ^^ spKind let display = toArray display diff --git a/src/Compiler/Service/ServiceLexing.fs b/src/Compiler/Service/ServiceLexing.fs index 9abe2199dc0..14f5744a073 100644 --- a/src/Compiler/Service/ServiceLexing.fs +++ b/src/Compiler/Service/ServiceLexing.fs @@ -392,6 +392,7 @@ module internal TokenClassifications = | HIGH_PRECEDENCE_PAREN_APP | FIXED | HIGH_PRECEDENCE_BRACK_APP + | BAR_JUST_BEFORE_NULL | TYPE_COMING_SOON | TYPE_IS_HERE | MODULE_COMING_SOON diff --git a/src/Compiler/Service/ServiceParamInfoLocations.fs b/src/Compiler/Service/ServiceParamInfoLocations.fs index 129a40b93f6..2556111a21a 100755 --- a/src/Compiler/Service/ServiceParamInfoLocations.fs +++ b/src/Compiler/Service/ServiceParamInfoLocations.fs @@ -62,6 +62,7 @@ module internal ParameterLocationsImpl = let isStaticArg (StripParenTypes synType) = match synType with | SynType.StaticConstant _ + | SynType.StaticConstantNull _ | SynType.StaticConstantExpr _ | SynType.StaticConstantNamed _ -> true | SynType.LongIdent _ -> true // NOTE: this is not a static constant, but it is a prefix of incomplete code, e.g. "TP<42, Arg3" is a prefix of "TP<42, Arg3=6>" and Arg3 shows up as a LongId diff --git a/src/Compiler/Service/ServiceParseTreeWalk.fs b/src/Compiler/Service/ServiceParseTreeWalk.fs index 42a461db90d..621d89e4cca 100644 --- a/src/Compiler/Service/ServiceParseTreeWalk.fs +++ b/src/Compiler/Service/ServiceParseTreeWalk.fs @@ -838,6 +838,7 @@ module SyntaxTraversal = | SynType.Fun(argType = ty1; returnType = ty2) -> [ ty1; ty2 ] |> List.tryPick (traverseSynType path) | SynType.MeasurePower(ty, _, _) | SynType.HashConstraint(ty, _) + | SynType.WithNull(ty, _, _) | SynType.WithGlobalConstraints(ty, _, _) | SynType.Array(_, ty, _) -> traverseSynType path ty | SynType.StaticConstantNamed(ty1, ty2, _) @@ -847,6 +848,7 @@ module SyntaxTraversal = | SynType.Paren(innerType = t) | SynType.SignatureParameter(usedType = t) -> traverseSynType path t | SynType.Intersection(types = types) -> List.tryPick (traverseSynType path) types + | SynType.StaticConstantNull _ | SynType.Anon _ | SynType.AnonRecd _ | SynType.LongIdent _ diff --git a/src/Compiler/Service/ServiceParsedInputOps.fs b/src/Compiler/Service/ServiceParsedInputOps.fs index 0f6f3bc0530..9881ac7ef75 100644 --- a/src/Compiler/Service/ServiceParsedInputOps.fs +++ b/src/Compiler/Service/ServiceParsedInputOps.fs @@ -647,6 +647,7 @@ module ParsedInput = | SynTypeConstraint.WhereTyparIsReferenceType(t, _) -> walkTypar t | SynTypeConstraint.WhereTyparIsUnmanaged(t, _) -> walkTypar t | SynTypeConstraint.WhereTyparSupportsNull(t, _) -> walkTypar t + | SynTypeConstraint.WhereTyparNotSupportsNull(t, _) -> walkTypar t | SynTypeConstraint.WhereTyparIsComparable(t, _) -> walkTypar t | SynTypeConstraint.WhereTyparIsEquatable(t, _) -> walkTypar t | SynTypeConstraint.WhereTyparSubtypeOfType(t, ty, _) -> walkTypar t |> Option.orElseWith (fun () -> walkType ty) @@ -710,6 +711,7 @@ module ParsedInput = | SynType.Array(_, t, _) -> walkType t | SynType.Fun(argType = t1; returnType = t2) -> walkType t1 |> Option.orElseWith (fun () -> walkType t2) | SynType.WithGlobalConstraints(t, _, _) -> walkType t + | SynType.WithNull(t, _, _) | SynType.HashConstraint(t, _) -> walkType t | SynType.Or(t1, t2, _, _) -> walkType t1 |> Option.orElseWith (fun () -> walkType t2) | SynType.MeasurePower(t, _, _) -> walkType t @@ -718,6 +720,7 @@ module ParsedInput = | SynType.StaticConstantExpr(e, _) -> walkExpr e | SynType.StaticConstantNamed(ident, value, _) -> List.tryPick walkType [ ident; value ] | SynType.Intersection(types = types) -> List.tryPick walkType types + | SynType.StaticConstantNull _ | SynType.Anon _ | SynType.AnonRecd _ | SynType.LongIdent _ @@ -1911,6 +1914,7 @@ module ParsedInput = | SynTypeConstraint.WhereTyparIsReferenceType(t, _) | SynTypeConstraint.WhereTyparIsUnmanaged(t, _) | SynTypeConstraint.WhereTyparSupportsNull(t, _) + | SynTypeConstraint.WhereTyparNotSupportsNull(t, _) | SynTypeConstraint.WhereTyparIsComparable(t, _) | SynTypeConstraint.WhereTyparIsEquatable(t, _) -> walkTypar t | SynTypeConstraint.WhereTyparDefaultsToType(t, ty, _) @@ -1972,6 +1976,7 @@ module ParsedInput = | SynType.Array(_, t, _) | SynType.HashConstraint(t, _) | SynType.MeasurePower(t, _, _) + | SynType.WithNull(t, _, _) | SynType.Paren(t, _) | SynType.SignatureParameter(usedType = t) -> walkType t | SynType.Fun(argType = t1; returnType = t2) @@ -1992,6 +1997,7 @@ module ParsedInput = walkType ident walkType value | SynType.Intersection(types = types) -> List.iter walkType types + | SynType.StaticConstantNull _ | SynType.Anon _ | SynType.AnonRecd _ | SynType.Var _ diff --git a/src/Compiler/Service/TransparentCompiler.fs b/src/Compiler/Service/TransparentCompiler.fs index f2af93736e3..734dd2a1eee 100644 --- a/src/Compiler/Service/TransparentCompiler.fs +++ b/src/Compiler/Service/TransparentCompiler.fs @@ -510,7 +510,8 @@ type internal TransparentCompiler tcConfig.primaryAssembly.Name, tcConfig.GetTargetFrameworkDirectories(), tcConfig.fsharpBinariesDir, - tcConfig.langVersion.SpecifiedVersion + tcConfig.langVersion.SpecifiedVersion, + tcConfig.checkNullness ) caches.FrameworkImports.Get( @@ -1319,7 +1320,7 @@ type internal TransparentCompiler let! finisher = CheckOneInputWithCallback nodeToCheck - ((fun () -> hadParseErrors || diagnosticsLogger.ErrorCount > 0), + ((fun () -> hadParseErrors || diagnosticsLogger.CheckForRealErrorsIgnoringWarnings), tcConfig, tcImports, tcGlobals, diff --git a/src/Compiler/Symbols/Exprs.fs b/src/Compiler/Symbols/Exprs.fs index 4d0b994f35b..15b1bb2a3f6 100644 --- a/src/Compiler/Symbols/Exprs.fs +++ b/src/Compiler/Symbols/Exprs.fs @@ -327,7 +327,7 @@ module FSharpExprConvert = let ConvILTypeRefApp (cenv: SymbolEnv) m tref tyargs = let tcref = Import.ImportILTypeRef cenv.amap m tref - ConvType cenv (mkAppTy tcref tyargs) + ConvType cenv (mkWoNullAppTy tcref tyargs) let ConvUnionCaseRef cenv (ucref: UnionCaseRef) = FSharpUnionCase(cenv, ucref) @@ -378,7 +378,7 @@ module FSharpExprConvert = // Large lists | Expr.Op (TOp.UnionCase ucref, tyargs, [e1;e2], _) -> let mkR = ConvUnionCaseRef cenv ucref - let typR = ConvType cenv (mkAppTy ucref.TyconRef tyargs) + let typR = ConvType cenv (mkWoNullAppTy ucref.TyconRef tyargs) let e1R = ConvExpr cenv env e1 // tail recursive ConvExprLinear cenv env e2 (contF << (fun e2R -> E.NewUnionCase(typR, mkR, [e1R; e2R]) )) @@ -622,7 +622,7 @@ module FSharpExprConvert = match op, tyargs, args with | TOp.UnionCase ucref, _, _ -> let mkR = ConvUnionCaseRef cenv ucref - let typR = ConvType cenv (mkAppTy ucref.TyconRef tyargs) + let typR = ConvType cenv (mkWoNullAppTy ucref.TyconRef tyargs) let argsR = ConvExprs cenv env args E.NewUnionCase(typR, mkR, argsR) @@ -637,13 +637,13 @@ module FSharpExprConvert = E.NewTuple(tyR, argsR) | TOp.Recd (_, tcref), _, _ -> - let typR = ConvType cenv (mkAppTy tcref tyargs) + let typR = ConvType cenv (mkWoNullAppTy tcref tyargs) let argsR = ConvExprs cenv env args E.NewRecord(typR, argsR) | TOp.UnionCaseFieldGet (ucref, n), tyargs, [e1] -> let mkR = ConvUnionCaseRef cenv ucref - let typR = ConvType cenv (mkAppTy ucref.TyconRef tyargs) + let typR = ConvType cenv (mkWoNullAppTy ucref.TyconRef tyargs) let projR = FSharpField(cenv, ucref, n) E.UnionCaseGet(ConvExpr cenv env e1, typR, mkR, projR) @@ -653,7 +653,7 @@ module FSharpExprConvert = | TOp.UnionCaseFieldSet (ucref, n), tyargs, [e1;e2] -> let mkR = ConvUnionCaseRef cenv ucref - let typR = ConvType cenv (mkAppTy ucref.TyconRef tyargs) + let typR = ConvType cenv (mkWoNullAppTy ucref.TyconRef tyargs) let projR = FSharpField(cenv, ucref, n) E.UnionCaseSet(ConvExpr cenv env e1, typR, mkR, projR, ConvExpr cenv env e2) @@ -665,13 +665,13 @@ module FSharpExprConvert = | TOp.ValFieldGet rfref, tyargs, [] -> let projR = ConvRecdFieldRef cenv rfref - let typR = ConvType cenv (mkAppTy rfref.TyconRef tyargs) + let typR = ConvType cenv (mkWoNullAppTy rfref.TyconRef tyargs) E.FSharpFieldGet(None, typR, projR) | TOp.ValFieldGet rfref, tyargs, [obj] -> let objR = ConvLValueExpr cenv env obj let projR = ConvRecdFieldRef cenv rfref - let typR = ConvType cenv (mkAppTy rfref.TyconRef tyargs) + let typR = ConvType cenv (mkWoNullAppTy rfref.TyconRef tyargs) E.FSharpFieldGet(Some objR, typR, projR) | TOp.TupleFieldGet (tupInfo, n), tyargs, [e] -> @@ -775,7 +775,7 @@ module FSharpExprConvert = let argTy2 = tyOfExpr g arg2 let resTy = match getMeasureOfType g argTy1, getMeasureOfType g argTy2 with - | Some (tcref, ms1), Some (_tcref2, ms2) -> mkAppTy tcref [TType_measure (Measure.Prod(ms1, if isMul then ms2 else Measure.Inv ms2))] + | Some (tcref, ms1), Some (_tcref2, ms2) -> mkWoNullAppTy tcref [TType_measure (Measure.Prod(ms1, if isMul then ms2 else Measure.Inv ms2))] | Some _, None -> argTy1 | None, Some _ -> argTy2 | None, None -> argTy1 @@ -805,18 +805,18 @@ module FSharpExprConvert = E.ILAsm(sprintf "%+A" instrs, ConvTypes cenv tyargs, ConvExprs cenv env args) | TOp.ExnConstr tcref, tyargs, args -> - E.NewRecord(ConvType cenv (mkAppTy tcref tyargs), ConvExprs cenv env args) + E.NewRecord(ConvType cenv (mkWoNullAppTy tcref tyargs), ConvExprs cenv env args) | TOp.ValFieldSet rfref, _tinst, [obj;arg] -> let objR = ConvLValueExpr cenv env obj let argR = ConvExpr cenv env arg - let typR = ConvType cenv (mkAppTy rfref.TyconRef tyargs) + let typR = ConvType cenv (mkWoNullAppTy rfref.TyconRef tyargs) let projR = ConvRecdFieldRef cenv rfref E.FSharpFieldSet(Some objR, typR, projR, argR) | TOp.ValFieldSet rfref, _tinst, [arg] -> let argR = ConvExpr cenv env arg - let typR = ConvType cenv (mkAppTy rfref.TyconRef tyargs) + let typR = ConvType cenv (mkWoNullAppTy rfref.TyconRef tyargs) let projR = ConvRecdFieldRef cenv rfref E.FSharpFieldSet(None, typR, projR, argR) @@ -824,16 +824,16 @@ module FSharpExprConvert = let exnc = stripExnEqns tcref let fspec = exnc.TrueInstanceFieldsAsList[i] let fref = mkRecdFieldRef tcref fspec.LogicalName - let typR = ConvType cenv (mkAppTy tcref tyargs) - let objR = ConvExpr cenv env (mkCoerceExpr (obj, mkAppTy tcref [], m, g.exn_ty)) + let typR = ConvType cenv (mkWoNullAppTy tcref tyargs) + let objR = ConvExpr cenv env (mkCoerceExpr (obj, mkWoNullAppTy tcref [], m, g.exn_ty)) E.FSharpFieldGet(Some objR, typR, ConvRecdFieldRef cenv fref) | TOp.ExnFieldSet (tcref, i), [], [obj;e2] -> let exnc = stripExnEqns tcref let fspec = exnc.TrueInstanceFieldsAsList[i] let fref = mkRecdFieldRef tcref fspec.LogicalName - let typR = ConvType cenv (mkAppTy tcref tyargs) - let objR = ConvExpr cenv env (mkCoerceExpr (obj, mkAppTy tcref [], m, g.exn_ty)) + let typR = ConvType cenv (mkWoNullAppTy tcref tyargs) + let objR = ConvExpr cenv env (mkCoerceExpr (obj, mkWoNullAppTy tcref [], m, g.exn_ty)) E.FSharpFieldSet(Some objR, typR, ConvRecdFieldRef cenv fref, ConvExpr cenv env e2) | TOp.Coerce, [tgtTy;srcTy], [x] -> @@ -896,7 +896,7 @@ module FSharpExprConvert = | TOp.UnionCaseProof _, _, [e] -> ConvExprPrim cenv env e // Note: we erase the union case proof conversions when converting to quotations | TOp.UnionCaseTagGet tycr, tyargs, [arg1] -> - let typR = ConvType cenv (mkAppTy tycr tyargs) + let typR = ConvType cenv (mkWoNullAppTy tycr tyargs) E.UnionCaseTag(ConvExpr cenv env arg1, typR) | TOp.TraitCall traitInfo, _, _ -> @@ -1019,7 +1019,7 @@ module FSharpExprConvert = | [v] -> makeFSCall isMember v | [] -> - let typR = ConvType cenv (mkAppTy tcref enclTypeArgs) + let typR = ConvType cenv (mkWoNullAppTy tcref enclTypeArgs) if enclosingEntity.IsModuleOrNamespace then let findModuleMemberByName = enclosingEntity.ModuleOrNamespaceType.AllValsAndMembers @@ -1149,9 +1149,12 @@ module FSharpExprConvert = // TODO: this will not work for curried methods in F# classes. // This is difficult to solve as the information in the ILMethodRef // is not sufficient to resolve to a symbol unambiguously in these cases. - let argTys = [ ilMethRef.ArgTypes |> List.map (ImportILTypeFromMetadata cenv.amap m scoref tinst1 tinst2) ] + + // If this was an ILTycon with potential nullness, try1 is Some(..) and this branch not hit + let argTys = [ ilMethRef.ArgTypes |> List.map (ImportILTypeFromMetadataSkipNullness cenv.amap m scoref tinst1 tinst2) ] let retTy = - match ImportReturnTypeFromMetadata cenv.amap m ilMethRef.ReturnType (fun _ -> emptyILCustomAttrs) scoref tinst1 tinst2 with + let nullableAttributes = Import.Nullness.NullableAttributesSource.Empty + match ImportReturnTypeFromMetadata cenv.amap m nullableAttributes ilMethRef.ReturnType scoref tinst1 tinst2 with | None -> if isCtor then enclosingTy else g.unit_ty | Some ty -> ty @@ -1292,7 +1295,7 @@ module FSharpExprConvert = | DecisionTreeTest.UnionCase (ucref, tyargs) -> let objR = ConvExpr cenv env inpExpr let ucR = ConvUnionCaseRef cenv ucref - let utypR = ConvType cenv (mkAppTy ucref.TyconRef tyargs) + let utypR = ConvType cenv (mkWoNullAppTy ucref.TyconRef tyargs) E.IfThenElse (E.UnionCaseTest (objR, utypR, ucR) |> Mk cenv m g.bool_ty, ConvDecisionTree cenv env dtreeRetTy dtree m, acc) | DecisionTreeTest.Const (Const.Bool true) -> let e1R = ConvExpr cenv env inpExpr diff --git a/src/Compiler/Symbols/SymbolHelpers.fs b/src/Compiler/Symbols/SymbolHelpers.fs index 1584e096edd..8a9300ea82b 100644 --- a/src/Compiler/Symbols/SymbolHelpers.fs +++ b/src/Compiler/Symbols/SymbolHelpers.fs @@ -542,6 +542,7 @@ module internal SymbolHelpers = let SimplerDisplayEnv denv = { denv with shortConstraints=true showStaticallyResolvedTyparAnnotations=false + showNullnessAnnotations = Some true abbreviateAdditionalConstraints=false suppressNestedTypes=true maxMembers=Some EnvMisc2.maxMembers } diff --git a/src/Compiler/Symbols/Symbols.fs b/src/Compiler/Symbols/Symbols.fs index 19fbfe9306b..a01ccf0068a 100644 --- a/src/Compiler/Symbols/Symbols.fs +++ b/src/Compiler/Symbols/Symbols.fs @@ -1570,6 +1570,11 @@ type FSharpGenericParameterConstraint(cenv, cx: TyparConstraint) = | TyparConstraint.SupportsComparison _ -> true | _ -> false + member _.IsNotSupportsNullConstraint = + match cx with + | TyparConstraint.NotSupportsNull _ -> true + | _ -> false + member _.IsEqualityConstraint = match cx with | TyparConstraint.SupportsEquality _ -> true @@ -2516,6 +2521,23 @@ type FSharpType(cenv, ty:TType) = | TType_measure (Measure.Inv _) -> FSharpEntity(cenv, cenv.g.measureinverse_tcr) | _ -> invalidOp "not a named type" + member _.HasNullAnnotation = + protect <| fun () -> + match stripTyparEqns ty with + | TType_var (_, nullness) + | TType_app (_, _, nullness) + | TType_fun(_, _, nullness) -> match nullness.Evaluate() with NullnessInfo.WithNull -> true | _ -> false + | TType_tuple (_, _) -> false + | _ -> false + + member _.IsNullAmbivalent = + protect <| fun () -> + match stripTyparEqns ty with + | TType_app (_, _, nullness) + | TType_fun(_, _, nullness) -> match nullness.Evaluate() with NullnessInfo.AmbivalentToNull -> true | _ -> false + | TType_tuple (_, _) -> false + | _ -> false + member _.GenericArguments = protect <| fun () -> match stripTyparEqns ty with diff --git a/src/Compiler/Symbols/Symbols.fsi b/src/Compiler/Symbols/Symbols.fsi index 5530ba53ec5..a61432accf1 100644 --- a/src/Compiler/Symbols/Symbols.fsi +++ b/src/Compiler/Symbols/Symbols.fsi @@ -1088,6 +1088,12 @@ type FSharpType = /// Get the type definition for a type member TypeDefinition: FSharpEntity + /// Indicates this type is known to have a null annotation + member HasNullAnnotation: bool + + /// Indicates this type is assumed to support the null value + member IsNullAmbivalent: bool + /// Get the generic arguments for a tuple type, a function type or a type constructed using a named entity member GenericArguments: IList diff --git a/src/Compiler/SyntaxTree/LexFilter.fs b/src/Compiler/SyntaxTree/LexFilter.fs index 79afdca04c3..19f7be5d31b 100644 --- a/src/Compiler/SyntaxTree/LexFilter.fs +++ b/src/Compiler/SyntaxTree/LexFilter.fs @@ -555,6 +555,7 @@ let (|TyparsCloseOp|_|) (txt: string) = | Equals "$" -> ValueSome DOLLAR | Equals "%" -> ValueSome (PERCENT_OP "%") | Equals "%%" -> ValueSome (PERCENT_OP "%%") + | Equals "" -> ValueNone | StartsWith "=" | StartsWith "!=" | StartsWith "<" @@ -1144,7 +1145,9 @@ type LexFilterImpl ( // f<{| C : int |}>x // fx // fx + // fx | DEFAULT | COLON | COLON_GREATER | STRUCT | NULL | DELEGATE | AND | WHEN | AMP + | BAR_JUST_BEFORE_NULL | BAR | DOT_DOT | NEW | LBRACE_BAR @@ -2482,6 +2485,9 @@ type LexFilterImpl ( pool.Return tokenTup hwTokenFetch useBlockRule + | BAR, _ when (lexbuf.SupportsFeature(LanguageFeature.NullnessChecking) && match peekNextToken() with NULL -> true | _ -> false) -> + returnToken tokenLexbufState BAR_JUST_BEFORE_NULL + // Ordinary tokens start a vanilla block | _, CtxtSeqBlock _ :: _ -> pushCtxt tokenTup (CtxtVanilla(tokenStartPos, isLongIdentEquals token)) diff --git a/src/Compiler/SyntaxTree/PrettyNaming.fs b/src/Compiler/SyntaxTree/PrettyNaming.fs index d91eddbeb04..51f4c3b786a 100755 --- a/src/Compiler/SyntaxTree/PrettyNaming.fs +++ b/src/Compiler/SyntaxTree/PrettyNaming.fs @@ -1098,12 +1098,21 @@ let FSharpOptimizationDataResourceName = "FSharpOptimizationData." let FSharpSignatureDataResourceName = "FSharpSignatureData." +let FSharpOptimizationDataResourceNameB = "FSharpOptimizationDataB." + +let FSharpSignatureDataResourceNameB = "FSharpSignatureDataB." + // Compressed OptimizationData/SignatureData name for embedded resource let FSharpOptimizationCompressedDataResourceName = "FSharpOptimizationCompressedData." let FSharpSignatureCompressedDataResourceName = "FSharpSignatureCompressedData." +let FSharpOptimizationCompressedDataResourceNameB = + "FSharpOptimizationCompressedDataB." + +let FSharpSignatureCompressedDataResourceNameB = "FSharpSignatureCompressedDataB." + // For historical reasons, we use a different resource name for FSharp.Core, so older F# compilers // don't complain when they see the resource. The prefix of these names must not be 'FSharpOptimizationData' // or 'FSharpSignatureData' diff --git a/src/Compiler/SyntaxTree/PrettyNaming.fsi b/src/Compiler/SyntaxTree/PrettyNaming.fsi index 511f60b9057..622a0ea657c 100644 --- a/src/Compiler/SyntaxTree/PrettyNaming.fsi +++ b/src/Compiler/SyntaxTree/PrettyNaming.fsi @@ -267,10 +267,18 @@ val internal FSharpOptimizationDataResourceName: string val internal FSharpSignatureDataResourceName: string +val internal FSharpOptimizationDataResourceNameB: string + +val internal FSharpSignatureDataResourceNameB: string + val internal FSharpOptimizationCompressedDataResourceName: string val internal FSharpSignatureCompressedDataResourceName: string +val internal FSharpOptimizationCompressedDataResourceNameB: string + +val internal FSharpSignatureCompressedDataResourceNameB: string + val internal FSharpOptimizationDataResourceName2: string val internal FSharpSignatureDataResourceName2: string diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fs b/src/Compiler/SyntaxTree/SyntaxTree.fs index 81b20ef4818..3670a299122 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fs +++ b/src/Compiler/SyntaxTree/SyntaxTree.fs @@ -332,6 +332,8 @@ type SynTypeConstraint = | WhereTyparSupportsNull of typar: SynTypar * range: range + | WhereTyparNotSupportsNull of genericName: SynTypar * range: range + | WhereTyparIsComparable of typar: SynTypar * range: range | WhereTyparIsEquatable of typar: SynTypar * range: range @@ -354,6 +356,7 @@ type SynTypeConstraint = | WhereTyparIsReferenceType(range = range) | WhereTyparIsUnmanaged(range = range) | WhereTyparSupportsNull(range = range) + | WhereTyparNotSupportsNull(range = range) | WhereTyparIsComparable(range = range) | WhereTyparIsEquatable(range = range) | WhereTyparDefaultsToType(range = range) @@ -456,10 +459,14 @@ type SynType = | StaticConstant of constant: SynConst * range: range + | StaticConstantNull of range: range + | StaticConstantExpr of expr: SynExpr * range: range | StaticConstantNamed of ident: SynType * value: SynType * range: range + | WithNull of innerType: SynType * ambivalent: bool * range: range + | Paren of innerType: SynType * range: range | SignatureParameter of attributes: SynAttributes * optional: bool * id: Ident option * usedType: SynType * range: range @@ -482,9 +489,11 @@ type SynType = | SynType.Anon(range = m) | SynType.WithGlobalConstraints(range = m) | SynType.StaticConstant(range = m) + | SynType.StaticConstantNull(range = m) | SynType.StaticConstantExpr(range = m) | SynType.StaticConstantNamed(range = m) | SynType.HashConstraint(range = m) + | SynType.WithNull(range = m) | SynType.MeasurePower(range = m) | SynType.Paren(range = m) | SynType.SignatureParameter(range = m) diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fsi b/src/Compiler/SyntaxTree/SyntaxTree.fsi index d766753e2ce..5b816b38fbe 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fsi +++ b/src/Compiler/SyntaxTree/SyntaxTree.fsi @@ -408,6 +408,9 @@ type SynTypeConstraint = /// F# syntax is 'typar: null | WhereTyparSupportsNull of typar: SynTypar * range: range + /// F# syntax is 'typar : null + | WhereTyparNotSupportsNull of genericName: SynTypar * range: range + /// F# syntax is 'typar: comparison | WhereTyparIsComparable of typar: SynTypar * range: range @@ -515,12 +518,17 @@ type SynType = /// For the dimensionless units i.e. 1, and static parameters to provided types | StaticConstant of constant: SynConst * range: range + /// F# syntax: null, used in parameters to type providers + | StaticConstantNull of range: range + /// F# syntax: const expr, used in static parameters to type providers | StaticConstantExpr of expr: SynExpr * range: range /// F# syntax: ident=1 etc., used in static parameters to type providers | StaticConstantNamed of ident: SynType * value: SynType * range: range + | WithNull of innerType: SynType * ambivalent: bool * range: range + | Paren of innerType: SynType * range: range /// F# syntax: a: b, used in signatures and type annotations diff --git a/src/Compiler/TypedTree/TcGlobals.fs b/src/Compiler/TypedTree/TcGlobals.fs index 69a99dfe119..d9d2270bcb4 100644 --- a/src/Compiler/TypedTree/TcGlobals.fs +++ b/src/Compiler/TypedTree/TcGlobals.fs @@ -187,6 +187,7 @@ type TcGlobals( directoryToResolveRelativePaths, mlCompatibility: bool, isInteractive: bool, + checkNullness: bool, useReflectionFreeCodeGen: bool, // The helper to find system types amongst referenced DLLs tryFindSysTypeCcuHelper, @@ -196,11 +197,20 @@ type TcGlobals( langVersion: LanguageVersion, realsig: bool) = - // empty flags - let v_knownWithoutNull = 0uy + let v_langFeatureNullness = langVersion.SupportsFeature LanguageFeature.NullnessChecking + + let v_renderNullness = checkNullness && v_langFeatureNullness + + let v_knownWithNull = + if v_langFeatureNullness then KnownWithNull else KnownAmbivalentToNull + + let v_knownWithoutNull = + if v_langFeatureNullness then KnownWithoutNull else KnownAmbivalentToNull let mkNonGenericTy tcref = TType_app(tcref, [], v_knownWithoutNull) + let mkNonGenericTyWithNullness tcref nullness = TType_app(tcref, [], nullness) + let mkNonLocalTyconRef2 ccu path n = mkNonLocalTyconRef (mkNonLocalEntityRef ccu path) n let mk_MFCore_tcref ccu n = mkNonLocalTyconRef2 ccu CorePathArray n @@ -340,6 +350,9 @@ type TcGlobals( match name with | "System.Runtime.CompilerServices.IsReadOnlyAttribute" | "System.Runtime.CompilerServices.IsUnmanagedAttribute" + | "System.Runtime.CompilerServices.NullableAttribute" + | "System.Runtime.CompilerServices.NullableContextAttribute" + | "System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute" | "System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute" | "System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes" -> true | _ -> false @@ -429,7 +442,9 @@ type TcGlobals( let v_enum_ty = mkNonGenericTy v_int_tcr let v_bool_ty = mkNonGenericTy v_bool_tcr let v_char_ty = mkNonGenericTy v_char_tcr - let v_obj_ty = mkNonGenericTy v_obj_tcr + let v_obj_ty_without_null = mkNonGenericTyWithNullness v_obj_tcr v_knownWithoutNull + let v_obj_ty_ambivalent = mkNonGenericTyWithNullness v_obj_tcr KnownAmbivalentToNull + let v_obj_ty_with_null = mkNonGenericTyWithNullness v_obj_tcr v_knownWithNull let v_IFormattable_tcref = findSysTyconRef sys "IFormattable" let v_FormattableString_tcref = findSysTyconRef sys "FormattableString" let v_IFormattable_ty = mkNonGenericTy v_IFormattable_tcref @@ -437,6 +452,7 @@ type TcGlobals( let v_FormattableStringFactory_tcref = findSysTyconRef sysCompilerServices "FormattableStringFactory" let v_FormattableStringFactory_ty = mkNonGenericTy v_FormattableStringFactory_tcref let v_string_ty = mkNonGenericTy v_string_tcr + let v_string_ty_ambivalent = mkNonGenericTyWithNullness v_string_tcr KnownAmbivalentToNull let v_decimal_ty = mkSysNonGenericTy sys "Decimal" let v_unit_ty = mkNonGenericTy v_unit_tcr_nice let v_system_Type_ty = mkSysNonGenericTy sys "Type" @@ -449,6 +465,7 @@ type TcGlobals( let mkByrefTy ty = TType_app(v_byref_tcr, [ty], v_knownWithoutNull) let mkNativePtrTy ty = TType_app(v_nativeptr_tcr, [ty], v_knownWithoutNull) let mkFunTy d r = TType_fun (d, r, v_knownWithoutNull) + let mkFunTyWithNullness d r nullness = TType_fun (d, r, nullness) let (-->) d r = mkFunTy d r let mkIteratedFunTy dl r = List.foldBack mkFunTy dl r let mkSmallRefTupledTy l = match l with [] -> v_unit_ty | [h] -> h | tys -> mkRawRefTupleTy tys @@ -646,16 +663,18 @@ type TcGlobals( | [_] -> None | _ -> TType_tuple (tupInfo, l) |> Some - - let decodeTupleTy tupInfo l = - match tryDecodeTupleTy tupInfo l with + let decodeTupleTyAndNullness tupInfo tinst _nullness = + match tryDecodeTupleTy tupInfo tinst with | Some ty -> ty | None -> failwith "couldn't decode tuple ty" - let decodeTupleTyIfPossible tcref tupInfo l = - match tryDecodeTupleTy tupInfo l with + let decodeTupleTyAndNullnessIfPossible tcref tupInfo tinst nullness = + match tryDecodeTupleTy tupInfo tinst with | Some ty -> ty - | None -> TType_app(tcref, l, v_knownWithoutNull) + | None -> TType_app(tcref, tinst, nullness) + + let decodeTupleTy tupInfo tinst = + decodeTupleTyAndNullness tupInfo tinst v_knownWithoutNull let mk_MFCore_attrib nm : BuiltinAttribInfo = AttribInfo(mkILTyRef(ilg.fsharpCoreAssemblyScopeRef, Core + "." + nm), mk_MFCore_tcref fslibCcu nm) @@ -720,11 +739,11 @@ type TcGlobals( let v_generic_hash_withc_inner_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "GenericHashWithComparerIntrinsic" , None , None , [vara], mk_hash_withc_sig varaTy) let v_create_instance_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "CreateInstance" , None , None , [vara], ([[v_unit_ty]], varaTy)) - let v_unbox_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "UnboxGeneric" , None , None , [vara], ([[v_obj_ty]], varaTy)) + let v_unbox_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "UnboxGeneric" , None , None , [vara], ([[v_obj_ty_with_null]], varaTy)) - let v_unbox_fast_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "UnboxFast" , None , None , [vara], ([[v_obj_ty]], varaTy)) - let v_istype_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "TypeTestGeneric" , None , None , [vara], ([[v_obj_ty]], v_bool_ty)) - let v_istype_fast_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "TypeTestFast" , None , None , [vara], ([[v_obj_ty]], v_bool_ty)) + let v_unbox_fast_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "UnboxFast" , None , None , [vara], ([[v_obj_ty_with_null]], varaTy)) + let v_istype_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "TypeTestGeneric" , None , None , [vara], ([[v_obj_ty_with_null]], v_bool_ty)) + let v_istype_fast_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "TypeTestFast" , None , None , [vara], ([[v_obj_ty_with_null]], v_bool_ty)) let v_dispose_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "Dispose" , None , None , [vara], ([[varaTy]], v_unit_ty)) @@ -790,7 +809,7 @@ type TcGlobals( let v_enum_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "enum" , None , Some "ToEnum", [vara], ([[varaTy]], v_enum_ty)) let v_hash_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "hash" , None , Some "Hash" , [vara], ([[varaTy]], v_int_ty)) - let v_box_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "box" , None , Some "Box" , [vara], ([[varaTy]], v_obj_ty)) + let v_box_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "box" , None , Some "Box" , [vara], ([[varaTy]], v_obj_ty_with_null)) let v_isnull_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "isNull" , None , Some "IsNull" , [vara], ([[varaTy]], v_bool_ty)) let v_raise_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "raise" , None , Some "Raise" , [vara], ([[mkSysNonGenericTy sys "Exception"]], varaTy)) let v_failwith_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "failwith" , None , Some "FailWith" , [vara], ([[v_string_ty]], varaTy)) @@ -849,7 +868,7 @@ type TcGlobals( let v_seq_finally_info = makeIntrinsicValRef(fslib_MFRuntimeHelpers_nleref, "EnumerateThenFinally" , None , None , [varb], ([[mkSeqTy varbTy]; [v_unit_ty --> v_unit_ty]], mkSeqTy varbTy)) let v_seq_trywith_info = makeIntrinsicValRef(fslib_MFRuntimeHelpers_nleref, "EnumerateTryWith" , None , None , [varb], ([[mkSeqTy varbTy]; [mkNonGenericTy v_exn_tcr --> v_int32_ty]; [mkNonGenericTy v_exn_tcr --> mkSeqTy varbTy]], mkSeqTy varbTy)) let v_seq_of_functions_info = makeIntrinsicValRef(fslib_MFRuntimeHelpers_nleref, "EnumerateFromFunctions" , None , None , [vara;varb], ([[v_unit_ty --> varaTy]; [varaTy --> v_bool_ty]; [varaTy --> varbTy]], mkSeqTy varbTy)) - let v_create_event_info = makeIntrinsicValRef(fslib_MFRuntimeHelpers_nleref, "CreateEvent" , None , None , [vara;varb], ([[varaTy --> v_unit_ty]; [varaTy --> v_unit_ty]; [(v_obj_ty --> (varbTy --> v_unit_ty)) --> varaTy]], mkIEvent2Ty varaTy varbTy)) + let v_create_event_info = makeIntrinsicValRef(fslib_MFRuntimeHelpers_nleref, "CreateEvent" , None , None , [vara;varb], ([[varaTy --> v_unit_ty]; [varaTy --> v_unit_ty]; [(v_obj_ty_with_null --> (varbTy --> v_unit_ty)) --> varaTy]], mkIEvent2Ty varaTy varbTy)) let v_cgh__useResumableCode_info = makeIntrinsicValRef(fslib_MFStateMachineHelpers_nleref, "__useResumableCode" , None , None , [vara], ([[]], v_bool_ty)) let v_cgh__debugPoint_info = makeIntrinsicValRef(fslib_MFStateMachineHelpers_nleref, "__debugPoint" , None , None , [vara], ([[v_int_ty]; [varaTy]], varaTy)) let v_cgh__resumeAt_info = makeIntrinsicValRef(fslib_MFStateMachineHelpers_nleref, "__resumeAt" , None , None , [vara], ([[v_int_ty]; [varaTy]], varaTy)) @@ -971,25 +990,28 @@ type TcGlobals( "Single" , v_float32_tcr |] |> Array.map (fun (nm, tcr) -> let ty = mkNonGenericTy tcr - nm, findSysTyconRef sys nm, (fun _ -> ty)) + nm, findSysTyconRef sys nm, (fun _ nullness -> + match nullness with + | Nullness.Known NullnessInfo.WithoutNull -> ty + | _ -> mkNonGenericTyWithNullness tcr nullness)) let decompileTyconEntries = [| - "FSharpFunc`2" , v_fastFunc_tcr , (fun tinst -> mkFunTy (List.item 0 tinst) (List.item 1 tinst)) - "Tuple`2" , v_ref_tuple2_tcr , decodeTupleTy tupInfoRef - "Tuple`3" , v_ref_tuple3_tcr , decodeTupleTy tupInfoRef - "Tuple`4" , v_ref_tuple4_tcr , decodeTupleTy tupInfoRef - "Tuple`5" , v_ref_tuple5_tcr , decodeTupleTy tupInfoRef - "Tuple`6" , v_ref_tuple6_tcr , decodeTupleTy tupInfoRef - "Tuple`7" , v_ref_tuple7_tcr , decodeTupleTy tupInfoRef - "Tuple`8" , v_ref_tuple8_tcr , decodeTupleTyIfPossible v_ref_tuple8_tcr tupInfoRef - "ValueTuple`2" , v_struct_tuple2_tcr , decodeTupleTy tupInfoStruct - "ValueTuple`3" , v_struct_tuple3_tcr , decodeTupleTy tupInfoStruct - "ValueTuple`4" , v_struct_tuple4_tcr , decodeTupleTy tupInfoStruct - "ValueTuple`5" , v_struct_tuple5_tcr , decodeTupleTy tupInfoStruct - "ValueTuple`6" , v_struct_tuple6_tcr , decodeTupleTy tupInfoStruct - "ValueTuple`7" , v_struct_tuple7_tcr , decodeTupleTy tupInfoStruct - "ValueTuple`8" , v_struct_tuple8_tcr , decodeTupleTyIfPossible v_struct_tuple8_tcr tupInfoStruct |] + "FSharpFunc`2" , v_fastFunc_tcr , (fun tinst -> mkFunTyWithNullness (List.item 0 tinst) (List.item 1 tinst)) + "Tuple`2" , v_ref_tuple2_tcr , decodeTupleTyAndNullness tupInfoRef + "Tuple`3" , v_ref_tuple3_tcr , decodeTupleTyAndNullness tupInfoRef + "Tuple`4" , v_ref_tuple4_tcr , decodeTupleTyAndNullness tupInfoRef + "Tuple`5" , v_ref_tuple5_tcr , decodeTupleTyAndNullness tupInfoRef + "Tuple`6" , v_ref_tuple6_tcr , decodeTupleTyAndNullness tupInfoRef + "Tuple`7" , v_ref_tuple7_tcr , decodeTupleTyAndNullness tupInfoRef + "Tuple`8" , v_ref_tuple8_tcr , decodeTupleTyAndNullnessIfPossible v_ref_tuple8_tcr tupInfoRef + "ValueTuple`2" , v_struct_tuple2_tcr , decodeTupleTyAndNullness tupInfoStruct + "ValueTuple`3" , v_struct_tuple3_tcr , decodeTupleTyAndNullness tupInfoStruct + "ValueTuple`4" , v_struct_tuple4_tcr , decodeTupleTyAndNullness tupInfoStruct + "ValueTuple`5" , v_struct_tuple5_tcr , decodeTupleTyAndNullness tupInfoStruct + "ValueTuple`6" , v_struct_tuple6_tcr , decodeTupleTyAndNullness tupInfoStruct + "ValueTuple`7" , v_struct_tuple7_tcr , decodeTupleTyAndNullness tupInfoStruct + "ValueTuple`8" , v_struct_tuple8_tcr , decodeTupleTyAndNullnessIfPossible v_struct_tuple8_tcr tupInfoStruct |] let betterEntries = Array.append betterTyconEntries decompileTyconEntries @@ -1020,11 +1042,11 @@ type TcGlobals( let t = Dictionary.newWithSize entries.Length for nm, tcref, builder in entries do t.Add(nm, - (fun tcref2 tinst2 -> + (fun tcref2 tinst2 nullness -> if tyconRefEq tcref tcref2 then - builder tinst2 + builder tinst2 nullness else - TType_app (tcref2, tinst2, v_knownWithoutNull))) + TType_app (tcref2, tinst2, nullness))) betterTypeDict1 <- t t | _ -> betterTypeDict1 @@ -1046,30 +1068,30 @@ type TcGlobals( /// For logical purposes equate some F# types with .NET types, e.g. TType_tuple == System.Tuple/ValueTuple. /// Doing this normalization is a fairly performance critical piece of code as it is frequently invoked /// in the process of converting .NET metadata to F# internal compiler data structures (see import.fs). - let decompileTy (tcref: EntityRef) tinst = + let decompileTy (tcref: EntityRef) tinst nullness = if compilingFSharpCore then // No need to decompile when compiling FSharp.Core.dll - TType_app (tcref, tinst, v_knownWithoutNull) + TType_app (tcref, tinst, nullness) else let dict = getDecompileTypeDict() match dict.TryGetValue tcref.Stamp with - | true, builder -> builder tinst - | _ -> TType_app (tcref, tinst, v_knownWithoutNull) + | true, builder -> builder tinst nullness + | _ -> TType_app (tcref, tinst, nullness) /// For cosmetic purposes "improve" some .NET types, e.g. Int32 --> int32. /// Doing this normalization is a fairly performance critical piece of code as it is frequently invoked /// in the process of converting .NET metadata to F# internal compiler data structures (see import.fs). - let improveTy (tcref: EntityRef) tinst = + let improveTy (tcref: EntityRef) tinst nullness = if compilingFSharpCore then let dict = getBetterTypeDict1() match dict.TryGetValue tcref.LogicalName with - | true, builder -> builder tcref tinst - | _ -> TType_app (tcref, tinst, v_knownWithoutNull) + | true, builder -> builder tcref tinst nullness + | _ -> TType_app (tcref, tinst, nullness) else let dict = getBetterTypeDict2() match dict.TryGetValue tcref.Stamp with - | true, builder -> builder tinst - | _ -> TType_app (tcref, tinst, v_knownWithoutNull) + | true, builder -> builder tinst nullness + | _ -> TType_app (tcref, tinst, nullness) // Adding an unnecessary "let" instead of inlining into a muiti-line pipelined compute-once "member val" that is too complex for @dsyme let v_attribs_Unsupported = [ @@ -1099,7 +1121,14 @@ type TcGlobals( // A table of all intrinsics that the compiler cares about member _.knownIntrinsics = v_knownIntrinsics - // empty flags + member _.checkNullness = checkNullness + + member _.langFeatureNullness = v_langFeatureNullness + + member _.renderNullnessAnnotations = v_renderNullness + + member _.knownWithNull = v_knownWithNull + member _.knownWithoutNull = v_knownWithoutNull // A table of known modules in FSharp.Core. Not all modules are necessarily listed, but the more we list the @@ -1332,6 +1361,7 @@ type TcGlobals( member _.bool_ty = v_bool_ty member _.int_ty = v_int_ty member _.string_ty = v_string_ty + member _.string_ty_ambivalent = v_string_ty_ambivalent member _.system_IFormattable_tcref = v_IFormattable_tcref member _.system_FormattableString_tcref = v_FormattableString_tcref member _.system_FormattableStringFactory_tcref = v_FormattableStringFactory_tcref @@ -1339,7 +1369,9 @@ type TcGlobals( member _.system_FormattableString_ty = v_FormattableString_ty member _.system_FormattableStringFactory_ty = v_FormattableStringFactory_ty member _.unit_ty = v_unit_ty - member _.obj_ty = v_obj_ty + member _.obj_ty_noNulls = v_obj_ty_without_null + member _.obj_ty_ambivalent = v_obj_ty_ambivalent + member _.obj_ty_withNulls = v_obj_ty_with_null member _.char_ty = v_char_ty member _.decimal_ty = v_decimal_ty @@ -1464,6 +1496,11 @@ type TcGlobals( member val attrib_IsReadOnlyAttribute = findOrEmbedSysPublicType "System.Runtime.CompilerServices.IsReadOnlyAttribute" member val attrib_IsUnmanagedAttribute = findOrEmbedSysPublicType "System.Runtime.CompilerServices.IsUnmanagedAttribute" member val attrib_DynamicDependencyAttribute = findOrEmbedSysPublicType "System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute" + member val attrib_NullableAttribute_opt = tryFindSysAttrib "System.Runtime.CompilerServices.NullableAttribute" + member val attrib_NullableContextAttribute_opt = tryFindSysAttrib "System.Runtime.CompilerServices.NullableContextAttribute" + member val attrib_NullableAttribute = findOrEmbedSysPublicType "System.Runtime.CompilerServices.NullableAttribute" + member val attrib_NullableContextAttribute = findOrEmbedSysPublicType "System.Runtime.CompilerServices.NullableContextAttribute" + member val attrib_MemberNotNullWhenAttribute = findOrEmbedSysPublicType "System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute" member val enum_DynamicallyAccessedMemberTypes = findOrEmbedSysPublicType "System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes" member val attrib_SystemObsolete = findSysAttrib "System.ObsoleteAttribute" @@ -1543,6 +1580,7 @@ type TcGlobals( member val attrib_MeasureableAttribute = mk_MFCore_attrib "MeasureAnnotatedAbbreviationAttribute" member val attrib_NoDynamicInvocationAttribute = mk_MFCore_attrib "NoDynamicInvocationAttribute" member val attrib_NoCompilerInliningAttribute = mk_MFCore_attrib "NoCompilerInliningAttribute" + member val attrib_WarnOnWithoutNullArgumentAttribute = mk_MFCore_attrib "WarnOnWithoutNullArgumentAttribute" member val attrib_SecurityAttribute = tryFindSysAttrib "System.Security.Permissions.SecurityAttribute" member val attrib_SecurityCriticalAttribute = findSysAttrib "System.Security.SecurityCriticalAttribute" member val attrib_SecuritySafeCriticalAttribute = findSysAttrib "System.Security.SecuritySafeCriticalAttribute" diff --git a/src/Compiler/TypedTree/TypeProviders.fs b/src/Compiler/TypedTree/TypeProviders.fs index aba063eb625..2978db62fd7 100644 --- a/src/Compiler/TypedTree/TypeProviders.fs +++ b/src/Compiler/TypedTree/TypeProviders.fs @@ -227,8 +227,13 @@ let TryTypeMemberArray (st: Tainted<_>, fullName, memberName, m, f) = [||] /// Try to access a member on a provided type, catching and reporting errors and checking the result is non-null, +#if NO_CHECKNULLS let TryTypeMemberNonNull<'T, 'U when 'U : null and 'U : not struct>(st: Tainted<'T>, fullName, memberName, m, recover: 'U, (f: 'T -> 'U)) : Tainted<'U> = match TryTypeMember(st, fullName, memberName, m, recover, f) with +#else +let TryTypeMemberNonNull<'T, 'U when 'U : not null and 'U : not struct>(st: Tainted<'T>, fullName, memberName, m, recover: 'U, (f: 'T -> 'U | null)) : Tainted<'U> = + match TryTypeMember<'T, 'U | null>(st, fullName, memberName, m, withNull recover, f) with +#endif | Tainted.Null -> errorR(Error(FSComp.SR.etUnexpectedNullFromProvidedTypeMember(fullName, memberName), m)) st.PApplyNoFailure(fun _ -> recover) @@ -340,7 +345,10 @@ type ProvidedTypeContext = dict )) -[] +[] +#if NO_CHECKNULLS +[] +#endif type ProvidedType (x: Type, ctxt: ProvidedTypeContext) = inherit ProvidedMemberInfo(x, ctxt) @@ -408,7 +416,7 @@ type ProvidedType (x: Type, ctxt: ProvidedTypeContext) = /// Type.BaseType can be null when Type is interface or object member _.BaseType = x.BaseType |> ProvidedType.Create ctxt - member _.GetStaticParameters(provider: ITypeProvider) = provider.GetStaticParameters x |> ProvidedParameterInfo.CreateArray ctxt + member _.GetStaticParameters(provider: ITypeProvider) : ProvidedParameterInfo[] MaybeNull = provider.GetStaticParameters x |> ProvidedParameterInfo.CreateArray ctxt /// Type.GetElementType can be null if i.e. Type is not array\pointer\byref type member _.GetElementType() = x.GetElementType() |> ProvidedType.Create ctxt @@ -467,17 +475,28 @@ type ProvidedType (x: Type, ctxt: ProvidedTypeContext) = let argTypes = args |> Array.map (fun arg -> arg.RawSystemType) ProvidedType.CreateNoContext(x.MakeGenericType(argTypes)) - member _.AsProvidedVar name = ProvidedVar.Create ctxt (Var(name, x)) + member _.AsProvidedVar name = ProvidedVar.CreateNonNull ctxt (Quotations.Var(name, x)) + + static member Create ctxt x : ProvidedType MaybeNull = + match x with + | Null -> null + | NonNull t -> ProvidedType (t, ctxt) - static member Create ctxt x = match x with null -> null | t -> ProvidedType (t, ctxt) + static member CreateNonNull ctxt x = ProvidedType (x, ctxt) - static member CreateWithNullCheck ctxt name x = match x with null -> nullArg name | t -> ProvidedType (t, ctxt) + static member CreateWithNullCheck ctxt name x = + match x with + | Null -> nullArg name + | t -> ProvidedType (t, ctxt) - static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedType.Create ctxt) + static member CreateArray ctxt (xs: Type[] MaybeNull) : ProvidedType[] MaybeNull = + match xs with + | Null -> null + | NonNull xs -> xs |> Array.map (ProvidedType.CreateNonNull ctxt) - static member CreateNoContext (x: Type) = ProvidedType.Create ProvidedTypeContext.Empty x + static member CreateNoContext (x:Type) = ProvidedType.Create ProvidedTypeContext.Empty x - static member Void = ProvidedType.CreateNoContext typeof + static member Void = ProvidedType.CreateNoContext typeof member _.Handle = x @@ -496,12 +515,17 @@ type ProvidedType (x: Type, ctxt: ProvidedTypeContext) = static member TaintedEquals (pt1: Tainted, pt2: Tainted) = Tainted.EqTainted (pt1.PApplyNoFailure(fun st -> st.Handle)) (pt2.PApplyNoFailure(fun st -> st.Handle)) -[] +#if NO_CHECKNULLS +[] +#endif type IProvidedCustomAttributeProvider = - abstract GetDefinitionLocationAttribute: provider: ITypeProvider -> (string * int * int) option - abstract GetXmlDocAttributes: provider: ITypeProvider -> string[] - abstract GetHasTypeProviderEditorHideMethodsAttribute: provider: ITypeProvider -> bool - abstract GetAttributeConstructorArgs: provider: ITypeProvider * attribName: string -> (obj option list * (string * obj option) list) option + abstract GetDefinitionLocationAttribute : provider: ITypeProvider -> (string MaybeNull * int * int) option + + abstract GetXmlDocAttributes : provider: ITypeProvider -> string[] + + abstract GetHasTypeProviderEditorHideMethodsAttribute : provider:ITypeProvider -> bool + + abstract GetAttributeConstructorArgs: provider:ITypeProvider * attribName:string -> (obj option list * (string * obj option) list) option type ProvidedCustomAttributeProvider (attributes :ITypeProvider -> seq) = @@ -536,7 +560,7 @@ type ProvidedCustomAttributeProvider (attributes :ITypeProvider -> seq Seq.tryFind (findAttrib typeof) |> Option.map (fun a -> - let filePath = defaultArg (a.NamedArguments |> Seq.tryPick (function Member "FilePath" (Arg (:? string as v)) -> Some v | _ -> None)) null + let filePath : string MaybeNull = defaultArg (a.NamedArguments |> Seq.tryPick (function Member "FilePath" (Arg (:? string as v)) -> Some v | _ -> None)) null let line = defaultArg (a.NamedArguments |> Seq.tryPick (function Member "Line" (Arg (:? int as v)) -> Some v | _ -> None)) 0 let column = defaultArg (a.NamedArguments |> Seq.tryPick (function Member "Column" (Arg (:? int as v)) -> Some v | _ -> None)) 0 (filePath, line, column)) @@ -552,7 +576,10 @@ type ProvidedCustomAttributeProvider (attributes :ITypeProvider -> seq Seq.toArray -[] +[] +#if NO_CHECKNULLS +[] +#endif type ProvidedMemberInfo (x: MemberInfo, ctxt) = let provide () = ProvidedCustomAttributeProvider (fun _ -> x.CustomAttributes) :> IProvidedCustomAttributeProvider @@ -574,11 +601,14 @@ type ProvidedMemberInfo (x: MemberInfo, ctxt) = member _.GetAttributeConstructorArgs (provider, attribName) = provide().GetAttributeConstructorArgs (provider, attribName) -[] +[] +#if NO_CHECKNULLS +[] +#endif type ProvidedParameterInfo (x: ParameterInfo, ctxt) = let provide () = ProvidedCustomAttributeProvider (fun _ -> x.CustomAttributes) :> IProvidedCustomAttributeProvider - member _.Name = x.Name + member _.Name = let nm = x.Name in match box nm with null -> "" | _ -> nm member _.IsOut = x.IsOut @@ -591,12 +621,25 @@ type ProvidedParameterInfo (x: ParameterInfo, ctxt) = member _.HasDefaultValue = x.Attributes.HasFlag(ParameterAttributes.HasDefault) /// ParameterInfo.ParameterType cannot be null - member _.ParameterType = ProvidedType.CreateWithNullCheck ctxt "ParameterType" x.ParameterType - - static member Create ctxt x = match x with null -> null | t -> ProvidedParameterInfo (t, ctxt) - - static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedParameterInfo.Create ctxt) // TODO null wrong? - + member _.ParameterType = ProvidedType.CreateWithNullCheck ctxt "ParameterType" x.ParameterType + + static member Create ctxt (x: ParameterInfo MaybeNull) : ProvidedParameterInfo MaybeNull = + match x with + | Null -> null + | NonNull x -> ProvidedParameterInfo (x, ctxt) + + static member CreateNonNull ctxt x = ProvidedParameterInfo (x, ctxt) + + static member CreateArray ctxt (xs: ParameterInfo[] MaybeNull) : ProvidedParameterInfo[] MaybeNull = + match xs with + | Null -> null + | NonNull xs -> xs |> Array.map (ProvidedParameterInfo.CreateNonNull ctxt) + + static member CreateArrayNonNull ctxt xs : ProvidedParameterInfo[] = + match box xs with + | Null -> [| |] + | _ -> xs |> Array.map (ProvidedParameterInfo.CreateNonNull ctxt) + interface IProvidedCustomAttributeProvider with member _.GetHasTypeProviderEditorHideMethodsAttribute provider = provide().GetHasTypeProviderEditorHideMethodsAttribute provider @@ -616,7 +659,10 @@ type ProvidedParameterInfo (x: ParameterInfo, ctxt) = override _.GetHashCode() = assert false; x.GetHashCode() -[] +[] +#if NO_CHECKNULLS +[] +#endif type ProvidedAssembly (x: Assembly) = member _.GetName() = x.GetName() @@ -625,7 +671,7 @@ type ProvidedAssembly (x: Assembly) = member _.GetManifestModuleContents(provider: ITypeProvider) = provider.GetGeneratedAssemblyContents x - static member Create (x: Assembly) = match x with null -> null | t -> ProvidedAssembly t + static member Create x : ProvidedAssembly MaybeNull = match x with null -> null | t -> ProvidedAssembly (t) member _.Handle = x @@ -633,7 +679,10 @@ type ProvidedAssembly (x: Assembly) = override _.GetHashCode() = assert false; x.GetHashCode() -[] +[] +#if NO_CHECKNULLS +[] +#endif type ProvidedMethodBase (x: MethodBase, ctxt) = inherit ProvidedMemberInfo(x, ctxt) @@ -668,12 +717,14 @@ type ProvidedMethodBase (x: MethodBase, ctxt) = member _.Handle = x static member TaintedGetHashCode (x: Tainted) = - Tainted.GetHashCodeTainted (x.PApplyNoFailure(fun st -> (st.Name, st.DeclaringType.Assembly.FullName, st.DeclaringType.FullName))) + Tainted.GetHashCodeTainted + (x.PApplyNoFailure(fun st -> (st.Name, (nonNull (nonNull st.DeclaringType).Assembly).FullName, + (nonNull st.DeclaringType).FullName))) static member TaintedEquals (pt1: Tainted, pt2: Tainted) = Tainted.EqTainted (pt1.PApplyNoFailure(fun st -> st.Handle)) (pt2.PApplyNoFailure(fun st -> st.Handle)) - member _.GetStaticParametersForMethod(provider: ITypeProvider) = + member _.GetStaticParametersForMethod(provider: ITypeProvider) : ProvidedParameterInfo[] = let bindingFlags = BindingFlags.Instance ||| BindingFlags.NonPublic ||| BindingFlags.Public let staticParams = @@ -692,7 +743,7 @@ type ProvidedMethodBase (x: MethodBase, ctxt) = with err -> raise (StripException (StripException err)) paramsAsObj :?> ParameterInfo[] - staticParams |> ProvidedParameterInfo.CreateArray ctxt + staticParams |> ProvidedParameterInfo.CreateArrayNonNull ctxt member _.ApplyStaticArgumentsForMethod(provider: ITypeProvider, fullNameAfterArguments: string, staticArgs: obj[]) = let bindingFlags = BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.InvokeMethod @@ -709,7 +760,7 @@ type ProvidedMethodBase (x: MethodBase, ctxt) = [| typeof; typeof; typeof |], null) match meth with - | null -> failwith (FSComp.SR.estApplyStaticArgumentsForMethodNotImplemented()) + | Null -> failwith (FSComp.SR.estApplyStaticArgumentsForMethodNotImplemented()) | _ -> let mbAsObj = try meth.Invoke(provider, bindingFlags ||| BindingFlags.InvokeMethod, null, [| box x; box fullNameAfterArguments; box staticArgs |], null) @@ -719,18 +770,29 @@ type ProvidedMethodBase (x: MethodBase, ctxt) = | :? MethodBase as mb -> mb | _ -> failwith (FSComp.SR.estApplyStaticArgumentsForMethodNotImplemented()) match mb with - | :? MethodInfo as mi -> (mi |> ProvidedMethodInfo.Create ctxt: ProvidedMethodInfo) :> ProvidedMethodBase - | :? ConstructorInfo as ci -> (ci |> ProvidedConstructorInfo.Create ctxt: ProvidedConstructorInfo) :> ProvidedMethodBase + | :? MethodInfo as mi -> (mi |> ProvidedMethodInfo.CreateNonNull ctxt : ProvidedMethodInfo) :> ProvidedMethodBase + | :? ConstructorInfo as ci -> (ci |> ProvidedConstructorInfo.CreateNonNull ctxt : ProvidedConstructorInfo) :> ProvidedMethodBase | _ -> failwith (FSComp.SR.estApplyStaticArgumentsForMethodNotImplemented()) -[] +[] +#if NO_CHECKNULLS +[] +#endif type ProvidedFieldInfo (x: FieldInfo, ctxt) = inherit ProvidedMemberInfo(x, ctxt) - static member Create ctxt x = match x with null -> null | t -> ProvidedFieldInfo (t, ctxt) + static member CreateNonNull ctxt x = ProvidedFieldInfo (x, ctxt) + + static member Create ctxt x : ProvidedFieldInfo MaybeNull = + match x with + | Null -> null + | NonNull x -> ProvidedFieldInfo (x, ctxt) - static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedFieldInfo.Create ctxt) + static member CreateArray ctxt (xs: FieldInfo[] MaybeNull) : ProvidedFieldInfo[] MaybeNull = + match xs with + | Null -> null + | NonNull xs -> xs |> Array.map (ProvidedFieldInfo.CreateNonNull ctxt) member _.IsInitOnly = x.IsInitOnly @@ -765,15 +827,27 @@ type ProvidedFieldInfo (x: FieldInfo, ctxt) = static member TaintedEquals (pt1: Tainted, pt2: Tainted) = Tainted.EqTainted (pt1.PApplyNoFailure(fun st -> st.Handle)) (pt2.PApplyNoFailure(fun st -> st.Handle)) -[] +[] +#if NO_CHECKNULLS +[] +#endif type ProvidedMethodInfo (x: MethodInfo, ctxt) = inherit ProvidedMethodBase(x, ctxt) member _.ReturnType = x.ReturnType |> ProvidedType.CreateWithNullCheck ctxt "ReturnType" - static member Create ctxt x = match x with null -> null | t -> ProvidedMethodInfo (t, ctxt) + static member CreateNonNull ctxt (x: MethodInfo) : ProvidedMethodInfo = + ProvidedMethodInfo (x, ctxt) + + static member Create ctxt (x: MethodInfo MaybeNull) : ProvidedMethodInfo MaybeNull = + match x with + | Null -> null + | NonNull x -> ProvidedMethodInfo (x, ctxt) - static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedMethodInfo.Create ctxt) + static member CreateArray ctxt (xs: MethodInfo[] MaybeNull) : ProvidedMethodInfo[] MaybeNull = + match xs with + | Null -> null + | NonNull xs -> xs |> Array.map (ProvidedMethodInfo.CreateNonNull ctxt) member _.Handle = x @@ -783,7 +857,10 @@ type ProvidedMethodInfo (x: MethodInfo, ctxt) = override _.GetHashCode() = assert false; x.GetHashCode() -[] +[] +#if NO_CHECKNULLS +[] +#endif type ProvidedPropertyInfo (x: PropertyInfo, ctxt) = inherit ProvidedMemberInfo(x, ctxt) @@ -800,9 +877,17 @@ type ProvidedPropertyInfo (x: PropertyInfo, ctxt) = /// PropertyInfo.PropertyType cannot be null member _.PropertyType = x.PropertyType |> ProvidedType.CreateWithNullCheck ctxt "PropertyType" - static member Create ctxt x = match x with null -> null | t -> ProvidedPropertyInfo (t, ctxt) + static member CreateNonNull ctxt x = ProvidedPropertyInfo (x, ctxt) + + static member Create ctxt x : ProvidedPropertyInfo MaybeNull = + match x with + | Null -> null + | NonNull x -> ProvidedPropertyInfo (x, ctxt) - static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedPropertyInfo.Create ctxt) + static member CreateArray ctxt (xs: PropertyInfo[] MaybeNull) : ProvidedPropertyInfo[] MaybeNull = + match xs with + | Null -> null + | NonNull xs -> xs |> Array.map (ProvidedPropertyInfo.CreateNonNull ctxt) member _.Handle = x @@ -811,12 +896,17 @@ type ProvidedPropertyInfo (x: PropertyInfo, ctxt) = override _.GetHashCode() = assert false; x.GetHashCode() static member TaintedGetHashCode (x: Tainted) = - Tainted.GetHashCodeTainted (x.PApplyNoFailure(fun st -> (st.Name, st.DeclaringType.Assembly.FullName, st.DeclaringType.FullName))) + Tainted.GetHashCodeTainted + (x.PApplyNoFailure(fun st -> (st.Name, (nonNull (nonNull st.DeclaringType).Assembly).FullName, + (nonNull st.DeclaringType).FullName))) static member TaintedEquals (pt1: Tainted, pt2: Tainted) = Tainted.EqTainted (pt1.PApplyNoFailure(fun st -> st.Handle)) (pt2.PApplyNoFailure(fun st -> st.Handle)) -[] +[] +#if NO_CHECKNULLS +[] +#endif type ProvidedEventInfo (x: EventInfo, ctxt) = inherit ProvidedMemberInfo(x, ctxt) @@ -826,11 +916,19 @@ type ProvidedEventInfo (x: EventInfo, ctxt) = /// EventInfo.EventHandlerType cannot be null member _.EventHandlerType = x.EventHandlerType |> ProvidedType.CreateWithNullCheck ctxt "EventHandlerType" - - static member Create ctxt x = match x with null -> null | t -> ProvidedEventInfo (t, ctxt) - - static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedEventInfo.Create ctxt) - + + static member CreateNonNull ctxt x = ProvidedEventInfo (x, ctxt) + + static member Create ctxt x : ProvidedEventInfo MaybeNull = + match x with + | Null -> null + | NonNull x -> ProvidedEventInfo (x, ctxt) + + static member CreateArray ctxt (xs: EventInfo[] MaybeNull) : ProvidedEventInfo[] MaybeNull = + match xs with + | Null -> null + | NonNull xs -> xs |> Array.map (ProvidedEventInfo.CreateNonNull ctxt) + member _.Handle = x override _.Equals y = assert false; match y with :? ProvidedEventInfo as y -> x.Equals y.Handle | _ -> false @@ -838,18 +936,31 @@ type ProvidedEventInfo (x: EventInfo, ctxt) = override _.GetHashCode() = assert false; x.GetHashCode() static member TaintedGetHashCode (x: Tainted) = - Tainted.GetHashCodeTainted (x.PApplyNoFailure(fun st -> (st.Name, st.DeclaringType.Assembly.FullName, st.DeclaringType.FullName))) + Tainted.GetHashCodeTainted + (x.PApplyNoFailure(fun st -> (st.Name, (nonNull (nonNull st.DeclaringType).Assembly).FullName, + (nonNull st.DeclaringType).FullName))) static member TaintedEquals (pt1: Tainted, pt2: Tainted) = Tainted.EqTainted (pt1.PApplyNoFailure(fun st -> st.Handle)) (pt2.PApplyNoFailure(fun st -> st.Handle)) -[] +[] +#if NO_CHECKNULLS +[] +#endif type ProvidedConstructorInfo (x: ConstructorInfo, ctxt) = inherit ProvidedMethodBase(x, ctxt) - static member Create ctxt x = match x with null -> null | t -> ProvidedConstructorInfo (t, ctxt) + static member CreateNonNull ctxt x = ProvidedConstructorInfo (x, ctxt) + + static member Create ctxt (x: ConstructorInfo MaybeNull) : ProvidedConstructorInfo MaybeNull = + match x with + | Null -> null + | NonNull x -> ProvidedConstructorInfo (x, ctxt) - static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedConstructorInfo.Create ctxt) + static member CreateArray ctxt (xs: ConstructorInfo[] MaybeNull) : ProvidedConstructorInfo[] MaybeNull = + match xs with + | Null -> null + | NonNull xs -> xs |> Array.map (ProvidedConstructorInfo.CreateNonNull ctxt) member _.Handle = x @@ -879,7 +990,11 @@ type ProvidedExprType = | ProvidedIfThenElseExpr of ProvidedExpr * ProvidedExpr * ProvidedExpr | ProvidedVarExpr of ProvidedVar +#if NO_CHECKNULLS [] +#else +[] +#endif type ProvidedExpr (x: Expr, ctxt) = member _.Type = x.Type |> ProvidedType.Create ctxt @@ -893,71 +1008,91 @@ type ProvidedExpr (x: Expr, ctxt) = member _.GetExprType() = match x with | Patterns.NewObject(ctor, args) -> - Some (ProvidedNewObjectExpr (ProvidedConstructorInfo.Create ctxt ctor, [| for a in args -> ProvidedExpr.Create ctxt a |])) + Some (ProvidedNewObjectExpr (ProvidedConstructorInfo.CreateNonNull ctxt ctor, [| for a in args -> ProvidedExpr.CreateNonNull ctxt a |])) | Patterns.WhileLoop(guardExpr, bodyExpr) -> - Some (ProvidedWhileLoopExpr (ProvidedExpr.Create ctxt guardExpr, ProvidedExpr.Create ctxt bodyExpr)) + Some (ProvidedWhileLoopExpr (ProvidedExpr.CreateNonNull ctxt guardExpr, ProvidedExpr.CreateNonNull ctxt bodyExpr)) | Patterns.NewDelegate(ty, vs, expr) -> - Some (ProvidedNewDelegateExpr(ProvidedType.Create ctxt ty, ProvidedVar.CreateArray ctxt (List.toArray vs), ProvidedExpr.Create ctxt expr)) + Some (ProvidedNewDelegateExpr(ProvidedType.CreateNonNull ctxt ty, ProvidedVar.CreateArray ctxt (List.toArray vs), ProvidedExpr.CreateNonNull ctxt expr)) | Patterns.Call(objOpt, meth, args) -> - Some (ProvidedCallExpr((match objOpt with None -> None | Some obj -> Some (ProvidedExpr.Create ctxt obj)), - ProvidedMethodInfo.Create ctxt meth, [| for a in args -> ProvidedExpr.Create ctxt a |])) + Some (ProvidedCallExpr((match objOpt with None -> None | Some obj -> Some (ProvidedExpr.CreateNonNull ctxt obj)), + ProvidedMethodInfo.CreateNonNull ctxt meth, [| for a in args -> ProvidedExpr.CreateNonNull ctxt a |])) | Patterns.DefaultValue ty -> - Some (ProvidedDefaultExpr (ProvidedType.Create ctxt ty)) + Some (ProvidedDefaultExpr (ProvidedType.CreateNonNull ctxt ty)) | Patterns.Value(obj, ty) -> - Some (ProvidedConstantExpr (obj, ProvidedType.Create ctxt ty)) + Some (ProvidedConstantExpr (obj, ProvidedType.CreateNonNull ctxt ty)) | Patterns.Coerce(arg, ty) -> - Some (ProvidedTypeAsExpr (ProvidedExpr.Create ctxt arg, ProvidedType.Create ctxt ty)) + Some (ProvidedTypeAsExpr (ProvidedExpr.CreateNonNull ctxt arg, ProvidedType.CreateNonNull ctxt ty)) | Patterns.NewTuple args -> Some (ProvidedNewTupleExpr(ProvidedExpr.CreateArray ctxt (Array.ofList args))) | Patterns.TupleGet(arg, n) -> - Some (ProvidedTupleGetExpr (ProvidedExpr.Create ctxt arg, n)) + Some (ProvidedTupleGetExpr (ProvidedExpr.CreateNonNull ctxt arg, n)) | Patterns.NewArray(ty, args) -> - Some (ProvidedNewArrayExpr(ProvidedType.Create ctxt ty, ProvidedExpr.CreateArray ctxt (Array.ofList args))) + Some (ProvidedNewArrayExpr(ProvidedType.CreateNonNull ctxt ty, ProvidedExpr.CreateArray ctxt (Array.ofList args))) | Patterns.Sequential(e1, e2) -> - Some (ProvidedSequentialExpr(ProvidedExpr.Create ctxt e1, ProvidedExpr.Create ctxt e2)) + Some (ProvidedSequentialExpr(ProvidedExpr.CreateNonNull ctxt e1, ProvidedExpr.CreateNonNull ctxt e2)) | Patterns.Lambda(v, body) -> - Some (ProvidedLambdaExpr (ProvidedVar.Create ctxt v, ProvidedExpr.Create ctxt body)) + Some (ProvidedLambdaExpr (ProvidedVar.CreateNonNull ctxt v, ProvidedExpr.CreateNonNull ctxt body)) | Patterns.TryFinally(b1, b2) -> - Some (ProvidedTryFinallyExpr (ProvidedExpr.Create ctxt b1, ProvidedExpr.Create ctxt b2)) + Some (ProvidedTryFinallyExpr (ProvidedExpr.CreateNonNull ctxt b1, ProvidedExpr.CreateNonNull ctxt b2)) | Patterns.TryWith(b, v1, e1, v2, e2) -> - Some (ProvidedTryWithExpr (ProvidedExpr.Create ctxt b, ProvidedVar.Create ctxt v1, ProvidedExpr.Create ctxt e1, ProvidedVar.Create ctxt v2, ProvidedExpr.Create ctxt e2)) + Some (ProvidedTryWithExpr (ProvidedExpr.CreateNonNull ctxt b, ProvidedVar.CreateNonNull ctxt v1, ProvidedExpr.CreateNonNull ctxt e1, ProvidedVar.CreateNonNull ctxt v2, ProvidedExpr.CreateNonNull ctxt e2)) | Patterns.TypeTest(e, ty) -> - Some (ProvidedTypeTestExpr(ProvidedExpr.Create ctxt e, ProvidedType.Create ctxt ty)) + Some (ProvidedTypeTestExpr(ProvidedExpr.CreateNonNull ctxt e, ProvidedType.CreateNonNull ctxt ty)) | Patterns.Let(v, e, b) -> - Some (ProvidedLetExpr (ProvidedVar.Create ctxt v, ProvidedExpr.Create ctxt e, ProvidedExpr.Create ctxt b)) + Some (ProvidedLetExpr (ProvidedVar.CreateNonNull ctxt v, ProvidedExpr.CreateNonNull ctxt e, ProvidedExpr.CreateNonNull ctxt b)) | Patterns.ForIntegerRangeLoop (v, e1, e2, e3) -> - Some (ProvidedForIntegerRangeLoopExpr (ProvidedVar.Create ctxt v, ProvidedExpr.Create ctxt e1, ProvidedExpr.Create ctxt e2, ProvidedExpr.Create ctxt e3)) + Some (ProvidedForIntegerRangeLoopExpr (ProvidedVar.CreateNonNull ctxt v, ProvidedExpr.CreateNonNull ctxt e1, ProvidedExpr.CreateNonNull ctxt e2, ProvidedExpr.CreateNonNull ctxt e3)) | Patterns.VarSet(v, e) -> - Some (ProvidedVarSetExpr (ProvidedVar.Create ctxt v, ProvidedExpr.Create ctxt e)) + Some (ProvidedVarSetExpr (ProvidedVar.CreateNonNull ctxt v, ProvidedExpr.CreateNonNull ctxt e)) | Patterns.IfThenElse(g, t, e) -> - Some (ProvidedIfThenElseExpr (ProvidedExpr.Create ctxt g, ProvidedExpr.Create ctxt t, ProvidedExpr.Create ctxt e)) + Some (ProvidedIfThenElseExpr (ProvidedExpr.CreateNonNull ctxt g, ProvidedExpr.CreateNonNull ctxt t, ProvidedExpr.CreateNonNull ctxt e)) | Patterns.Var v -> - Some (ProvidedVarExpr (ProvidedVar.Create ctxt v)) + Some (ProvidedVarExpr (ProvidedVar.CreateNonNull ctxt v)) | _ -> None + static member Create ctxt t : ProvidedExpr MaybeNull = + match box t with + | Null -> null + | _ -> ProvidedExpr (t, ctxt) - static member Create ctxt t = match box t with null -> null | _ -> ProvidedExpr (t, ctxt) + static member CreateNonNull ctxt t : ProvidedExpr = + ProvidedExpr (t, ctxt) - static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedExpr.Create ctxt) + static member CreateArray ctxt xs : ProvidedExpr[] = + match box xs with + | Null -> [| |] + | _ -> xs |> Array.map (ProvidedExpr.CreateNonNull ctxt) override _.Equals y = match y with :? ProvidedExpr as y -> x.Equals y.Handle | _ -> false override _.GetHashCode() = x.GetHashCode() +#if NO_CHECKNULLS [] +#else +[] +#endif type ProvidedVar (x: Var, ctxt) = member _.Type = x.Type |> ProvidedType.Create ctxt member _.Name = x.Name member _.IsMutable = x.IsMutable member _.Handle = x member _.Context = ctxt - static member Create ctxt t = match box t with null -> null | _ -> ProvidedVar (t, ctxt) - static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedVar.Create ctxt) + + static member CreateNonNull ctxt t = + ProvidedVar (t, ctxt) + + static member CreateArray ctxt xs : ProvidedVar[] = + match box xs with + | Null -> [| |] + | _ -> xs |> Array.map (ProvidedVar.CreateNonNull ctxt) + override _.Equals y = match y with :? ProvidedVar as y -> x.Equals y.Handle | _ -> false + override _.GetHashCode() = x.GetHashCode() /// Get the provided invoker expression for a particular use of a method. let GetInvokerExpression (provider: ITypeProvider, methodBase: ProvidedMethodBase, paramExprs: ProvidedVar[]) = - provider.GetInvokerExpression(methodBase.Handle, [| for p in paramExprs -> Expr.Var p.Handle |]) |> ProvidedExpr.Create methodBase.Context + provider.GetInvokerExpression(methodBase.Handle, [| for p in paramExprs -> Quotations.Expr.Var p.Handle |]) |> ProvidedExpr.Create methodBase.Context /// Compute the Name or FullName property of a provided type, reporting appropriate errors let CheckAndComputeProvidedNameProperty(m, st: Tainted, proj, propertyString) = @@ -977,8 +1112,7 @@ let ValidateAttributesOfProvidedType (m, st: Tainted) = errorR(Error(FSComp.SR.etMustNotBeGeneric fullName, m)) if TryTypeMember(st, fullName, "IsArray", m, false, fun st->st.IsArray) |> unmarshal then errorR(Error(FSComp.SR.etMustNotBeAnArray fullName, m)) - TryTypeMemberNonNull(st, fullName, "GetInterfaces", m, [||], fun st -> st.GetInterfaces()) |> ignore - + TryTypeMemberNonNull(st, fullName, "GetInterfaces", m, [||], fun st -> st.GetInterfaces()) |> ignore /// Verify that a provided type has the expected name let ValidateExpectedName m expectedPath expectedName (st: Tainted) = @@ -986,19 +1120,23 @@ let ValidateExpectedName m expectedPath expectedName (st: Tainted) if name <> expectedName then raise (TypeProviderError(FSComp.SR.etProvidedTypeHasUnexpectedName(expectedName, name), st.TypeProviderDesignation, m)) +#if NO_CHECKNULLS let namespaceName = TryTypeMember(st, name, "Namespace", m, "", fun st -> st.Namespace) |> unmarshal +#else + let namespaceName = TryTypeMember<_, string | null>(st, name, "Namespace", m, "", fun st -> st.Namespace) |> unmarshal // TODO NULLNESS: why is this explicit instantiation needed? +#endif let rec declaringTypes (st: Tainted) accu = match TryTypeMember(st, name, "DeclaringType", m, null, fun st -> st.DeclaringType) with | Tainted.Null -> accu - | dt -> declaringTypes dt (CheckAndComputeProvidedNameProperty(m, dt, (fun dt -> dt.Name), "Name") :: accu) + | Tainted.NonNull dt -> declaringTypes dt (CheckAndComputeProvidedNameProperty(m, dt, (fun dt -> dt.Name), "Name") :: accu) let path = - [| match namespaceName with - | null -> () - | _ -> yield! namespaceName.Split([|'.'|]) - yield! declaringTypes st [] |] - + [| match namespaceName with + | Null -> () + | NonNull namespaceName -> yield! namespaceName.Split([|'.'|]) + yield! declaringTypes st [] |] + if path <> expectedPath then let expectedPath = String.Join(".", expectedPath) let path = String.Join(".", path) @@ -1009,7 +1147,11 @@ let ValidateProvidedTypeAfterStaticInstantiation(m, st: Tainted, e // Do all the calling into st up front with recovery let fullName, namespaceName, usedMembers = let name = CheckAndComputeProvidedNameProperty(m, st, (fun st -> st.Name), "Name") +#if NO_CHECKNULLS let namespaceName = TryTypeMember(st, name, "Namespace", m, FSComp.SR.invalidNamespaceForProvidedType(), fun st -> st.Namespace) |> unmarshal +#else + let namespaceName = TryTypeMember<_, string | null>(st, name, "Namespace", m, FSComp.SR.invalidNamespaceForProvidedType(), fun st -> st.Namespace) |> unmarshal +#endif let fullName = TryTypeMemberNonNull(st, name, "FullName", m, FSComp.SR.invalidFullNameForProvidedType(), fun st -> st.FullName) |> unmarshal ValidateExpectedName m expectedPath expectedName st // Must be able to call (GetMethods|GetEvents|GetProperties|GetNestedTypes|GetConstructors)(bindingFlags). @@ -1034,19 +1176,18 @@ let ValidateProvidedTypeAfterStaticInstantiation(m, st: Tainted, e for mi in usedMembers do match mi with | Tainted.Null -> errorR(Error(FSComp.SR.etNullMember fullName, m)) - | _ -> + | Tainted.NonNull _ -> let memberName = TryMemberMember(mi, fullName, "Name", "Name", m, "invalid provided type member name", fun mi -> mi.Name) |> unmarshal if String.IsNullOrEmpty memberName then errorR(Error(FSComp.SR.etNullOrEmptyMemberName fullName, m)) else let miDeclaringType = TryMemberMember(mi, fullName, memberName, "DeclaringType", m, ProvidedType.CreateNoContext(typeof), fun mi -> mi.DeclaringType) - match miDeclaringType with // Generated nested types may have null DeclaringType | Tainted.Null when mi.OfType().IsSome -> () | Tainted.Null -> errorR(Error(FSComp.SR.etNullMemberDeclaringType(fullName, memberName), m)) - | _ -> + | Tainted.NonNull miDeclaringType -> let miDeclaringTypeFullName = TryMemberMember (miDeclaringType, fullName, memberName, "FullName", m, "invalid declaring type full name", @@ -1063,11 +1204,9 @@ let ValidateProvidedTypeAfterStaticInstantiation(m, st: Tainted, e if not isPublic || isGenericMethod then errorR(Error(FSComp.SR.etMethodHasRequirements(fullName, memberName), m)) | None -> - match mi.OfType() with | Some subType -> ValidateAttributesOfProvidedType(m, subType) | None -> - match mi.OfType() with | Some pi -> // Property must have a getter or setter @@ -1092,8 +1231,8 @@ let ValidateProvidedTypeAfterStaticInstantiation(m, st: Tainted, e | true, false -> errorR(Error(FSComp.SR.etPropertyHasSetterButNoCanWrite(memberName, fullName), m)) if not canRead && not canWrite then errorR(Error(FSComp.SR.etPropertyNeedsCanWriteOrCanRead(memberName, fullName), m)) - | None -> + | None -> match mi.OfType() with | Some ei -> // Event must have adder and remover @@ -1105,11 +1244,9 @@ let ValidateProvidedTypeAfterStaticInstantiation(m, st: Tainted, e | _, Tainted.Null -> errorR(Error(FSComp.SR.etEventNoRemove(memberName, fullName), m)) | _, _ -> () | None -> - match mi.OfType() with | Some _ -> () // TODO: Constructors must be public etc. | None -> - match mi.OfType() with | Some _ -> () // TODO: Fields must be public, literals must have a value etc. | None -> @@ -1119,7 +1256,11 @@ let ValidateProvidedTypeDefinition(m, st: Tainted, expectedPath: s // Validate the Name, Namespace and FullName properties let name = CheckAndComputeProvidedNameProperty(m, st, (fun st -> st.Name), "Name") +#if NO_CHECKNULLS let _namespaceName = TryTypeMember(st, name, "Namespace", m, FSComp.SR.invalidNamespaceForProvidedType(), fun st -> st.Namespace) |> unmarshal +#else + let _namespaceName = TryTypeMember<_, string | null>(st, name, "Namespace", m, FSComp.SR.invalidNamespaceForProvidedType(), fun st -> st.Namespace) |> unmarshal +#endif let _fullname = TryTypeMemberNonNull(st, name, "FullName", m, FSComp.SR.invalidFullNameForProvidedType(), fun st -> st.FullName) |> unmarshal ValidateExpectedName m expectedPath expectedName st @@ -1130,15 +1271,15 @@ let ValidateProvidedTypeDefinition(m, st: Tainted, expectedPath: s | -1 -> () | n -> errorR(Error(FSComp.SR.etIllegalCharactersInTypeName(string expectedName[n], expectedName), m)) - let staticParameters = st.PApplyWithProvider((fun (st, provider) -> st.GetStaticParameters provider), range=m) - if staticParameters.PUntaint((fun a -> a.Length), m) = 0 then + let staticParameters : Tainted = st.PApplyWithProvider((fun (st, provider) -> st.GetStaticParameters provider), range=m) + if staticParameters.PUntaint((fun a -> (nonNull a).Length), m) = 0 then ValidateProvidedTypeAfterStaticInstantiation(m, st, expectedPath, expectedName) /// Resolve a (non-nested) provided type given a full namespace name and a type name. /// May throw an exception which will be turned into an error message by one of the 'Try' function below. /// If resolution is successful the type is then validated. -let ResolveProvidedType (resolver: Tainted, m, moduleOrNamespace: string[], typeName) = +let ResolveProvidedType (resolver: Tainted, m, moduleOrNamespace: string[], typeName) : Tainted = let displayName = String.Join(".", moduleOrNamespace) // Try to find the type in the given provided namespace @@ -1168,7 +1309,7 @@ let ResolveProvidedType (resolver: Tainted, m, moduleOrNamespace: match tryNamespaces providedNamespaces with | None -> resolver.PApply((fun _ -> null), m) | Some res -> res - + /// Try to resolve a type against the given host with the given resolution environment. let TryResolveProvidedType(resolver: Tainted, m, moduleOrNamespace, typeName) = try @@ -1185,14 +1326,14 @@ let ILPathToProvidedType (st: Tainted, m) = match st.PApply((fun st -> st.DeclaringType), m) with | Tainted.Null -> match st.PUntaint((fun st -> st.Namespace), m) with - | Null -> typeName + | Null -> typeName | NonNull ns -> ns + "." + typeName | _ -> typeName let rec encContrib (st: Tainted) = match st.PApply((fun st ->st.DeclaringType), m) with | Tainted.Null -> [] - | enc -> encContrib enc @ [ nameContrib enc ] + | Tainted.NonNull enc -> encContrib enc @ [ nameContrib enc ] encContrib st, nameContrib st @@ -1213,7 +1354,6 @@ let TryApplyProvidedMethod(methBeforeArgs: Tainted, staticAr let staticParams = methBeforeArgs.PApplyWithProvider((fun (mb, resolver) -> mb.GetStaticParametersForMethod resolver), range=m) let mangledName = ComputeMangledNameForApplyStaticParameters(nm, staticArgs, staticParams, m) mangledName - match methBeforeArgs.PApplyWithProvider((fun (mb, provider) -> mb.ApplyStaticArgumentsForMethod(provider, mangledName, staticArgs)), range=m) with | Tainted.Null -> None | Tainted.NonNull methWithArguments -> @@ -1228,7 +1368,7 @@ let TryApplyProvidedType(typeBeforeArguments: Tainted, optGenerate if staticArgs.Length = 0 then Some (typeBeforeArguments, (fun () -> ())) else - + let fullTypePathAfterArguments = // If there is a generated type name, then use that match optGeneratedTypePath with @@ -1237,10 +1377,10 @@ let TryApplyProvidedType(typeBeforeArguments: Tainted, optGenerate // Otherwise, use the full path of the erased type, including mangled arguments let nm = typeBeforeArguments.PUntaint((fun x -> x.Name), m) let enc, _ = ILPathToProvidedType (typeBeforeArguments, m) - let staticParams = typeBeforeArguments.PApplyWithProvider((fun (mb, resolver) -> mb.GetStaticParameters resolver), range=m) + let staticParams : Tainted = typeBeforeArguments.PApplyWithProvider((fun (st, resolver) -> st.GetStaticParameters resolver |> nonNull), range=m) let mangledName = ComputeMangledNameForApplyStaticParameters(nm, staticArgs, staticParams, m) enc @ [ mangledName ] - + match typeBeforeArguments.PApplyWithProvider((fun (typeBeforeArguments, provider) -> typeBeforeArguments.ApplyStaticArguments(provider, Array.ofList fullTypePathAfterArguments, staticArgs)), range=m) with | Tainted.Null -> None | Tainted.NonNull typeWithArguments -> @@ -1254,7 +1394,7 @@ let TryApplyProvidedType(typeBeforeArguments: Tainted, optGenerate /// Given a mangled name reference to a non-nested provided type, resolve it. /// If necessary, demangle its static arguments before applying them. let TryLinkProvidedType(resolver: Tainted, moduleOrNamespace: string[], typeLogicalName: string, range: range) = - + // Demangle the static parameters let typeName, argNamesAndValues = try @@ -1267,7 +1407,7 @@ let TryLinkProvidedType(resolver: Tainted, moduleOrNamespace: str match typeBeforeArguments with | Tainted.Null -> None - | _ -> + | Tainted.NonNull typeBeforeArguments -> // Take the static arguments (as strings, taken from the text in the reference we're relinking), // and convert them to objects of the appropriate type, based on the expected kind. let staticParameters = @@ -1275,7 +1415,7 @@ let TryLinkProvidedType(resolver: Tainted, moduleOrNamespace: str typeBeforeArguments.GetStaticParameters resolver),range=range0) let staticParameters = staticParameters.PApplyArray(id, "", range) - + let staticArgs = staticParameters |> Array.map (fun sp -> let typeBeforeArgumentsName = typeBeforeArguments.PUntaint ((fun st -> st.Name), range) @@ -1313,7 +1453,7 @@ let TryLinkProvidedType(resolver: Tainted, moduleOrNamespace: str | NonNull v -> v else error(Error(FSComp.SR.etProvidedTypeReferenceMissingArgument spName, range0))) - + match TryApplyProvidedType(typeBeforeArguments, None, staticArgs, range0) with | Some (typeWithArguments, checkTypeName) -> @@ -1322,7 +1462,7 @@ let TryLinkProvidedType(resolver: Tainted, moduleOrNamespace: str | None -> None /// Get the parts of a .NET namespace. Special rules: null means global, empty is not allowed. -let GetPartsOfNamespaceRecover(namespaceName: string) = +let GetPartsOfNamespaceRecover(namespaceName: string MaybeNull) = match namespaceName with | Null -> [] | NonNull namespaceName -> @@ -1330,7 +1470,7 @@ let GetPartsOfNamespaceRecover(namespaceName: string) = else splitNamespace (nonNull namespaceName) /// Get the parts of a .NET namespace. Special rules: null means global, empty is not allowed. -let GetProvidedNamespaceAsPath (m, resolver: Tainted, namespaceName: string) = +let GetProvidedNamespaceAsPath (m, resolver: Tainted, namespaceName:string MaybeNull) = match namespaceName with | Null -> [] | NonNull namespaceName -> @@ -1343,7 +1483,7 @@ let GetFSharpPathToProvidedType (st: Tainted, range) = // Can't use st.Fullname because it may be like IEnumerable // We want [System;Collections;Generic] let namespaceParts = GetPartsOfNamespaceRecover(st.PUntaint((fun st -> st.Namespace), range)) - let rec walkUpNestedClasses(st: Tainted, soFar) = + let rec walkUpNestedClasses(st: Tainted, soFar) = match st with | Tainted.Null -> soFar | Tainted.NonNull st -> walkUpNestedClasses(st.PApply((fun st ->st.DeclaringType), range), soFar) @ [st.PUntaint((fun st -> st.Name), range)] @@ -1360,8 +1500,8 @@ let GetOriginalILAssemblyRefOfProvidedAssembly (assembly: Tainted, range) = - - let aref = GetOriginalILAssemblyRefOfProvidedAssembly (st.PApply((fun st -> st.Assembly), range), range) + + let aref = GetOriginalILAssemblyRefOfProvidedAssembly (st.PApply((fun st -> nonNull st.Assembly), range), range) // NULLNESS TODO: why is explicit instantiation needed here let scoperef = ILScopeRef.Assembly aref let enc, nm = ILPathToProvidedType (st, range) let tref = ILTypeRef.Create(scoperef, enc, nm) @@ -1380,7 +1520,6 @@ type ProviderGeneratedType = ProviderGeneratedType of ilOrigTyRef: ILTypeRef * i /// names in the statically linked, embedded assembly, plus what types are nested in side what types. type ProvidedAssemblyStaticLinkingMap = { ILTypeMap: Dictionary } - static member CreateNew() = { ILTypeMap = Dictionary() } diff --git a/src/Compiler/TypedTree/TypeProviders.fsi b/src/Compiler/TypedTree/TypeProviders.fsi index 770536dfd81..112b3a09c1b 100755 --- a/src/Compiler/TypedTree/TypeProviders.fsi +++ b/src/Compiler/TypedTree/TypeProviders.fsi @@ -9,6 +9,7 @@ module internal rec FSharp.Compiler.TypeProviders open System open System.Collections.Concurrent open System.Collections.Generic +open Internal.Utilities.Library open FSharp.Core.CompilerServices open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.Text @@ -90,7 +91,10 @@ type ProvidedTypeContext = /// Map the TyconRef objects, if any member RemapTyconRefs: (obj -> obj) -> ProvidedTypeContext -[] +[] +#if NO_CHECKNULLS +[] +#endif type ProvidedType = inherit ProvidedMemberInfo @@ -110,7 +114,7 @@ type ProvidedType = member Assembly: ProvidedAssembly - member BaseType: ProvidedType + member BaseType: ProvidedType MaybeNull member GetNestedType: string -> ProvidedType @@ -204,9 +208,10 @@ type ProvidedType = static member TaintedEquals: Tainted * Tainted -> bool +#if NO_CHECKNULLS [] +#endif type IProvidedCustomAttributeProvider = - abstract GetHasTypeProviderEditorHideMethodsAttribute: provider: ITypeProvider -> bool abstract GetDefinitionLocationAttribute: provider: ITypeProvider -> (string * int * int) option @@ -215,10 +220,12 @@ type IProvidedCustomAttributeProvider = abstract GetAttributeConstructorArgs: provider: ITypeProvider * attribName: string -> (obj option list * (string * obj option) list) option - -[] -type ProvidedAssembly = - + +[] +#if NO_CHECKNULLS +[] +#endif +type ProvidedAssembly = member GetName: unit -> System.Reflection.AssemblyName member FullName: string @@ -227,18 +234,23 @@ type ProvidedAssembly = member Handle: System.Reflection.Assembly -[] -type ProvidedMemberInfo = +[] +#if NO_CHECKNULLS +[] +#endif +type ProvidedMemberInfo = member Name: string - member DeclaringType: ProvidedType - - interface IProvidedCustomAttributeProvider + member DeclaringType: ProvidedType MaybeNull -[] -type ProvidedMethodBase = + interface IProvidedCustomAttributeProvider +[] +#if NO_CHECKNULLS +[] +#endif +type ProvidedMethodBase = inherit ProvidedMemberInfo member IsGenericMethod: bool @@ -273,8 +285,11 @@ type ProvidedMethodBase = static member TaintedEquals: Tainted * Tainted -> bool -[] -type ProvidedMethodInfo = +[] +#if NO_CHECKNULLS +[] +#endif +type ProvidedMethodInfo = inherit ProvidedMethodBase @@ -282,8 +297,11 @@ type ProvidedMethodInfo = member MetadataToken: int -[] -type ProvidedParameterInfo = +[] +#if NO_CHECKNULLS +[] +#endif +type ProvidedParameterInfo = member Name: string @@ -301,8 +319,11 @@ type ProvidedParameterInfo = interface IProvidedCustomAttributeProvider -[] -type ProvidedFieldInfo = +[] +#if NO_CHECKNULLS +[] +#endif +type ProvidedFieldInfo = inherit ProvidedMemberInfo @@ -330,8 +351,11 @@ type ProvidedFieldInfo = static member TaintedEquals: Tainted * Tainted -> bool -[] -type ProvidedPropertyInfo = +[] +#if NO_CHECKNULLS +[] +#endif +type ProvidedPropertyInfo = inherit ProvidedMemberInfo @@ -351,8 +375,11 @@ type ProvidedPropertyInfo = static member TaintedEquals: Tainted * Tainted -> bool -[] -type ProvidedEventInfo = +[] +#if NO_CHECKNULLS +[] +#endif +type ProvidedEventInfo = inherit ProvidedMemberInfo @@ -366,8 +393,11 @@ type ProvidedEventInfo = static member TaintedEquals: Tainted * Tainted -> bool -[] -type ProvidedConstructorInfo = +[] +#if NO_CHECKNULLS +[] +#endif +type ProvidedConstructorInfo = inherit ProvidedMethodBase type ProvidedExprType = @@ -411,8 +441,11 @@ type ProvidedExprType = | ProvidedIfThenElseExpr of ProvidedExpr * ProvidedExpr * ProvidedExpr | ProvidedVarExpr of ProvidedVar - -[] + +[] +#if NO_CHECKNULLS +[] +#endif type ProvidedExpr = member Type: ProvidedType @@ -422,7 +455,10 @@ type ProvidedExpr = member GetExprType: unit -> ProvidedExprType option -[] +[] +#if NO_CHECKNULLS +[] +#endif type ProvidedVar = member Type: ProvidedType diff --git a/src/Compiler/TypedTree/TypedTree.fs b/src/Compiler/TypedTree/TypedTree.fs index ec455fcbee8..6f897c7889a 100644 --- a/src/Compiler/TypedTree/TypedTree.fs +++ b/src/Compiler/TypedTree/TypedTree.fs @@ -300,7 +300,7 @@ type TyparRigidity = [] type TyparFlags(flags: int32) = - new (kind: TyparKind, rigidity: TyparRigidity, isFromError: bool, isCompGen: bool, staticReq: TyparStaticReq, dynamicReq: TyparDynamicReq, equalityDependsOn: bool, comparisonDependsOn: bool) = + new (kind: TyparKind, rigidity: TyparRigidity, isFromError: bool, isCompGen: bool, staticReq: TyparStaticReq, dynamicReq: TyparDynamicReq, equalityDependsOn: bool, comparisonDependsOn: bool, supportsNullFlex: bool) = TyparFlags((if isFromError then 0b00000000000000010 else 0) ||| (if isCompGen then 0b00000000000000100 else 0) ||| (match staticReq with @@ -321,7 +321,11 @@ type TyparFlags(flags: int32) = | TyparDynamicReq.No -> 0b00000000000000000 | TyparDynamicReq.Yes -> 0b00000010000000000) ||| (if equalityDependsOn then - 0b00000100000000000 else 0)) + 0b00000100000000000 else 0) ||| + // 0b00001000100000000 is being checked by x.Kind, but never set in this version of the code + // 0b00010000000000000 is taken by compat flex + (if supportsNullFlex then + 0b00100000000000000 else 0)) /// Indicates if the type inference variable was generated after an error when type checking expressions or patterns member x.IsFromError = (flags &&& 0b00000000000000010) <> 0x0 @@ -380,8 +384,20 @@ type TyparFlags(flags: int32) = else TyparFlags(flags &&& ~~~0b00010000000000000) + /// Indicates that whether this type parameter is flexible for 'supports null' constraint, e.g. in the case of assignment to a mutable value + member x.IsSupportsNullFlex = + (flags &&& 0b00100000000000000) <> 0x0 + + member x.WithSupportsNullFlex b = + if b then + TyparFlags(flags ||| 0b00100000000000000) + else + TyparFlags(flags &&& ~~~0b00100000000000000) + + + member x.WithStaticReq staticReq = - TyparFlags(x.Kind, x.Rigidity, x.IsFromError, x.IsCompilerGenerated, staticReq, x.DynamicReq, x.EqualityConditionalOn, x.ComparisonConditionalOn) + TyparFlags(x.Kind, x.Rigidity, x.IsFromError, x.IsCompilerGenerated, staticReq, x.DynamicReq, x.EqualityConditionalOn, x.ComparisonConditionalOn, x.IsSupportsNullFlex) /// Get the flags as included in the F# binary metadata. We pickle this as int64 to allow for future expansion member x.PickledBits = flags @@ -2238,6 +2254,9 @@ type TyparOptionalData = /// The declared attributes of the type parameter. Empty for type inference variables. mutable typar_attribs: Attribs + + /// Set to true if the typar is contravariant, i.e. declared as in C# + mutable typar_is_contravariant: bool } [] @@ -2321,6 +2340,8 @@ type Typar = /// Set whether this type parameter is a compat-flex type parameter (i.e. where "expr :> tp" only emits an optional warning) member x.SetIsCompatFlex b = x.typar_flags <- x.typar_flags.WithCompatFlex b + member x.SetSupportsNullFlex b = x.typar_flags <- x.typar_flags.WithSupportsNullFlex b + /// Indicates whether a type variable can be instantiated by types or units-of-measure. member x.Kind = x.typar_flags.Kind @@ -2337,10 +2358,10 @@ type Typar = member x.SetAttribs attribs = match attribs, x.typar_opt_data with | [], None -> () - | [], Some { typar_il_name = None; typar_xmldoc = doc; typar_constraints = [] } when doc.IsEmpty -> + | [], Some { typar_il_name = None; typar_xmldoc = doc; typar_constraints = []; typar_is_contravariant = false } when doc.IsEmpty -> x.typar_opt_data <- None | _, Some optData -> optData.typar_attribs <- attribs - | _ -> x.typar_opt_data <- Some { typar_il_name = None; typar_xmldoc = XmlDoc.Empty; typar_constraints = []; typar_attribs = attribs } + | _ -> x.typar_opt_data <- Some { typar_il_name = None; typar_xmldoc = XmlDoc.Empty; typar_constraints = []; typar_attribs = attribs; typar_is_contravariant = false } /// Get the XML documetnation for the type parameter member x.XmlDoc = @@ -2358,7 +2379,7 @@ type Typar = member x.SetILName il_name = match x.typar_opt_data with | Some optData -> optData.typar_il_name <- il_name - | _ -> x.typar_opt_data <- Some { typar_il_name = il_name; typar_xmldoc = XmlDoc.Empty; typar_constraints = []; typar_attribs = [] } + | _ -> x.typar_opt_data <- Some { typar_il_name = il_name; typar_xmldoc = XmlDoc.Empty; typar_constraints = []; typar_attribs = []; typar_is_contravariant = false } /// Indicates the display name of a type variable member x.DisplayName = if x.Name = "?" then "?"+string x.Stamp else x.Name @@ -2367,10 +2388,17 @@ type Typar = member x.SetConstraints cs = match cs, x.typar_opt_data with | [], None -> () - | [], Some { typar_il_name = None; typar_xmldoc = doc; typar_attribs = [] } when doc.IsEmpty -> + | [], Some { typar_il_name = None; typar_xmldoc = doc; typar_attribs = [];typar_is_contravariant = false } when doc.IsEmpty -> x.typar_opt_data <- None | _, Some optData -> optData.typar_constraints <- cs - | _ -> x.typar_opt_data <- Some { typar_il_name = None; typar_xmldoc = XmlDoc.Empty; typar_constraints = cs; typar_attribs = [] } + | _ -> x.typar_opt_data <- Some { typar_il_name = None; typar_xmldoc = XmlDoc.Empty; typar_constraints = cs; typar_attribs = []; typar_is_contravariant = false } + + /// Marks the typar as being contravariant + member x.MarkAsContravariant() = + match x.typar_opt_data with + | Some optData -> optData.typar_is_contravariant <- true + | _ -> + x.typar_opt_data <- Some { typar_il_name = None; typar_xmldoc = XmlDoc.Empty; typar_constraints = []; typar_attribs = []; typar_is_contravariant = true } /// Creates a type variable that contains empty data, and is not yet linked. Only used during unpickling of F# metadata. static member NewUnlinked() : Typar = @@ -2392,19 +2420,23 @@ type Typar = x.typar_solution <- tg.typar_solution match tg.typar_opt_data with | Some tg -> - let optData = { typar_il_name = tg.typar_il_name; typar_xmldoc = tg.typar_xmldoc; typar_constraints = tg.typar_constraints; typar_attribs = tg.typar_attribs } + let optData = { typar_il_name = tg.typar_il_name; typar_xmldoc = tg.typar_xmldoc; typar_constraints = tg.typar_constraints; typar_attribs = tg.typar_attribs; typar_is_contravariant = tg.typar_is_contravariant } x.typar_opt_data <- Some optData | None -> () /// Links a previously unlinked type variable to the given data. Only used during unpickling of F# metadata. - member x.AsType = - let ty = x.typar_astype - match box ty with - | null -> - let ty2 = TType_var (x, 0uy) - x.typar_astype <- ty2 - ty2 - | _ -> ty + member x.AsType nullness = + match nullness with + | Nullness.Known NullnessInfo.AmbivalentToNull -> + let ty = x.typar_astype + match box ty with + | null -> + let ty2 = TType_var (x, Nullness.Known NullnessInfo.AmbivalentToNull) + x.typar_astype <- ty2 + ty2 + | _ -> ty + | _ -> + TType_var (x, nullness) /// Indicates if a type variable has been linked. Only used during unpickling of F# metadata. member x.IsLinked = x.typar_stamp <> -1L @@ -2421,12 +2453,12 @@ type Typar = /// Sets the rigidity of a type variable member x.SetRigidity b = let flags = x.typar_flags - x.typar_flags <- TyparFlags(flags.Kind, b, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, flags.DynamicReq, flags.EqualityConditionalOn, flags.ComparisonConditionalOn) + x.typar_flags <- TyparFlags(flags.Kind, b, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, flags.DynamicReq, flags.EqualityConditionalOn, flags.ComparisonConditionalOn, flags.IsSupportsNullFlex) /// Sets whether a type variable is compiler generated member x.SetCompilerGenerated b = let flags = x.typar_flags - x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, b, flags.StaticReq, flags.DynamicReq, flags.EqualityConditionalOn, flags.ComparisonConditionalOn) + x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, b, flags.StaticReq, flags.DynamicReq, flags.EqualityConditionalOn, flags.ComparisonConditionalOn, flags.IsSupportsNullFlex) /// Sets whether a type variable has a static requirement member x.SetStaticReq b = @@ -2435,17 +2467,17 @@ type Typar = /// Sets whether a type variable is required at runtime member x.SetDynamicReq b = let flags = x.typar_flags - x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, b, flags.EqualityConditionalOn, flags.ComparisonConditionalOn) + x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, b, flags.EqualityConditionalOn, flags.ComparisonConditionalOn, flags.IsSupportsNullFlex) /// Sets whether the equality constraint of a type definition depends on this type variable member x.SetEqualityDependsOn b = let flags = x.typar_flags - x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, flags.DynamicReq, b, flags.ComparisonConditionalOn) + x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, flags.DynamicReq, b, flags.ComparisonConditionalOn, flags.IsSupportsNullFlex) /// Sets whether the comparison constraint of a type definition depends on this type variable member x.SetComparisonDependsOn b = let flags = x.typar_flags - x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, flags.DynamicReq, flags.EqualityConditionalOn, b) + x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, flags.DynamicReq, flags.EqualityConditionalOn, b, flags.IsSupportsNullFlex) [] member x.DebugText = x.ToString() @@ -2465,6 +2497,9 @@ type TyparConstraint = /// A constraint that a type has a 'null' value | SupportsNull of range: range + /// A constraint that a type doesn't support nullness + | NotSupportsNull of range + /// A constraint that a type has a member with the given signature | MayResolveMember of constraintInfo: TraitConstraintInfo * range: range @@ -4284,6 +4319,66 @@ type RecdFieldRef = override x.ToString() = x.FieldName +[] +type Nullness = + | Known of NullnessInfo + | Variable of NullnessVar + + member n.Evaluate() = + match n with + | Known info -> info + | Variable v -> v.Evaluate() + + member n.TryEvaluate() = + match n with + | Known info -> ValueSome info + | Variable v -> v.TryEvaluate() + + override n.ToString() = match n.Evaluate() with NullnessInfo.WithNull -> "?" | NullnessInfo.WithoutNull -> "" | NullnessInfo.AmbivalentToNull -> "%" + + member n.ToFsharpCodeString() = match n.Evaluate() with NullnessInfo.WithNull -> " | null " | NullnessInfo.WithoutNull -> "" | NullnessInfo.AmbivalentToNull -> "" + +// Note, nullness variables are only created if the nullness checking feature is on +[] +type NullnessVar() = + let mutable solution: Nullness option = None + + member nv.Evaluate() = + match solution with + | None -> NullnessInfo.WithoutNull + | Some soln -> soln.Evaluate() + + member nv.TryEvaluate() = + match solution with + | None -> ValueNone + | Some soln -> soln.TryEvaluate() + + member nv.IsSolved = solution.IsSome + + member nv.Set(nullness) = + assert (not nv.IsSolved) + solution <- Some nullness + + member nv.Unset() = + assert nv.IsSolved + solution <- None + + member nv.Solution = + assert nv.IsSolved + solution.Value + +[] +type NullnessInfo = + + /// we know that there is an extra null value in the type + | WithNull + + /// we know that there is no extra null value in the type + | WithoutNull + + /// we know we don't care + | AmbivalentToNull + /// Represents a type in the typed abstract syntax [] type TType = @@ -4291,10 +4386,10 @@ type TType = /// Indicates the type is a universal type, only used for types of values and members | TType_forall of typars: Typars * bodyTy: TType - /// Indicates the type is built from a named type and a number of type arguments. + /// TType_app(tyconRef, typeInstantiation, nullness). /// - /// 'flags' is a placeholder for future features, in particular nullness analysis - | TType_app of tyconRef: TyconRef * typeInstantiation: TypeInst * flags: byte + /// Indicates the type is built from a named type and a number of type arguments + | TType_app of tyconRef: TyconRef * typeInstantiation: TypeInst * nullness: Nullness /// Indicates the type is an anonymous record type whose compiled representation is located in the given assembly | TType_anon of anonInfo: AnonRecdTypeInfo * tys: TType list @@ -4302,10 +4397,10 @@ type TType = /// Indicates the type is a tuple type. elementTypes must be of length 2 or greater. | TType_tuple of tupInfo: TupInfo * elementTypes: TTypes - /// Indicates the type is a function type. + /// TType_fun(domainType, rangeType, nullness). /// - /// 'flags' is a placeholder for future features, in particular nullness analysis. - | TType_fun of domainType: TType * rangeType: TType * flags: byte + /// Indicates the type is a function type + | TType_fun of domainType: TType * rangeType: TType * nullness: Nullness /// Indicates the type is a non-F#-visible type representing a "proof" that a union value belongs to a particular union case /// These types are not user-visible and will never appear as an inferred type. They are the types given to @@ -4313,9 +4408,7 @@ type TType = | TType_ucase of unionCaseRef: UnionCaseRef * typeInstantiation: TypeInst /// Indicates the type is a variable type, whether declared, generalized or an inference type parameter - /// - /// 'flags' is a placeholder for future features, in particular nullness analysis - | TType_var of typar: Typar * flags: byte + | TType_var of typar: Typar * nullness: Nullness /// Indicates the type is a unit-of-measure expression being used as an argument to a type or member | TType_measure of measure: Measure @@ -4341,18 +4434,18 @@ type TType = override x.ToString() = match x with | TType_forall (_tps, ty) -> "forall ... " + ty.ToString() - | TType_app (tcref, tinst, _) -> tcref.DisplayName + (match tinst with [] -> "" | tys -> "<" + String.concat "," (List.map string tys) + ">") + | TType_app (tcref, tinst, nullness) -> tcref.DisplayName + (match tinst with [] -> "" | tys -> "<" + String.concat "," (List.map string tys) + ">") + nullness.ToString() | TType_tuple (tupInfo, tinst) -> (match tupInfo with | TupInfo.Const false -> "" | TupInfo.Const true -> "struct ") - + String.concat "," (List.map string tinst) + + String.concat "," (List.map string tinst) + ")" | TType_anon (anonInfo, tinst) -> (match anonInfo.TupInfo with | TupInfo.Const false -> "" | TupInfo.Const true -> "struct ") + "{|" + String.concat "," (Seq.map2 (fun nm ty -> nm + " " + string ty + ";") anonInfo.SortedNames tinst) + "|}" - | TType_fun (domainTy, retTy, _) -> "(" + string domainTy + " -> " + string retTy + ")" + | TType_fun (domainTy, retTy, nullness) -> "(" + string domainTy + " -> " + string retTy + ")" + nullness.ToString() | TType_ucase (uc, tinst) -> "ucase " + uc.CaseName + (match tinst with [] -> "" | tys -> "<" + String.concat "," (List.map string tys) + ">") | TType_var (tp, _) -> match tp.Solution with @@ -4433,7 +4526,7 @@ type AnonRecdTypeInfo = x.SortedNames <- sortedNames x.IlTypeName <- d.IlTypeName - member x.IsLinked = (match x.SortedIds with null -> true | _ -> false) + member x.IsLinked = (match box x.SortedIds with null -> true | _ -> false) member x.DisplayNameCoreByIdx idx = x.SortedNames[idx] @@ -5652,12 +5745,12 @@ type CcuThunk = /// Dereference the assembly reference member ccu.Deref = - if isNull (ccu.target :> obj) then + if isNull (box ccu.target) then raise(UnresolvedReferenceNoRange ccu.name) ccu.target /// Indicates if this assembly reference is unresolved - member ccu.IsUnresolvedReference = isNull (ccu.target :> obj) + member ccu.IsUnresolvedReference = isNull (box ccu.target) /// Ensure the ccu is derefable in advance. Supply a path to attach to any resulting error message. member ccu.EnsureDerefable(requiringPath: string[]) = @@ -5918,7 +6011,7 @@ type Construct() = let lazyBaseTy = LazyWithContext.Create ((fun (m, objTy) -> - let baseSystemTy = st.PApplyOption((fun st -> match st.BaseType with null -> None | ty -> Some ty), m) + let baseSystemTy = st.PApplyOption((fun st -> match st.BaseType with null -> None | ty -> Some (nonNull ty)), m) match baseSystemTy with | None -> objTy | Some t -> importProvidedType t), @@ -5932,7 +6025,9 @@ type Construct() = IsDelegate = (fun () -> st.PUntaint((fun st -> let baseType = st.BaseType match baseType with - | null -> false + | Null -> false + | NonNull x -> + match x with | x when x.IsGenericType -> false | x when x.DeclaringType <> null -> false | x -> x.FullName = "System.Delegate" || x.FullName = "System.MulticastDelegate"), m)) @@ -6051,13 +6146,13 @@ type Construct() = Typar.New { typar_id = id typar_stamp = newStamp() - typar_flags= TyparFlags(kind, rigid, isFromError, isCompGen, staticReq, dynamicReq, eqDep, compDep) + typar_flags= TyparFlags(kind, rigid, isFromError, isCompGen, staticReq, dynamicReq, eqDep, compDep, false) typar_solution = None typar_astype = Unchecked.defaultof<_> typar_opt_data = match attribs with | [] -> None - | _ -> Some { typar_il_name = None; typar_xmldoc = XmlDoc.Empty; typar_constraints = []; typar_attribs = attribs } } + | _ -> Some { typar_il_name = None; typar_xmldoc = XmlDoc.Empty; typar_constraints = []; typar_attribs = attribs; typar_is_contravariant = false } } /// Create a new type parameter node for a declared type parameter static member NewRigidTypar nm m = @@ -6234,8 +6329,8 @@ type Construct() = static member ComputeDefinitionLocationOfProvidedItem<'T when 'T :> IProvidedCustomAttributeProvider> (p: Tainted<'T>) : range option = let attrs = p.PUntaintNoFailure(fun x -> x.GetDefinitionLocationAttribute(p.TypeProvider.PUntaintNoFailure id)) match attrs with - | None | Some (null, _, _) -> None - | Some (filePath, line, column) -> + | None | Some (Null, _, _) -> None + | Some (NonNull filePath, line, column) -> // Coordinates from type provider are 1-based for lines and columns // Coordinates internally in the F# compiler are 1-based for lines and 0-based for columns let pos = Position.mkPos line (max 0 (column - 1)) diff --git a/src/Compiler/TypedTree/TypedTree.fsi b/src/Compiler/TypedTree/TypedTree.fsi index ca766220265..2abe8ed08f7 100644 --- a/src/Compiler/TypedTree/TypedTree.fsi +++ b/src/Compiler/TypedTree/TypedTree.fsi @@ -205,7 +205,8 @@ type TyparFlags = staticReq: Syntax.TyparStaticReq * dynamicReq: TyparDynamicReq * equalityDependsOn: bool * - comparisonDependsOn: bool -> + comparisonDependsOn: bool * + supportsNullFlex: bool -> TyparFlags new: flags: int32 -> TyparFlags @@ -232,6 +233,9 @@ type TyparFlags = /// Indicates if the type inference variable was generated after an error when type checking expressions or patterns member IsFromError: bool + /// Indicates whether this type parameter is flexible for 'supports null' constraint, e.g. in the case of assignment to a mutable value + member IsSupportsNullFlex: bool + /// Indicates whether a type variable can be instantiated by types or units-of-measure. member Kind: TyparKind @@ -1481,6 +1485,9 @@ type TyparOptionalData = /// The declared attributes of the type parameter. Empty for type inference variables. mutable typar_attribs: Attribs + + /// Set to true if the typar is contravariant, i.e. declared as in C# + mutable typar_is_contravariant: bool } override ToString: unit -> string @@ -1537,6 +1544,9 @@ type Typar = /// Adjusts the constraints associated with a type variable member SetConstraints: cs: TyparConstraint list -> unit + /// Marks the typar as being contravariant + member MarkAsContravariant: unit -> unit + /// Sets whether a type variable is required at runtime member SetDynamicReq: b: TyparDynamicReq -> unit @@ -1552,6 +1562,9 @@ type Typar = /// Set whether this type parameter is a compat-flex type parameter (i.e. where "expr :> tp" only emits an optional warning) member SetIsCompatFlex: b: bool -> unit + /// Set whether this type parameter is flexible for 'supports null' constraint, e.g. in the case of assignment to a mutable value + member SetSupportsNullFlex: b: bool -> unit + /// Sets the rigidity of a type variable member SetRigidity: b: TyparRigidity -> unit @@ -1561,7 +1574,7 @@ type Typar = override ToString: unit -> string /// Links a previously unlinked type variable to the given data. Only used during unpickling of F# metadata. - member AsType: TType + member AsType: nullness: Nullness -> TType /// The declared attributes of the type parameter. Empty for type inference variables type parameters from .NET. member Attribs: Attribs @@ -1646,6 +1659,9 @@ type TyparConstraint = /// A constraint that a type has a 'null' value | SupportsNull of range: range + /// A constraint that a type doesn't support nullness + | NotSupportsNull of range + /// A constraint that a type has a member with the given signature | MayResolveMember of constraintInfo: TraitConstraintInfo * range: range @@ -3052,6 +3068,39 @@ type RecdFieldRef = /// Get a reference to the type containing this record field member TyconRef: TyconRef +[] +type NullnessInfo = + + /// we know that there is an extra null value in the type + | WithNull + + /// we know that there is no extra null value in the type + | WithoutNull + + /// we know we don't care + | AmbivalentToNull + +[] +type Nullness = + | Known of NullnessInfo + | Variable of NullnessVar + + member Evaluate: unit -> NullnessInfo + + member TryEvaluate: unit -> NullnessInfo voption + + member ToFsharpCodeString: unit -> string + +[] +type NullnessVar = + new: unit -> NullnessVar + member Evaluate: unit -> NullnessInfo + member TryEvaluate: unit -> NullnessInfo voption + member IsSolved: bool + member Set: Nullness -> unit + member Unset: unit -> unit + member Solution: Nullness + /// Represents a type in the typed abstract syntax [] type TType = @@ -3062,7 +3111,7 @@ type TType = /// Indicates the type is built from a named type and a number of type arguments. /// /// 'flags' is a placeholder for future features, in particular nullness analysis - | TType_app of tyconRef: TyconRef * typeInstantiation: TypeInst * flags: byte + | TType_app of tyconRef: TyconRef * typeInstantiation: TypeInst * nullness: Nullness /// Indicates the type is an anonymous record type whose compiled representation is located in the given assembly | TType_anon of anonInfo: AnonRecdTypeInfo * tys: TType list @@ -3073,7 +3122,7 @@ type TType = /// Indicates the type is a function type. /// /// 'flags' is a placeholder for future features, in particular nullness analysis. - | TType_fun of domainType: TType * rangeType: TType * flags: byte + | TType_fun of domainType: TType * rangeType: TType * nullness: Nullness /// Indicates the type is a non-F#-visible type representing a "proof" that a union value belongs to a particular union case /// These types are not user-visible type will never appear as an inferred type. They are the types given to @@ -3083,7 +3132,7 @@ type TType = /// Indicates the type is a variable type, whether declared, generalized or an inference type parameter /// /// 'flags' is a placeholder for future features, in particular nullness analysis - | TType_var of typar: Typar * flags: byte + | TType_var of typar: Typar * nullness: Nullness /// Indicates the type is a unit-of-measure expression being used as an argument to a type or member | TType_measure of measure: Measure diff --git a/src/Compiler/TypedTree/TypedTreeBasics.fs b/src/Compiler/TypedTree/TypedTreeBasics.fs index ca2674f873f..c8268ffcf8a 100644 --- a/src/Compiler/TypedTree/TypedTreeBasics.fs +++ b/src/Compiler/TypedTree/TypedTreeBasics.fs @@ -182,15 +182,23 @@ let ccuOfTyconRef eref = // Type parameters and inference unknowns //------------------------------------------------------------------------- -let mkTyparTy (tp: Typar) = +let NewNullnessVar() = Nullness.Variable (NullnessVar()) // we don't known (and if we never find out then it's non-null) + +let KnownAmbivalentToNull = Nullness.Known NullnessInfo.AmbivalentToNull + +let KnownWithNull = Nullness.Known NullnessInfo.WithNull + +let KnownWithoutNull = Nullness.Known NullnessInfo.WithoutNull + +let mkTyparTy (tp:Typar) = match tp.Kind with - | TyparKind.Type -> tp.AsType + | TyparKind.Type -> tp.AsType KnownWithoutNull | TyparKind.Measure -> TType_measure (Measure.Var tp) // For fresh type variables clear the StaticReq when copying because the requirement will be re-established through the // process of type inference. let copyTypar clearStaticReq (tp: Typar) = - let optData = tp.typar_opt_data |> Option.map (fun tg -> { typar_il_name = tg.typar_il_name; typar_xmldoc = tg.typar_xmldoc; typar_constraints = tg.typar_constraints; typar_attribs = tg.typar_attribs }) + let optData = tp.typar_opt_data |> Option.map (fun tg -> { typar_il_name = tg.typar_il_name; typar_xmldoc = tg.typar_xmldoc; typar_constraints = tg.typar_constraints; typar_attribs = tg.typar_attribs; typar_is_contravariant = tg.typar_is_contravariant }) let flags = if clearStaticReq then tp.typar_flags.WithStaticReq(TyparStaticReq.None) else tp.typar_flags Typar.New { typar_id = tp.typar_id typar_flags = flags @@ -227,9 +235,71 @@ let rec stripUnitEqnsAux canShortcut unt = | Measure.Var r when r.IsSolved -> stripUnitEqnsAux canShortcut (tryShortcutSolvedUnitPar canShortcut r) | _ -> unt -let rec stripTyparEqnsAux canShortcut ty = +let combineNullness (nullnessOrig: Nullness) (nullnessNew: Nullness) = + match nullnessOrig, nullnessNew with + | Nullness.Variable _, Nullness.Known NullnessInfo.WithoutNull -> + nullnessOrig + | _ -> + match nullnessOrig.Evaluate() with + | NullnessInfo.WithoutNull -> nullnessNew + | NullnessInfo.AmbivalentToNull -> + match nullnessNew.Evaluate() with + | NullnessInfo.WithoutNull -> nullnessOrig + | NullnessInfo.AmbivalentToNull -> nullnessOrig + | NullnessInfo.WithNull -> nullnessNew + | NullnessInfo.WithNull -> + match nullnessNew.Evaluate() with + | NullnessInfo.WithoutNull -> nullnessOrig + | NullnessInfo.AmbivalentToNull -> nullnessNew + | NullnessInfo.WithNull -> nullnessOrig + +let nullnessEquiv (nullnessOrig: Nullness) (nullnessNew: Nullness) = LanguagePrimitives.PhysicalEquality nullnessOrig nullnessNew + +let tryAddNullnessToTy nullnessNew (ty:TType) = + match ty with + | TType_var (tp, nullnessOrig) -> + let nullnessAfter = combineNullness nullnessOrig nullnessNew + if nullnessEquiv nullnessAfter nullnessOrig then + Some ty + else + Some (TType_var (tp, nullnessAfter)) + | TType_app (tcr, tinst, nullnessOrig) -> + let nullnessAfter = combineNullness nullnessOrig nullnessNew + if nullnessEquiv nullnessAfter nullnessOrig then + Some ty + else + Some (TType_app (tcr, tinst, nullnessAfter)) + | TType_ucase _ -> None + | TType_tuple _ -> None + | TType_anon _ -> None + | TType_fun (d, r, nullnessOrig) -> + let nullnessAfter = combineNullness nullnessOrig nullnessNew + if nullnessEquiv nullnessAfter nullnessOrig then + Some ty + else + Some (TType_fun (d, r, nullnessAfter)) + | TType_forall _ -> None + | TType_measure _ -> None + +let addNullnessToTy (nullness: Nullness) (ty:TType) = + match nullness with + | Nullness.Known NullnessInfo.WithoutNull -> ty + | Nullness.Variable nv when nv.IsSolved && nv.Evaluate() = NullnessInfo.WithoutNull -> ty + | _ -> + match ty with + | TType_var (tp, nullnessOrig) -> TType_var (tp, combineNullness nullnessOrig nullness) + | TType_app (tcr, tinst, nullnessOrig) -> + let tycon = tcr.Deref + if tycon.IsStructRecordOrUnionTycon || tycon.IsStructOrEnumTycon then + ty + else + TType_app (tcr, tinst, combineNullness nullnessOrig nullness) + | TType_fun (d, r, nullnessOrig) -> TType_fun (d, r, combineNullness nullnessOrig nullness) + | _ -> ty + +let rec stripTyparEqnsAux nullness0 canShortcut ty = match ty with - | TType_var (r, _) -> + | TType_var (r, nullness) -> match r.Solution with | Some soln -> if canShortcut then @@ -238,23 +308,33 @@ let rec stripTyparEqnsAux canShortcut ty = // This is only because IterType likes to walk _all_ the constraints _everywhere_ in a type, including // those attached to _solved_ type variables. In an ideal world this would never be needed - see the notes // on IterType. - | TType_var (r2, _) when r2.Constraints.IsEmpty -> - match r2.Solution with - | None -> () - | Some _ as soln2 -> - r.typar_solution <- soln2 + | TType_var (r2, nullness2) when r2.Constraints.IsEmpty -> + match nullness2.Evaluate() with + | NullnessInfo.WithoutNull -> + match r2.Solution with + | None -> () + | Some _ as soln2 -> + r.typar_solution <- soln2 + | _ -> () | _ -> () - stripTyparEqnsAux canShortcut soln + stripTyparEqnsAux (combineNullness nullness0 nullness) canShortcut soln | None -> - ty + addNullnessToTy nullness0 ty | TType_measure unt -> TType_measure (stripUnitEqnsAux canShortcut unt) - | _ -> ty + | _ -> addNullnessToTy nullness0 ty -let stripTyparEqns ty = stripTyparEqnsAux false ty +let stripTyparEqns ty = stripTyparEqnsAux KnownWithoutNull false ty let stripUnitEqns unt = stripUnitEqnsAux false unt +let replaceNullnessOfTy nullness (ty:TType) = + match stripTyparEqns ty with + | TType_var (tp, _) -> TType_var (tp, nullness) + | TType_app (tcr, tinst, _) -> TType_app (tcr, tinst, nullness) + | TType_fun (d, r, _) -> TType_fun (d, r, nullness) + | sty -> sty + /// Detect a use of a nominal type, including type abbreviations. [] let (|AbbrevOrAppTy|_|) (ty: TType) = diff --git a/src/Compiler/TypedTree/TypedTreeBasics.fsi b/src/Compiler/TypedTree/TypedTreeBasics.fsi index 001e4129d06..c064be67c9e 100644 --- a/src/Compiler/TypedTree/TypedTreeBasics.fsi +++ b/src/Compiler/TypedTree/TypedTreeBasics.fsi @@ -118,6 +118,20 @@ val ccuOfValRef: vref: ValRef -> CcuThunk option val ccuOfTyconRef: eref: EntityRef -> CcuThunk option +val NewNullnessVar: unit -> Nullness + +val KnownAmbivalentToNull: Nullness + +val KnownWithNull: Nullness + +val KnownWithoutNull: Nullness + +val combineNullness: Nullness -> Nullness -> Nullness + +val tryAddNullnessToTy: Nullness -> TType -> TType option + +val addNullnessToTy: Nullness -> TType -> TType + val mkTyparTy: tp: Typar -> TType val copyTypars: clearStaticReq: bool -> tps: Typar list -> Typar list @@ -126,7 +140,9 @@ val tryShortcutSolvedUnitPar: canShortcut: bool -> r: Typar -> Measure val stripUnitEqnsAux: canShortcut: bool -> unt: Measure -> Measure -val stripTyparEqnsAux: canShortcut: bool -> ty: TType -> TType +val stripTyparEqnsAux: nullness0: Nullness -> canShortcut: bool -> ty: TType -> TType + +val replaceNullnessOfTy: nullness: Nullness -> ty: TType -> TType val stripTyparEqns: ty: TType -> TType diff --git a/src/Compiler/TypedTree/TypedTreeOps.fs b/src/Compiler/TypedTree/TypedTreeOps.fs index 120baae8461..81466446bde 100644 --- a/src/Compiler/TypedTree/TypedTreeOps.fs +++ b/src/Compiler/TypedTree/TypedTreeOps.fs @@ -166,8 +166,9 @@ let generalizeTypars tps = List.map generalizeTypar tps let rec remapTypeAux (tyenv: Remap) (ty: TType) = let ty = stripTyparEqns ty match ty with - | TType_var (tp, _) as ty -> - instTyparRef tyenv.tpinst ty tp + | TType_var (tp, nullness) as ty -> + let res = instTyparRef tyenv.tpinst ty tp + addNullnessToTy nullness res | TType_app (tcref, tinst, flags) as ty -> match tyenv.tyconRefRemap.TryFind tcref with @@ -257,6 +258,7 @@ and remapTyparConstraintsAux tyenv cs = | TyparConstraint.SupportsComparison _ | TyparConstraint.SupportsEquality _ | TyparConstraint.SupportsNull _ + | TyparConstraint.NotSupportsNull _ | TyparConstraint.IsUnmanaged _ | TyparConstraint.IsNonNullableStruct _ | TyparConstraint.IsReferenceType _ @@ -622,12 +624,12 @@ let mkByrefTyWithInference (g: TcGlobals) ty1 ty2 = else TType_app (g.byref_tcr, [ty1], g.knownWithoutNull) -let mkArrayTy (g: TcGlobals) rank ty m = +let mkArrayTy (g: TcGlobals) rank nullness ty m = if rank < 1 || rank > 32 then errorR(Error(FSComp.SR.tastopsMaxArrayThirtyTwo rank, m)) - TType_app (g.il_arr_tcr_map[3], [ty], g.knownWithoutNull) + TType_app (g.il_arr_tcr_map[3], [ty], nullness) else - TType_app (g.il_arr_tcr_map[rank - 1], [ty], g.knownWithoutNull) + TType_app (g.il_arr_tcr_map[rank - 1], [ty], nullness) //-------------------------------------------------------------------------- // Tuple compilation (types) @@ -718,7 +720,7 @@ let reduceTyconMeasureableOrProvided (g: TcGlobals) (tycon: Tycon) tyargs = | TMeasureableRepr ty -> if isNil tyargs then ty else instType (mkTyconInst tycon tyargs) ty #if !NO_TYPEPROVIDERS - | TProvidedTypeRepr info when info.IsErased -> info.BaseTypeForErased (range0, g.obj_ty) + | TProvidedTypeRepr info when info.IsErased -> info.BaseTypeForErased (range0, g.obj_ty_withNulls) #endif | _ -> invalidArg "tc" "this type definition is not a refinement" @@ -726,13 +728,15 @@ let reduceTyconRefMeasureableOrProvided (g: TcGlobals) (tcref: TyconRef) tyargs reduceTyconMeasureableOrProvided g tcref.Deref tyargs let rec stripTyEqnsA g canShortcut ty = - let ty = stripTyparEqnsAux canShortcut ty + let ty = stripTyparEqnsAux KnownWithoutNull canShortcut ty match ty with - | TType_app (tcref, tinst, _) -> + | TType_app (tcref, tinst, nullness) -> let tycon = tcref.Deref match tycon.TypeAbbrev with | Some abbrevTy -> - stripTyEqnsA g canShortcut (applyTyconAbbrev abbrevTy tycon tinst) + let reducedTy = applyTyconAbbrev abbrevTy tycon tinst + let reducedTy2 = addNullnessToTy nullness reducedTy + stripTyEqnsA g canShortcut reducedTy2 | None -> // This is the point where we get to add additional conditional normalizing equations // into the type system. Such power! @@ -744,7 +748,9 @@ let rec stripTyEqnsA g canShortcut ty = // Add the equation double<1> = double for units of measure. elif tycon.IsMeasureableReprTycon && List.forall (isDimensionless g) tinst then - stripTyEqnsA g canShortcut (reduceTyconMeasureableOrProvided g tycon tinst) + let reducedTy = reduceTyconMeasureableOrProvided g tycon tinst + let reducedTy2 = addNullnessToTy nullness reducedTy + stripTyEqnsA g canShortcut reducedTy2 else ty | ty -> ty @@ -765,17 +771,19 @@ let evalAnonInfoIsStruct (anonInfo: AnonRecdTypeInfo) = let rec stripTyEqnsAndErase eraseFuncAndTuple (g: TcGlobals) ty = let ty = stripTyEqns g ty match ty with - | TType_app (tcref, args, _) -> + | TType_app (tcref, args, nullness) -> let tycon = tcref.Deref - if tycon.IsErased then - stripTyEqnsAndErase eraseFuncAndTuple g (reduceTyconMeasureableOrProvided g tycon args) + if tycon.IsErased then + let reducedTy = reduceTyconMeasureableOrProvided g tycon args + let reducedTy2 = addNullnessToTy nullness reducedTy + stripTyEqnsAndErase eraseFuncAndTuple g reducedTy2 elif tyconRefEq g tcref g.nativeptr_tcr && eraseFuncAndTuple then stripTyEqnsAndErase eraseFuncAndTuple g g.nativeint_ty else ty - | TType_fun(domainTy, rangeTy, flags) when eraseFuncAndTuple -> - TType_app(g.fastFunc_tcr, [ domainTy; rangeTy ], flags) + | TType_fun(domainTy, rangeTy, nullness) when eraseFuncAndTuple -> + TType_app(g.fastFunc_tcr, [ domainTy; rangeTy ], nullness) | TType_tuple(tupInfo, l) when eraseFuncAndTuple -> mkCompiledTupleTy g (evalTupInfoIsStruct tupInfo) l @@ -855,7 +863,7 @@ let isMeasureTy g ty = ty |> stripTyEqns g |> (function TType_measure _ -> true let isProvenUnionCaseTy ty = match ty with TType_ucase _ -> true | _ -> false -let mkAppTy tcref tyargs = TType_app(tcref, tyargs, 0uy) +let mkWoNullAppTy tcref tyargs = TType_app(tcref, tyargs, KnownWithoutNull) let mkProvenUnionCaseTy ucref tyargs = TType_ucase(ucref, tyargs) @@ -891,14 +899,14 @@ let (|RefTupleTy|_|) g ty = ty |> stripTyEqns g |> (function TType_tuple(tupInfo let (|FunTy|_|) g ty = ty |> stripTyEqns g |> (function TType_fun(domainTy, rangeTy, _) -> ValueSome (domainTy, rangeTy) | _ -> ValueNone) let tryNiceEntityRefOfTy ty = - let ty = stripTyparEqnsAux false ty + let ty = stripTyparEqnsAux KnownWithoutNull false ty match ty with | TType_app (tcref, _, _) -> ValueSome tcref | TType_measure (Measure.Const tcref) -> ValueSome tcref | _ -> ValueNone let tryNiceEntityRefOfTyOption ty = - let ty = stripTyparEqnsAux false ty + let ty = stripTyparEqnsAux KnownWithoutNull false ty match ty with | TType_app (tcref, _, _) -> Some tcref | TType_measure (Measure.Const tcref) -> Some tcref @@ -918,7 +926,7 @@ let convertToTypeWithMetadataIfPossible g ty = mkOuterCompiledTupleTy g (evalTupInfoIsStruct tupInfo) tupElemTys elif isFunTy g ty then let a,b = destFunTy g ty - mkAppTy g.fastFunc_tcr [a; b] + mkWoNullAppTy g.fastFunc_tcr [a; b] else ty //--------------------------------------------------------------------------- @@ -927,9 +935,9 @@ let convertToTypeWithMetadataIfPossible g ty = let stripMeasuresFromTy g ty = match ty with - | TType_app(tcref, tinst, flags) -> + | TType_app(tcref, tinst, nullness) -> let tinstR = tinst |> List.filter (isMeasureTy g >> not) - TType_app(tcref, tinstR, flags) + TType_app(tcref, tinstR, nullness) | _ -> ty //--------------------------------------------------------------------------- @@ -1014,6 +1022,7 @@ and typarConstraintsAEquivAux erasureFlag g aenv tpc1 tpc2 = | TyparConstraint.SupportsComparison _, TyparConstraint.SupportsComparison _ | TyparConstraint.SupportsEquality _, TyparConstraint.SupportsEquality _ | TyparConstraint.SupportsNull _, TyparConstraint.SupportsNull _ + | TyparConstraint.NotSupportsNull _, TyparConstraint.NotSupportsNull _ | TyparConstraint.IsNonNullableStruct _, TyparConstraint.IsNonNullableStruct _ | TyparConstraint.IsReferenceType _, TyparConstraint.IsReferenceType _ | TyparConstraint.IsUnmanaged _, TyparConstraint.IsUnmanaged _ @@ -1040,7 +1049,7 @@ and typeAEquivAux erasureFlag g aenv ty1 ty2 = | TType_forall(tps1, rty1), TType_forall(tps2, retTy2) -> typarsAEquivAux erasureFlag g aenv tps1 tps2 && typeAEquivAux erasureFlag g (aenv.BindEquivTypars tps1 tps2) rty1 retTy2 - | TType_var (tp1, _), TType_var (tp2, _) when typarEq tp1 tp2 -> + | TType_var (tp1, _), TType_var (tp2, _) when typarEq tp1 tp2 -> // NOTE: nullness annotations are ignored for type equivalence true | TType_var (tp1, _), _ -> @@ -1048,7 +1057,8 @@ and typeAEquivAux erasureFlag g aenv ty1 ty2 = | Some tpTy1 -> typeEquivAux erasureFlag g tpTy1 ty2 | None -> false - | TType_app (tcref1, tinst1, _), TType_app (tcref2, tinst2, _) -> + // NOTE: nullness annotations are ignored for type equivalence + | TType_app (tcref1, tinst1, _), TType_app (tcref2, tinst2, _) -> tcrefAEquiv g aenv tcref1 tcref2 && typesAEquivAux erasureFlag g aenv tinst1 tinst2 @@ -1060,13 +1070,14 @@ and typeAEquivAux erasureFlag g aenv ty1 ty2 = | TType_tuple (tupInfo1, l1), TType_tuple (tupInfo2, l2) -> structnessAEquiv tupInfo1 tupInfo2 && typesAEquivAux erasureFlag g aenv l1 l2 + // NOTE: nullness annotations are ignored for type equivalence + | TType_fun (domainTy1, rangeTy1, _), TType_fun (domainTy2, rangeTy2, _) -> + typeAEquivAux erasureFlag g aenv domainTy1 domainTy2 && typeAEquivAux erasureFlag g aenv rangeTy1 rangeTy2 + | TType_anon (anonInfo1, l1), TType_anon (anonInfo2, l2) -> anonInfoEquiv anonInfo1 anonInfo2 && typesAEquivAux erasureFlag g aenv l1 l2 - | TType_fun (domainTy1, rangeTy1, _), TType_fun (domainTy2, rangeTy2, _) -> - typeAEquivAux erasureFlag g aenv domainTy1 domainTy2 && typeAEquivAux erasureFlag g aenv rangeTy1 rangeTy2 - | TType_measure m1, TType_measure m2 -> match erasureFlag with | EraseNone -> measureAEquiv g aenv m1 m2 @@ -1074,6 +1085,18 @@ and typeAEquivAux erasureFlag g aenv ty1 ty2 = | _ -> false +and nullnessSensitivetypeAEquivAux erasureFlag g aenv ty1 ty2 = + let ty1 = stripTyEqnsWrtErasure erasureFlag g ty1 + let ty2 = stripTyEqnsWrtErasure erasureFlag g ty2 + match ty1, ty2 with + | TType_var (_,n1), TType_var (_,n2) + | TType_app (_,_,n1), TType_app (_,_,n2) + | TType_fun (_,_,n1), TType_fun (_,_,n2) -> + n1 === n2 + | _ -> true + + && typeAEquivAux erasureFlag g aenv ty1 ty2 + and anonInfoEquiv (anonInfo1: AnonRecdTypeInfo) (anonInfo2: AnonRecdTypeInfo) = ccuEq anonInfo1.Assembly anonInfo2.Assembly && structnessAEquiv anonInfo1.TupInfo anonInfo2.TupInfo && @@ -1133,18 +1156,30 @@ let isErasedType g ty = | _ -> false // Return all components of this type expression that cannot be tested at runtime -let rec getErasedTypes g ty = +let rec getErasedTypes g ty checkForNullness = let ty = stripTyEqns g ty if isErasedType g ty then [ty] else match ty with | TType_forall(_, bodyTy) -> - getErasedTypes g bodyTy - | TType_var (tp, _) -> - if tp.IsErased then [ty] else [] - | TType_app (_, b, _) | TType_ucase(_, b) | TType_anon (_, b) | TType_tuple (_, b) -> - List.foldBack (fun ty tys -> getErasedTypes g ty @ tys) b [] - | TType_fun (domainTy, rangeTy, _) -> - getErasedTypes g domainTy @ getErasedTypes g rangeTy + getErasedTypes g bodyTy checkForNullness + + | TType_var (tp, nullness) -> + match checkForNullness, nullness.Evaluate() with + | true, NullnessInfo.WithNull -> [ty] // with-null annotations can't be tested at runtime, Nullabe<> is not part of Nullness feature as of now. + | _ -> if tp.IsErased then [ty] else [] + + | TType_app (_, b, nullness) -> + match checkForNullness, nullness.Evaluate() with + | true, NullnessInfo.WithNull -> [ty] + | _ -> List.foldBack (fun ty tys -> getErasedTypes g ty false @ tys) b [] + + | TType_ucase(_, b) | TType_anon (_, b) | TType_tuple (_, b) -> + List.foldBack (fun ty tys -> getErasedTypes g ty false @ tys) b [] + + | TType_fun (domainTy, rangeTy, nullness) -> + match checkForNullness, nullness.Evaluate() with + | true, NullnessInfo.WithNull -> [ty] + | _ -> getErasedTypes g domainTy false @ getErasedTypes g rangeTy false | TType_measure _ -> [ty] @@ -1823,6 +1858,7 @@ let isInByrefTy g ty = | _ -> false) let isOutByrefTag g ty = ty |> stripTyEqns g |> (function TType_app(tcref, [], _) -> tyconRefEq g g.byrefkind_Out_tcr tcref | _ -> false) + let isOutByrefTy g ty = ty |> stripTyEqns g |> (function | TType_app(tcref, [_; tagTy], _) when g.byref2_tcr.CanDeref -> tyconRefEq g g.byref2_tcr tcref && isOutByrefTag g tagTy @@ -2289,6 +2325,7 @@ and accFreeInTyparConstraint opts tpc acc = | TyparConstraint.SupportsComparison _ | TyparConstraint.SupportsEquality _ | TyparConstraint.SupportsNull _ + | TyparConstraint.NotSupportsNull _ | TyparConstraint.IsNonNullableStruct _ | TyparConstraint.IsReferenceType _ | TyparConstraint.IsUnmanaged _ @@ -2424,6 +2461,7 @@ and accFreeInTyparConstraintLeftToRight g cxFlag thruFlag acc tpc = | TyparConstraint.SupportsComparison _ | TyparConstraint.SupportsEquality _ | TyparConstraint.SupportsNull _ + | TyparConstraint.NotSupportsNull _ | TyparConstraint.IsNonNullableStruct _ | TyparConstraint.IsUnmanaged _ | TyparConstraint.IsReferenceType _ @@ -2472,7 +2510,7 @@ and accFreeInTypeLeftToRight g cxFlag thruFlag acc ty = let racc = accFreeInTypeLeftToRight g cxFlag thruFlag emptyFreeTyparsLeftToRight r unionFreeTyparsLeftToRight (boundTyparsLeftToRight g cxFlag thruFlag tps racc) acc - | TType_measure unt -> + | TType_measure unt -> let mvars = ListMeasureVarOccsWithNonZeroExponents unt List.foldBack (fun (tp, _) acc -> accFreeTyparRefLeftToRight g cxFlag thruFlag acc tp) mvars acc @@ -2810,7 +2848,10 @@ let generalizedTyconRef (g: TcGlobals) tcref = let tinst = generalTyconRefInst tcref TType_app(tcref, tinst, g.knownWithoutNull) -let isTTyparCoercesToType = function TyparConstraint.CoercesTo _ -> true | _ -> false +let isTTyparCoercesToType tpc = + match tpc with + | TyparConstraint.CoercesTo _ -> true + | _ -> false //-------------------------------------------------------------------------- // Print Signatures/Types - prelude @@ -3103,6 +3144,7 @@ type DisplayEnv = showAttributes: bool showOverrides: bool showStaticallyResolvedTyparAnnotations: bool + showNullnessAnnotations: bool option abbreviateAdditionalConstraints: bool showTyparDefaultConstraints: bool showDocumentation: bool @@ -3137,6 +3179,7 @@ type DisplayEnv = showAttributes = false showOverrides = true showStaticallyResolvedTyparAnnotations = true + showNullnessAnnotations = None showDocumentation = false abbreviateAdditionalConstraints = false showTyparDefaultConstraints = false @@ -3387,7 +3430,7 @@ let trimPathByDisplayEnv denv path = let superOfTycon (g: TcGlobals) (tycon: Tycon) = match tycon.TypeContents.tcaug_super with - | None -> g.obj_ty + | None -> g.obj_ty_noNulls | Some ty -> ty /// walk a TyconRef's inheritance tree, yielding any parent types as an array @@ -3466,6 +3509,19 @@ let TryFindFSharpStringAttribute g nm attrs = match TryFindFSharpAttribute g nm attrs with | Some(Attrib(_, _, [ AttribStringArg b ], _, _, _, _)) -> Some b | _ -> None + +let TryFindLocalizedFSharpStringAttribute g nm attrs = + match TryFindFSharpAttribute g nm attrs with + | Some(Attrib(_, _, [ AttribStringArg b ], namedArgs, _, _, _)) -> + match namedArgs with + | ExtractAttribNamedArg "Localize" (AttribBoolArg true) -> + #if PROTO || BUILDING_WITH_LKG + Some b + #else + FSComp.SR.GetTextOpt(b) + #endif + | _ -> Some b + | _ -> None let TryFindILAttribute (AttribInfo (atref, _)) attrs = HasILAttribute atref attrs @@ -3475,6 +3531,9 @@ let TryFindILAttributeOpt attr attrs = | Some (AttribInfo (atref, _)) -> HasILAttribute atref attrs | _ -> false +let IsILAttrib (AttribInfo (builtInAttrRef, _)) attr = isILAttrib builtInAttrRef attr + + /// Analyze three cases for attributes declared on type definitions: IL-declared attributes, F#-declared attributes and /// provided attributes. // @@ -4005,32 +4064,44 @@ module DebugPrint = else tupleL tinstL ^^ tcL + and auxAddNullness coreL (nullness: Nullness) = + match nullness.Evaluate() with + | NullnessInfo.WithNull -> coreL ^^ wordL (tagText "?") + | NullnessInfo.WithoutNull -> coreL + | NullnessInfo.AmbivalentToNull -> coreL //^^ wordL (tagText "%") + and auxTypeWrapL env isAtomic ty = let wrap x = bracketIfL isAtomic x in // wrap iff require atomic expr match stripTyparEqns ty with | TType_forall (typars, bodyTy) -> (leftL (tagText "!") ^^ layoutTyparDecls typars --- auxTypeL env bodyTy) |> wrap - | TType_ucase (UnionCaseRef(tcref, _), tinst) - - | TType_app (tcref, tinst, _) -> + | TType_ucase (UnionCaseRef(tcref, _), tinst) -> let prefix = tcref.IsPrefixDisplay let tcL = layoutTyconRef tcref auxTyparsL env tcL prefix tinst + | TType_app (tcref, tinst, nullness) -> + let prefix = tcref.IsPrefixDisplay + let tcL = layoutTyconRef tcref + let coreL = auxTyparsL env tcL prefix tinst + auxAddNullness coreL nullness + | TType_tuple (_tupInfo, tys) -> sepListL (wordL (tagText "*")) (List.map (auxTypeAtomL env) tys) |> wrap - | TType_fun (domainTy, rangeTy, _) -> - ((auxTypeAtomL env domainTy ^^ wordL (tagText "->")) --- auxTypeL env rangeTy) |> wrap + | TType_fun (domainTy, rangeTy, nullness) -> + let coreL = ((auxTypeAtomL env domainTy ^^ wordL (tagText "->")) --- auxTypeL env rangeTy) |> wrap + auxAddNullness coreL nullness - | TType_var (typar, _) -> - auxTyparWrapL env isAtomic typar + | TType_var (typar, nullness) -> + let coreL = auxTyparWrapL env isAtomic typar + auxAddNullness coreL nullness | TType_anon (anonInfo, tys) -> - braceBarL (sepListL (wordL (tagText ";")) (List.map2 (fun nm ty -> wordL (tagField nm) --- auxTypeAtomL env ty) (Array.toList anonInfo.SortedNames) tys)) + braceBarL (sepListL (wordL (tagText ";")) (List.map2 (fun nm ty -> wordL (tagField nm) --- auxTypeAtomL env ty) (Array.toList anonInfo.SortedNames) tys)) - | TType_measure unt -> + | TType_measure unt -> #if DEBUG leftL (tagText "{") ^^ (match global_g with @@ -4130,6 +4201,8 @@ module DebugPrint = wordL (tagText "struct") |> constraintPrefix | TyparConstraint.IsReferenceType _ -> wordL (tagText "not struct") |> constraintPrefix + | TyparConstraint.NotSupportsNull _ -> + wordL (tagText "not null") |> constraintPrefix | TyparConstraint.IsUnmanaged _ -> wordL (tagText "unmanaged") |> constraintPrefix | TyparConstraint.SimpleChoice(tys, _) -> @@ -6153,7 +6226,7 @@ and remapTyconRepr ctxt tmenv repr = | TProvidedTypeRepr info -> TProvidedTypeRepr { info with - LazyBaseType = info.LazyBaseType.Force (range0, ctxt.g.obj_ty) |> remapType tmenv |> LazyWithContext.NotLazy + LazyBaseType = info.LazyBaseType.Force (range0, ctxt.g.obj_ty_withNulls) |> remapType tmenv |> LazyWithContext.NotLazy // The load context for the provided type contains TyconRef objects. We must remap these. // This is actually done on-demand (see the implementation of ProvidedTypeContext) ProvidedType = @@ -6630,7 +6703,7 @@ let rec tyOfExpr g expr = | TOp.ILCall (_, _, _, _, _, _, _, _, _, _, retTypes) | TOp.ILAsm (_, retTypes) -> (match retTypes with [h] -> h | _ -> g.unit_ty) | TOp.UnionCase uc -> actualResultTyOfUnionCase tinst uc | TOp.UnionCaseProof uc -> mkProvenUnionCaseTy uc tinst - | TOp.Recd (_, tcref) -> mkAppTy tcref tinst + | TOp.Recd (_, tcref) -> mkWoNullAppTy tcref tinst | TOp.ExnConstr _ -> g.exn_ty | TOp.Bytes _ -> mkByteArrayTy g | TOp.UInt16s _ -> mkArrayType g g.uint16_ty @@ -7620,7 +7693,7 @@ let permuteExprList (sigma: int[]) (exprs: Expr list) (ty: TType list) (names: s /// We still need to sort by index. let mkRecordExpr g (lnk, tcref, tinst, unsortedRecdFields: RecdFieldRef list, unsortedFieldExprs, m) = // Remove any abbreviations - let tcref, tinst = destAppTy g (mkAppTy tcref tinst) + let tcref, tinst = destAppTy g (mkWoNullAppTy tcref tinst) let sortedRecdFields = unsortedRecdFields |> List.indexed |> Array.ofList |> Array.sortBy (fun (_, r) -> r.Index) let sigma = Array.create sortedRecdFields.Length -1 @@ -7909,9 +7982,9 @@ let TryEliminateDesugaredConstants g m c = | _ -> None -let mkSeqTy (g: TcGlobals) ty = mkAppTy g.seq_tcr [ty] +let mkSeqTy (g: TcGlobals) ty = mkWoNullAppTy g.seq_tcr [ty] -let mkIEnumeratorTy (g: TcGlobals) ty = mkAppTy g.tcref_System_Collections_Generic_IEnumerator [ty] +let mkIEnumeratorTy (g: TcGlobals) ty = mkWoNullAppTy g.tcref_System_Collections_Generic_IEnumerator [ty] let mkCallSeqCollect g m alphaTy betaTy arg1 arg2 = let enumty2 = try rangeOfFunTy g (tyOfExpr g arg1) with _ -> (* defensive programming *) (mkSeqTy g betaTy) @@ -8839,6 +8912,9 @@ let typarEnc _g (gtpsType, gtpsMethod) typar = warning(InternalError("Typar not found during XmlDoc generation", typar.Range)) "``0" +let nullnessEnc (g:TcGlobals) (nullness:Nullness) = + if g.renderNullnessAnnotations then nullness.ToFsharpCodeString() else "" + let rec typeEnc g (gtpsType, gtpsMethod) ty = let stripped = stripTyEqnsAndMeasureEqns g ty match stripped with @@ -8853,26 +8929,26 @@ let rec typeEnc g (gtpsType, gtpsMethod) ty = let ety = destNativePtrTy g ty typeEnc g (gtpsType, gtpsMethod) ety + "*" - | _ when isArrayTy g ty -> - let tcref, tinst = destAppTy g ty + | TType_app (_, _, nullness) when isArrayTy g ty -> + let tcref, tinst = destAppTy g ty let rank = rankOfArrayTyconRef g tcref let arraySuffix = "[" + String.concat ", " (List.replicate (rank-1) "0:") + "]" - typeEnc g (gtpsType, gtpsMethod) (List.head tinst) + arraySuffix + typeEnc g (gtpsType, gtpsMethod) (List.head tinst) + arraySuffix + nullnessEnc g nullness | TType_ucase (_, tinst) | TType_app (_, tinst, _) -> - let tyName = + let tyName,nullness = let ty = stripTyEqnsAndMeasureEqns g ty match ty with - | TType_app (tcref, _tinst, _) -> + | TType_app (tcref, _tinst, nullness) -> // Generic type names are (name + "`" + digits) where name does not contain "`". // In XML doc, when used in type instances, these do not use the ticks. let path = Array.toList (fullMangledPathToTyconRef tcref) @ [tcref.CompiledName] - textOfPath (List.map DemangleGenericTypeName path) + textOfPath (List.map DemangleGenericTypeName path),nullness | _ -> assert false failwith "impossible" - tyName + tyargsEnc g (gtpsType, gtpsMethod) tinst + tyName + tyargsEnc g (gtpsType, gtpsMethod) tinst + nullnessEnc g nullness | TType_anon (anonInfo, tinst) -> sprintf "%s%s" anonInfo.ILTypeRef.FullName (tyargsEnc g (gtpsType, gtpsMethod) tinst) @@ -8883,11 +8959,11 @@ let rec typeEnc g (gtpsType, gtpsMethod) ty = else sprintf "System.Tuple%s"(tyargsEnc g (gtpsType, gtpsMethod) tys) - | TType_fun (domainTy, rangeTy, _) -> - "Microsoft.FSharp.Core.FSharpFunc" + tyargsEnc g (gtpsType, gtpsMethod) [domainTy; rangeTy] + | TType_fun (domainTy, rangeTy, nullness) -> + "Microsoft.FSharp.Core.FSharpFunc" + tyargsEnc g (gtpsType, gtpsMethod) [domainTy; rangeTy] + nullnessEnc g nullness - | TType_var (typar, _) -> - typarEnc g (gtpsType, gtpsMethod) typar + | TType_var (typar, nullness) -> + typarEnc g (gtpsType, gtpsMethod) typar + nullnessEnc g nullness | TType_measure _ -> "?" @@ -8899,7 +8975,7 @@ and tyargsEnc g (gtpsType, gtpsMethod) args = let XmlDocArgsEnc g (gtpsType, gtpsMethod) argTys = if isNil argTys then "" - else "(" + String.concat "," (List.map (typeEnc g (gtpsType, gtpsMethod)) argTys) + ")" + else "(" + String.concat "," (List.map (typeEnc g (gtpsType, gtpsMethod)) argTys) + ")" let buildAccessPath (cp: CompilationPath option) = match cp with @@ -9023,64 +9099,131 @@ let isNonNullableStructTyparTy g ty = | ValueNone -> false -// Note, isRefTy does not include type parameters with the ': not struct' constraint +// Note, isRefTy does not include type parameters with the ': not struct' or ': null' constraints // This predicate is used to detect those type parameters. let isReferenceTyparTy g ty = match tryDestTyparTy g ty with | ValueSome tp -> - tp.Constraints |> List.exists (function TyparConstraint.IsReferenceType _ -> true | _ -> false) + tp.Constraints |> List.exists (function + | TyparConstraint.IsReferenceType _ -> true + | TyparConstraint.SupportsNull _ -> true + | _ -> false) | ValueNone -> false +let isSupportsNullTyparTy g ty = + if isReferenceTyparTy g ty then + (destTyparTy g ty).Constraints |> List.exists (function TyparConstraint.SupportsNull _ -> true | _ -> false) + else + false + let TypeNullNever g ty = let underlyingTy = stripTyEqnsAndMeasureEqns g ty isStructTy g underlyingTy || isByrefTy g underlyingTy || isNonNullableStructTyparTy g ty -/// Indicates if the type admits the use of 'null' as a value +/// The pre-nullness logic about whether a type admits the use of 'null' as a value. let TypeNullIsExtraValue g m ty = if isILReferenceTy g ty || isDelegateTy g ty then - // Putting AllowNullLiteralAttribute(false) on an IL or provided type means 'null' can't be used with that type - not (match tryTcrefOfAppTy g ty with ValueSome tcref -> TryFindTyconRefBoolAttribute g m g.attrib_AllowNullLiteralAttribute tcref = Some false | _ -> false) + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> + // Putting AllowNullLiteralAttribute(false) on an IL or provided + // type means 'null' can't be used with that type, otherwise it can + TryFindTyconRefBoolAttribute g m g.attrib_AllowNullLiteralAttribute tcref <> Some false + | _ -> + // In pre-nullness, other IL reference types (e.g. arrays) always support null + true elif TypeNullNever g ty then false else - // Putting AllowNullLiteralAttribute(true) on an F# type means 'null' can be used with that type + // In F# 4.x, putting AllowNullLiteralAttribute(true) on an F# type means 'null' can be used with that type match tryTcrefOfAppTy g ty with | ValueSome tcref -> TryFindTyconRefBoolAttribute g m g.attrib_AllowNullLiteralAttribute tcref = Some true | ValueNone -> // Consider type parameters - if isReferenceTyparTy g ty then - (destTyparTy g ty).Constraints |> List.exists (function TyparConstraint.SupportsNull _ -> true | _ -> false) - else - false - + isSupportsNullTyparTy g ty + +// Any mention of a type with AllowNullLiteral(true) is considered to be with-null +let intrinsicNullnessOfTyconRef g (tcref: TyconRef) = + match TryFindTyconRefBoolAttribute g tcref.Range g.attrib_AllowNullLiteralAttribute tcref with + | Some true -> g.knownWithNull + | _ -> g.knownWithoutNull + +let nullnessOfTy g ty = + ty + |> stripTyEqns g + |> function + | TType_app(tcref, _, nullness) -> + let nullness2 = intrinsicNullnessOfTyconRef g tcref + if nullness2 === g.knownWithoutNull then + nullness + else + combineNullness nullness nullness2 + | TType_fun (_, _, nullness) | TType_var (_, nullness) -> + nullness + | _ -> g.knownWithoutNull + +let changeWithNullReqTyToVariable g reqTy = + let sty = stripTyEqns g reqTy + match isTyparTy g sty with + | false -> + match nullnessOfTy g sty with + | Nullness.Known NullnessInfo.WithNull -> + reqTy |> replaceNullnessOfTy (NewNullnessVar()) + | _ -> reqTy + | true -> reqTy + +/// When calling a null-allowing API, we prefer to infer a without null argument for idiomatic F# code. +/// That is, unless caller explicitely marks a value (e.g. coming from a function parameter) as WithNull, it should not be infered as such. +let reqTyForArgumentNullnessInference g actualTy reqTy = + // Only change reqd nullness if actualTy is an inference variable + match tryDestTyparTy g actualTy with + | ValueSome t when t.IsCompilerGenerated && not(t.Constraints |> List.exists(function | TyparConstraint.SupportsNull _ -> true | _ -> false))-> + changeWithNullReqTyToVariable g reqTy + | _ -> reqTy + +/// The new logic about whether a type admits the use of 'null' as a value. +let TypeNullIsExtraValueNew g m ty = + let sty = stripTyparEqns ty + + // Check if the type has AllowNullLiteral + (match tryTcrefOfAppTy g sty with + | ValueSome tcref -> + not tcref.IsStructOrEnumTycon && + not (isByrefLikeTyconRef g m tcref) && + (TryFindTyconRefBoolAttribute g m g.attrib_AllowNullLiteralAttribute tcref = Some true) + | _ -> false) + || + // Check if the type has a nullness annotation + (match (nullnessOfTy g sty).Evaluate() with + | NullnessInfo.AmbivalentToNull -> false + | NullnessInfo.WithoutNull -> false + | NullnessInfo.WithNull -> true) + || + // Check if the type has a ': null' constraint + isSupportsNullTyparTy g ty + +/// The pre-nullness logic about whether a type uses 'null' as a true representation value let TypeNullIsTrueValue g ty = (match tryTcrefOfAppTy g ty with | ValueSome tcref -> IsUnionTypeWithNullAsTrueValue g tcref.Deref | _ -> false) || isUnitTy g ty +/// Indicates if unbox(null) is actively rejected at runtime. See nullability RFC. This applies to types that don't have null +/// as a valid runtime representation under old compatiblity rules. let TypeNullNotLiked g m ty = not (TypeNullIsExtraValue g m ty) && not (TypeNullIsTrueValue g ty) && not (TypeNullNever g ty) -// The non-inferring counter-part to SolveTypeUseSupportsNull -let TypeSatisfiesNullConstraint g m ty = - TypeNullIsExtraValue g m ty - -// The non-inferring counter-part to SolveTypeRequiresDefaultValue (and SolveTypeRequiresDefaultConstructor for struct types) -let rec TypeHasDefaultValue g m ty = +let rec TypeHasDefaultValueAux isNew g m ty = let ty = stripTyEqnsAndMeasureEqns g ty - // Check reference types - precisely the ones satisfying the ': null' constraint have default values - TypeSatisfiesNullConstraint g m ty - || - // Check nominal struct types - (isStructTy g ty && - // F# struct types have a DefaultValue if all their field types have a default value excluding those with DefaultValue(false) + (if isNew then TypeNullIsExtraValueNew g m ty else TypeNullIsExtraValue g m ty) + || (isStructTy g ty && + // Is it an F# struct type? (if isFSharpStructTy g ty then let tcref, tinst = destAppTy g ty let flds = @@ -9089,17 +9232,17 @@ let rec TypeHasDefaultValue g m ty = // We can ignore fields with the DefaultValue(false) attribute |> List.filter (fun fld -> TryFindFSharpBoolAttribute g g.attrib_DefaultValueAttribute fld.FieldAttribs <> Some false) - flds |> List.forall (actualTyOfRecdField (mkTyconRefInst tcref tinst) >> TypeHasDefaultValue g m) + flds |> List.forall (actualTyOfRecdField (mkTyconRefInst tcref tinst) >> TypeHasDefaultValueAux isNew g m) // Struct tuple types have a DefaultValue if all their element types have a default value elif isStructTupleTy g ty then - destStructTupleTy g ty |> List.forall (TypeHasDefaultValue g m) + destStructTupleTy g ty |> List.forall (TypeHasDefaultValueAux isNew g m) // Struct anonymous record types have a DefaultValue if all their element types have a default value elif isStructAnonRecdTy g ty then match tryDestAnonRecdTy g ty with | ValueNone -> true - | ValueSome (_, ptys) -> ptys |> List.forall (TypeHasDefaultValue g m) + | ValueSome (_, ptys) -> ptys |> List.forall (TypeHasDefaultValueAux isNew g m) else // All nominal struct types defined in other .NET languages have a DefaultValue regardless of their instantiation true)) @@ -9108,6 +9251,10 @@ let rec TypeHasDefaultValue g m ty = (isNonNullableStructTyparTy g ty && (destTyparTy g ty).Constraints |> List.exists (function TyparConstraint.RequiresDefaultConstructor _ -> true | _ -> false)) +let TypeHasDefaultValue (g: TcGlobals) m ty = TypeHasDefaultValueAux false g m ty + +let TypeHasDefaultValueNew g m ty = TypeHasDefaultValueAux true g m ty + /// Determines types that are potentially known to satisfy the 'comparable' constraint and returns /// a set of residual types that must also satisfy the constraint [] @@ -9343,7 +9490,7 @@ let mkChoiceTy (g: TcGlobals) m tinst = match List.length tinst with | 0 -> g.unit_ty | 1 -> List.head tinst - | length -> mkAppTy (mkChoiceTyconRef g m length) tinst + | length -> mkWoNullAppTy (mkChoiceTyconRef g m length) tinst let mkChoiceCaseRef g m n i = mkUnionCaseRef (mkChoiceTyconRef g m n) ("Choice"+string (i+1)+"Of"+string n) diff --git a/src/Compiler/TypedTree/TypedTreeOps.fsi b/src/Compiler/TypedTree/TypedTreeOps.fsi index cec67a4961d..3671d5ff306 100755 --- a/src/Compiler/TypedTree/TypedTreeOps.fsi +++ b/src/Compiler/TypedTree/TypedTreeOps.fsi @@ -647,6 +647,12 @@ val destStructAnonRecdTy: TcGlobals -> TType -> TTypes val tryDestForallTy: TcGlobals -> TType -> Typars * TType +val nullnessOfTy: TcGlobals -> TType -> Nullness + +val changeWithNullReqTyToVariable: TcGlobals -> reqTy: TType -> TType + +val reqTyForArgumentNullnessInference: TcGlobals -> actualTy: TType -> reqTy: TType -> TType + val isFunTy: TcGlobals -> TType -> bool val isForallTy: TcGlobals -> TType -> bool @@ -685,7 +691,7 @@ val tryAnyParTyOption: TcGlobals -> TType -> Typar option val isMeasureTy: TcGlobals -> TType -> bool -val mkAppTy: TyconRef -> TypeInst -> TType +val mkWoNullAppTy: TyconRef -> TypeInst -> TType val mkProvenUnionCaseTy: UnionCaseRef -> TypeInst -> TType @@ -899,6 +905,8 @@ val typarsAEquiv: TcGlobals -> TypeEquivEnv -> Typars -> Typars -> bool val typeAEquivAux: Erasure -> TcGlobals -> TypeEquivEnv -> TType -> TType -> bool +val nullnessSensitivetypeAEquivAux: Erasure -> TcGlobals -> TypeEquivEnv -> TType -> TType -> bool + val typeAEquiv: TcGlobals -> TypeEquivEnv -> TType -> TType -> bool val returnTypesAEquivAux: Erasure -> TcGlobals -> TypeEquivEnv -> TType option -> TType option -> bool @@ -919,7 +927,7 @@ val anonInfoEquiv: AnonRecdTypeInfo -> AnonRecdTypeInfo -> bool val isErasedType: TcGlobals -> TType -> bool // Return all components (units-of-measure, and types) of this type that would be erased -val getErasedTypes: TcGlobals -> TType -> TType list +val getErasedTypes: TcGlobals -> TType -> checkForNullness: bool -> TType list //------------------------------------------------------------------------- // Unit operations @@ -1073,6 +1081,7 @@ type DisplayEnv = showAttributes: bool showOverrides: bool showStaticallyResolvedTyparAnnotations: bool + showNullnessAnnotations: bool option abbreviateAdditionalConstraints: bool showTyparDefaultConstraints: bool /// If set, signatures will be rendered with XML documentation comments for members if they exist @@ -1645,7 +1654,7 @@ val destArrayTy: TcGlobals -> TType -> TType val destListTy: TcGlobals -> TType -> TType /// Build an array type of the given rank -val mkArrayTy: TcGlobals -> int -> TType -> range -> TType +val mkArrayTy: TcGlobals -> int -> Nullness -> TType -> range -> TType /// Check if a type definition is one of the artificial type definitions used for array types of different ranks val isArrayTyconRef: TcGlobals -> TyconRef -> bool @@ -1683,7 +1692,7 @@ val isFSharpDelegateTy: TcGlobals -> TType -> bool /// Determine if a type is an interface type val isInterfaceTy: TcGlobals -> TType -> bool -/// Determine if a type is a FSharpRef type +/// Determine if a type is a reference type val isRefTy: TcGlobals -> TType -> bool /// Determine if a type is a function (including generic). Not the same as isFunTy. @@ -1795,18 +1804,18 @@ val ModuleNameIsMangled: TcGlobals -> Attribs -> bool val CompileAsEvent: TcGlobals -> Attribs -> bool -val TypeNullIsExtraValue: TcGlobals -> range -> TType -> bool - val TypeNullIsTrueValue: TcGlobals -> TType -> bool -val TypeNullNotLiked: TcGlobals -> range -> TType -> bool +val TypeNullIsExtraValue: TcGlobals -> range -> TType -> bool -val TypeNullNever: TcGlobals -> TType -> bool +val TypeNullIsExtraValueNew: TcGlobals -> range -> TType -> bool -val TypeSatisfiesNullConstraint: TcGlobals -> range -> TType -> bool +val TypeNullNever: TcGlobals -> TType -> bool val TypeHasDefaultValue: TcGlobals -> range -> TType -> bool +val TypeHasDefaultValueNew: TcGlobals -> range -> TType -> bool + val isAbstractTycon: Tycon -> bool val isUnionCaseRefDefinitelyMutable: UnionCaseRef -> bool @@ -2275,6 +2284,8 @@ val mkLdelem: TcGlobals -> range -> TType -> Expr -> Expr -> Expr val TryDecodeILAttribute: ILTypeRef -> ILAttributes -> (ILAttribElem list * ILAttributeNamedArg list) option +val IsILAttrib: BuiltinAttribInfo -> ILAttribute -> bool + val TryFindILAttribute: BuiltinAttribInfo -> ILAttributes -> bool val TryFindILAttributeOpt: BuiltinAttribInfo option -> ILAttributes -> bool @@ -2297,6 +2308,8 @@ val TryFindFSharpBoolAttributeAssumeFalse: TcGlobals -> BuiltinAttribInfo -> Att val TryFindFSharpStringAttribute: TcGlobals -> BuiltinAttribInfo -> Attribs -> string option +val TryFindLocalizedFSharpStringAttribute: TcGlobals -> BuiltinAttribInfo -> Attribs -> string option + val TryFindFSharpInt32Attribute: TcGlobals -> BuiltinAttribInfo -> Attribs -> int32 option /// Try to find a specific attribute on a type definition, where the attribute accepts a string argument. diff --git a/src/Compiler/TypedTree/TypedTreePickle.fs b/src/Compiler/TypedTree/TypedTreePickle.fs index 038909659ce..6093f9cd391 100644 --- a/src/Compiler/TypedTree/TypedTreePickle.fs +++ b/src/Compiler/TypedTree/TypedTreePickle.fs @@ -121,6 +121,7 @@ type NodeOutTable<'Data, 'Node> = [] type WriterState = { os: ByteBuffer + osB: ByteBuffer oscope: CcuThunk occus: Table oentities: NodeOutTable @@ -154,6 +155,8 @@ type NodeInTable<'Data, 'Node> = [] type ReaderState = { is: ByteStream + // secondary stream of information for F# 5.0 + isB: ByteStream iilscope: ILScopeRef iccus: InputTable ientities: NodeInTable @@ -178,18 +181,28 @@ type 'T pickler = 'T -> WriterState -> unit let p_byte b st = st.os.EmitIntAsByte b +let p_byteB b st = st.osB.EmitIntAsByte b + let p_bool b st = p_byte (if b then 1 else 0) st -let prim_p_int32 i st = +/// Write an uncompressed integer to the main stream. +let prim_p_int32 i st = p_byte (b0 i) st p_byte (b1 i) st p_byte (b2 i) st p_byte (b3 i) st -/// Compress integers according to the same scheme used by CLR metadata -/// This halves the size of pickled data -let p_int32 n st = - if n >= 0 && n <= 0x7F then +/// Write an uncompressed integer to the B stream. +let prim_p_int32B i st = + p_byteB (b0 i) st + p_byteB (b1 i) st + p_byteB (b2 i) st + p_byteB (b3 i) st + +/// Compress integers according to the same scheme used by CLR metadata +/// This halves the size of pickled data +let p_int32 n st = + if n >= 0 && n <= 0x7F then p_byte (b0 n) st else if n >= 0x80 && n <= 0x3FFF then p_byte (0x80 ||| (n >>> 8)) st @@ -198,6 +211,17 @@ let p_int32 n st = p_byte 0xFF st prim_p_int32 n st +/// Write a compressed integer to the B stream. +let p_int32B n st = + if n >= 0 && n <= 0x7F then + p_byteB (b0 n) st + else if n >= 0x80 && n <= 0x3FFF then + p_byteB ( (0x80 ||| (n >>> 8))) st + p_byteB ( (n &&& 0xFF)) st + else + p_byteB 0xFF st + prim_p_int32B n st + let space = () let p_space n () st = for i = 0 to n - 1 do @@ -227,6 +251,7 @@ let p_prim_string (s: string) st = st.os.EmitBytes bytes let p_int c st = p_int32 c st +let p_intB c st = p_int32B c st let p_int8 (i: sbyte) st = p_int32 (int32 i) st let p_uint8 (i: byte) st = p_byte (int i) st let p_int16 (i: int16) st = p_int32 (int32 i) st @@ -267,12 +292,16 @@ let inline p_tup11 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 (a, b, c, d, e, f, x7, x8 let u_byte st = int (st.is.ReadByte()) +/// Unpickle an uncompressed integer from the B stream +/// The extra B stream of bytes is implicitly 0 if not present +let u_byteB st = + if st.isB.IsEOF then 0 else int (st.isB.ReadByte()) + type unpickler<'T> = ReaderState -> 'T let u_bool st = let b = u_byte st in (b = 1) - - +/// Unpickle an uncompressed integer from the main stream let prim_u_int32 st = let b0 = (u_byte st) let b1 = (u_byte st) @@ -280,6 +309,14 @@ let prim_u_int32 st = let b3 = (u_byte st) b0 ||| (b1 <<< 8) ||| (b2 <<< 16) ||| (b3 <<< 24) +/// Unpickle an uncompressed integer from the B stream +let prim_u_int32B st = + let b0 = u_byteB st + let b1 = u_byteB st + let b2 = u_byteB st + let b3 = u_byteB st + b0 ||| (b1 <<< 8) ||| (b2 <<< 16) ||| (b3 <<< 24) + let u_int32 st = let b0 = u_byte st if b0 <= 0x7F then b0 @@ -291,6 +328,19 @@ let u_int32 st = assert(b0 = 0xFF) prim_u_int32 st +/// Unpickle a compressed integer from the B stream. +/// The integer is 0 if the B stream is not present. +let u_int32B st = + let b0 = u_byteB st + if b0 <= 0x7F then b0 + else if b0 <= 0xbf then + let b0 = b0 &&& 0x7F + let b1 = u_byteB st + (b0 <<< 8) ||| b1 + else + assert(b0 = 0xFF) + prim_u_int32B st + let u_byte_memory st = let n = (u_int32 st) st.is.ReadBytes n @@ -303,6 +353,7 @@ let u_prim_string st = st.is.ReadUtf8String len let u_int st = u_int32 st +let u_intB st = u_int32B st let u_int8 st = sbyte (u_int32 st) let u_uint8 st = byte (u_byte st) let u_int16 st = int16 (u_int32 st) @@ -444,7 +495,12 @@ let p_list_core f (xs: 'T list) st = let p_list f x st = p_int (List.length x) st p_list_core f x st -let p_list_ext extraf f x st = + +let p_listB f x st = + p_intB (List.length x) st + p_list_core f x st + +let p_list_ext extraf f x st = let n = List.length x let n = if Option.isSome extraf then n ||| 0x80000000 else n p_int n st @@ -530,6 +586,12 @@ let u_list_core f n st = let u_list f st = let n = u_int st u_list_core f n st + +/// Unpickle a list from the B stream. The resulting list is empty if the B stream is not present. +let u_listB f st = + let n = u_intB st + u_list_core f n st + let u_list_ext extra f st = let n = u_int st let extraItem = @@ -647,7 +709,12 @@ let p_nleref x st = p_int (encode_nleref st.occus st.ostrings st.onlerefs st.osc // Simple types are types like "int", represented as TType(Ref_nonlocal(..., "int"), []). // A huge number of these occur in pickled F# data, so make them unique. -let decode_simpletyp st _ccuTab _stringTab nlerefTab a = TType_app(ERefNonLocal (lookup_nleref st nlerefTab a), [], 0uy) +// +// NULLNESS - the simpletyp table now holds KnownAmbivalentToNull by default. +// For old assemblies it is, if we give those assemblies the ambivalent interpretation. +// For new asemblies compiled with null-checking on it isn't, if the default is to give +// those the KnownWithoutNull interpretation by default. +let decode_simpletyp st _ccuTab _stringTab nlerefTab a = TType_app(ERefNonLocal (lookup_nleref st nlerefTab a), [], KnownAmbivalentToNull) let u_encoded_simpletyp st = u_int st let u_simpletyp st = lookup_uniq st st.isimpletys (u_int st) let encode_simpletyp ccuTab stringTab nlerefTab simpleTyTab thisCcu a = encode_uniq simpleTyTab (encode_nleref ccuTab stringTab nlerefTab thisCcu a) @@ -661,6 +728,7 @@ let PickleBufferCapacity = 50000 let pickleObjWithDanglingCcus inMem file g scope p x = let st1 = { os = ByteBuffer.Create(PickleBufferCapacity, useArrayPool = true) + osB = ByteBuffer.Create(PickleBufferCapacity, useArrayPool = true) oscope=scope occus= Table<_>.Create "occus" oentities=NodeOutTable<_, _>.Create((fun (tc: Tycon) -> tc.Stamp), (fun tc -> tc.LogicalName), (fun tc -> tc.Range), id , "otycons") @@ -674,22 +742,24 @@ let pickleObjWithDanglingCcus inMem file g scope p x = oglobals=g ofile=file oInMem=inMem - isStructThisArgPos = false} - let ccuNameTab, (ntycons, ntypars, nvals, nanoninfos), stringTab, pubpathTab, nlerefTab, simpleTyTab, phase1bytes = + isStructThisArgPos = false } + + let ccuNameTab,(ntycons, ntypars, nvals, nanoninfos),stringTab,pubpathTab,nlerefTab,simpleTyTab,phase1bytes,phase1bytesB = p x st1 let sizes = st1.oentities.Size, st1.otypars.Size, st1.ovals.Size, st1.oanoninfos.Size - st1.occus, sizes, st1.ostrings, st1.opubpaths, st1.onlerefs, st1.osimpletys, st1.os.AsMemory() + st1.occus, sizes, st1.ostrings, st1.opubpaths, st1.onlerefs, st1.osimpletys, st1.os.AsMemory(), st1.osB let st2 = { os = ByteBuffer.Create(PickleBufferCapacity, useArrayPool = true) + osB = ByteBuffer.Create(PickleBufferCapacity, useArrayPool = true) oscope=scope occus= Table<_>.Create "occus (fake)" - oentities=NodeOutTable<_, _>.Create((fun (tc: Tycon) -> tc.Stamp), (fun tc -> tc.LogicalName), (fun tc -> tc.Range), id , "otycons") - otypars=NodeOutTable<_, _>.Create((fun (tp: Typar) -> tp.Stamp), (fun tp -> tp.DisplayName), (fun tp -> tp.Range), id , "otypars") + oentities=NodeOutTable<_, _>.Create((fun (tc: Tycon) -> tc.Stamp), (fun tc -> tc.LogicalName), (fun tc -> tc.Range), id, "otycons") + otypars=NodeOutTable<_, _>.Create((fun (tp: Typar) -> tp.Stamp), (fun tp -> tp.DisplayName), (fun tp -> tp.Range), id, "otypars") ovals=NodeOutTable<_, _>.Create((fun (v: Val) -> v.Stamp), (fun v -> v.LogicalName), (fun v -> v.Range), (fun osgn -> osgn), "ovals") oanoninfos=NodeOutTable<_, _>.Create((fun (v: AnonRecdTypeInfo) -> v.Stamp), (fun v -> string v.IlTypeName), (fun _ -> range0), id, "oanoninfos") ostrings=Table<_>.Create "ostrings (fake)" @@ -717,12 +787,18 @@ let pickleObjWithDanglingCcus inMem file g scope p x = p_memory (stringTab.AsArray, pubpathTab.AsArray, nlerefTab.AsArray, simpleTyTab.AsArray, phase1bytes) st2 + + // The B stream should be empty in the second phase + let phase2bytesB = st2.osB.AsMemory() + if phase2bytesB.Length <> 0 then failwith "expected phase2bytesB.Length = 0" + (st2.osB :> System.IDisposable).Dispose() st2.os (st1.os :> System.IDisposable).Dispose() - phase2bytes -let check (ilscope: ILScopeRef) (inMap: NodeInTable<_, _>) = + phase2bytes, phase1bytesB + +let check (ilscope: ILScopeRef) (inMap: NodeInTable<_,_>) = for i = 0 to inMap.Count - 1 do let n = inMap.Get i if not (inMap.IsLinked n) then @@ -732,9 +808,10 @@ let check (ilscope: ILScopeRef) (inMap: NodeInTable<_, _>) = // an identical copy of the source for the DLL containing the data being unpickled. A message will // then be printed indicating the name of the item. -let unpickleObjWithDanglingCcus file viewedScope (ilModule: ILModuleDef option) u (phase2bytes: ReadOnlyByteMemory) = +let unpickleObjWithDanglingCcus file viewedScope (ilModule: ILModuleDef option) u (phase2bytes: ReadOnlyByteMemory) (phase1bytesB: ReadOnlyByteMemory) = let st2 = { is = ByteStream.FromBytes (phase2bytes, 0, phase2bytes.Length) + isB = ByteStream.FromBytes (ByteMemory.FromArray([| |]).AsReadOnly(), 0, 0) iilscope = viewedScope iccus = new_itbl "iccus (fake)" [| |] ientities = NodeInTable<_, _>.Create (Tycon.NewUnlinked, (fun osgn tg -> osgn.Link tg), (fun osgn -> osgn.IsLinked), "itycons", 0) @@ -768,6 +845,7 @@ let unpickleObjWithDanglingCcus file viewedScope (ilModule: ILModuleDef option) let data = let st1 = { is = ByteStream.FromBytes (phase1bytes, 0, phase1bytes.Length) + isB = ByteStream.FromBytes (phase1bytesB, 0, phase1bytesB.Length) iccus = ccuTab iilscope = viewedScope ientities = NodeInTable<_, _>.Create(Tycon.NewUnlinked, (fun osgn tg -> osgn.Link tg), (fun osgn -> osgn.IsLinked), "itycons", ntycons) @@ -782,6 +860,7 @@ let unpickleObjWithDanglingCcus file viewedScope (ilModule: ILModuleDef option) iILModule = ilModule } let res = u st1 check viewedScope st1.ientities + check viewedScope st1.ientities check viewedScope st1.ivals check viewedScope st1.itypars res @@ -1529,7 +1608,20 @@ let p_tyar_constraint x st = | TyparConstraint.SupportsComparison _ -> p_byte 10 st | TyparConstraint.SupportsEquality _ -> p_byte 11 st | TyparConstraint.IsUnmanaged _ -> p_byte 12 st -let p_tyar_constraints = (p_list p_tyar_constraint) + | TyparConstraint.NotSupportsNull _ -> + failwith "NotSupportsNull constraints should only be emitted to streamB" + +// Some extra F# 5.0 constraints are stored in stream B, these will be ignored by earlier F# compilers +let p_tyar_constraintB x st = + match x with + | TyparConstraint.NotSupportsNull _ -> p_byteB 1 st + | _ -> failwith "only NotSupportsNull constraints should be emitted to streamB" + +let p_tyar_constraints cxs st = + let cxs1, cxs2 = cxs |> List.partition (function TyparConstraint.NotSupportsNull _ -> false | _ -> true) + p_list p_tyar_constraint cxs1 st + // Some extra F# 5.0 constraints are stored in stream B, these will be ignored by earlier F# compilers + p_listB p_tyar_constraintB cxs2 st let u_tyar_constraint st = let tag = u_byte st @@ -1549,9 +1641,21 @@ let u_tyar_constraint st = | 12 -> (fun _ -> TyparConstraint.IsUnmanaged range0) | _ -> ufailwith st "u_tyar_constraint" - -let u_tyar_constraints = (u_list_revi u_tyar_constraint) - +// Some extra F# 5.0 constraints are stored in stream B, these will be ignored by earlier F# compilers +let u_tyar_constraintB st = + let tag = u_byteB st + match tag with + | 1 -> TyparConstraint.NotSupportsNull range0 + | _ -> ufailwith st "u_tyar_constraintB - unexpected constraint in streamB" + +let u_tyar_constraints st = + let cxs1 = u_list_revi u_tyar_constraint st + // Some extra F# 5.0 constraints are stored in stream B, these will be ignored by earlier F# compilers + // + // If the B stream is not present (e.g. reading F# 4.5 components) then this list will be empty + // via the implementation of u_listB. + let cxs2 = u_listB u_tyar_constraintB st + cxs1 @ cxs2 let p_tyar_spec_data (x: Typar) st = p_tup5 @@ -1579,7 +1683,7 @@ let u_tyar_spec_data st = typar_opt_data= match g, e, c with | doc, [], [] when doc.IsEmpty -> None - | _ -> Some { typar_il_name = None; typar_xmldoc = g; typar_constraints = e; typar_attribs = c } } + | _ -> Some { typar_il_name = None; typar_xmldoc = g; typar_constraints = e; typar_attribs = c;typar_is_contravariant = false } } let u_tyar_spec st = u_osgn_decl st.itypars u_tyar_spec_data st @@ -1604,19 +1708,41 @@ let _ = fill_p_ty2 (fun isStructThisArgPos ty st -> else p_byte 0 st; p_tys l st - | TType_app(ERefNonLocal nleref, [], _) -> + | TType_app(ERefNonLocal nleref, [], nullness) -> + if st.oglobals.langFeatureNullness then + match nullness.Evaluate() with + | NullnessInfo.WithNull -> p_byteB 9 st + | NullnessInfo.WithoutNull -> p_byteB 10 st + | NullnessInfo.AmbivalentToNull -> p_byteB 11 st p_byte 1 st; p_simpletyp nleref st - | TType_app (tc, tinst, _) -> - p_byte 2 st; p_tup2 (p_tcref "typ") p_tys (tc, tinst) st - - | TType_fun (d, r, _) -> + | TType_app (tc, tinst, nullness) -> + if st.oglobals.langFeatureNullness then + match nullness.Evaluate() with + | NullnessInfo.WithNull -> p_byteB 12 st + | NullnessInfo.WithoutNull -> p_byteB 13 st + | NullnessInfo.AmbivalentToNull -> p_byteB 14 st + p_byte 2 st; p_tcref "typ" tc st; p_tys tinst st + + | TType_fun (d,r,nullness) -> + if st.oglobals.langFeatureNullness then + match nullness.Evaluate() with + | NullnessInfo.WithNull -> p_byteB 15 st + | NullnessInfo.WithoutNull -> p_byteB 16 st + | NullnessInfo.AmbivalentToNull -> p_byteB 17 st p_byte 3 st // Note, the "this" argument may be found in the domain position of a function type, so propagate the isStructThisArgPos value p_ty2 isStructThisArgPos d st p_ty r st - | TType_var (r, _) -> p_byte 4 st; p_tpref r st + | TType_var (r, nullness) -> + if st.oglobals.langFeatureNullness then + match nullness.Evaluate() with + | NullnessInfo.WithNull -> p_byteB 18 st + | NullnessInfo.WithoutNull -> p_byteB 19 st + | NullnessInfo.AmbivalentToNull -> p_byteB 20 st + p_byte 4 st + p_tpref r st | TType_forall (tps, r) -> p_byte 5 st @@ -1642,27 +1768,59 @@ let _ = fill_p_ty2 (fun isStructThisArgPos ty st -> let _ = fill_u_ty (fun st -> let tag = u_byte st + match tag with | 0 -> let l = u_tys st TType_tuple (tupInfoRef, l) - - | 1 -> - u_simpletyp st - - | 2 -> - let tc = u_tcref st + | 1 -> + let tagB = u_byteB st + let sty = u_simpletyp st + match tagB with + | 0 -> + sty + | 9 -> + match sty with + | TType_app(tcref, _, _) -> TType_app(tcref, [], KnownWithNull) + | _ -> ufailwith st "u_ty 9a" + | 10 -> + match sty with + | TType_app(tcref, _, _) -> TType_app(tcref, [], KnownWithoutNull) + | _ -> ufailwith st "u_ty 9b" + | 11 -> + match sty with + | TType_app(tcref, _, _) -> TType_app(tcref, [], KnownAmbivalentToNull) + | _ -> ufailwith st "u_ty 9c" + | b -> ufailwith st (sprintf "u_ty - 1/B, byte = %A" b) + | 2 -> + let tagB = u_byteB st + let tcref = u_tcref st let tinst = u_tys st - TType_app (tc, tinst, 0uy) - - | 3 -> + match tagB with + | 0 -> TType_app (tcref, tinst, KnownAmbivalentToNull) + | 12 -> TType_app (tcref, tinst, KnownWithNull) + | 13 -> TType_app (tcref, tinst, KnownWithoutNull) + | 14 -> TType_app (tcref, tinst, KnownAmbivalentToNull) + | _ -> ufailwith st "u_ty - 2/B" + | 3 -> + let tagB = u_byteB st let d = u_ty st let r = u_ty st - TType_fun (d, r, 0uy) - + match tagB with + | 0 -> TType_fun (d, r, KnownAmbivalentToNull) + | 15 -> TType_fun (d, r, KnownWithNull) + | 16 -> TType_fun (d, r, KnownWithoutNull) + | 17 -> TType_fun (d, r, KnownAmbivalentToNull) + | _ -> ufailwith st "u_ty - 3/B" | 4 -> + let tagB = u_byteB st let r = u_tpref st - r.AsType + match tagB with + | 0 -> r.AsType KnownAmbivalentToNull + | 18 -> r.AsType KnownWithNull + | 19 -> r.AsType KnownWithoutNull + | 20 -> r.AsType KnownAmbivalentToNull + | _ -> ufailwith st "u_ty - 4/B" | 5 -> let tps = u_tyar_specs st diff --git a/src/Compiler/TypedTree/TypedTreePickle.fsi b/src/Compiler/TypedTree/TypedTreePickle.fsi index 5e0fa9915c3..3e3910bd4e1 100644 --- a/src/Compiler/TypedTree/TypedTreePickle.fsi +++ b/src/Compiler/TypedTree/TypedTreePickle.fsi @@ -85,7 +85,7 @@ val internal pickleCcuInfo: pickler /// Serialize an arbitrary object using the given pickler val pickleObjWithDanglingCcus: - inMem: bool -> file: string -> TcGlobals -> scope: CcuThunk -> pickler<'T> -> 'T -> ByteBuffer + inMem: bool -> file: string -> TcGlobals -> scope: CcuThunk -> pickler<'T> -> 'T -> ByteBuffer * ByteBuffer /// The type of state unpicklers read from type ReaderState @@ -151,5 +151,6 @@ val internal unpickleObjWithDanglingCcus: viewedScope: ILScopeRef -> ilModule: ILModuleDef option -> 'T unpickler -> + ReadOnlyByteMemory -> ReadOnlyByteMemory -> PickledDataWithReferences<'T> diff --git a/src/Compiler/TypedTree/tainted.fs b/src/Compiler/TypedTree/tainted.fs index 609e66fe0d4..7b27c4745f4 100644 --- a/src/Compiler/TypedTree/tainted.fs +++ b/src/Compiler/TypedTree/tainted.fs @@ -132,8 +132,8 @@ type internal Tainted<'T> (context: TaintedContext, value: 'T) = let u = this.Protect (fun x -> f (x, context.TypeProvider)) range Tainted(context, u) - member this.PApplyArray(f, methodName, range: range) = - let a : 'U[] = this.Protect f range + member this.PApplyArray(f, methodName, range:range) = + let a : 'U[] MaybeNull = this.Protect f range match a with | Null -> raise <| TypeProviderError(FSComp.SR.etProviderReturnedNull(methodName), this.TypeProviderDesignation, range) | NonNull a -> a |> Array.map (fun u -> Tainted(context,u)) @@ -164,8 +164,14 @@ type internal Tainted<'T> (context: TaintedContext, value: 'T) = Tainted(context, this.Protect(fun value -> box value :?> 'U) range) module internal Tainted = - let (|Null|NonNull|) (p:Tainted<'T>) : Choice> when 'T : null and 'T : not struct = + +#if NO_CHECKNULLS + let (|Null|NonNull|) (p:Tainted<'T>) : Choice> when 'T : null and 'T : not struct = if p.PUntaintNoFailure isNull then Null else NonNull (p.PApplyNoFailure id) +#else + let (|Null|NonNull|) (p:Tainted<'T | null>) : Choice> when 'T : not null and 'T : not struct = + if p.PUntaintNoFailure isNull then Null else NonNull (p.PApplyNoFailure nonNull) +#endif let Eq (p:Tainted<'T>) (v:'T) = p.PUntaintNoFailure (fun pv -> pv = v) diff --git a/src/Compiler/TypedTree/tainted.fsi b/src/Compiler/TypedTree/tainted.fsi index ee1a6d94069..61392794b5f 100644 --- a/src/Compiler/TypedTree/tainted.fsi +++ b/src/Compiler/TypedTree/tainted.fsi @@ -101,7 +101,11 @@ type internal Tainted<'T> = module internal Tainted = /// Test whether the tainted value is null - val (|Null|NonNull|): Tainted<'T MaybeNull> -> Choice> when 'T: null and 'T: not struct +#if NO_CHECKNULLS + val (|Null|NonNull|) : Tainted<'T MaybeNull> -> Choice> when 'T : null and 'T : not struct +#else + val (|Null|NonNull|) : Tainted<'T MaybeNull> -> Choice> when 'T : not null and 'T : not struct +#endif /// Test whether the tainted value equals given value. /// Failure in call to equality operation will be blamed on type provider of first operand diff --git a/src/Compiler/Utilities/Activity.fs b/src/Compiler/Utilities/Activity.fs index ebc08633021..180f9c4c4e3 100644 --- a/src/Compiler/Utilities/Activity.fs +++ b/src/Compiler/Utilities/Activity.fs @@ -67,20 +67,21 @@ module internal Activity = module Events = let cacheHit = "cacheHit" - type System.Diagnostics.Activity with + type Diagnostics.Activity with member this.RootId = let rec rootID (act: Activity) = - if isNull act.ParentId then act.Id else rootID act.Parent + match act.Parent with + | null -> act.Id + | parent -> rootID parent rootID this member this.Depth = let rec depth (act: Activity) acc = - if isNull act.ParentId then - acc - else - depth act.Parent (acc + 1) + match act.Parent with + | null -> acc + | parent -> depth parent (acc + 1) depth this 0 @@ -100,8 +101,10 @@ module internal Activity = let startNoTags (name: string) : IDisposable = activitySource.StartActivity name let addEvent name = - if (not (isNull Activity.Current)) && Activity.Current.Source = activitySource then - Activity.Current.AddEvent(ActivityEvent name) |> ignore + match Activity.Current with + | null -> () + | activity when activity.Source = activitySource -> activity.AddEvent(ActivityEvent name) |> ignore + | _ -> () module Profiling = diff --git a/src/Compiler/Utilities/illib.fs b/src/Compiler/Utilities/illib.fs index ec797443dd0..aa1fffaf826 100644 --- a/src/Compiler/Utilities/illib.fs +++ b/src/Compiler/Utilities/illib.fs @@ -16,29 +16,30 @@ type InterruptibleLazy<'T> private (value, valueFactory: unit -> 'T) = let syncObj = obj () [] - let mutable valueFactory = valueFactory + // TODO nullness - this is boxed to obj because of an attribute targets bug fixed in main, but not yet shipped (needs shipped 8.0.400) + let mutable valueFactory : obj = valueFactory let mutable value = value new(valueFactory: unit -> 'T) = InterruptibleLazy(Unchecked.defaultof<_>, valueFactory) member this.IsValueCreated = - match box valueFactory with + match valueFactory with | null -> true | _ -> false member this.Value = - match box valueFactory with + match valueFactory with | null -> value | _ -> Monitor.Enter(syncObj) try - match box valueFactory with + match valueFactory with | null -> () | _ -> - value <- valueFactory () + value <- (valueFactory |> unbox 'T>) () valueFactory <- Unchecked.defaultof<_> finally Monitor.Exit(syncObj) @@ -85,10 +86,11 @@ module internal PervasiveAutoOpens = | [ _ ] -> true | _ -> false - type 'T MaybeNull when 'T: null and 'T: not struct = 'T - let inline isNotNull (x: 'T) = not (isNull x) +#if NO_CHECKNULLS + type 'T MaybeNull when 'T: null and 'T: not struct = 'T + let inline (|NonNullQuick|) (x: 'T MaybeNull) = match x with | null -> raise (NullReferenceException()) @@ -108,6 +110,10 @@ module internal PervasiveAutoOpens = match x with | null -> raise (ArgumentNullException(paramName)) | v -> v +#else + type 'T MaybeNull when 'T: not null and 'T: not struct = 'T | null + +#endif let inline (===) x y = LanguagePrimitives.PhysicalEquality x y @@ -142,17 +148,15 @@ module internal PervasiveAutoOpens = | Some x -> x let reportTime = - let mutable tPrev: IDisposable = null + let mutable tPrev: IDisposable MaybeNull = null fun descr -> if isNotNull tPrev then tPrev.Dispose() + tPrev <- null - tPrev <- - if descr <> "Finish" then - FSharp.Compiler.Diagnostics.Activity.Profiling.startAndMeasureEnvironmentStats descr - else - null + if descr <> "Finish" then + tPrev <- FSharp.Compiler.Diagnostics.Activity.Profiling.startAndMeasureEnvironmentStats descr let foldOn p f z x = f z (p x) @@ -361,10 +365,7 @@ module Array = /// ~0.8x slower for ints let inline areEqual (xs: 'T[]) (ys: 'T[]) = match xs, ys with - | null, null -> true | [||], [||] -> true - | null, _ - | _, null -> false | _ when xs.Length <> ys.Length -> false | _ -> let mutable break' = false @@ -438,6 +439,9 @@ module Option = with _ -> None +module internal ValueTuple = + let inline map1Of2 ([]f) struct(a1, a2) = struct(f a1, a2) + module List = let sortWithOrder (c: IComparer<'T>) elements = @@ -664,6 +668,22 @@ module List = | Some x -> x :: l | _ -> l + + [] + let rec private vMapFoldWithAcc<'T, 'State, 'Result> (mapping: 'State -> 'T -> struct('Result * 'State)) state list acc : struct('Result list * 'State) = + match list with + | [] -> acc, state + | [h] -> + mapping state h + |> ValueTuple.map1Of2 (fun x -> x::acc) + | h :: t -> + let struct(mappedHead, stateHead) = mapping state h + vMapFoldWithAcc mapping stateHead t (mappedHead :: acc) + + let vMapFold<'T, 'State, 'Result> (mapping: 'State -> 'T -> struct('Result * 'State)) state list : struct('Result list * 'State) = + vMapFoldWithAcc mapping state list [] + |> ValueTuple.map1Of2 List.rev + module ResizeArray = /// Split a ResizeArray into an array of smaller chunks. diff --git a/src/Compiler/Utilities/illib.fsi b/src/Compiler/Utilities/illib.fsi index a9ee48c4be9..2df0d9c0959 100644 --- a/src/Compiler/Utilities/illib.fsi +++ b/src/Compiler/Utilities/illib.fsi @@ -44,6 +44,7 @@ module internal PervasiveAutoOpens = /// Returns true if the argument is non-null. val inline isNotNull: x: 'T -> bool when 'T: null +#if NO_CHECKNULLS /// Indicates that a type may be null. 'MaybeNull' is used internally in the F# compiler as /// replacement for 'string?' to align with FS-1060. type 'T MaybeNull when 'T: null and 'T: not struct = 'T @@ -59,6 +60,11 @@ module internal PervasiveAutoOpens = /// Checks the argument is non-null val inline nullArgCheck: paramName: string -> x: 'T MaybeNull -> 'T +#else + /// Indicates that a type may be null. 'MaybeNull' used internally in the F# compiler as unchecked + /// replacement for 'string?' + type 'T MaybeNull when 'T: not null and 'T: not struct = 'T | null +#endif val inline (===): x: 'a -> y: 'a -> bool when 'a: not struct @@ -240,6 +246,8 @@ module internal List = val prependIfSome: x: 'a option -> l: 'a list -> 'a list + val vMapFold<'T,'State,'Result> : mapping:('State -> 'T -> struct('Result * 'State)) -> state:'State -> list:'T list -> struct('Result list * 'State) + module internal ResizeArray = /// Split a ResizeArray into an array of smaller chunks. diff --git a/src/Compiler/Utilities/lib.fs b/src/Compiler/Utilities/lib.fs index 87e50acd74a..921b0a6dba3 100755 --- a/src/Compiler/Utilities/lib.fs +++ b/src/Compiler/Utilities/lib.fs @@ -330,15 +330,15 @@ type Graph<'Data, 'Id when 'Id : comparison and 'Id : equality> // with care. //---------------------------------------------------------------------------- -type NonNullSlot<'T> = 'T -let nullableSlotEmpty() = Unchecked.defaultof<'T> -let nullableSlotFull x = x +type NonNullSlot<'T when 'T : not struct> = 'T +let nullableSlotEmpty() : NonNullSlot<'T> = Unchecked.defaultof<_> +let nullableSlotFull (x: 'T) : NonNullSlot<'T> = x //--------------------------------------------------------------------------- // Caches, mainly for free variables //--------------------------------------------------------------------------- -type cache<'T> = { mutable cacheVal: 'T NonNullSlot } +type cache<'T when 'T : not struct> = { mutable cacheVal: NonNullSlot<'T> } let newCache() = { cacheVal = nullableSlotEmpty() } let inline cached cache ([] resF) = diff --git a/src/Compiler/Utilities/lib.fsi b/src/Compiler/Utilities/lib.fsi index c7bccd4211d..cbdb893c5b8 100644 --- a/src/Compiler/Utilities/lib.fsi +++ b/src/Compiler/Utilities/lib.fsi @@ -228,24 +228,24 @@ type Graph<'Data, 'Id when 'Id: comparison> = /// This is an unsafe trick, as it relies on the fact that the type of values /// being placed into the slot never utilizes "null" as a representation. To be used with /// with care. -type NonNullSlot<'T> = 'T +type NonNullSlot<'T when 'T: not struct> = 'T -val nullableSlotEmpty: unit -> 'T +val nullableSlotEmpty: unit -> NonNullSlot<'T> -val nullableSlotFull: x: 'a -> 'a +val nullableSlotFull: x: 'a -> NonNullSlot<'a> /// Caches, mainly for free variables -type cache<'T> = { mutable cacheVal: NonNullSlot<'T> } +type cache<'T when 'T: not struct> = { mutable cacheVal: NonNullSlot<'T> } -val newCache: unit -> cache<'a> +val newCache: unit -> cache<'a> when 'a: not struct -val inline cached: cache: cache<'a> -> resF: (unit -> 'a) -> 'a +val inline cached: cache: cache<'a> -> resF: (unit -> 'a) -> 'a when 'a: not struct val inline cacheOptByref: cache: byref<'T option> -> f: (unit -> 'T) -> 'T val inline cacheOptRef: cache: 'a option ref -> f: (unit -> 'a) -> 'a -val inline tryGetCacheValue: cache: cache<'a> -> NonNullSlot<'a> voption +val inline tryGetCacheValue: cache: cache<'a> -> NonNullSlot<'a> voption when 'a: not struct [] type MaybeLazy<'T> = diff --git a/src/Compiler/Utilities/sformat.fs b/src/Compiler/Utilities/sformat.fs index 2a11d4fee98..611c31235d9 100644 --- a/src/Compiler/Utilities/sformat.fs +++ b/src/Compiler/Utilities/sformat.fs @@ -116,6 +116,13 @@ type IEnvironment = abstract MaxColumns: int abstract MaxRows: int +#if NO_CHECKNULLS +[] +module NullShim = + // Shim to match nullness checking library support in preview + let inline (|Null|NonNull|) (x: 'T) : Choice = match x with null -> Null | v -> NonNull v +#endif + [] module TaggedText = let mkTag tag text = TaggedText(tag, text) @@ -496,7 +503,7 @@ module ReflectUtils = // of an F# value. let GetValueInfoOfObject (bindingFlags: BindingFlags) (obj: obj) = match obj with - | null -> NullValue + | Null -> NullValue | _ -> let reprty = obj.GetType() @@ -561,9 +568,8 @@ module ReflectUtils = let GetValueInfo bindingFlags (x: 'a, ty: Type) (* x could be null *) = let obj = (box x) - match obj with - | null -> + | Null -> let isNullaryUnion = match ty.GetCustomAttributes(typeof, false) with | [| :? CompilationRepresentationAttribute as attr |] -> @@ -581,7 +587,8 @@ module ReflectUtils = UnitValue else NullValue - | _ -> GetValueInfoOfObject bindingFlags obj + | NonNull obj -> + GetValueInfoOfObject bindingFlags obj module Display = open ReflectUtils @@ -841,8 +848,8 @@ module Display = let getListValueInfo bindingFlags (x: obj, ty: Type) = match x with - | null -> None - | _ -> + | Null -> None + | NonNull x -> match Value.GetValueInfo bindingFlags (x, ty) with | UnionCaseValue("Cons", recd) -> Some(unpackCons recd) | UnionCaseValue("Empty", [||]) -> None @@ -1000,14 +1007,13 @@ module Display = and objL showMode depthLim prec (x: obj, ty: Type) = let info = Value.GetValueInfo bindingFlags (x, ty) - try if depthLim <= 0 || exceededPrintSize () then wordL (tagPunctuation "...") else match x with - | null -> reprL showMode (depthLim - 1) prec info x - | _ -> + | Null -> reprL showMode (depthLim - 1) prec info x + | NonNull x -> if (path.ContainsKey(x)) then wordL (tagPunctuation "...") else @@ -1021,10 +1027,9 @@ module Display = Some(wordL (tagText (x.ToString()))) else // Try the StructuredFormatDisplayAttribute extensibility attribute - match ty.GetCustomAttributes(typeof, true) with - | null - | [||] -> None - | res -> structuredFormatObjectL showMode ty depthLim (res[0] :?> StructuredFormatDisplayAttribute) x + match ty.GetCustomAttributes (typeof, true) with + | Null | [| |] -> None + | NonNull res -> structuredFormatObjectL showMode ty depthLim (res[0] :?> StructuredFormatDisplayAttribute) x #if COMPILER // This is the PrintIntercepts extensibility point currently revealed by fsi.exe's AddPrinter @@ -1057,8 +1062,7 @@ module Display = // Format an object that has a layout specified by StructuredFormatAttribute and structuredFormatObjectL showMode ty depthLim (attr: StructuredFormatDisplayAttribute) (obj: obj) = let txt = attr.Value - - if isNull txt || txt.Length <= 1 then + if isNull (box txt) || txt.Length <= 1 then None else @@ -1523,7 +1527,7 @@ module Display = let leafFormatter (opts: FormatOptions) (obj: obj) = match obj with - | null -> tagKeyword "null" + | Null -> tagKeyword "null" | :? double as d -> let s = d.ToString(opts.FloatingPointFormat, opts.FormatProvider) diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 7bc495e9139..9e19fec1c20 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -89,6 +89,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %token GREATER_RBRACK STRUCT SIG %token STATIC MEMBER CLASS ABSTRACT OVERRIDE DEFAULT CONSTRUCTOR INHERIT %token EXTERN VOID PUBLIC PRIVATE INTERNAL GLOBAL +%token BAR_JUST_BEFORE_NULL /* for parser 'escape hatch' out of expression context without consuming the 'recover' token */ %token TYPE_COMING_SOON TYPE_IS_HERE MODULE_COMING_SOON MODULE_IS_HERE @@ -255,6 +256,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> /* Lower than "if a then b" */ %left prec_then_before %nonassoc prec_then_if +%nonassoc BAR_JUST_BEFORE_NULL %left BAR %right SEMICOLON prec_semiexpr_sep OBLOCKSEP @@ -979,11 +981,11 @@ classMemberSpfn: let trivia: SynMemberSigMemberTrivia = { GetSetKeywords = getSetRangeOpt } SynMemberSig.Member(valSpfn, flags, mWhole, trivia) } - | opt_attributes opt_access interfaceMember appType + | opt_attributes opt_access interfaceMember appTypeWithoutNull { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) SynMemberSig.Interface($4, unionRanges (rhs parseState 3) ($4).Range) } - | opt_attributes opt_access INHERIT appType + | opt_attributes opt_access INHERIT appTypeWithoutNull { if Option.isSome $2 then errorR (Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier (), rhs parseState 2)) SynMemberSig.Inherit($4, unionRanges (rhs parseState 1) $4.Range) } @@ -1379,7 +1381,7 @@ openDecl: { let mOpen = rhs parseState 1 SynOpenDeclTarget.ModuleOrNamespace(SynLongIdent([], [], []), mOpen.EndRange), mOpen } - | OPEN typeKeyword appType + | OPEN typeKeyword appTypeWithoutNull { let mOpen = rhs parseState 1 let mPath = $3.Range SynOpenDeclTarget.Type($3, mPath), unionRanges mOpen mPath } @@ -1626,12 +1628,9 @@ tyconDefn: let (tcDefRepr, mWith, members) = $8 nameRange let (SynComponentInfo(_, _, _, lid, _, _, _, _)) = $1 let mEquals = rhs parseState 7 - // Gets the XML doc comments prior to the implicit constructor let xmlDoc = grabXmlDoc (parseState, $2, 2) - let m = match lid with [] -> rhs parseState 1 | _ -> rangeOfLid lid - let memberCtorPattern = pat |> Option.map (fun pat -> SynMemberDefn.ImplicitCtor(vis, $2, pat, Option.bind snd az, xmlDoc, m, { AsKeyword = Option.map fst az }) @@ -1659,14 +1658,11 @@ tyconDefn: | Some(_, Some id) -> reportParseErrorAt (rhs parseState 6) (FSComp.SR.tcLetAndDoRequiresImplicitConstructionSequence ()) | _ -> () - tcDefRepr - let declRange = unionRanges (rhs parseState 1) tcDefRepr.Range let mWhole = (declRange, members) ||> unionRangeWithListBy (fun (mem: SynMemberDefn) -> mem.Range) |> unionRangeWithXmlDoc xmlDoc - fun leadingKeyword -> let trivia: SynTypeDefnTrivia = { LeadingKeyword = leadingKeyword; EqualsRange = Some mEquals; WithKeyword = mWith } SynTypeDefn($1, tcDefRepr, members, memberCtorPattern, mWhole, trivia) } @@ -1683,7 +1679,6 @@ tyconDefn: | Some pat, _, _ -> let memberCtorPattern = SynMemberDefn.ImplicitCtor(vis, $2, pat, Option.bind snd az, xmlDoc, m, { AsKeyword = Option.map fst az }) [memberCtorPattern], unionRanges mName memberCtorPattern.Range - | _, _, Some(mAs, asId) -> let mAs = asId |> Option.map (fun id -> @@ -1691,12 +1686,9 @@ tyconDefn: id.idRange ) |> Option.defaultValue mAs - [], unionRanges mName mAs - | _, Some vis, _ -> [], unionRanges mName vis.Range - | _ -> [], mName @@ -1704,7 +1696,6 @@ tyconDefn: let trivia = { SynTypeDefnTrivia.Zero with LeadingKeyword = leadingKeyword } SynTypeDefn($1, SynTypeDefnRepr.Simple(SynTypeDefnSimpleRepr.None(mName), mName), members, None, mWhole, trivia) } - /* The right-hand-side of a type definition */ tyconDefnRhsBlock: /* This rule allows members to be given for record and union types in the #light syntax */ @@ -2025,7 +2016,7 @@ classDefnMember: [SynMemberDefn.Member(binding, mWhole)] } - | opt_attributes opt_access interfaceMember appType opt_interfaceImplDefn + | opt_attributes opt_access interfaceMember appTypeWithoutNull opt_interfaceImplDefn { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesAreNotPermittedOnInterfaceImplementations(), rhs parseState 1)) if Option.isSome $2 then errorR(Error(FSComp.SR.parsInterfacesHaveSameVisibilityAsEnclosingType(), rhs parseState 3)) let mWithKwd, members, mWhole = @@ -2426,12 +2417,12 @@ tyconDefnOrSpfnSimpleRepr: | opt_attributes opt_access path LQUOTE STRING recover { errorR(Error(FSComp.SR.parsUnexpectedQuotationOperatorInTypeAliasDidYouMeanVerbatimString(), rhs parseState 4)) SynTypeDefnSimpleRepr.TypeAbbrev(ParserDetail.ErrorRecovery, SynType.LongIdent($3), unionRanges (rhs parseState 1) $3.Range) } - - /* A type abbreviation */ + + /* A type abbreviation */ | opt_attributes opt_access typ { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesIllegalHere(), rhs parseState 1)) if Option.isSome $2 then errorR(Error(FSComp.SR.parsTypeAbbreviationsCannotHaveVisibilityDeclarations(), rhs parseState 2)) - SynTypeDefnSimpleRepr.TypeAbbrev(ParserDetail.Ok, $3, unionRanges (rhs parseState 1) $3.Range) } + SynTypeDefnSimpleRepr.TypeAbbrev(ParserDetail.Ok, $3, unionRanges (rhs parseState 1) $3.Range) } /* A union type definition */ | opt_attributes opt_access unionTypeRepr @@ -2643,6 +2634,10 @@ typeConstraint: | typar COLON NULL { SynTypeConstraint.WhereTyparSupportsNull($1, lhs parseState) } + | typar COLON IDENT NULL + { if $3 <> "not" then reportParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedIdentifier($3 + " (2)")) + SynTypeConstraint.WhereTyparNotSupportsNull($1, lhs parseState) } + | typar COLON LPAREN classMemberSpfn rparen { let tp = $1 SynTypeConstraint.WhereTyparSupportsMember(SynType.Var(tp, tp.Range), $4, lhs parseState) } @@ -2661,25 +2656,25 @@ typeConstraint: | "enum" -> let _ltm, _gtm, args, _commas, mWhole = $4 SynTypeConstraint.WhereTyparIsEnum($1, args, unionRanges $1.Range mWhole) - | nm -> raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedIdentifier(nm)) } + | nm -> raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedIdentifier(nm + " (3)")) } | typar COLON IDENT { match $3 with | "comparison" -> SynTypeConstraint.WhereTyparIsComparable($1, lhs parseState) | "equality" -> SynTypeConstraint.WhereTyparIsEquatable($1, lhs parseState) | "unmanaged" -> SynTypeConstraint.WhereTyparIsUnmanaged($1, lhs parseState) - | nm -> raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedIdentifier(nm)) } + | nm -> raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedIdentifier(nm + " (4)")) } - | appType + | appTypeWithoutNull { SynTypeConstraint.WhereSelfConstrained($1, lhs parseState) } typeAlts: - | typeAlts OR appType + | typeAlts OR appTypeWithoutNull { let mOr = rhs parseState 2 let m = unionRanges $1.Range $3.Range SynType.Or($1, $3, m, { OrKeyword = mOr }) } - | appType + | appTypeWithoutNull { $1 } /* The core of a union type definition */ @@ -2807,6 +2802,13 @@ firstUnionCaseDecl: let mDecl = rhs2 parseState 1 3 |> unionRangeWithXmlDoc xmlDoc Choice2Of2(SynUnionCase([], SynIdent($1, None), SynUnionCaseKind.Fields $3, xmlDoc, None, mDecl, trivia)) } + | unionCaseName COLON topType + { if parseState.LexBuffer.ReportLibraryOnlyFeatures then libraryOnlyWarning(lhs parseState) + let trivia: SynUnionCaseTrivia = { BarRange = None } + let xmlDoc = grabXmlDoc (parseState, [], 1) + let mDecl = rhs2 parseState 1 3 |> unionRangeWithXmlDoc xmlDoc + Choice2Of2(SynUnionCase([], $1, SynUnionCaseKind.FullType $3, xmlDoc, None, mDecl, trivia)) } + | ident OF recover { let trivia: SynUnionCaseTrivia = { BarRange = None } let xmlDoc = grabXmlDoc (parseState, [], 1) @@ -2847,12 +2849,12 @@ unionCaseReprElements: { [$1] } unionCaseReprElement: - | ident COLON appType + | ident COLON appTypeNullableInParens { let xmlDoc = grabXmlDoc(parseState, [], 1) let mWhole = rhs2 parseState 1 3 |> unionRangeWithXmlDoc xmlDoc mkSynNamedField ($1, $3, xmlDoc, mWhole) } - | appType + | appTypeNullableInParens { let xmlDoc = grabXmlDoc(parseState, [], 1) mkSynAnonField ($1, xmlDoc) } @@ -3175,6 +3177,9 @@ cType: { let m = lhs parseState SynType.App(SynType.LongIdent(SynLongIdent([ident("nativeptr", m)], [], [ Some(IdentTrivia.OriginalNotation "*") ])), None, [$1], [], None, true, m) } + | cType BAR_JUST_BEFORE_NULL NULL + { SynType.WithNull($1, false, lhs parseState) } + | cType AMP { let m = lhs parseState SynType.App(SynType.LongIdent(SynLongIdent([ident("byref", m)], [], [ Some(IdentTrivia.OriginalNotation "&") ])), None, [$1], [], None, true, m) } @@ -3454,9 +3459,15 @@ simplePatterns: | LPAREN rparen { SynPat.Const(SynConst.Unit, rhs2 parseState 1 2) } +barCanBeRightBeforeNull: + | BAR + { } + | BAR_JUST_BEFORE_NULL + { } + headBindingPattern: - | headBindingPattern AS constrPattern + | headBindingPattern AS constrPattern %prec AS { SynPat.As($1, $3, rhs2 parseState 1 3) } | headBindingPattern AS recover @@ -3470,7 +3481,7 @@ headBindingPattern: let pat2 = SynPat.Wild(mAs.EndRange) SynPat.As($1, pat2, rhs2 parseState 1 2) } - | headBindingPattern BAR headBindingPattern + | headBindingPattern barCanBeRightBeforeNull headBindingPattern %prec BAR { let mBar = rhs parseState 2 SynPat.Or($1, $3, rhs2 parseState 1 3, { BarRange = mBar }) } @@ -3751,7 +3762,7 @@ parenPatternBody: /* duplicating the entire expression grammar, or making a fairly severe breaking change */ /* to the language. */ parenPattern: - | parenPattern AS constrPattern + | parenPattern AS constrPattern %prec AS { SynPat.As($1, $3, rhs2 parseState 1 3) } | parenPattern AS recover @@ -3765,7 +3776,7 @@ parenPattern: reportParseErrorAt mAs (FSComp.SR.parsExpectingPattern ()) SynPat.As($1, pat2, rhs2 parseState 1 2) } - | parenPattern BAR parenPattern + | parenPattern barCanBeRightBeforeNull parenPattern %prec BAR { let mBar = rhs parseState 2 SynPat.Or($1, $3, rhs2 parseState 1 3, { BarRange = mBar }) } @@ -4675,11 +4686,11 @@ withPatternClauses: | patternClauses { $1 None } - | BAR patternClauses + | barCanBeRightBeforeNull patternClauses { let mBar = rhs parseState 1 |> Some $2 mBar } - | BAR BAR patternClauses + | BAR barCanBeRightBeforeNull patternClauses { let mBar1 = rhs parseState 1 let mBar2 = rhs parseState 2 reportParseErrorAt mBar2 (FSComp.SR.parsExpectingPattern ()) @@ -4687,7 +4698,7 @@ withPatternClauses: let clauses = addEmptyMatchClause mBar1 mBar2 clauses clauses, mLast } - | BAR error + | barCanBeRightBeforeNull error { // silent recovery let mLast = rhs parseState 1 [], mLast } @@ -4711,7 +4722,7 @@ patternClauses: fun mBar -> [SynMatchClause(pat, guard, resultExpr, m, DebugPointAtTarget.Yes, { ArrowRange = Some mArrow; BarRange = mBar })], mLast } - | patternAndGuard patternResult BAR patternClauses + | patternAndGuard patternResult barCanBeRightBeforeNull patternClauses { let pat, guard = $1 let mArrow, resultExpr = $2 let mNextBar = rhs parseState 3 |> Some @@ -4720,7 +4731,7 @@ patternClauses: fun mBar -> (SynMatchClause(pat, guard, resultExpr, m, DebugPointAtTarget.Yes, { ArrowRange = Some mArrow; BarRange = mBar }) :: clauses), mLast } - | patternAndGuard patternResult BAR BAR patternClauses + | patternAndGuard patternResult BAR barCanBeRightBeforeNull patternClauses { let pat, guard = $1 let mArrow, resultExpr = $2 let mBar1 = rhs parseState 3 @@ -4734,7 +4745,7 @@ patternClauses: let trivia = { ArrowRange = Some mArrow; BarRange = mBar } SynMatchClause(pat, guard, resultExpr, m, DebugPointAtTarget.Yes, trivia) :: clauses, mLast } - | patternAndGuard error BAR patternClauses + | patternAndGuard error barCanBeRightBeforeNull patternClauses { let pat, guard = $1 let mNextBar = rhs parseState 3 |> Some let clauses, mLast = $4 mNextBar @@ -4743,7 +4754,7 @@ patternClauses: fun _mBar -> (SynMatchClause(pat, guard, arbExpr ("patternClauses1", m.EndRange), m, DebugPointAtTarget.Yes, SynMatchClauseTrivia.Zero) :: clauses), mLast } - | patternAndGuard patternResult BAR recover + | patternAndGuard patternResult barCanBeRightBeforeNull recover { let pat, guard = $1 let mArrow, resultExpr = $2 let mLast = rhs parseState 3 @@ -5294,9 +5305,10 @@ typars: SynType.Paren($2, m) } typarAlts: - | typarAlts OR appType + | typarAlts OR appTypeCanBeNullable { let mOr = rhs parseState 2 - let m = unionRanges $1.Range $3.Range + let appType : SynType = $3 + let m = unionRanges $1.Range appType.Range SynType.Or($1, $3, m, { OrKeyword = mOr }) } | typar @@ -5643,7 +5655,7 @@ opt_objExprInterfaces: { (* silent recovery *) $2 } objExprInterface: - | interfaceMember appType opt_objExprBindings opt_declEnd opt_OBLOCKSEP + | interfaceMember appTypeWithoutNull opt_objExprBindings opt_declEnd opt_OBLOCKSEP { let mWithKwd, bindings, members = $3 let m = match List.tryLast members with @@ -5865,14 +5877,14 @@ topTupleTypeElements: [ SynTupleTypeSegment.Type t, Some argInfo ] } topAppType: - | attributes appType COLON appType + | attributes appTypeCanBeNullable COLON appTypeCanBeNullable { match $2 with | SynType.LongIdent(SynLongIdent([id], _, _)) -> let m = unionRanges (rhs parseState 1) $4.Range SynType.SignatureParameter($1, false, Some id, $4, m), SynArgInfo($1, false, Some id) | _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) } - | attributes appType COLON recover + | attributes appTypeCanBeNullable COLON recover { match $2 with | SynType.LongIdent(SynLongIdent([id], _, _)) -> let mColon = rhs parseState 2 @@ -5881,7 +5893,7 @@ topAppType: SynType.SignatureParameter($1, false, Some id, ty, m), SynArgInfo($1, false, Some id) | _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) } - | attributes QMARK ident COLON appType + | attributes QMARK ident COLON appTypeCanBeNullable { let m = unionRanges (rhs parseState 1) $5.Range SynType.SignatureParameter($1, true, Some $3, $5, m), SynArgInfo($1, true, Some $3) } @@ -5891,18 +5903,18 @@ topAppType: let ty = SynType.FromParseError(mColon.EndRange) SynType.SignatureParameter($1, true, Some $3, ty, m), SynArgInfo($1, true, Some $3) } - | attributes appType + | attributes appTypeCanBeNullable { let m = unionRanges (rhs parseState 1) $2.Range SynType.SignatureParameter($1, false, None, $2, m), SynArgInfo($1, false, None) } - | appType COLON appType + | appTypeCanBeNullable COLON appTypeCanBeNullable { match $1 with | SynType.LongIdent(SynLongIdent([id], _, _)) -> let m = unionRanges (rhs parseState 1) $3.Range SynType.SignatureParameter([], false, Some id, $3, m), SynArgInfo([], false, Some id) | _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) } - | appType COLON recover + | appTypeCanBeNullable COLON recover { match $1 with | SynType.LongIdent(SynLongIdent([id], _, _)) -> let mColon = rhs parseState 2 @@ -5911,7 +5923,7 @@ topAppType: SynType.SignatureParameter([], false, Some id, ty, m), SynArgInfo([], false, Some id) | _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) } - | QMARK ident COLON appType + | QMARK ident COLON appTypeCanBeNullable { let m = unionRanges (rhs parseState 1) $4.Range SynType.SignatureParameter([], true, Some $2, $4, m), SynArgInfo([], true, Some $2) } @@ -5921,22 +5933,22 @@ topAppType: let ty = SynType.FromParseError(mColon.EndRange) SynType.SignatureParameter([], true, Some $2, ty, m), SynArgInfo([], true, Some $2) } - | appType + | appTypeCanBeNullable { $1, SynArgInfo([], false, None) } /* Grammar rule meant for recovery scenarios */ /* For example in unionCaseReprElement where function type is not allowed */ invalidUseOfAppTypeFunction: - | appType RARROW invalidUseOfAppTypeFunction + | appTypeWithoutNull RARROW invalidUseOfAppTypeFunction { let mArrow = rhs parseState 2 let m = unionRanges (rhs2 parseState 1 2) $3.Range SynType.Fun($1, $3, m, { ArrowRange = mArrow }) } - | appType RARROW recover + | appTypeWithoutNull RARROW recover { let mArrow = rhs parseState 2 let ty = SynType.FromParseError(mArrow.EndRange) let m = rhs2 parseState 1 2 SynType.Fun($1, ty, m, { ArrowRange = mArrow }) } - | appType RARROW RARROW invalidUseOfAppTypeFunction + | appTypeWithoutNull RARROW RARROW invalidUseOfAppTypeFunction { let mArrow1 = rhs parseState 2 let mArrow2 = rhs parseState 3 reportParseErrorAt mArrow2 (FSComp.SR.parsExpectingType ()) @@ -5944,7 +5956,7 @@ invalidUseOfAppTypeFunction: let m1 = unionRanges $1.Range $4.Range let m2 = unionRanges mArrow2 $4.Range SynType.Fun($1, SynType.Fun(ty, $4, m2, { ArrowRange = mArrow2 }), m1, { ArrowRange = mArrow1 }) } - | appType RARROW appType + | appTypeWithoutNull RARROW appTypeWithoutNull { let mArrow = rhs parseState 2 let m = rhs2 parseState 1 3 SynType.Fun($1, $3, m, { ArrowRange = mArrow }) } @@ -5980,12 +5992,12 @@ typEOF: tupleType: - | appType STAR tupleOrQuotTypeElements + | appTypeCanBeNullable STAR tupleOrQuotTypeElements { let mStar = rhs parseState 2 let path = SynTupleTypeSegment.Type $1 :: SynTupleTypeSegment.Star mStar :: $3 mkSynTypeTuple path } - | appType STAR recover + | appTypeCanBeNullable STAR recover { let mStar = rhs parseState 2 let ty = SynType.FromParseError(mStar.EndRange) let path = [SynTupleTypeSegment.Type $1; SynTupleTypeSegment.Star mStar; SynTupleTypeSegment.Type ty] @@ -6011,28 +6023,28 @@ tupleType: let path = [SynTupleTypeSegment.Slash mSlash; SynTupleTypeSegment.Type ty] mkSynTypeTuple path } - | appType INFIX_STAR_DIV_MOD_OP tupleOrQuotTypeElements + | appTypeCanBeNullable INFIX_STAR_DIV_MOD_OP tupleOrQuotTypeElements { if $2 <> "/" then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedInfixOperator()) let mSlash = rhs parseState 2 let path = SynTupleTypeSegment.Type $1 :: SynTupleTypeSegment.Slash mSlash :: $3 mkSynTypeTuple path } - | appType INFIX_STAR_DIV_MOD_OP recover + | appTypeCanBeNullable INFIX_STAR_DIV_MOD_OP recover { if $2 <> "/" then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedInfixOperator ()) let mSlash = rhs parseState 2 let ty = SynType.FromParseError(mSlash.EndRange) let path = [SynTupleTypeSegment.Type $1; SynTupleTypeSegment.Slash mSlash; SynTupleTypeSegment.Type ty] mkSynTypeTuple path } - | appType %prec prec_tuptyp_prefix + | appTypeCanBeNullable %prec prec_tuptyp_prefix { $1 } tupleOrQuotTypeElements: - | appType STAR tupleOrQuotTypeElements + | appTypeCanBeNullable STAR tupleOrQuotTypeElements { let mStar = rhs parseState 2 SynTupleTypeSegment.Type $1 :: SynTupleTypeSegment.Star mStar :: $3 } - | appType STAR recover + | appTypeCanBeNullable STAR recover { let mStar = rhs parseState 2 let ty = SynType.FromParseError(mStar.EndRange) [SynTupleTypeSegment.Type $1; SynTupleTypeSegment.Star mStar; SynTupleTypeSegment.Type ty] } @@ -6043,12 +6055,12 @@ tupleOrQuotTypeElements: reportParseErrorAt mStar (FSComp.SR.parsExpectingType ()) SynTupleTypeSegment.Type ty :: SynTupleTypeSegment.Star mStar :: $2 } - | appType INFIX_STAR_DIV_MOD_OP tupleOrQuotTypeElements + | appTypeCanBeNullable INFIX_STAR_DIV_MOD_OP tupleOrQuotTypeElements { if $2 <> "/" then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedInfixOperator ()) let mSlash = rhs parseState 2 SynTupleTypeSegment.Type $1 :: SynTupleTypeSegment.Slash mSlash :: $3 } - | appType INFIX_STAR_DIV_MOD_OP recover + | appTypeCanBeNullable INFIX_STAR_DIV_MOD_OP recover { if $2 <> "/" then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedInfixOperator ()) let mSlash = rhs parseState 2 let ty = SynType.FromParseError(mSlash.EndRange) @@ -6061,7 +6073,7 @@ tupleOrQuotTypeElements: reportParseErrorAt mSlash (FSComp.SR.parsExpectingType ()) SynTupleTypeSegment.Type ty :: SynTupleTypeSegment.Slash mSlash :: $2 } - | appType %prec prec_tuptyptail_prefix + | appTypeCanBeNullable %prec prec_tuptyptail_prefix { [ SynTupleTypeSegment.Type $1 ] } intersectionType: @@ -6093,14 +6105,28 @@ appTypeConPower: | appTypeCon { $1 } -appType: - | appType arrayTypeSuffix +appTypeCanBeNullable: + | appTypeWithoutNull BAR_JUST_BEFORE_NULL NULL + { SynType.WithNull($1, false, lhs parseState) } + + | appTypeWithoutNull + { $1 } + +appTypeNullableInParens: + | appTypeWithoutNull + { $1 } + + | LPAREN appTypeCanBeNullable rparen + { SynType.Paren($2, lhs parseState) } + +appTypeWithoutNull: + | appTypeWithoutNull arrayTypeSuffix { SynType.Array($2, $1, lhs parseState) } - | appType HIGH_PRECEDENCE_BRACK_APP arrayTypeSuffix /* only HPA for "name[]" allowed here */ + | appTypeWithoutNull HIGH_PRECEDENCE_BRACK_APP arrayTypeSuffix /* only HPA for "name[]" allowed here */ { SynType.Array($3, $1, lhs parseState) } - | appType appTypeConPower + | appTypeWithoutNull appTypeConPower /* note: use "rhs parseState 1" to deal with parens in "(int) list" */ { SynType.App($2, None, [$1], [], None, true, unionRanges (rhs parseState 1) $2.Range) } @@ -6301,24 +6327,24 @@ atomType: { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedParen ()) SynType.Paren($2, lhs parseState) } - | STRUCT LPAREN appType STAR tupleOrQuotTypeElements rparen + | STRUCT LPAREN appTypeCanBeNullable STAR tupleOrQuotTypeElements rparen { let mStar = rhs parseState 4 let path = SynTupleTypeSegment.Type $3 :: SynTupleTypeSegment.Star mStar :: $5 let m = rhs2 parseState 1 6 SynType.Tuple(true, path, m) } - | STRUCT LPAREN appType STAR tupleOrQuotTypeElements recover + | STRUCT LPAREN appTypeCanBeNullable STAR tupleOrQuotTypeElements recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnmatchedParen()) let mStar = rhs parseState 4 let path = SynTupleTypeSegment.Type $3 :: SynTupleTypeSegment.Star mStar :: $5 let m = rhs2 parseState 1 5 SynType.Tuple(true, path, m) } - | STRUCT LPAREN appType STAR recover + | STRUCT LPAREN appTypeCanBeNullable STAR recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnmatchedParen()) SynType.Anon(lhs parseState) } - | STRUCT LPAREN appType recover + | STRUCT LPAREN appTypeCanBeNullable recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnmatchedParen()) SynType.Anon(lhs parseState) } @@ -6331,7 +6357,7 @@ atomType: | NULL { let m = rhs parseState 1 - SynType.StaticConstant(SynConst.String(null, SynStringKind.Regular, m), m) } + SynType.StaticConstantNull(m) } | CONST atomicExpr { let e, _ = $2 @@ -6766,12 +6792,6 @@ deprecated_opt_equals: | EQUALS { deprecatedWithError (FSComp.SR.parsNoEqualShouldFollowNamespace()) (lhs parseState); () } | /* EMPTY */ { } -opt_equals: - | EQUALS - { let mEquals = rhs parseState 1 - Some mEquals } - | /* EMPTY */ { None } - opt_OBLOCKSEP: | OBLOCKSEP { } | /* EMPTY */ { } @@ -6784,10 +6804,6 @@ opt_rec: | REC { true } | /* EMPTY */ { false } -opt_bar: - | BAR { } - | /* EMPTY */ { } - opt_inline: | INLINE { Some(rhs parseState 1) } | /* EMPTY */ { None } diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 6ff88000aa8..5559f2b191d 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -192,6 +192,11 @@ Známý typ parametru: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match Argument na indexu {0} neodpovídá @@ -202,6 +207,16 @@ Argument {0} neodpovídá + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent Omezení „unmanaged“ a „not struct“ jsou nekonzistentní @@ -227,6 +242,11 @@ Atribut sestavení {0} odkazuje na navržené sestavení {1}, které se nedá načíst nebo neexistuje. Ohlášená výjimka: {2} – {3} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function zkrácený tvar podtržítka pouze pro funkci přístupový objekt @@ -447,6 +467,11 @@ nepovinný zprostředkovatel komunikace s možnou hodnotou null + + nullness checking + nullness checking + + open type declaration Otevřít deklaraci typu @@ -832,6 +857,11 @@ Vytiskněte odvozená rozhraní všech kompilovaných souborů do přidružených souborů podpisu. + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache Vymazat mezipaměť výsledků správce balíčků @@ -1422,6 +1452,11 @@ Hodnota {0} není funkce a nepodporuje zápis indexu. + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. Syntaxe expr1[expr2] je při použití jako argument nejednoznačná. Více informací: https://aka.ms/fsharp-index-notation. Pokud plánujete indexování nebo vytváření řezů, musíte použít expr1.[expr2] na pozici argumentu. Pokud voláte funkci s vícenásobnými curryfikovanými argumenty, přidejte mezi ně mezeru, třeba someFunction expr1 [expr2]. @@ -1447,6 +1482,36 @@ Syntaxe (expr1)[expr2] je teď pro indexování vyhrazená a je při použití jako argument nejednoznačná. Více informací: https://aka.ms/fsharp-index-notation. Pokud voláte funkci s vícenásobnými curryfikovanými argumenty, přidejte mezi ně mezeru, třeba someFunction (expr1) [expr2]. + + Value known to be without null passed to a function meant for nullables: {0} + Value known to be without null passed to a function meant for nullables: {0} + + + + You can remove this |Null|NonNull| pattern usage. + You can remove this |Null|NonNull| pattern usage. + + + + You can remove this |NonNullQuick| pattern usage. + You can remove this |NonNullQuick| pattern usage. + + + + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + + + + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + + + + You can remove this `nonNull` assertion. + You can remove this `nonNull` assertion. + + The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSources' and 'Bind' methods Konstrukt „let! ... and! ...“ se dá použít jen v případě, že tvůrce výpočetních výrazů definuje buď metodu „{0}“, nebo vhodné metody „MergeSource“ a „Bind“. @@ -1532,6 +1597,11 @@ Vlastnost nesmí určovat volitelné argumenty, in, out, ParamArray, CallerInfo nebo Quote. + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} Neplatný interpolovaný řetězec. {0} diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 7eedd1621e1..a1e0be98a8c 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -192,6 +192,11 @@ Bekannter Typparameter: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match Das Argument bei Index {0} stimmt nicht überein. @@ -202,6 +207,16 @@ Das Argument "{0}" stimmt nicht überein. + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent Die Einschränkungen "unmanaged" und "not struct" sind nicht konsistent. @@ -227,6 +242,11 @@ Das Assemblyattribut "{0}" verweist auf eine Designerassembly "{1}", die entweder nicht geladen werden kann oder nicht vorhanden ist. Gemeldete Ausnahme: {2} – {3} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function Unterstrich-Punkt-Kurzschreibweise für Accessorfunktion @@ -447,6 +467,11 @@ Interop, NULL-Werte zulassend, optional + + nullness checking + nullness checking + + open type declaration Deklaration für offene Typen @@ -832,6 +857,11 @@ Drucken der abgeleiteten Schnittstellen aller Dateien an zugehörige Signaturdateien + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache Löschen Sie den Ergebniscache des Paketmanagers @@ -1422,6 +1452,11 @@ Der Wert "{0}" ist keine Funktion und unterstützt keine Indexnotation. + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. Die Syntax "expr1[expr2]" ist mehrdeutig, wenn sie als Argument verwendet wird. Siehe https://aka.ms/fsharp-index-notation. Wenn Sie indizieren oder aufteilen möchten, müssen Sie "expr1.[expr2]' in Argumentposition verwenden. Wenn Sie eine Funktion mit mehreren geschweiften Argumenten aufrufen, fügen Sie ein Leerzeichen dazwischen hinzu, z. B. "someFunction expr1 [expr2]". @@ -1447,6 +1482,36 @@ Die Syntax "(expr1)[expr2]" ist jetzt für die Indizierung reserviert und mehrdeutig, wenn sie als Argument verwendet wird. Siehe https://aka.ms/fsharp-index-notation. Wenn Sie eine Funktion mit mehreren geschweiften Argumenten aufrufen, fügen Sie ein Leerzeichen dazwischen hinzu, z. B. "someFunction (expr1) [expr2]". + + Value known to be without null passed to a function meant for nullables: {0} + Value known to be without null passed to a function meant for nullables: {0} + + + + You can remove this |Null|NonNull| pattern usage. + You can remove this |Null|NonNull| pattern usage. + + + + You can remove this |NonNullQuick| pattern usage. + You can remove this |NonNullQuick| pattern usage. + + + + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + + + + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + + + + You can remove this `nonNull` assertion. + You can remove this `nonNull` assertion. + + The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSources' and 'Bind' methods Das Konstrukt "let! ... and! ..." kann nur verwendet werden, wenn der Berechnungsausdrucks-Generator entweder eine {0}-Methode oder geeignete MergeSources- und Bind-Methoden definiert. @@ -1532,6 +1597,11 @@ Ein Merkmal darf keine Argumente für „optional“, „in“, „out“, „ParamArray“", „CallerInfo“ oder „Quote“ angeben. + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} Ungültige interpolierte Zeichenfolge. {0} diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index fa499f1cd42..a9e9dee5ed5 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -192,6 +192,11 @@ Parámetro de tipo conocido: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match El argumento del índice {0} no coincide. @@ -202,6 +207,16 @@ El argumento "{0}" no coincide. + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent Las restricciones “no administrado” y "no estructurado" son incoherentes @@ -227,6 +242,11 @@ El atributo de ensamblado "{0}" hace referencia a un ensamblado de diseñador "{1}" que no se puede cargar o no existe. Se notificó la excepción: {2} - {3}. + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function forma abreviada de punto y guion bajo para la función de solo descriptor de acceso @@ -447,6 +467,11 @@ interoperabilidad opcional que admite valores NULL + + nullness checking + nullness checking + + open type declaration declaración de tipo abierto @@ -832,6 +857,11 @@ Imprimir las interfaces deducidas de todos los archivos de compilación en los archivos de signatura asociados + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache Borrar la caché de resultados del administrador de paquetes @@ -1422,6 +1452,11 @@ El valor "{0}" no es una función y no admite la notación de índices. + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. La sintaxis "expr1[expr2]" es ambigua cuando se usa como argumento. Vea https://aka.ms/fsharp-index-notation. Si piensa indexar o segmentar, debe usar "expr1.[expr2]" en la posición del argumento. Si se llama a una función con varios argumentos currificados, se agregará un espacio entre ellos, por ejemplo, "unaFunción expr1 [expr2]". @@ -1447,6 +1482,36 @@ La sintaxis "(expr1)[expr2]" está reservada ahora para la indexación y es ambigua cuando se usa como argumento. Vea https://aka.ms/fsharp-index-notation. Si se llama a una función con varios argumentos currificados, agregue un espacio entre ellos, por ejemplo, "unaFunción (expr1) [expr2]". + + Value known to be without null passed to a function meant for nullables: {0} + Value known to be without null passed to a function meant for nullables: {0} + + + + You can remove this |Null|NonNull| pattern usage. + You can remove this |Null|NonNull| pattern usage. + + + + You can remove this |NonNullQuick| pattern usage. + You can remove this |NonNullQuick| pattern usage. + + + + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + + + + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + + + + You can remove this `nonNull` assertion. + You can remove this `nonNull` assertion. + + The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSources' and 'Bind' methods La construcción "let! ... and! ..." solo se puede usar si el generador de expresiones de cálculo define un método "{0}" o bien los métodos "MergeSources" y "Bind" adecuados. @@ -1532,6 +1597,11 @@ Un rasgo no puede especificar argumentos opcionales, in, out, ParamArray, CallerInfo o Quote + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} Cadena interpolada no válida. {0} diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 7ad21f1b389..fa3b567b86d 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -192,6 +192,11 @@ Paramètre de type connu : {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match L'argument à l'index {0} ne correspond pas @@ -202,6 +207,16 @@ L'argument '{0}' ne correspond pas + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent Les contraintes « non gérées » et « non structurées » sont incohérentes @@ -227,6 +242,11 @@ L'attribut d'assembly '{0}' fait référence à un assembly de concepteur '{1}' qui ne peut pas être chargé ou qui n'existe pas. Exception signalée : {2} - {3} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function raccourci de point de soulignement pour la fonction d'accesseur uniquement @@ -447,6 +467,11 @@ interopérabilité facultative pouvant accepter une valeur null + + nullness checking + nullness checking + + open type declaration déclaration de type ouverte @@ -832,6 +857,11 @@ Imprimer les interfaces inférées de tous les fichiers de compilation sur les fichiers de signature associés + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache Effacer le cache des résultats du Gestionnaire de package @@ -1422,6 +1452,11 @@ La valeur « {0} » n’est pas une fonction et ne prend pas en charge la notation d’index. + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. La syntaxe « expr1[expr2] » est ambiguë lorsqu’elle est utilisée comme argument. Voir https://aka.ms/fsharp-index-notation. Si vous avez l’intention d’indexer ou de découper, vous devez utiliser « expr1.[expr2] » en position d’argument. Si vous appelez une fonction avec plusieurs arguments codés, ajoutez un espace entre eux, par exemple « someFunction expr1 [expr2] ». @@ -1447,6 +1482,36 @@ La syntaxe « (expr1)[expr2] » est désormais réservée à l’indexation et est ambiguë lorsqu’elle est utilisée comme argument. Voir https://aka.ms/fsharp-index-notation. Si vous appelez une fonction avec plusieurs arguments codés, ajoutez un espace entre eux, par exemple « someFunction (expr1) [expr2] ». + + Value known to be without null passed to a function meant for nullables: {0} + Value known to be without null passed to a function meant for nullables: {0} + + + + You can remove this |Null|NonNull| pattern usage. + You can remove this |Null|NonNull| pattern usage. + + + + You can remove this |NonNullQuick| pattern usage. + You can remove this |NonNullQuick| pattern usage. + + + + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + + + + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + + + + You can remove this `nonNull` assertion. + You can remove this `nonNull` assertion. + + The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSources' and 'Bind' methods Le « laissez ! » ... et! ...' ne peut être utilisée que si le générateur d'expression de calcul définit soit une méthode '{0}', soit des méthodes 'MergeSources' et 'Bind' appropriées. @@ -1532,6 +1597,11 @@ Une caractéristique ne peut pas spécifier d’arguments facultatifs, in, out, ParamArray, CallerInfo ou Quote + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} Chaîne interpolée non valide. {0} diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 80c600dcfb9..699c21f3d9b 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -192,6 +192,11 @@ Parametro di tipo noto: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match L'argomento alla posizione di indice {0} non corrisponde @@ -202,6 +207,16 @@ L'argomento '{0}' non corrisponde + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent I vincoli 'unmanaged' e 'not struct' sono incoerenti @@ -227,6 +242,11 @@ L'attributo di assembly '{0}' fa riferimento a un assembly '{1}' della finestra di progettazione che non è stato caricato o non esiste. L'eccezione restituita è {2} - {3} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function sintassi abbreviata del punto di sottolineatura solo per la funzione di accesso @@ -447,6 +467,11 @@ Interop facoltativo nullable + + nullness checking + nullness checking + + open type declaration dichiarazione di tipo aperto @@ -832,6 +857,11 @@ Stampare le interfacce derivate di tutti i file di compilazione nei file di firma associati + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache Cancellare la cache dei risultati di Gestione pacchetti @@ -1422,6 +1452,11 @@ Questo valore '{0}' non è una funzione e non supporta la notazione degli indici. + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. La sintassi 'expr1[expr2]' è ambigua se usata come argomento. Vedere https://aka.ms/fsharp-index-notation. Se si intende eseguire l'indicizzazione o il sezionamento, è necessario usare 'expr1.[expr2]' nella posizione dell'argomento. Se si chiama una funzione con più argomenti sottoposti a corsi, aggiungere uno spazio tra di essi, ad esempio 'someFunction expr1 [expr2]'. @@ -1447,6 +1482,36 @@ La sintassi '(expr1)[expr2]' è ora riservata per l'indicizzazione ed è ambigua quando usata come argomento. Vedere https://aka.ms/fsharp-index-notation. Se si chiama una funzione con più argomenti sottoposti a corsi, aggiungere uno spazio tra di essi, ad esempio 'someFunction (expr1) [expr2]'. + + Value known to be without null passed to a function meant for nullables: {0} + Value known to be without null passed to a function meant for nullables: {0} + + + + You can remove this |Null|NonNull| pattern usage. + You can remove this |Null|NonNull| pattern usage. + + + + You can remove this |NonNullQuick| pattern usage. + You can remove this |NonNullQuick| pattern usage. + + + + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + + + + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + + + + You can remove this `nonNull` assertion. + You can remove this `nonNull` assertion. + + The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSources' and 'Bind' methods È possibile usare il costrutto "let! ... and! ..." solo se il generatore di espressioni di calcolo definisce un metodo "{0}" o metodi "MergeSource" e "Bind" appropriati @@ -1532,6 +1597,11 @@ Un tratto non può specificare argomenti optional, in, out, ParamArray, CallerInfo o Quote + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} La stringa interpolata non è valida. {0} diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 94043ae19dc..9bb6e79a4b1 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -192,6 +192,11 @@ 既知の型パラメーター: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match インデックス {0} の引数が一致しません @@ -202,6 +207,16 @@ 引数 '{0}' が一致しません + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent 制約 'unmanaged' と 'not struct' が矛盾しています @@ -227,6 +242,11 @@ アセンブリ属性 '{0}' は、デザイナー アセンブリ '{1}' を参照していますが、これは読み込むことができないか、存在していません。報告された例外: {2} - {3} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function アクセサー専用関数のアンダースコア ドット短縮形 @@ -447,6 +467,11 @@ Null 許容のオプションの相互運用 + + nullness checking + nullness checking + + open type declaration オープン型宣言 @@ -832,6 +857,11 @@ すべてのコンパイル ファイルの推定されたインターフェイスを関連する署名ファイルに印刷します + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache パッケージ マネージャーの結果キャッシュをクリアする @@ -1422,6 +1452,11 @@ 値 '{0}' は関数ではなく、インデックス表記をサポートしていません。 + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. 構文 'expr1[expr2]' は引数として使用されている場合、あいまいです。https://aka.ms/fsharp-index-notation を参照してください。インデックス作成またはスライスを行う場合は、'expr1.[expr2]' を引数の位置に使用する必要があります。複数のカリー化された引数を持つ関数を呼び出す場合は、'expr1 [expr2]' のように間にスペースを追加します。 @@ -1447,6 +1482,36 @@ 構文 '(expr1)[expr2]' はインデックス作成に予約されているので、引数として使うとあいまいです。https://aka.ms/fsharp-index-notation を参照してください。複数のカリー化された引数を持つ関数を呼び出す場合には、'someFunction (expr1) [expr2]' のように間にスペースを追加します。 + + Value known to be without null passed to a function meant for nullables: {0} + Value known to be without null passed to a function meant for nullables: {0} + + + + You can remove this |Null|NonNull| pattern usage. + You can remove this |Null|NonNull| pattern usage. + + + + You can remove this |NonNullQuick| pattern usage. + You can remove this |NonNullQuick| pattern usage. + + + + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + + + + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + + + + You can remove this `nonNull` assertion. + You can remove this `nonNull` assertion. + + The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSources' and 'Bind' methods 'let! ... and! ...' コンストラクトは、コンピュテーション式ビルダーが '{0}' メソッドまたは適切な 'MergeSource' および 'Bind' メソッドのいずれかを定義している場合にのみ使用できます @@ -1532,6 +1597,11 @@ 特性では、オプションの、in 引数、out 引数、ParamArray 引数、CallerInfo 引数、または Quote 引数を指定することはできません + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} 補間された文字列が無効です。{0} diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index d55738f005c..044f0423ec9 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -192,6 +192,11 @@ 알려진 형식 매개 변수: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match 인덱스 {0}의 인수가 일치하지 않습니다. @@ -202,6 +207,16 @@ '{0}' 인수가 일치하지 않습니다. + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent 제약 조건 'unmanaged' 및 'not struct'가 일치하지 않습니다. @@ -227,6 +242,11 @@ '{0}' 어셈블리 특성이 로드할 수 없거나 존재하지 않는 디자이너 어셈블리'{1}'을(를) 참조합니다. 보고된 예외: {2} - {3} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function 접근자 전용 함수에 대한 밑줄 점 약어 @@ -447,6 +467,11 @@ nullable 선택적 interop + + nullness checking + nullness checking + + open type declaration 개방형 형식 선언 @@ -832,6 +857,11 @@ 모든 컴파일 파일의 유추된 인터페이스를 관련 서명 파일로 인쇄합니다. + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache 패키지 관리자 결과 캐시 지우기 @@ -1422,6 +1452,11 @@ '{0}' 값은 함수가 아니며 인덱스 표기법을 지원하지 않습니다. + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. 'expr1[expr2]' 구문은 인수로 사용될 때 모호합니다. https://aka.ms/fsharp-index-notation을 참조하세요. 인덱싱이나 슬라이싱을 하려면 인수 위치에 'expr1.[expr2]'를 사용해야 합니다. 여러 개의 커리된 인수로 함수를 호출하는 경우 그 사이에 공백을 추가하세요(예: 'someFunction expr1 [expr2]'). @@ -1447,6 +1482,36 @@ 구문 '(expr1)[expr2]'는 이제 인덱싱을 위해 예약되었으며 인수로 사용될 때 모호합니다. https://aka.ms/fsharp-index-notation을 참조하세요. 여러 개의 커리된 인수로 함수를 호출하는 경우 그 사이에 공백을 추가하세요(예: 'someFunction (expr1) [expr2]'). + + Value known to be without null passed to a function meant for nullables: {0} + Value known to be without null passed to a function meant for nullables: {0} + + + + You can remove this |Null|NonNull| pattern usage. + You can remove this |Null|NonNull| pattern usage. + + + + You can remove this |NonNullQuick| pattern usage. + You can remove this |NonNullQuick| pattern usage. + + + + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + + + + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + + + + You can remove this `nonNull` assertion. + You can remove this `nonNull` assertion. + + The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSources' and 'Bind' methods 'let! ... and! ...' 구문은 계산 식 작성기에서 '{0}' 메서드 또는 적절한 'MergeSources' 및 'Bind' 메서드를 정의한 경우에만 사용할 수 있습니다. @@ -1532,6 +1597,11 @@ 특성은 optional, in, out, ParamArray, CallerInfo, Quote 인수를 지정할 수 없습니다. + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} 잘못된 보간 문자열. {0} diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index b054772bc43..02096c371d0 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -192,6 +192,11 @@ Parametr znanego typu: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match Argument pod indeksem {0} nie jest zgodny @@ -202,6 +207,16 @@ Argument „{0}” nie jest zgodny + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent Ograniczenia „unmanaged” i „not struct” są niespójne @@ -227,6 +242,11 @@ Atrybut zestawu „{0}” odwołuje się do zestawu projektanta „{1}”, którego nie można załadować lub który nie istnieje. Zgłoszony wyjątek: {2} — {3} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function skrót podkreślenia kropki dla funkcji tylko metody dostępu @@ -447,6 +467,11 @@ opcjonalna międzyoperacyjność dopuszczająca wartość null + + nullness checking + nullness checking + + open type declaration deklaracja typu otwartego @@ -832,6 +857,11 @@ Drukowanie wywnioskowanych interfejsów wszystkich plików kompilacji do skojarzonych plików sygnatur + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache Wyczyść pamięć podręczną wyników menedżera pakietów @@ -1422,6 +1452,11 @@ Wartość elementu „{0}” nie jest funkcją i nie obsługuje notacji indeksowej. + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. Składnia wyrażenia „expr1[expr2]” jest niejednoznaczna, gdy jest używana jako argument. Zobacz https://aka.ms/fsharp-index-notation. Jeśli zamierzasz indeksować lub fragmentować, to w pozycji argumentu musi być użyte wyrażenie „expr1.[expr2]”. Jeśli wywołujesz funkcję z wieloma argumentami typu curried, dodaj spację między nimi, np. „someFunction expr1 [expr2]”. @@ -1447,6 +1482,36 @@ Składnia wyrażenia „(expr1)[expr2]” jest teraz zarezerwowana do indeksowania i jest niejednoznaczna, gdy jest używana jako argument. Zobacz: https://aka.ms/fsharp-index-notation. Jeśli wywołujesz funkcję z wieloma argumentami typu curried, dodaj spację między nimi, np. „someFunction (expr1) [expr2]”. + + Value known to be without null passed to a function meant for nullables: {0} + Value known to be without null passed to a function meant for nullables: {0} + + + + You can remove this |Null|NonNull| pattern usage. + You can remove this |Null|NonNull| pattern usage. + + + + You can remove this |NonNullQuick| pattern usage. + You can remove this |NonNullQuick| pattern usage. + + + + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + + + + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + + + + You can remove this `nonNull` assertion. + You can remove this `nonNull` assertion. + + The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSources' and 'Bind' methods Konstrukcji „let! ... and! ...” można użyć tylko wtedy, gdy konstruktor wyrażeń obliczeniowych definiuje metodę „{0}” lub odpowiednie metody „MergeSource” i „Bind” @@ -1532,6 +1597,11 @@ Cecha nie może określać opcjonalnych argumentów in, out, ParamArray, CallerInfo lub Quote + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} Nieprawidłowy ciąg interpolowany. {0} diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index ea7eabd09e5..9eb867ca94b 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -192,6 +192,11 @@ Parâmetro de tipo conhecido: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match O argumento no índice {0} não corresponde @@ -202,6 +207,16 @@ O argumento '{0}' não corresponde + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent As restrições "unmanaged" e "not struct" são inconsistentes @@ -227,6 +242,11 @@ O atributo de assembly '{0}' refere-se a um assembly de designer '{1}' que não pode ser carregado ou que não existe. A exceção relatada foi {2} – {3} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function sublinhado ponto abreviação para função somente acessador @@ -447,6 +467,11 @@ interoperabilidade opcional anulável + + nullness checking + nullness checking + + open type declaration declaração de tipo aberto @@ -832,6 +857,11 @@ Imprimir as interfaces inferidas de todos os arquivos de compilação para os arquivos de assinatura associados + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache Limpar o cache de resultados do gerenciador de pacotes @@ -1422,6 +1452,11 @@ O valor '{0}' não é uma função e não dá suporte à notação de índice. + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. A sintaxe '[expr1][expr2]' é ambígua quando usada como um argumento. Consulte https://aka.ms/fsharp-index-notation. Se você pretende indexar ou colocar em fatias, deve usar '(expr1).[expr2]' na posição do argumento. Se chamar uma função com vários argumentos na forma curried, adicione um espaço entre eles, por exemplo, 'someFunction [expr1] [expr2]'. @@ -1447,6 +1482,36 @@ A sintaxe 'expr1[expr2]' agora está reservada para indexação e é ambígua quando usada como um argumento. Consulte https://aka.ms/fsharp-index-notation. Se chamar uma função com vários argumentos na forma curried, adicione um espaço entre eles, por exemplo, 'someFunction expr1 [expr2]'. + + Value known to be without null passed to a function meant for nullables: {0} + Value known to be without null passed to a function meant for nullables: {0} + + + + You can remove this |Null|NonNull| pattern usage. + You can remove this |Null|NonNull| pattern usage. + + + + You can remove this |NonNullQuick| pattern usage. + You can remove this |NonNullQuick| pattern usage. + + + + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + + + + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + + + + You can remove this `nonNull` assertion. + You can remove this `nonNull` assertion. + + The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSources' and 'Bind' methods O “let! ... and! ...” só poderá ser usada se o construtor de expressão de cálculo definir um método “{0}” ou métodos “MergeSources” e “Bind” apropriados @@ -1532,6 +1597,11 @@ Uma característica não pode especificar os argumentos optional, in, out, ParamArray, CallerInfo ou Quote + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} Cadeia de caracteres interpolada inválida. {0} diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 74b19581d7e..7da677e4bdf 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -192,6 +192,11 @@ Известный параметр типа: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match Аргумент в индексе {0} не соответствует @@ -202,6 +207,16 @@ Аргумент "{0}" не соответствует + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent Ограничения "unmanaged" и "not struct" несовместимы @@ -227,6 +242,11 @@ Атрибут сборки "{0}" ссылается на сборку конструктора "{1}", которая не может быть загружена или не существует. Получено исключение: {2} — {3} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function символ подчеркивания, сокращение точки для функции только для метода доступа @@ -447,6 +467,11 @@ необязательное взаимодействие, допускающее значение NULL + + nullness checking + nullness checking + + open type declaration объявление открытого типа @@ -832,6 +857,11 @@ Печать определяемых интерфейсов всех файлов компиляции в связанные файлы подписей + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache Очистка кэша результатов диспетчера пакетов @@ -1422,6 +1452,11 @@ Значение {0} не является функцией и не поддерживает нотацию индекса. + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. Синтаксис "expr1[expr2]" неоднозначен при использовании в качестве аргумента. См. https://aka.ms/fsharp-index-notation. Если вы намереваетесь индексировать или разрезать, необходимо использовать "expr1.[expr2]" в позиции аргумента. При вызове функции с несколькими каррированными аргументами добавьте пробел между ними, например "someFunction expr1 [expr2]". @@ -1447,6 +1482,36 @@ Синтаксис "(expr1)[expr2]" теперь зарезервирован для индексирования и неоднозначен при использовании в качестве аргумента. См. https://aka.ms/fsharp-index-notation. При вызове функции с несколькими каррированными аргументами добавьте между ними пробел, например "someFunction (expr1) [expr2]". + + Value known to be without null passed to a function meant for nullables: {0} + Value known to be without null passed to a function meant for nullables: {0} + + + + You can remove this |Null|NonNull| pattern usage. + You can remove this |Null|NonNull| pattern usage. + + + + You can remove this |NonNullQuick| pattern usage. + You can remove this |NonNullQuick| pattern usage. + + + + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + + + + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + + + + You can remove this `nonNull` assertion. + You can remove this `nonNull` assertion. + + The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSources' and 'Bind' methods Конструкцию "let! ... and! ..." можно использовать только в том случае, если построитель выражений с вычислениями определяет либо метод "{0}", либо соответствующие методы "MergeSources" и "Bind" @@ -1532,6 +1597,11 @@ Признак не может указывать необязательные аргументы in, out, ParamArray, CallerInfo или Quote + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} Недопустимая интерполированная строка. {0} diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 7bb1622d4af..abc2339f904 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -192,6 +192,11 @@ Bilinen tür parametresi: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match {0} dizinindeki bağımsız değişken eşleşmiyor @@ -202,6 +207,16 @@ '{0}' bağımsız değişkeni eşleşmiyor + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent 'unmanaged' ve 'not struct' kısıtlamaları tutarsız @@ -227,6 +242,11 @@ '{0}' bütünleştirilmiş kod özniteliği, yüklenemeyen veya mevcut olmayan '{1}' tasarımcı bütünleştirilmiş koduna başvuruyor. Bildirilen özel durum: {2} - {3} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function yalnızca erişimci işlevi için alt çizgi nokta kısaltma @@ -447,6 +467,11 @@ null atanabilir isteğe bağlı birlikte çalışma + + nullness checking + nullness checking + + open type declaration açık tür bildirimi @@ -832,6 +857,11 @@ Tüm derleme dosyalarının çıkarsanan arabirimlerini ilişkili imza dosyalarına yazdır + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache Paket yöneticisi sonuçları önbelleğini temizle @@ -1422,6 +1452,11 @@ “{0}” değeri bir işlev değildir ve dizin gösterimini desteklemez. + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. Söz dizimi “expr1[expr2]” artık dizin oluşturma için ayrılmıştır ve bağımsız değişken olarak kullanıldığında belirsizdir. https://aka.ms/fsharp-index-notation'a bakın. Dizin oluşturmayı veya dilimlemeyi düşünüyorsanız, bağımsız değişken konumunda “expr1.[expr2]” kullanmalısınız. Birden çok curry bağımsız değişkenli bir işlev çağırıyorsanız, aralarına bir boşluk ekleyin, örn. “someFunction expr1 [expr2]”. @@ -1447,6 +1482,36 @@ Söz dizimi “(expr1)[expr2]” artık dizin oluşturma için ayrılmıştır ve bağımsız değişken olarak kullanıldığında belirsizdir. https://aka.ms/fsharp-index-notation'a bakın. Birden çok curry bağımsız değişkenli bir işlev çağırıyorsanız, aralarına bir boşluk ekleyin, örn. “someFunction (expr1) [expr2]”. + + Value known to be without null passed to a function meant for nullables: {0} + Value known to be without null passed to a function meant for nullables: {0} + + + + You can remove this |Null|NonNull| pattern usage. + You can remove this |Null|NonNull| pattern usage. + + + + You can remove this |NonNullQuick| pattern usage. + You can remove this |NonNullQuick| pattern usage. + + + + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + + + + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + + + + You can remove this `nonNull` assertion. + You can remove this `nonNull` assertion. + + The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSources' and 'Bind' methods 'let! ... and! ...' yapısı, yalnızca hesaplama ifadesi oluşturucu bir '{0}' metodunu ya da uygun 'MergeSources' ve 'Bind' metotlarını tanımlarsa kullanılabilir @@ -1532,6 +1597,11 @@ Bir nitelik optional, in, out, ParamArray, CallerInfo veya Quote bağımsız değişkenlerini belirtemiyor + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} Geçersiz düz metin arasına kod eklenmiş dize. {0} diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 07d149b0f65..c484d93b4be 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -192,6 +192,11 @@ 已知类型参数: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match 索引 {0} 处的参数不匹配 @@ -202,6 +207,16 @@ 参数 "{0}" 不匹配 + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent 约束 "unmanaged" 和 "not struct" 不一致 @@ -227,6 +242,11 @@ 程序集属性“{0}”引用了无法加载或不存在的设计器程序集“{1}”。报告的异常是: {2} - {3} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function 用于仅存取器函数的下划线点速记 @@ -447,6 +467,11 @@ 可以为 null 的可选互操作 + + nullness checking + nullness checking + + open type declaration 开放类型声明 @@ -832,6 +857,11 @@ 将所有编译文件的推断接口打印到关联的签名文件 + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache 清除包管理器结果缓存 @@ -1422,6 +1452,11 @@ 值 '{0}' 不是函数,不支持索引表示法。 + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. 语法“expr1[expr2]”用作参数时不明确。请参阅 https://aka.ms/fsharp-index-notation。如果要索引或切片,则必须在参数位置使用“expr1.[expr2]”。如果使用多个扩充参数调用函数,请在它们之间添加空格,例如“someFunction expr1 [expr2]”。 @@ -1447,6 +1482,36 @@ 语法“(expr1)[expr2]”现在保留用于索引,用作参数时不明确。请参见 https://aka.ms/fsharp-index-notation。如果使用多个扩充参数调用函数, 请在它们之间添加空格,例如“someFunction (expr1) [expr2]”。 + + Value known to be without null passed to a function meant for nullables: {0} + Value known to be without null passed to a function meant for nullables: {0} + + + + You can remove this |Null|NonNull| pattern usage. + You can remove this |Null|NonNull| pattern usage. + + + + You can remove this |NonNullQuick| pattern usage. + You can remove this |NonNullQuick| pattern usage. + + + + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + + + + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + + + + You can remove this `nonNull` assertion. + You can remove this `nonNull` assertion. + + The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSources' and 'Bind' methods 仅当计算表达式生成器定义了 "{0}" 方法或适当的 "MergeSources" 和 "Bind" 方法时,才可以使用 "let! ... and! ..." 构造 @@ -1532,6 +1597,11 @@ 特征不能指定 option、in、out、ParamArray、CallerInfo 或 Quote 参数 + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} 内插字符串无效。{0} diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 3e5b8d167ae..1fd0f4a1de6 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -192,6 +192,11 @@ 已知的型別參數: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match 位於索引 {0} 的引數不相符 @@ -202,6 +207,16 @@ 引數 '{0}' 不相符 + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent 條件約束 'unmanaged' 與 'not struct' 不一致 @@ -227,6 +242,11 @@ 無法載入組件屬性 '{0}' 參考的設計工具組件 '{1}' 或其不存在。回報的例外狀況: {2} - {3} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function 僅存取子函式的底線點速記 @@ -447,6 +467,11 @@ 可為 Null 的選擇性 Interop + + nullness checking + nullness checking + + open type declaration 開放式類型宣告 @@ -832,6 +857,11 @@ 將所有編譯檔案的推斷介面列印至相關聯的簽章檔案 + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache 清除封裝管理員結果快取 @@ -1422,6 +1452,11 @@ 值 '{0}' 並非函式,不支援索引標記法。 + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. 語法 'expr1[expr2]' 用作引數時不明確。請參閱 https://aka.ms/fsharp-index-notation。如果您要編製索引或切割,則必須在引數位置使用 'expr1.[expr2]'。如果要呼叫具有多個調用引數的函式,請在它們之間新增空格,例如 'someFunction expr1 [expr2]'。 @@ -1447,6 +1482,36 @@ 語法 '(expr1)[expr2]' 現已為編製索引保留,但用作引數時不明確。請參閱 https://aka.ms/fsharp-index-notation。如果要呼叫具有多個調用引數的函式,請在它們之間新增空格,例如 'someFunction (expr1) [expr2]'。 + + Value known to be without null passed to a function meant for nullables: {0} + Value known to be without null passed to a function meant for nullables: {0} + + + + You can remove this |Null|NonNull| pattern usage. + You can remove this |Null|NonNull| pattern usage. + + + + You can remove this |NonNullQuick| pattern usage. + You can remove this |NonNullQuick| pattern usage. + + + + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value. + + + + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + You can create 'ValueSome value' directly instead of 'ofObj', or consider not using a voption for this value. + + + + You can remove this `nonNull` assertion. + You can remove this `nonNull` assertion. + + The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSources' and 'Bind' methods 只有在計算運算式產生器定義 '{0}' 方法或正確的 'MergeSource' 和 'Bind' 方法時,才可使用 'let! ... and! ...' 建構 @@ -1532,6 +1597,11 @@ 特徵不能指定選擇性、in、out、ParamArray、CallerInfo 或 Quote 引數 + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} 插補字串無效。{0} diff --git a/src/Compiler/xlf/FSStrings.cs.xlf b/src/Compiler/xlf/FSStrings.cs.xlf index 4c71607759e..46ce3f6091b 100644 --- a/src/Compiler/xlf/FSStrings.cs.xlf +++ b/src/Compiler/xlf/FSStrings.cs.xlf @@ -12,6 +12,26 @@ Definice {0} pro typ {1} v signatuře a implementaci nejsou kompatibilní, protože se liší zkratky:\n {2}\noproti\n {3} + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n Neshoda typů Očekává se řazená kolekce členů o délce {0} typu\n {1} \nale odevzdala se řazená kolekce členů o délce {2} typu\n {3}{4}\n @@ -37,6 +57,11 @@ Očekává se statický člen. + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' symbol ..^ diff --git a/src/Compiler/xlf/FSStrings.de.xlf b/src/Compiler/xlf/FSStrings.de.xlf index a4798632f7b..2ce4652974c 100644 --- a/src/Compiler/xlf/FSStrings.de.xlf +++ b/src/Compiler/xlf/FSStrings.de.xlf @@ -12,6 +12,26 @@ Die {0}-Definitionen für den Typ „{1}“ in der Signatur und in der Implementierung sind aufgrund unterschiedlicher Abkürzungen nicht kompatibel:\n {2}\nversus\n {3} + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n Typenkonflikt. Es wurde ein Tupel der Länge {0} des Typs\n {1} \nerwartet, aber ein Tupel der Länge {2} des Typs\n {3}{4}\n angegeben. @@ -37,6 +57,11 @@ Ein statischer Member wird erwartet. + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' Symbol "..^" diff --git a/src/Compiler/xlf/FSStrings.es.xlf b/src/Compiler/xlf/FSStrings.es.xlf index 49ca0efe4e2..51bfee3cd37 100644 --- a/src/Compiler/xlf/FSStrings.es.xlf +++ b/src/Compiler/xlf/FSStrings.es.xlf @@ -12,6 +12,26 @@ Las definiciones de {0} para el tipo "{1}" de la firma y la implementación no son compatibles porque las abreviaciones difieren:\n {2}\nversus\n {3} + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n Error de coincidencia de tipos. Se espera una tupla de longitud {0} de tipo\n {1} \nperero se ha proporcionado una tupla de longitud {2} de tipo\n {3}{4}\n @@ -37,6 +57,11 @@ Se espera un miembro estático. + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' símbolo "..^" diff --git a/src/Compiler/xlf/FSStrings.fr.xlf b/src/Compiler/xlf/FSStrings.fr.xlf index 7b56833eace..f74d120e3f4 100644 --- a/src/Compiler/xlf/FSStrings.fr.xlf +++ b/src/Compiler/xlf/FSStrings.fr.xlf @@ -12,6 +12,26 @@ Les définitions {0} pour le type « {1} » dans la signature et l'implémentation ne sont pas compatibles, car les abréviations sont différentes :\n {2}\npar opposition à\n {3} + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n Incompatibilité de type. Tuple de longueur attendu {0} de type\n {1} \nmais tuple de longueur {2} de type\n {3}{4}\n @@ -37,6 +57,11 @@ Un membre statique est attendu. + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' symbole '..^' diff --git a/src/Compiler/xlf/FSStrings.it.xlf b/src/Compiler/xlf/FSStrings.it.xlf index 595f6758384..c2c699b779c 100644 --- a/src/Compiler/xlf/FSStrings.it.xlf +++ b/src/Compiler/xlf/FSStrings.it.xlf @@ -12,6 +12,26 @@ Le definizioni di {0} per il tipo '{1}' nella firma e nell'implementazione non sono compatibili perché le abbreviazioni sono diverse:\n {2}\n anziché \n {3} + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n Tipo non corrispondente. È prevista una tupla di lunghezza {0} di tipo\n {1} \n, ma è stata specificata una tupla di lunghezza {2} di tipo\n {3}{4}\n @@ -37,6 +57,11 @@ È previsto un membro statico. + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' simbolo '..^' diff --git a/src/Compiler/xlf/FSStrings.ja.xlf b/src/Compiler/xlf/FSStrings.ja.xlf index 2b0f25af2ba..87716ab3c1f 100644 --- a/src/Compiler/xlf/FSStrings.ja.xlf +++ b/src/Compiler/xlf/FSStrings.ja.xlf @@ -12,6 +12,26 @@ シグネチャおよび実装内の型 '{0}' の {1} 定義は、省略形が異なるため\n ({2}\nと \n {3})、互換性がありません + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n 型が一致しません。型の長さ {0} のタプルが必要です\n {1} \nただし、型の長さ {2} のタプルが指定された場合\n {3}{4}\n @@ -37,6 +57,11 @@ 静的メンバーが必要です。 + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' シンボル '..^' diff --git a/src/Compiler/xlf/FSStrings.ko.xlf b/src/Compiler/xlf/FSStrings.ko.xlf index a7641343802..527329a3c10 100644 --- a/src/Compiler/xlf/FSStrings.ko.xlf +++ b/src/Compiler/xlf/FSStrings.ko.xlf @@ -12,6 +12,26 @@ 약어가 다르기 때문에 시그니처 및 구현의 '{1}' 형식에 대한 {0} 정의가 호환되지 않습니다.\n {2}\n 대 \n {3} + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n 유형 불일치. 형식이 \n {1}이고 길이가 {0}인 튜플이 필요합니다. \n그러나 형식이 \n {3}이고 길이가 {2}인 튜플이 제공되었습니다.{4}\n @@ -37,6 +57,11 @@ 정적 멤버가 필요합니다. + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' 기호 '..^' diff --git a/src/Compiler/xlf/FSStrings.pl.xlf b/src/Compiler/xlf/FSStrings.pl.xlf index 34d583d2d25..2dc8aa6a132 100644 --- a/src/Compiler/xlf/FSStrings.pl.xlf +++ b/src/Compiler/xlf/FSStrings.pl.xlf @@ -12,6 +12,26 @@ Definicje {0} dla typu „{1}” w sygnaturze i implementacji są niezgodne, ponieważ skróty są różne:\n {2}\nversus\n {3} + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n Niezgodność. Oczekiwano krotki o długości {0} typu\n {1} \nale otrzymano krotkę o długości {2} typu\n {3}{4}\n @@ -37,6 +57,11 @@ Oczekiwano statycznego elementu członkowskiego. + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' symbol „..^” diff --git a/src/Compiler/xlf/FSStrings.pt-BR.xlf b/src/Compiler/xlf/FSStrings.pt-BR.xlf index 9e802b99c8f..0dcc18c0019 100644 --- a/src/Compiler/xlf/FSStrings.pt-BR.xlf +++ b/src/Compiler/xlf/FSStrings.pt-BR.xlf @@ -12,6 +12,26 @@ As definições {0} para o tipo '{1}' na assinatura e na implementação não são compatíveis porque as abreviações são diferentes:\n {2}\nversus\n {3} + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n Tipo incompatível. Esperando uma tupla de comprimento {0} do tipo\n {1} \nmas recebeu uma tupla de comprimento {2} do tipo\n {3}{4}\n @@ -37,6 +57,11 @@ O membro estático é esperado. + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' símbolo '..^' diff --git a/src/Compiler/xlf/FSStrings.ru.xlf b/src/Compiler/xlf/FSStrings.ru.xlf index afe017d8096..3795ca1da5c 100644 --- a/src/Compiler/xlf/FSStrings.ru.xlf +++ b/src/Compiler/xlf/FSStrings.ru.xlf @@ -12,6 +12,26 @@ Определения {0} для типа "{1}" в сигнатуре и реализации несовместимы, так как сокращения различаются:\n {2}\nв сравнении с\n {3} + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n Несоответствие типов. Ожидается кортеж длиной {0} типа\n {1}, \nно предоставлен кортеж длиной {2} типа\n {3}{4}\n @@ -37,6 +57,11 @@ Ожидается статический элемент. + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' символ "..^" diff --git a/src/Compiler/xlf/FSStrings.tr.xlf b/src/Compiler/xlf/FSStrings.tr.xlf index 68faf3f9355..88042f52603 100644 --- a/src/Compiler/xlf/FSStrings.tr.xlf +++ b/src/Compiler/xlf/FSStrings.tr.xlf @@ -12,6 +12,26 @@ Kısaltmalar \n {2}\nile\n {3} olarak farklı olduğundan imzadaki ve uygulamadaki '{1}' türü için {0} tanımları uyumlu değil + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n Tür uyuşmazlığı. {0} uzunluğunda türü\n {1} \nolan bir demet bekleniyordu ancak {2} uzunluğunda türü\n {3}{4}\nolan bir demet verildi @@ -37,6 +57,11 @@ Statik üye bekleniyor. + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' '..^' sembolü diff --git a/src/Compiler/xlf/FSStrings.zh-Hans.xlf b/src/Compiler/xlf/FSStrings.zh-Hans.xlf index 432882db81e..1c6d39d3715 100644 --- a/src/Compiler/xlf/FSStrings.zh-Hans.xlf +++ b/src/Compiler/xlf/FSStrings.zh-Hans.xlf @@ -12,6 +12,26 @@ 签名和实现中类型“{1}”的 {0} 定义不兼容,因为缩写不同:\n {2}\nversus\n {3} + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n 类型不匹配。应为长度为 {0} 的类型的元组\n {1} \n但提供了长度为 {2} 的类型的元组\n {3}{4}\n @@ -37,6 +57,11 @@ 应为静态成员。 + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' 符号 "..^" diff --git a/src/Compiler/xlf/FSStrings.zh-Hant.xlf b/src/Compiler/xlf/FSStrings.zh-Hant.xlf index 0d50870b5c7..48d2a50d2e4 100644 --- a/src/Compiler/xlf/FSStrings.zh-Hant.xlf +++ b/src/Compiler/xlf/FSStrings.zh-Hant.xlf @@ -12,6 +12,26 @@ 簽章與實作中類型 '{1}' 的 {0} 定義不相容,因為縮寫不同:\n {2}\n與\n {3} + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n 類型不符。必須是類型為\n {1} \n 的元組長度 {0},但提供的是類型為\n {3}{4}\n 的元組長度 {2} @@ -37,6 +57,11 @@ 必須是靜態成員。 + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' 符號 '..^' diff --git a/src/FSharp.Build/FSharpCommandLineBuilder.fs b/src/FSharp.Build/FSharpCommandLineBuilder.fs index bf86d185edc..fd886c741d1 100644 --- a/src/FSharp.Build/FSharpCommandLineBuilder.fs +++ b/src/FSharp.Build/FSharpCommandLineBuilder.fs @@ -15,7 +15,7 @@ do () // Shim to match nullness checking library support in preview [] module Utils = - +#if NO_CHECKNULLS /// Match on the nullness of an argument. let inline (|Null|NonNull|) (x: 'T) : Choice = match x with @@ -24,7 +24,12 @@ module Utils = /// Indicates that a type may be null. 'MaybeNull' used internally in the F# compiler as unchecked /// replacement for 'string?' for example for future FS-1060. - type 'T MaybeNull when 'T: null and 'T: not struct = 'T + type MaybeNull<'T when 'T : null> = 'T +#else + /// Indicates that a type may be null. 'MaybeNull' used internally in the F# compiler as unchecked + /// replacement for 'string?' for example for future FS-1060. + type MaybeNull<'T when 'T : not null and 'T : not struct> = 'T | null +#endif type FSharpCommandLineBuilder() = diff --git a/src/FSharp.Build/FSharpEmbedResourceText.fs b/src/FSharp.Build/FSharpEmbedResourceText.fs index 397842b41f6..ebaff1986a6 100644 --- a/src/FSharp.Build/FSharpEmbedResourceText.fs +++ b/src/FSharp.Build/FSharpEmbedResourceText.fs @@ -361,6 +361,8 @@ open Printf messageString <- postProcessString messageString createMessageString messageString fmt + static member GetTextOpt(key:string) = GetString(key) |> Option.ofObj + /// If set to true, then all error messages will just return the filled 'holes' delimited by ',,,'s - this is for language-neutral testing (e.g. localization-invariant baselines). static member SwallowResourceText with get () = swallowResourceText and set (b) = swallowResourceText <- b @@ -369,6 +371,9 @@ open Printf let StringBoilerPlateSignature = " // BEGIN BOILERPLATE + + static member GetTextOpt: key:string -> string option + /// If set to true, then all error messages will just return the filled 'holes' delimited by ',,,'s - this is for language-neutral testing (e.g. localization-invariant baselines). static member SwallowResourceText: bool with get, set // END BOILERPLATE" diff --git a/src/FSharp.Build/Fsc.fs b/src/FSharp.Build/Fsc.fs index 6682208c0ac..9de88c9dbca 100644 --- a/src/FSharp.Build/Fsc.fs +++ b/src/FSharp.Build/Fsc.fs @@ -230,16 +230,13 @@ type public Fsc() as this = // checksumAlgorithm builder.AppendSwitchIfNotNull( "--checksumalgorithm:", - let ToUpperInvariant (s: string) = - if isNull s then - null - else - s.ToUpperInvariant() - - match ToUpperInvariant(checksumAlgorithm) with - | "SHA1" -> "Sha1" - | "SHA256" -> "Sha256" - | _ -> null + match checksumAlgorithm with + | Null -> null + | NonNull checksumAlgorithm -> + match checksumAlgorithm.ToUpperInvariant() with + | "SHA1" -> "Sha1" + | "SHA256" -> "Sha256" + | _ -> null ) // Resources diff --git a/src/FSharp.Build/SubstituteText.fs b/src/FSharp.Build/SubstituteText.fs index 2e4950a62b3..97e8758ce55 100644 --- a/src/FSharp.Build/SubstituteText.fs +++ b/src/FSharp.Build/SubstituteText.fs @@ -24,7 +24,7 @@ type SubstituteText() = override _.Execute() = copiedFiles.Clear() - if not (isNull embeddedResources) then + if not (isNull (box embeddedResources)) then // this check can't fail, the type is non-nullable for item in embeddedResources do // Update ITaskItem metadata to point to new location let sourcePath = item.GetMetadata("FullPath") diff --git a/src/FSharp.Core/ILLink.LinkAttributes.xml b/src/FSharp.Core/ILLink.LinkAttributes.xml index 70eba54ff4e..47a3ff01f02 100644 --- a/src/FSharp.Core/ILLink.LinkAttributes.xml +++ b/src/FSharp.Core/ILLink.LinkAttributes.xml @@ -169,5 +169,11 @@ + + + + + + diff --git a/src/FSharp.Core/ILLink.Substitutions.xml b/src/FSharp.Core/ILLink.Substitutions.xml index 42d44a0b4c4..13ceee32a14 100644 --- a/src/FSharp.Core/ILLink.Substitutions.xml +++ b/src/FSharp.Core/ILLink.Substitutions.xml @@ -4,5 +4,10 @@ + + + + + diff --git a/src/FSharp.Core/Linq.fs b/src/FSharp.Core/Linq.fs index cf7033e09db..12ae077dfdb 100644 --- a/src/FSharp.Core/Linq.fs +++ b/src/FSharp.Core/Linq.fs @@ -55,15 +55,15 @@ module LeafExpressionConverter = tyargs.[0], tyargs.[1] let StringConcat = - methodhandleof (fun (x:obj, y:obj) -> String.Concat (x, y)) + methodhandleof (fun (x:objnull, y:objnull) -> String.Concat (x, y)) |> System.Reflection.MethodInfo.GetMethodFromHandle :?> MethodInfo - let SubstHelperRaw (q:Expr, x:Var array, y:obj array) : Expr = + let SubstHelperRaw (q:Expr, x:Var array, y:objnull array) : Expr = let d = Map.ofArray (Array.zip x y) q.Substitute(fun v -> v |> d.TryFind |> Option.map (fun x -> Expr.Value (x, v.Type))) - let SubstHelper<'T> (q:Expr, x:Var array, y:obj array) : Expr<'T> = + let SubstHelper<'T> (q:Expr, x:Var array, y:objnull array) : Expr<'T> = SubstHelperRaw(q, x, y) |> Expr.Cast let showAll = @@ -393,12 +393,12 @@ module LeafExpressionConverter = //let (|ArrayAssignQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun -> LanguagePrimitives.IntrinsicFunctions.SetArray : int array -> int -> int -> unit)) //let (|ArrayTypeQ|_|) (ty:System.Type) = if ty.IsArray && ty.GetArrayRank() = 1 then Some (ty.GetElementType()) else None let substHelperMeth = - methodhandleof (fun (x:Expr, y:Var array, z:obj array) -> SubstHelper (x, y, z)) + methodhandleof (fun (x:Expr, y:Var array, z:objnull array) -> SubstHelper (x, y, z)) |> System.Reflection.MethodInfo.GetMethodFromHandle :?> MethodInfo let substHelperRawMeth = - methodhandleof (fun (x:Expr, y:Var array, z:obj array) -> SubstHelperRaw (x, y, z)) + methodhandleof (fun (x:Expr, y:Var array, z:objnull array) -> SubstHelperRaw (x, y, z)) |> System.Reflection.MethodInfo.GetMethodFromHandle :?> MethodInfo @@ -895,7 +895,7 @@ module LeafExpressionConverter = // provides no other way to evaluate the expression. // // REVIEW: It is possible it is just better to interpret the expression in many common cases, e.g. property-gets, values etc. - let EvaluateQuotation (e: Microsoft.FSharp.Quotations.Expr) : obj = + let EvaluateQuotation (e: Microsoft.FSharp.Quotations.Expr) : objnull = #if FX_NO_QUOTATIONS_COMPILE raise (new NotSupportedException()) #else diff --git a/src/FSharp.Core/Linq.fsi b/src/FSharp.Core/Linq.fsi index 5064de12f55..f03cc7976d3 100644 --- a/src/FSharp.Core/Linq.fsi +++ b/src/FSharp.Core/Linq.fsi @@ -71,21 +71,21 @@ module LeafExpressionConverter = /// /// /// - val EvaluateQuotation: Expr -> obj + val EvaluateQuotation: Expr -> objnull /// /// A runtime helper used to evaluate nested quotation literals. /// /// /// - val SubstHelper: Expr * Var array * obj array -> Expr<'T> + val SubstHelper: Expr * Var array * objnull array -> Expr<'T> /// /// A runtime helper used to evaluate nested quotation literals. /// /// /// - val SubstHelperRaw: Expr * Var array * obj array -> Expr + val SubstHelperRaw: Expr * Var array * objnull array -> Expr val internal (|SpecificCallToMethod|_|): System.RuntimeMethodHandle -> (Expr -> (Expr option * Reflection.MethodInfo * Expr list) option) diff --git a/src/FSharp.Core/Query.fs b/src/FSharp.Core/Query.fs index 9905362371d..f64e6c1c0f3 100644 --- a/src/FSharp.Core/Query.fs +++ b/src/FSharp.Core/Query.fs @@ -372,7 +372,7 @@ module Query = let CallGenericStaticMethod (methHandle:System.RuntimeMethodHandle) = let methInfo = methHandle |> System.Reflection.MethodInfo.GetMethodFromHandle :?> MethodInfo - fun (tyargs: Type list, args: obj list) -> + fun (tyargs: Type list, args: objnull list) -> let methInfo = if methInfo.IsGenericMethod then methInfo.MakeGenericMethod(Array.ofList tyargs) else methInfo try methInfo.Invoke(null, Array.ofList args) @@ -381,7 +381,7 @@ module Query = let CallGenericInstanceMethod (methHandle:System.RuntimeMethodHandle) = let methInfo = methHandle |> System.Reflection.MethodInfo.GetMethodFromHandle :?> MethodInfo - fun (objExpr:obj, tyargs: Type list, args: obj list) -> + fun (objExpr:obj, tyargs: Type list, args: objnull list) -> let methInfo = if methInfo.IsGenericMethod then methInfo.MakeGenericMethod(Array.ofList tyargs) else methInfo try methInfo.Invoke(objExpr, Array.ofList args) @@ -467,7 +467,7 @@ module Query = else ME ([srcItemTy], [src; key]) - let Call (isIQ, srcItemTy, src:obj, key: Expr) = + let Call (isIQ, srcItemTy, src:objnull, key: Expr) = let key = key |> LeafExpressionConverter.EvaluateQuotation let C = if isIQ then CQ else CE C ([srcItemTy], [src; box key]) @@ -496,7 +496,7 @@ module Query = else ME ([srcItemTy; keyElemTy], [src; valSelector]) - let Call (isIQ, srcItemTy: Type, _keyItemTy: Type, src:obj, keyElemTy: Type, v: Var, res: Expr) = + let Call (isIQ, srcItemTy: Type, _keyItemTy: Type, src:objnull, keyElemTy: Type, v: Var, res: Expr) = if isIQ then let selector = FuncExprToLinqFunc2Expression (srcItemTy, keyElemTy, v, res) CQ ([srcItemTy; keyElemTy], [src; box selector]) @@ -505,7 +505,7 @@ module Query = CE ([srcItemTy; keyElemTy], [src; selector]) Make, Call - let (MakeMinBy: bool * Expr * Var * Expr -> Expr), (CallMinBy : bool * Type * Type * obj * Type * Var * Expr -> obj) = + let (MakeMinBy: bool * Expr * Var * Expr -> Expr), (CallMinBy : bool * Type * Type * objnull * Type * Var * Expr -> obj) = let FQ = methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.Min(x, y)) let FE = methodhandleof (fun (x, y: Func<_, 'Result>) -> Enumerable.Min(x, y)) MakeOrCallMinByOrMaxBy FQ FE @@ -539,7 +539,7 @@ module Query = else ME ([srcItemTy], [src; predicate]) - let Call (isIQ, srcItemTy: Type, src:obj, v: Var, res: Expr) = + let Call (isIQ, srcItemTy: Type, src:objnull, v: Var, res: Expr) = if isIQ then let selector = FuncExprToLinqFunc2Expression (srcItemTy, boolTy, v, res) CQ ([srcItemTy], [src; box selector]) @@ -612,7 +612,7 @@ module Query = let selector = Expr.Lambda (v, res) ME (qb, [srcItemTy; qTy; resTyNoNullable], [src; selector]) - let Call (qb:obj, isIQ, srcItemTy: Type, resTyNoNullable: Type, src:obj, resTy: Type, v: Var, res: Expr) = + let Call (qb:obj, isIQ, srcItemTy: Type, resTyNoNullable: Type, src:objnull, resTy: Type, v: Var, res: Expr) = if isIQ then let selector = FuncExprToLinqFunc2Expression (srcItemTy, resTy, v, res) let caller = diff --git a/src/FSharp.Core/array.fs b/src/FSharp.Core/array.fs index 77153012a5e..03aaaf25b49 100644 --- a/src/FSharp.Core/array.fs +++ b/src/FSharp.Core/array.fs @@ -836,12 +836,21 @@ module Array = count +#if BUILDING_WITH_LKG || NO_NULLCHECKING_LIB_SUPPORT let private createMask<'a> (f: 'a -> bool) (src: 'a array) (maskArrayOut: byref) (leftoverMaskOut: byref) = +#else + let private createMask<'a> + (f: 'a -> bool) + (src: array<'a>) + (maskArrayOut: byref | null>) + (leftoverMaskOut: byref) + = +#endif let maskArrayLength = src.Length / 0x20 // null when there are less than 32 items in src array. @@ -1031,7 +1040,11 @@ module Array = dstIdx +#if BUILDING_WITH_LKG || NO_NULLCHECKING_LIB_SUPPORT let private filterViaMask (maskArray: uint32 array) (leftoverMask: uint32) (count: int) (src: _ array) = +#else + let private filterViaMask (maskArray: uint32 array | null) (leftoverMask: uint32) (count: int) (src: _ array) = +#endif let dst = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked count let mutable dstIdx = 0 diff --git a/src/FSharp.Core/async.fs b/src/FSharp.Core/async.fs index 9f9a2d1ef48..7fdf3c0a199 100644 --- a/src/FSharp.Core/async.fs +++ b/src/FSharp.Core/async.fs @@ -868,7 +868,11 @@ 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 @@ -1072,7 +1076,7 @@ module AsyncPrimitives = /// Create an instance of an arbitrary delegate type delegating to the given F# function type FuncDelegate<'T>(f) = - member _.Invoke(sender: obj, a: 'T) : unit = + member _.Invoke(sender: objnull, a: 'T) : unit = ignore sender f a @@ -1305,7 +1309,7 @@ module AsyncPrimitives = | None -> () [] - type AsyncIAsyncResult<'T>(callback: System.AsyncCallback, state: obj) = + type AsyncIAsyncResult<'T>(callback: System.AsyncCallback, state: objnull) = // This gets set to false if the result is not available by the // time the IAsyncResult is returned to the caller of Begin let mutable completedSynchronously = true @@ -2031,7 +2035,7 @@ type Async = // Register the result. resultCell.RegisterResult(res, reuseThread = true) |> unfake) - let (iar: IAsyncResult) = beginAction (callback, (null: obj)) + let (iar: IAsyncResult) = beginAction (callback, (null: objnull)) if iar.CompletedSynchronously then // Ensure cancellation is not possible beyond this point @@ -2063,7 +2067,7 @@ type Async = static member AsBeginEnd<'Arg, 'T> (computation: ('Arg -> Async<'T>)) // The 'Begin' member - : ('Arg * System.AsyncCallback * obj -> System.IAsyncResult) * + : ('Arg * System.AsyncCallback * objnull -> System.IAsyncResult) * (System.IAsyncResult -> 'T) * (System.IAsyncResult -> unit) = @@ -2330,7 +2334,7 @@ module WebExtensions = Async.FromContinuations(fun (cont, econt, ccont) -> let userToken = obj () - let rec delegate' (_: obj) (args: #ComponentModel.AsyncCompletedEventArgs) = + let rec delegate' (_: objnull) (args: #ComponentModel.AsyncCompletedEventArgs) = // ensure we handle the completed event from correct download call if userToken = args.UserState then event.RemoveHandler handle diff --git a/src/FSharp.Core/async.fsi b/src/FSharp.Core/async.fsi index 6b621176c9d..fcbde6c24ac 100644 --- a/src/FSharp.Core/async.fsi +++ b/src/FSharp.Core/async.fsi @@ -860,7 +860,7 @@ namespace Microsoft.FSharp.Control /// Legacy .NET Async Interoperability /// /// - static member FromBeginEnd : beginAction:(System.AsyncCallback * obj -> System.IAsyncResult) * endAction:(System.IAsyncResult -> 'T) * ?cancelAction : (unit -> unit) -> Async<'T> + static member FromBeginEnd : beginAction:(System.AsyncCallback * objnull -> System.IAsyncResult) * endAction:(System.IAsyncResult -> 'T) * ?cancelAction : (unit -> unit) -> Async<'T> /// /// Creates an asynchronous computation in terms of a Begin/End pair of actions in @@ -885,7 +885,7 @@ namespace Microsoft.FSharp.Control /// Legacy .NET Async Interoperability /// /// - static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * System.AsyncCallback * obj -> System.IAsyncResult) * endAction:(System.IAsyncResult -> 'T) * ?cancelAction : (unit -> unit) -> Async<'T> + static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * System.AsyncCallback * objnull -> System.IAsyncResult) * endAction:(System.IAsyncResult -> 'T) * ?cancelAction : (unit -> unit) -> Async<'T> /// /// Creates an asynchronous computation in terms of a Begin/End pair of actions in @@ -909,7 +909,7 @@ namespace Microsoft.FSharp.Control /// Legacy .NET Async Interoperability /// /// - static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * System.AsyncCallback * obj -> System.IAsyncResult) * endAction:(System.IAsyncResult -> 'T) * ?cancelAction : (unit -> unit) -> Async<'T> + static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * System.AsyncCallback * objnull -> System.IAsyncResult) * endAction:(System.IAsyncResult -> 'T) * ?cancelAction : (unit -> unit) -> Async<'T> /// Creates an asynchronous computation in terms of a Begin/End pair of actions in /// the style used in .NET 2.0 APIs. @@ -933,7 +933,7 @@ namespace Microsoft.FSharp.Control /// Legacy .NET Async Interoperability /// /// - static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * System.AsyncCallback * obj -> System.IAsyncResult) * endAction:(System.IAsyncResult -> 'T) * ?cancelAction : (unit -> unit) -> Async<'T> + static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * System.AsyncCallback * objnull -> System.IAsyncResult) * endAction:(System.IAsyncResult -> 'T) * ?cancelAction : (unit -> unit) -> Async<'T> /// Creates three functions that can be used to implement the .NET 1.0 Asynchronous /// Programming Model (APM) for a given asynchronous computation. @@ -948,7 +948,7 @@ namespace Microsoft.FSharp.Control /// static member AsBeginEnd : computation:('Arg -> Async<'T>) -> // The 'Begin' member - ('Arg * System.AsyncCallback * obj -> System.IAsyncResult) * + ('Arg * System.AsyncCallback * objnull -> System.IAsyncResult) * // The 'End' member (System.IAsyncResult -> 'T) * // The 'Cancel' member diff --git a/src/FSharp.Core/event.fs b/src/FSharp.Core/event.fs index 338d7275fc3..483ea38d64f 100644 --- a/src/FSharp.Core/event.fs +++ b/src/FSharp.Core/event.fs @@ -31,7 +31,7 @@ module private Atomic = type DelegateEvent<'Delegate when 'Delegate :> System.Delegate>() = let mutable multicast: System.Delegate = null - member x.Trigger(args: obj array) = + member x.Trigger(args: objnull array) = match multicast with | null -> () | d -> d.DynamicInvoke(args) |> ignore @@ -54,30 +54,30 @@ type EventDelegee<'Args>(observer: System.IObserver<'Args>) = assert false null // should not be called, one-argument case don't use makeTuple function - member x.Invoke(_sender: obj, args: 'Args) = + member x.Invoke(_sender: objnull, args: 'Args) = observer.OnNext args - member x.Invoke(_sender: obj, a, b) = + member x.Invoke(_sender: objnull, a, b) = let args = makeTuple ([| a; b |]) :?> 'Args observer.OnNext args - member x.Invoke(_sender: obj, a, b, c) = + member x.Invoke(_sender: objnull, a, b, c) = let args = makeTuple ([| a; b; c |]) :?> 'Args observer.OnNext args - member x.Invoke(_sender: obj, a, b, c, d) = + member x.Invoke(_sender: objnull, a, b, c, d) = let args = makeTuple ([| a; b; c; d |]) :?> 'Args observer.OnNext args - member x.Invoke(_sender: obj, a, b, c, d, e) = + member x.Invoke(_sender: objnull, a, b, c, d, e) = let args = makeTuple ([| a; b; c; d; e |]) :?> 'Args observer.OnNext args - member x.Invoke(_sender: obj, a, b, c, d, e, f) = + member x.Invoke(_sender: objnull, a, b, c, d, e, f) = let args = makeTuple ([| a; b; c; d; e; f |]) :?> 'Args observer.OnNext args -type EventWrapper<'Delegate, 'Args> = delegate of 'Delegate * obj * 'Args -> unit +type EventWrapper<'Delegate, 'Args> = delegate of 'Delegate * objnull * 'Args -> unit [] type Event<'Delegate, 'Args @@ -122,7 +122,7 @@ type Event<'Delegate, 'Args else mi - member x.Trigger(sender: obj, args: 'Args) = + member x.Trigger(sender: objnull, args: 'Args) = // Copy multicast value into local variable to avoid changing during member call. let multicast = multicast diff --git a/src/FSharp.Core/event.fsi b/src/FSharp.Core/event.fsi index 09225b9b0fa..0a52d440c0e 100644 --- a/src/FSharp.Core/event.fsi +++ b/src/FSharp.Core/event.fsi @@ -23,7 +23,7 @@ type DelegateEvent<'Delegate when 'Delegate :> System.Delegate> = /// The parameters for the event. /// /// - member Trigger: args: obj array -> unit + member Trigger: args: objnull array -> unit /// Publishes the event as a first class event value. /// @@ -49,7 +49,7 @@ type Event<'Delegate, 'Args /// The parameters for the event. /// /// - member Trigger: sender: obj * args: 'Args -> unit + member Trigger: sender: objnull * args: 'Args -> unit /// Publishes the event as a first class event value. /// diff --git a/src/FSharp.Core/fslib-extra-pervasives.fs b/src/FSharp.Core/fslib-extra-pervasives.fs index b5cf5dee3af..8ce025606eb 100644 --- a/src/FSharp.Core/fslib-extra-pervasives.fs +++ b/src/FSharp.Core/fslib-extra-pervasives.fs @@ -483,7 +483,7 @@ type ITypeProvider = abstract GetStaticParameters: typeWithoutArguments: Type -> ParameterInfo array abstract ApplyStaticArguments: - typeWithoutArguments: Type * typePathWithArguments: string array * staticArguments: obj array -> Type + typeWithoutArguments: Type * typePathWithArguments: string array * staticArguments: objnull array -> Type abstract GetInvokerExpression: syntheticMethodBase: MethodBase * parameters: Expr array -> Expr @@ -496,4 +496,5 @@ type ITypeProvider2 = abstract GetStaticParametersForMethod: methodWithoutArguments: MethodBase -> ParameterInfo array abstract ApplyStaticArgumentsForMethod: - methodWithoutArguments: MethodBase * methodNameWithArguments: string * staticArguments: obj array -> MethodBase + methodWithoutArguments: MethodBase * methodNameWithArguments: string * staticArguments: objnull array -> + MethodBase diff --git a/src/FSharp.Core/fslib-extra-pervasives.fsi b/src/FSharp.Core/fslib-extra-pervasives.fsi index 97120245f87..aff5d162b0a 100644 --- a/src/FSharp.Core/fslib-extra-pervasives.fsi +++ b/src/FSharp.Core/fslib-extra-pervasives.fsi @@ -542,7 +542,7 @@ namespace Microsoft.FSharp.Core.CompilerServices /// the static parameters, indexed by name /// /// - abstract ApplyStaticArguments : typeWithoutArguments:Type * typePathWithArguments:string array * staticArguments:obj array -> Type + abstract ApplyStaticArguments : typeWithoutArguments:Type * typePathWithArguments:string array * staticArguments:objnull array -> Type /// /// Called by the compiler to ask for an Expression tree to replace the given MethodBase with. @@ -586,4 +586,4 @@ namespace Microsoft.FSharp.Core.CompilerServices /// the values of the static parameters, indexed by name /// /// The provided method definition corresponding to the given static parameter values - abstract ApplyStaticArgumentsForMethod : methodWithoutArguments:MethodBase * methodNameWithArguments:string * staticArguments:obj array -> MethodBase + abstract ApplyStaticArgumentsForMethod : methodWithoutArguments:MethodBase * methodNameWithArguments:string * staticArguments:objnull array -> MethodBase diff --git a/src/FSharp.Core/local.fs b/src/FSharp.Core/local.fs index 1e7df3c2ec8..206ccf4ee3d 100644 --- a/src/FSharp.Core/local.fs +++ b/src/FSharp.Core/local.fs @@ -1090,7 +1090,11 @@ module internal Array = if array.Length > 1 then Array.Sort<_>(array, fastComparerForArraySort()) +#if BUILDING_WITH_LKG || NO_NULLCHECKING_LIB_SUPPORT let stableSortWithKeysAndComparer (cFast:IComparer<'Key>) (c:IComparer<'Key>) (array:'T array) (keys: 'Key array) = +#else + let stableSortWithKeysAndComparer (cFast:IComparer<'Key> | null) (c:IComparer<'Key>) (array:array<'T>) (keys:array<'Key>) = +#endif // 'places' is an array or integers storing the permutation performed by the sort let len = array.Length let places = zeroCreateUnchecked len diff --git a/src/FSharp.Core/local.fsi b/src/FSharp.Core/local.fsi index 9de6b8c8152..11f645c9788 100644 --- a/src/FSharp.Core/local.fsi +++ b/src/FSharp.Core/local.fsi @@ -6,8 +6,8 @@ open Microsoft.FSharp.Core [] module internal DetailedExceptions = - val inline invalidArgFmt: arg: string -> format: string -> paramArray: obj array -> 'T - val inline invalidOpFmt: format: string -> paramArray: obj array -> 'T + val inline invalidArgFmt: arg: string -> format: string -> paramArray: objnull array -> 'T + val inline invalidOpFmt: format: string -> paramArray: objnull array -> 'T val invalidArgDifferentListLength: arg1: string -> arg2: string -> diff: int -> 'T val invalidArg3ListsDifferent: diff --git a/src/FSharp.Core/map.fs b/src/FSharp.Core/map.fs index 43459ecdf33..b46bd9d357d 100644 --- a/src/FSharp.Core/map.fs +++ b/src/FSharp.Core/map.fs @@ -958,7 +958,7 @@ type Map<[] 'Key, [ as m2 -> Seq.compareWith diff --git a/src/FSharp.Core/map.fsi b/src/FSharp.Core/map.fsi index e6b0b1afb30..5b982141a34 100644 --- a/src/FSharp.Core/map.fsi +++ b/src/FSharp.Core/map.fsi @@ -215,7 +215,7 @@ type Map<[] 'Key, [> interface IReadOnlyDictionary<'Key, 'Value> - override Equals: obj -> bool + override Equals: objnull -> bool /// Contains operations for working with values of type . [] diff --git a/src/FSharp.Core/math/z.fs b/src/FSharp.Core/math/z.fs index 28d0deead19..f3eec1b950e 100644 --- a/src/FSharp.Core/math/z.fs +++ b/src/FSharp.Core/math/z.fs @@ -28,10 +28,10 @@ module NumericLiterals = module NumericLiteralI = - let tab64 = new System.Collections.Generic.Dictionary() - let tabParse = new System.Collections.Generic.Dictionary() + let tab64 = new System.Collections.Generic.Dictionary() + let tabParse = new System.Collections.Generic.Dictionary() - let FromInt64Dynamic (value: int64) : obj = + let FromInt64Dynamic (value: int64) : objnull = lock tab64 (fun () -> let mutable res = Unchecked.defaultof<_> let ok = tab64.TryGetValue(value, &res) @@ -82,7 +82,7 @@ module NumericLiterals = tabParse.[s] <- res res) - let FromStringDynamic (text: string) : obj = + let FromStringDynamic (text: string) : objnull = getParse text let FromString (text: string) : 'T = diff --git a/src/FSharp.Core/math/z.fsi b/src/FSharp.Core/math/z.fsi index 2dc51708530..9c2261ff5b6 100644 --- a/src/FSharp.Core/math/z.fsi +++ b/src/FSharp.Core/math/z.fsi @@ -43,7 +43,7 @@ module NumericLiterals = val FromString: text: string -> 'T /// Provides a default implementations of F# numeric literal syntax for literals of the form 'dddI' - val FromInt64Dynamic: value: int64 -> obj + val FromInt64Dynamic: value: int64 -> objnull /// Provides a default implementations of F# numeric literal syntax for literals of the form 'dddI' - val FromStringDynamic: text: string -> obj + val FromStringDynamic: text: string -> objnull diff --git a/src/FSharp.Core/option.fs b/src/FSharp.Core/option.fs index 205eac0265a..9c441bcad01 100644 --- a/src/FSharp.Core/option.fs +++ b/src/FSharp.Core/option.fs @@ -152,6 +152,7 @@ module Option = else None +#if BUILDING_WITH_LKG || NO_NULLCHECKING_LIB_SUPPORT [] let inline ofObj value = match value with @@ -163,6 +164,19 @@ module Option = match value with | None -> null | Some x -> x +#else + [] + let inline ofObj (value: 'T | null) : 'T option when 'T: not struct and 'T : not null = + match value with + | null -> None + | _ -> Some value + + [] + let inline toObj (value: 'T option) : 'T | null when 'T: not struct (* and 'T : not null *) = + match value with + | None -> null + | Some x -> x +#endif module ValueOption = @@ -316,6 +330,7 @@ module ValueOption = else ValueNone +#if BUILDING_WITH_LKG || NO_NULLCHECKING_LIB_SUPPORT [] let inline ofObj value = match value with @@ -327,3 +342,16 @@ module ValueOption = match value with | ValueNone -> null | ValueSome x -> x +#else + [] + let inline ofObj (value: 'T | null) : 'T voption when 'T: not struct and 'T : not null = + match value with + | null -> ValueNone + | _ -> ValueSome value + + [] + let inline toObj (value : 'T voption) : 'T | null when 'T: not struct (* and 'T : not null *) = + match value with + | ValueNone -> null + | ValueSome x -> x +#endif diff --git a/src/FSharp.Core/option.fsi b/src/FSharp.Core/option.fsi index d6375c6d39e..6b9f00be200 100644 --- a/src/FSharp.Core/option.fsi +++ b/src/FSharp.Core/option.fsi @@ -440,7 +440,13 @@ module Option = /// /// [] - val inline ofObj: value: 'T -> 'T option when 'T: null +#if BUILDING_WITH_LKG || NO_NULLCHECKING_LIB_SUPPORT + val inline ofObj: value: 'T -> 'T option when 'T : null +#else + // TODO NULLNESS: assess this change - is it a breaking change? + [] + val inline ofObj: value: 'T | null -> 'T option when 'T : not null and 'T : not struct +#endif /// Convert an option to a potentially null value. /// @@ -455,7 +461,12 @@ module Option = /// /// [] - val inline toObj: value: 'T option -> 'T when 'T: null +#if BUILDING_WITH_LKG || NO_NULLCHECKING_LIB_SUPPORT + val inline toObj: value: 'T option -> 'T when 'T : null +#else + // TODO NULLNESS: assess this change - is it a breaking change? + val inline toObj: value: 'T option -> 'T | null when 'T : not struct (* and 'T : not null *) +#endif /// Contains operations for working with value options. /// @@ -888,7 +899,13 @@ module ValueOption = /// /// [] - val inline ofObj: value: 'T -> 'T voption when 'T: null +#if BUILDING_WITH_LKG || NO_NULLCHECKING_LIB_SUPPORT + val inline ofObj: value: 'T -> 'T voption when 'T : null +#else + // TODO NULLNESS: assess this change - is it a breaking change? + [] + val inline ofObj: value: 'T | null -> 'T voption when 'T : not struct and 'T : not null +#endif /// Convert an option to a potentially null value. /// @@ -903,4 +920,9 @@ module ValueOption = /// /// [] - val inline toObj: value: 'T voption -> 'T when 'T: null +#if BUILDING_WITH_LKG || NO_NULLCHECKING_LIB_SUPPORT + val inline toObj: value: 'T voption -> 'T when 'T : null +#else + // TODO NULLNESS: assess this change - is it a breaking change? + val inline toObj: value: 'T voption -> 'T | null when 'T : not struct (* and 'T : not null *) +#endif diff --git a/src/FSharp.Core/prim-types-prelude.fs b/src/FSharp.Core/prim-types-prelude.fs index 9a002450382..12ed91cfba2 100644 --- a/src/FSharp.Core/prim-types-prelude.fs +++ b/src/FSharp.Core/prim-types-prelude.fs @@ -6,6 +6,11 @@ namespace Microsoft.FSharp.Core // Basic type abbreviations type obj = System.Object +#if BUILDING_WITH_LKG || NO_NULLCHECKING_LIB_SUPPORT + type objnull = obj +#else + type objnull = obj | null +#endif type exn = System.Exception type nativeint = System.IntPtr type unativeint = System.UIntPtr diff --git a/src/FSharp.Core/prim-types-prelude.fsi b/src/FSharp.Core/prim-types-prelude.fsi index b9bbc5c125f..8cc0515350d 100644 --- a/src/FSharp.Core/prim-types-prelude.fsi +++ b/src/FSharp.Core/prim-types-prelude.fsi @@ -18,6 +18,16 @@ namespace Microsoft.FSharp.Core /// Basic Types type obj = System.Object + /// An abbreviation for the CLI type or null. + /// With the 'nullable reference types' feature, this is an alias to 'obj | null'. + /// + /// Basic Types +#if BUILDING_WITH_LKG || NO_NULLCHECKING_LIB_SUPPORT + type objnull = obj +#else + type objnull = obj | null +#endif + /// An abbreviation for the CLI type . /// /// Basic Types diff --git a/src/FSharp.Core/prim-types.fs b/src/FSharp.Core/prim-types.fs index 2474dfcd39c..211496b99d1 100644 --- a/src/FSharp.Core/prim-types.fs +++ b/src/FSharp.Core/prim-types.fs @@ -9,6 +9,8 @@ #nowarn "69" // Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case. #nowarn "77" // Member constraints with the name 'Exp' are given special status by the F# compiler... #nowarn "3218" // mismatch of parameter name for 'fst' and 'snd' +#nowarn "3244" // no nullness checking +#nowarn "3245" // no nullness checking namespace Microsoft.FSharp.Core @@ -23,11 +25,11 @@ namespace Microsoft.FSharp.Core type Unit() = override _.GetHashCode() = 0 - override _.Equals(obj:obj) = + override _.Equals(obj:objnull) = match obj with null -> true | :? Unit -> true | _ -> false interface System.IComparable with - member _.CompareTo(_obj:obj) = 0 + member _.CompareTo(_obj:objnull) = 0 and unit = Unit @@ -165,6 +167,7 @@ namespace Microsoft.FSharp.Core AttributeTargets.Parameter ||| AttributeTargets.Method ||| AttributeTargets.Property ||| AttributeTargets.Constructor ||| AttributeTargets.Delegate, AllowMultiple=false)>] + [] type ReflectedDefinitionAttribute(includeValue: bool) = inherit Attribute() @@ -376,6 +379,13 @@ namespace Microsoft.FSharp.Core type NoCompilerInliningAttribute() = inherit Attribute() + [] + [] + type WarnOnWithoutNullArgumentAttribute(warningMessage:string) = + inherit Attribute() + member _.WarningMessage = warningMessage + member val internal Localize = false with get, set + [] [] type TailCallAttribute() = @@ -495,8 +505,8 @@ namespace Microsoft.FSharp.Core type outref<'T> = byref<'T, ByRefKinds.Out> module internal BasicInlinedOperations = - let inline unboxPrim<'T>(x:obj) = (# "unbox.any !0" type ('T) x : 'T #) - let inline box (x:'T) = (# "box !0" type ('T) x : obj #) + let inline unboxPrim<'T>(x:objnull) = (# "unbox.any !0" type ('T) x : 'T #) + let inline box (x:'T) = (# "box !0" type ('T) x : objnull #) let inline convPrim<'T1, 'T2>(x: 'T1) : 'T2 = unboxPrim<'T2> (box x) let inline not (b:bool) = (# "ceq" b false : bool #) let inline (=) (x:int) (y:int) = (# "ceq" x y : bool #) @@ -531,7 +541,7 @@ namespace Microsoft.FSharp.Core let set (arr: 'T array) (n:int) (x:'T) = (# "stelem.any !0" type ('T) arr n x #) - let inline objEq (xobj:obj) (yobj:obj) = (# "ceq" xobj yobj : bool #) + let inline objEq (xobj:objnull) (yobj:objnull) = (# "ceq" xobj yobj : bool #) let inline int64Eq (x:int64) (y:int64) = (# "ceq" x y : bool #) let inline int32Eq (x:int32) (y:int32) = (# "ceq" x y : bool #) let inline floatEq (x:float) (y:float) = (# "ceq" x y : bool #) @@ -556,11 +566,11 @@ namespace Microsoft.FSharp.Core (# "sizeof !0" type('T) : int #) let inline unsafeDefault<'T> : 'T = (# "ilzero !0" type ('T) : 'T #) - let inline isinstPrim<'T>(x:obj) = (# "isinst !0" type ('T) x : obj #) + let inline isinstPrim<'T>(x:objnull) = (# "isinst !0" type ('T) x : objnull #) let inline castclassPrim<'T>(x:obj) = (# "castclass !0" type ('T) x : 'T #) let inline notnullPrim<'T when 'T : not struct>(x:'T) = (# "ldnull cgt.un" x : bool #) - let inline iscastPrim<'T when 'T : not struct>(x:obj) = (# "isinst !0" type ('T) x : 'T #) + let inline iscastPrim<'T when 'T : not struct>(x:objnull) = (# "isinst !0" type ('T) x : 'T #) let inline mask (n:int) (m:int) = (# "and" n m : int #) @@ -706,7 +716,7 @@ namespace Microsoft.FSharp.Core // IL_0006: brtrue.s IL_000e // worst case: nothing known about source or destination - let UnboxGeneric<'T>(source: obj) = + let UnboxGeneric<'T>(source: objnull) = if notnullPrim(source) or TypeInfo<'T>.TypeInfo <> TypeNullnessSemantics_NullNotLiked then unboxPrim<'T>(source) else @@ -714,19 +724,19 @@ namespace Microsoft.FSharp.Core raise (System.NullReferenceException()) // better: source is NOT TypeNullnessSemantics_NullNotLiked - let inline UnboxFast<'T>(source: obj) = + let inline UnboxFast<'T>(source: objnull) = // assert not(TypeInfo<'T>.TypeInfo = TypeNullnessSemantics_NullNotLiked) unboxPrim<'T>(source) // worst case: nothing known about source or destination - let TypeTestGeneric<'T>(source: obj) = + let TypeTestGeneric<'T>(source: objnull) = if notnullPrim(isinstPrim<'T>(source)) then true elif notnullPrim(source) then false else (TypeInfo<'T>.TypeInfo = TypeNullnessSemantics_NullTrueValue) // quick entry: source is NOT TypeNullnessSemantics_NullTrueValue - let inline TypeTestFast<'T>(source: obj) = + let inline TypeTestFast<'T>(source: objnull) = //assert not(TypeInfo<'T>.TypeInfo = TypeNullnessSemantics_NullTrueValue) notnullPrim(isinstPrim<'T>(source)) @@ -926,7 +936,7 @@ namespace Microsoft.FSharp.Core let inline HashCombine nr x y = (x <<< 1) + y + 631 * nr - let GenericHashObjArray (iec : IEqualityComparer) (x: obj array) : int = + let GenericHashObjArray (iec : IEqualityComparer) (x: objnull array) : int = let len = x.Length let mutable i = len - 1 if i > defaultHashNodes then i <- defaultHashNodes // limit the hash @@ -992,7 +1002,7 @@ namespace Microsoft.FSharp.Core // Arrays are structurally hashed through a separate technique. // // "iec" is either fsEqualityComparerUnlimitedHashingER, fsEqualityComparerUnlimitedHashingPER or a CountLimitedHasherPER. - let rec GenericHashParamObj (iec : IEqualityComparer) (x: obj) : int = + let rec GenericHashParamObj (iec : IEqualityComparer) (x: objnull) : int = match x with | null -> 0 | (:? System.Array as a) -> @@ -1056,7 +1066,7 @@ namespace Microsoft.FSharp.Core /// Implements generic comparison between two objects. This corresponds to the pseudo-code in the F# /// specification. The treatment of NaNs is governed by "comp". - let rec GenericCompare (comp:GenericComparer) (xobj:obj, yobj:obj) = + let rec GenericCompare (comp:GenericComparer) (xobj:objnull, yobj:objnull) = match xobj,yobj with | null,null -> 0 | null,_ -> -1 @@ -1188,7 +1198,7 @@ namespace Microsoft.FSharp.Core check 0 /// optimized case: Core implementation of structural comparison on object arrays. - and GenericComparisonObjArrayWithComparer (comp:GenericComparer) (x:obj array) (y:obj array) : int = + and GenericComparisonObjArrayWithComparer (comp:GenericComparer) (x:objnull array) (y:objnull array) : int = let lenx = x.Length let leny = y.Length let c = intOrder lenx leny @@ -1219,7 +1229,7 @@ namespace Microsoft.FSharp.Core type GenericComparer with interface IComparer with - override c.Compare(x:obj,y:obj) = GenericCompare c (x,y) + override c.Compare(x:objnull,y:objnull) = GenericCompare c (x,y) /// The unique object for comparing values in PER mode (where local exceptions are thrown when NaNs are compared) let fsComparerPER = GenericComparer(true) @@ -1555,7 +1565,7 @@ namespace Microsoft.FSharp.Core // // If "er" is true the "iec" is fsEqualityComparerUnlimitedHashingER // If "er" is false the "iec" is fsEqualityComparerUnlimitedHashingPER - let rec GenericEqualityObj (er:bool) (iec:IEqualityComparer) ((xobj:obj),(yobj:obj)) : bool = + let rec GenericEqualityObj (er:bool) (iec:IEqualityComparer) ((xobj:objnull),(yobj:objnull)) : bool = (*if objEq xobj yobj then true else *) match xobj,yobj with | null,null -> true @@ -1644,7 +1654,7 @@ namespace Microsoft.FSharp.Core check 0 /// optimized case: Core implementation of structural equality on object arrays. - and GenericEqualityObjArray er iec (x:obj array) (y:obj array) : bool = + and GenericEqualityObjArray er iec (x:objnull array) (y:objnull array) : bool = let lenx = x.Length let leny = y.Length let c = (lenx = leny ) @@ -1747,12 +1757,12 @@ namespace Microsoft.FSharp.Core checkType 0 [| rootType |] let arrayEqualityComparer<'T> er comparer = - let arrayEquals (er: bool) (iec: IEqualityComparer) (xobj: obj) (yobj: obj) : bool = + let arrayEquals (er: bool) (iec: IEqualityComparer) (xobj: objnull) (yobj: objnull) : bool = match xobj, yobj with | null, null -> true | null, _ -> false | _, null -> false - | (:? (obj array) as arr1), (:? (obj array) as arr2) -> GenericEqualityObjArray er iec arr1 arr2 + | (:? (objnull array) as arr1), (:? (objnull array) as arr2) -> GenericEqualityObjArray er iec arr1 arr2 | (:? (byte array) as arr1), (:? (byte array) as arr2) -> GenericEqualityByteArray arr1 arr2 | (:? (int32 array) as arr1), (:? (int32 array) as arr2) -> GenericEqualityInt32Array arr1 arr2 | (:? (int64 array) as arr1), (:? (int64 array) as arr2) -> GenericEqualityInt64Array arr1 arr2 @@ -1762,10 +1772,10 @@ namespace Microsoft.FSharp.Core | (:? Array as arr1), (:? Array as arr2) -> GenericEqualityArbArray er iec arr1 arr2 | _ -> raise (Exception "invalid logic - expected array") - let getHashCode (iec, xobj: obj) = + let getHashCode (iec, xobj: objnull) = match xobj with | null -> 0 - | :? (obj array) as oa -> GenericHashObjArray iec oa + | :? (objnull array) as oa -> GenericHashObjArray iec oa | :? (byte array) as ba -> GenericHashByteArray ba | :? (int array) as ia -> GenericHashInt32Array ia | :? (int64 array) as ia -> GenericHashInt64Array ia @@ -1951,9 +1961,9 @@ namespace Microsoft.FSharp.Core type CountLimitedHasherPER with interface IEqualityComparer with - override iec.Equals(x:obj,y:obj) = + override iec.Equals(x:objnull,y:objnull) = GenericEqualityObj false iec (x,y) - override iec.GetHashCode(x:obj) = + override iec.GetHashCode(x:objnull) = iec.nodeCount <- iec.nodeCount - 1 if iec.nodeCount > 0 then GenericHashParamObj iec x @@ -1964,14 +1974,14 @@ namespace Microsoft.FSharp.Core type UnlimitedHasherER with interface IEqualityComparer with - override iec.Equals(x:obj,y:obj) = GenericEqualityObj true iec (x,y) - override iec.GetHashCode(x:obj) = GenericHashParamObj iec x + override iec.Equals(x:objnull,y:objnull) = GenericEqualityObj true iec (x,y) + override iec.GetHashCode(x:objnull) = GenericHashParamObj iec x /// Fill in the implementation of UnlimitedHasherPER type UnlimitedHasherPER with interface IEqualityComparer with - override iec.Equals(x:obj,y:obj) = GenericEqualityObj false iec (x,y) - override iec.GetHashCode(x:obj) = GenericHashParamObj iec x + override iec.Equals(x:objnull,y:objnull) = GenericEqualityObj false iec (x,y) + override iec.GetHashCode(x:objnull) = GenericHashParamObj iec x /// Intrinsic for calls to depth-unlimited structural hashing that were not optimized by static conditionals. // @@ -4378,20 +4388,20 @@ namespace Microsoft.FSharp.Core let seq (sequence: seq<'T>) = sequence [] - let inline unbox (value: obj) = UnboxGeneric(value) + let inline unbox (value: objnull) = UnboxGeneric(value) [] - let inline box (value: 'T) = (# "box !0" type ('T) value : obj #) + let inline box (value: 'T) = (# "box !0" type ('T) value : objnull #) [] - let inline tryUnbox (value:obj) = + let inline tryUnbox (value:objnull) = match value with | :? 'T as v -> Some v | _ -> None [] - let inline isNull (value : 'T) = - match value with + let inline isNull (value : 'T when 'T : null) = + match box value with | null -> true | _ -> false @@ -4401,6 +4411,68 @@ namespace Microsoft.FSharp.Core | null -> false | _ -> true +#if !BUILDING_WITH_LKG && !NO_NULLCHECKING_LIB_SUPPORT + + [] + let inline isNullV (value : Nullable<'T>) = not value.HasValue + + [] + let inline nonNull (value : 'T | null when 'T : not null and 'T : not struct) = + match box value with + | null -> raise (NullReferenceException()) + | _ -> (# "" value : 'T #) + + [] + let inline nonNullV (value : Nullable<'T>) = + if value.HasValue then + value.Value + else + raise (NullReferenceException()) + + [] + let inline (|Null|NonNull|) (value : 'T | null when 'T : not null and 'T : not struct) = + match value with + | null -> Null () + | _ -> NonNull (# "" value : 'T #) + + [] + let inline (|NullV|NonNullV|) (value : Nullable<'T>) = + if value.HasValue then NonNullV value.Value + else NullV () + + [] + let inline (|NonNullQuick|) (value : 'T | null when 'T : not null and 'T : not struct) = + match box value with + | null -> raise (NullReferenceException()) + | _ -> (# "" value : 'T #) + + [] + let inline (|NonNullQuickV|) (value : Nullable<'T>) = + if value.HasValue then value.Value + else raise (NullReferenceException()) + + [] + let inline withNull (value : 'T when 'T : not null and 'T : not struct) = (# "" value : 'T | null #) + + [] + let inline withNullV (value : 'T) : Nullable<'T> = Nullable<'T>(value) + + [] + let inline nullV<'T when 'T : struct and 'T : (new : unit -> 'T) and 'T :> ValueType> = Nullable<'T>() + + [] + let inline nullArgCheck (argumentName:string) (value: 'T | null when 'T : not null and 'T : not struct) = + match value with + | null -> raise (new ArgumentNullException(argumentName)) + | _ -> (# "" value : 'T #) +#else + [] + let inline (|Null|NonNull|) (value : 'T) : Choice when 'T : null and 'T : not struct = + match value with + | null -> Null () + | _ -> NonNull (# "" value : 'T #) +#endif + [] let inline raise (exn: exn) = (# "throw" exn : 'T #) @@ -4493,6 +4565,16 @@ namespace Microsoft.FSharp.Core [] let defaultValueArg arg defaultValue = match arg with ValueNone -> defaultValue | ValueSome v -> v +#if !BUILDING_WITH_LKG && !NO_NULLCHECKING_LIB_SUPPORT + [] + let inline defaultIfNull defaultValue (arg: 'T | null when 'T : not null and 'T : not struct) = + match arg with null -> defaultValue | _ -> (# "" arg : 'T #) + + [] + let inline defaultIfNullV defaultValue (arg: Nullable<'T>) = + if arg.HasValue then arg.Value else defaultValue +#endif + [] let inline (~-) (n: ^T) : ^T = UnaryNegationDynamic<(^T), (^T)> n @@ -5423,7 +5505,7 @@ namespace Microsoft.FSharp.Core module Unchecked = [] - let inline unbox<'T> (v:obj) = unboxPrim<'T> v + let inline unbox<'T> (v:objnull) = unboxPrim<'T> v [] let inline defaultof<'T> = unsafeDefault<'T> @@ -5437,6 +5519,24 @@ namespace Microsoft.FSharp.Core [] let inline hash x = GenericHash x + #if !BUILDING_WITH_LKG && !NO_NULLCHECKING_LIB_SUPPORT + + [] + let inline nonNull (x: 'T | null when 'T : not null and 'T : not struct) : 'T = (# "" x : 'T #) + + [] + let inline (|NonNullQuick|) (value : 'T | null when 'T : not null and 'T : not struct) = nonNull value + + #else + + [] + let inline nonNull (x: 'T ) : 'T = x + + [] + let inline (|NonNullQuick|) (value) = nonNull value + + #endif + module Checked = let inline (+) (x: ^T) (y: ^U) : ^V = @@ -7232,7 +7332,7 @@ namespace Microsoft.FSharp.Control inherit IObservable<'Args> [] - type Handler<'Args> = delegate of sender:obj * args:'Args -> unit + type Handler<'Args> = delegate of sender:objnull * args:'Args -> unit type IEvent<'Args> = IEvent, 'Args> diff --git a/src/FSharp.Core/prim-types.fsi b/src/FSharp.Core/prim-types.fsi index 44a870853a6..ae631cf2114 100644 --- a/src/FSharp.Core/prim-types.fsi +++ b/src/FSharp.Core/prim-types.fsi @@ -1,3 +1,4 @@ + // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. #nowarn "35" // This construct is deprecated: the treatment of this operator is now handled directly by the F# compiler and its meaning may not be redefined. @@ -954,6 +955,24 @@ namespace Microsoft.FSharp.Core /// NoCompilerInliningAttribute new: unit -> NoCompilerInliningAttribute + /// When used in a compilation with null-checking enabled, indicates that a function is meant to be used only with potentially-nullable values and warns accordingly. + /// + /// Attributes + [] + [] + type WarnOnWithoutNullArgumentAttribute = + inherit Attribute + + /// Creates an instance of the attribute + /// The message displayed when the annotated function is used with a value known to be without null + /// WarnOnWithoutNullArgumentAttribute + new: warningMessage:string -> WarnOnWithoutNullArgumentAttribute + + /// Warning message displayed when the annotated function is used with a value known to be without null + member WarningMessage: string + + member internal Localize: bool with get,set + /// Indicates a function that should be called in a tail recursive way inside its recursive scope. /// A warning is emitted if the function is analyzed as not tail recursive after the optimization phase. /// @@ -1372,7 +1391,11 @@ namespace Microsoft.FSharp.Core val inline FastGenericComparer<'T> : System.Collections.Generic.IComparer<'T> when 'T: comparison /// Make an F# comparer object for the given type, where it can be null if System.Collections.Generic.Comparer<'T>.Default - val internal FastGenericComparerCanBeNull<'T> : System.Collections.Generic.IComparer<'T> when 'T: comparison +#if BUILDING_WITH_LKG || NO_NULLCHECKING_LIB_SUPPORT + val internal FastGenericComparerCanBeNull<'T> : System.Collections.Generic.IComparer<'T> when 'T : comparison +#else + val internal FastGenericComparerCanBeNull<'T> : System.Collections.Generic.IComparer<'T> | null when 'T : comparison +#endif /// Make an F# hash/equality object for the given type val inline FastGenericEqualityComparer<'T> : System.Collections.Generic.IEqualityComparer<'T> when 'T: equality @@ -1744,19 +1767,19 @@ namespace Microsoft.FSharp.Core /// A compiler intrinsic that implements the ':?>' operator [] - val UnboxGeneric<'T> : source: obj -> 'T + val UnboxGeneric<'T> : source: objnull -> 'T /// A compiler intrinsic that implements the ':?>' operator [] - val inline UnboxFast<'T> : source: obj -> 'T + val inline UnboxFast<'T> : source: objnull -> 'T /// A compiler intrinsic that implements the ':?' operator [] - val TypeTestGeneric<'T> : source: obj -> bool + val TypeTestGeneric<'T> : source: objnull -> bool /// A compiler intrinsic that implements the ':?' operator [] - val inline TypeTestFast<'T> : source: obj -> bool + val inline TypeTestFast<'T> : source: objnull -> bool /// Primitive used by pattern match compilation //[] @@ -3179,6 +3202,24 @@ namespace Microsoft.FSharp.Core /// val inline (<|||): func: ('T1 -> 'T2 -> 'T3 -> 'U) -> arg1: 'T1 * arg2: 'T2 * arg3: 'T3 -> 'U +#if !BUILDING_WITH_LKG && !NO_NULLCHECKING_LIB_SUPPORT + /// Used to specify a default value for a nullable reference argument in the implementation of a function + /// The default value of the argument. + /// A nullable value representing the argument. + /// The argument value. If it is null, the defaultValue is returned. + [] + [] + val inline defaultIfNull : defaultValue:'T -> arg:'T | null -> 'T when 'T : not null and 'T : not struct + + /// Used to specify a default value for an nullable value argument in the implementation of a function + /// The default value of the argument. + /// A nullable value representing the argument. + /// The argument value. If it is null, the defaultValue is returned. + [] + [] + val inline defaultIfNullV : defaultValue:'T -> arg:Nullable<'T> -> 'T +#endif + /// Used to specify a default value for an optional argument in the implementation of a function /// /// An option representing the argument. @@ -3422,7 +3463,7 @@ namespace Microsoft.FSharp.Core /// /// [] - val inline unbox: value: obj -> 'T + val inline unbox: value: objnull -> 'T /// Boxes a strongly typed value. /// @@ -3440,7 +3481,7 @@ namespace Microsoft.FSharp.Core /// /// [] - val inline box: value: 'T -> obj + val inline box: value: 'T -> objnull /// Try to unbox a strongly typed value. /// @@ -3458,7 +3499,7 @@ namespace Microsoft.FSharp.Core /// /// [] - val inline tryUnbox: value: obj -> 'T option + val inline tryUnbox: value: objnull -> 'T option /// Determines whether the given value is null. /// @@ -3476,13 +3517,102 @@ namespace Microsoft.FSharp.Core [] val inline isNull: value: 'T -> bool when 'T: null +#if !BUILDING_WITH_LKG && !NO_NULLCHECKING_LIB_SUPPORT + /// Determines whether the given value is null. + /// The value to check. + /// A choice indicating whether the value is null or not-null. + [] + [] + [] + val inline (|Null|NonNull|) : value: 'T | null -> Choice when 'T : not null and 'T : not struct + + /// Determines whether the given value is null. + /// In a future revision of nullness support this may be unified with 'Null|NonNull'. + /// The value to check. + /// A choice indicating whether the value is null or not-null. + [] + [] + val inline (|NullV|NonNullV|) : value: Nullable<'T> -> Choice + + /// When used in a pattern checks the given value is not null. + /// The value to check. + /// The non-null value. + [] + [] + [] + val inline (|NonNullQuick|) : value: 'T | null -> 'T when 'T : not null and 'T : not struct + + /// When used in a pattern checks the given value is not null. + /// In a future revision of nullness support this may be unified with 'NonNullQuick'. + /// The value to check. + /// The non-null value. + [] + [] + val inline (|NonNullQuickV|) : value: Nullable<'T> -> 'T + + /// Determines whether the given value is null. + /// In a future revision of nullness support this may be unified with 'isNull'. + /// The value to check. + /// True when value is null, false otherwise. + [] + [] + val inline isNullV : value:Nullable<'T> -> bool +#else + /// Determines whether the given value is null. + /// The value to check. + /// A choice indicating whether the value is null or not-null. + [] + [] + val inline (|Null|NonNull|) : value: 'T -> Choice when 'T : null and 'T : not struct +#endif + /// Determines whether the given value is not null. /// /// The value to check. /// /// True when value is not null, false otherwise. [] - val inline internal isNotNull: value: 'T -> bool when 'T: null + val inline internal isNotNull: value:'T -> bool when 'T : null + +#if !BUILDING_WITH_LKG && !NO_NULLCHECKING_LIB_SUPPORT + /// Get the null value for a value type. + /// In a future revision of nullness support this may be unified with 'null'. + /// The null value for a value type. + [] + [] + val inline nullV<'T when 'T : struct and 'T : (new : unit -> 'T) and 'T :> ValueType> : Nullable<'T> + + /// Asserts that the value is non-null. + /// The value to check. + /// The value when it is not null. If the value is null an exception is raised. + [] + [] + [] + val inline nonNull : value: 'T | null -> 'T when 'T : not null and 'T : not struct + + /// Asserts that the value is non-null. + /// In a future revision of nullness support this may be unified with 'nonNull'. + /// The value to check. + /// True when value is null, false otherwise. + [] + [] + val inline nonNullV : value:Nullable<'T> -> 'T + + /// Asserts that the value is non-null. + /// The value to check. + /// True when value is null, false otherwise. + [] + [] + val inline withNull : value:'T -> 'T | null when 'T : not null and 'T : not struct + + /// Asserts that the value is non-null. + /// In a future revision of nullness support this may be unified with 'withNull'. + /// The value to check. + /// True when value is null, false otherwise. + [] + [] + val inline withNullV : value:'T -> Nullable<'T> +#endif /// Throw a exception. /// @@ -3548,6 +3678,17 @@ namespace Microsoft.FSharp.Core [] val inline nullArg: argumentName: string -> 'T +#if !BUILDING_WITH_LKG && !NO_NULLCHECKING_LIB_SUPPORT + /// Throw a System.ArgumentNullException if the given value is null exception + /// + /// The argument name. + /// + /// The result value. + [] + [] + val inline nullArgCheck : argumentName:string -> 'T | null -> 'T when 'T : not null and 'T : not struct +#endif + /// Throw a exception /// /// The exception message. @@ -3722,7 +3863,7 @@ namespace Microsoft.FSharp.Core /// otherwise raise an exception. Calls . /// /// The exit code to use. - /// + /// /// Never returns. /// /// @@ -5638,7 +5779,7 @@ namespace Microsoft.FSharp.Core /// /// [] - val inline unbox<'T> : value: obj -> 'T + val inline unbox<'T> : value: objnull -> 'T /// Generate a default value for any type. This is null for reference types, /// For structs, this is struct value where all fields have the default value. @@ -5677,6 +5818,28 @@ namespace Microsoft.FSharp.Core [] val inline hash: 'T -> int + /// Unsafely retypes the value from ('T | null) to 'T without doing any null check at runtime. This is an unsafe operation. + /// The possibly nullable value. + /// The same value as in the input. + [] + [] + #if !BUILDING_WITH_LKG && !NO_NULLCHECKING_LIB_SUPPORT + val inline nonNull : value: 'T | null -> 'T when 'T : not null and 'T : not struct + #else + val inline nonNull : value: 'T -> 'T + #endif + + /// When used in a pattern forgets 'nullness' of the value without any runtime check. This is an unsafe operation, as null check is being skipped and null value can be returned. + /// The value to retype from ('T | null) to 'T . + /// The non-null value. + [] + [] + #if !BUILDING_WITH_LKG && !NO_NULLCHECKING_LIB_SUPPORT + val inline (|NonNullQuick|) : value: 'T | null -> 'T when 'T : not null and 'T : not struct + #else + val inline (|NonNullQuick|) : value: 'T -> 'T + #endif + /// A module of comparison and equality operators that are statically resolved, but which are not fully generic and do not make structural comparison. Opening this /// module may make code that relies on structural or generic comparison no longer compile. module NonStructuralComparison = @@ -6096,7 +6259,7 @@ namespace Microsoft.FSharp.Control /// /// Events and Observables [] - type Handler<'T> = delegate of sender:obj * args:'T -> unit + type Handler<'T> = delegate of sender:objnull * args:'T -> unit /// First-class listening points (i.e. objects that permit you to register a callback /// activated when the event is triggered). diff --git a/src/FSharp.Core/printf.fs b/src/FSharp.Core/printf.fs index a326492c672..7862de53de5 100644 --- a/src/FSharp.Core/printf.fs +++ b/src/FSharp.Core/printf.fs @@ -19,7 +19,7 @@ open LanguagePrimitives.IntrinsicOperators type PrintfFormat<'Printer, 'State, 'Residue, 'Result> [] - (value:string, captures: obj array, captureTys: Type array) = + (value:string, captures: objnull array, captureTys: Type array) = [] new (value) = new PrintfFormat<'Printer, 'State, 'Residue, 'Result>(value, null, null) @@ -263,14 +263,14 @@ module internal PrintfImpl = /// Represents one step in the execution of a format string [] type Step = - | StepWithArg of prefix: string * conv: (obj -> string) - | StepWithTypedArg of prefix: string * conv: (obj -> Type -> string) + | StepWithArg of prefix: string * conv: (objnull -> string) + | StepWithTypedArg of prefix: string * conv: (objnull -> Type -> string) | StepString of prefix: string | StepLittleT of prefix: string | StepLittleA of prefix: string - | StepStar1 of prefix: string * conv: (obj -> int -> string) + | StepStar1 of prefix: string * conv: (objnull -> int -> string) | StepPercentStar1 of prefix: string - | StepStar2 of prefix: string * conv: (obj -> int -> int -> string) + | StepStar2 of prefix: string * conv: (objnull -> int -> int -> string) | StepPercentStar2 of prefix: string // Count the number of string fragments in a sequence of steps @@ -323,7 +323,7 @@ module internal PrintfImpl = if not (String.IsNullOrEmpty s) then env.Write s - member env.RunSteps (args: obj array, argTys: Type array, steps: Step array) = + member env.RunSteps (args: objnull array, argTys: Type array, steps: Step array) = let mutable argIndex = 0 let mutable tyIndex = 0 @@ -359,7 +359,7 @@ module internal PrintfImpl = argIndex <- argIndex + 1 let arg = args.[argIndex] argIndex <- argIndex + 1 - let f = farg :?> ('State -> obj -> 'Residue) + let f = farg :?> ('State -> objnull -> 'Residue) env.WriteT(f env.State arg) | StepStar1(prefix, conv) -> @@ -410,7 +410,7 @@ module internal PrintfImpl = /// If we captured into an mutable array then these would interfere type PrintfInitial<'State, 'Residue, 'Result> = (unit -> PrintfEnv<'State, 'Residue, 'Result>) type PrintfFuncFactory<'Printer, 'State, 'Residue, 'Result> = - delegate of obj list * PrintfInitial<'State, 'Residue, 'Result> -> 'Printer + delegate of objnull list * PrintfInitial<'State, 'Residue, 'Result> -> 'Printer [] let MaxArgumentsInSpecialization = 3 @@ -477,7 +477,7 @@ module internal PrintfImpl = static member CaptureLittleA<'A, 'Tail>(next: PrintfFuncFactory<_, 'State, 'Residue, 'Result>) = PrintfFuncFactory<_, 'State, 'Residue, 'Result>(fun args initial -> (fun (f: 'State -> 'A -> 'Residue) (arg1: 'A) -> - let args = box arg1 :: box (fun s (arg:obj) -> f s (unbox arg)) :: args + let args = box arg1 :: box (fun s (arg:objnull) -> f s (unbox arg)) :: args next.Invoke(args, initial) : 'Tail ) ) @@ -546,12 +546,12 @@ module internal PrintfImpl = /// A wrapper struct used to slightly strengthen the types of "ValueConverter" objects produced during composition of /// the dynamic implementation. These are always functions but sometimes they take one argument, sometimes two. [] - type ValueConverter internal (f: obj) = + type ValueConverter internal (f: objnull) = member x.FuncObj = f - static member inline Make (f: obj -> string) = ValueConverter(box f) - static member inline Make (f: obj -> int -> string) = ValueConverter(box f) - static member inline Make (f: obj -> int-> int -> string) = ValueConverter(box f) + static member inline Make (f: objnull -> string) = ValueConverter(box f) + static member inline Make (f: objnull -> int -> string) = ValueConverter(box f) + static member inline Make (f: objnull -> int-> int -> string) = ValueConverter(box f) let getFormatForFloat (ch: char) (prec: int) = ch.ToString() + prec.ToString() @@ -569,7 +569,7 @@ module internal PrintfImpl = /// pad here is function that converts T to string with respect of justification /// basic - function that converts T to string without applying justification rules /// adaptPaddedFormatted returns boxed function that has various number of arguments depending on if width\precision flags has '*' value - let adaptPaddedFormatted (spec: FormatSpecifier) getFormat (basic: string -> obj -> string) (pad: string -> int -> obj -> string) : ValueConverter = + let adaptPaddedFormatted (spec: FormatSpecifier) getFormat (basic: string -> objnull -> string) (pad: string -> int -> objnull -> string) : ValueConverter = if spec.IsStarWidth then if spec.IsStarPrecision then // width=*, prec=* @@ -609,7 +609,7 @@ module internal PrintfImpl = /// pad here is function that converts T to string with respect of justification /// basic - function that converts T to string without applying justification rules /// adaptPadded returns boxed function that has various number of arguments depending on if width flags has '*' value - let adaptPadded (spec: FormatSpecifier) (basic: obj -> string) (pad: int -> obj -> string) : ValueConverter = + let adaptPadded (spec: FormatSpecifier) (basic: objnull -> string) (pad: int -> objnull -> string) : ValueConverter = if spec.IsStarWidth then // width=*, prec=? ValueConverter.Make (fun v width -> @@ -624,7 +624,7 @@ module internal PrintfImpl = ValueConverter.Make ( basic) - let withPaddingFormatted (spec: FormatSpecifier) getFormat (defaultFormat: string) (f: string -> obj -> string) left right : ValueConverter = + let withPaddingFormatted (spec: FormatSpecifier) getFormat (defaultFormat: string) (f: string -> objnull -> string) left right : ValueConverter = if not (spec.IsWidthSpecified || spec.IsPrecisionSpecified) then ValueConverter.Make (f defaultFormat) else @@ -633,7 +633,7 @@ module internal PrintfImpl = else adaptPaddedFormatted spec getFormat f right - let withPadding (spec: FormatSpecifier) (f: obj -> string) left right : ValueConverter = + let withPadding (spec: FormatSpecifier) (f: objnull -> string) left right : ValueConverter = if not spec.IsWidthSpecified then ValueConverter.Make f else @@ -644,11 +644,11 @@ module internal PrintfImpl = /// Contains functions to handle left/right justifications for non-numeric types (strings/bools) module Basic = - let leftJustify (f: obj -> string) padChar = + let leftJustify (f: objnull -> string) padChar = fun (w: int) v -> (f v).PadRight(w, padChar) - let rightJustify (f: obj -> string) padChar = + let rightJustify (f: objnull -> string) padChar = fun (w: int) v -> (f v).PadLeft(w, padChar) @@ -725,16 +725,16 @@ module internal PrintfImpl = else str /// noJustification handler for f: 'T -> string - basic integer types - let noJustification (f: obj -> string) (prefix: string) isUnsigned = + let noJustification (f: objnull -> string) (prefix: string) isUnsigned = if isUnsigned then - fun (v: obj) -> noJustificationCore (f v) true true prefix + fun (v: objnull) -> noJustificationCore (f v) true true prefix else - fun (v: obj) -> noJustificationCore (f v) true (isPositive v) prefix + fun (v: objnull) -> noJustificationCore (f v) true (isPositive v) prefix /// contains functions to handle left/right and no justification case for numbers module Integer = - let eliminateNative (v: obj) = + let eliminateNative (v: objnull) = match v with | :? nativeint as n -> if IntPtr.Size = 4 then box (n.ToInt32()) @@ -744,7 +744,7 @@ module internal PrintfImpl = else box (uint64 (n.ToUInt64())) | _ -> v - let rec toString (v: obj) = + let rec toString (v: objnull) = match v with | :? int32 as n -> n.ToString(CultureInfo.InvariantCulture) | :? int64 as n -> n.ToString(CultureInfo.InvariantCulture) @@ -770,7 +770,7 @@ module internal PrintfImpl = | :? nativeint | :? unativeint -> toFormattedString fmt (eliminateNative v) | _ -> failwith "toFormattedString: unreachable" - let rec toUnsigned (v: obj) = + let rec toUnsigned (v: objnull) = match v with | :? int32 as n -> box (uint32 n) | :? int64 as n -> box (uint64 n) @@ -780,35 +780,35 @@ module internal PrintfImpl = | _ -> v /// Left justification handler for f: 'T -> string - basic integer types - let leftJustify isGFormat (f: obj -> string) (prefix: string) padChar isUnsigned = + let leftJustify isGFormat (f: objnull -> string) (prefix: string) padChar isUnsigned = if isUnsigned then if isGFormat then - fun (w: int) (v: obj) -> + fun (w: int) (v: objnull) -> GenericNumber.leftJustifyWithGFormat (f v) true true true w prefix padChar else - fun (w: int) (v: obj) -> + fun (w: int) (v: objnull) -> GenericNumber.leftJustifyWithNonGFormat (f v) true true w prefix padChar else if isGFormat then - fun (w: int) (v: obj) -> + fun (w: int) (v: objnull) -> GenericNumber.leftJustifyWithGFormat (f v) true true (GenericNumber.isPositive v) w prefix padChar else - fun (w: int) (v: obj) -> + fun (w: int) (v: objnull) -> GenericNumber.leftJustifyWithNonGFormat (f v) true (GenericNumber.isPositive v) w prefix padChar /// Right justification handler for f: 'T -> string - basic integer types let rightJustify f (prefixForPositives: string) padChar isUnsigned = if isUnsigned then if padChar = '0' then - fun (w: int) (v: obj) -> + fun (w: int) (v: objnull) -> GenericNumber.rightJustifyWithZeroAsPadChar (f v) true true w prefixForPositives else System.Diagnostics.Debug.Assert((padChar = ' ')) - fun (w: int) (v: obj) -> + fun (w: int) (v: objnull) -> GenericNumber.rightJustifyWithSpaceAsPadChar (f v) true true w prefixForPositives else if padChar = '0' then - fun (w: int) (v: obj) -> + fun (w: int) (v: objnull) -> GenericNumber.rightJustifyWithZeroAsPadChar (f v) true (GenericNumber.isPositive v) w prefixForPositives else @@ -819,7 +819,7 @@ module internal PrintfImpl = /// Computes a new function from 'f' that wraps the basic conversion given /// by 'f' with padding for 0, spacing and justification, if the flags specify /// it. If they don't, f is made into a value converter - let withPadding (spec: FormatSpecifier) isUnsigned (f: obj -> string) = + let withPadding (spec: FormatSpecifier) isUnsigned (f: objnull -> string) = let allowZeroPadding = not (isLeftJustify spec.Flags) || spec.IsDecimalFormat let padChar, prefix = spec.GetPadAndPrefix allowZeroPadding Padding.withPadding spec @@ -838,13 +838,13 @@ module internal PrintfImpl = | 'X' -> withPadding spec true (toFormattedString "X") | 'o' -> - withPadding spec true (fun (v: obj) -> + withPadding spec true (fun (v: objnull) -> // Convert.ToInt64 throws for uint64 with values above int64 range so cast directly match toUnsigned v with | :? uint64 as u -> Convert.ToString(int64 u, 8) | u -> Convert.ToString(Convert.ToInt64 u, 8)) | 'B' -> - withPadding spec true (fun (v: obj) -> + withPadding spec true (fun (v: objnull) -> match toUnsigned v with | :? uint64 as u -> Convert.ToString(int64 u, 2) | u -> Convert.ToString(Convert.ToInt64 u, 2)) @@ -910,7 +910,7 @@ module internal PrintfImpl = type ObjectPrinter = static member ObjectToString(spec: FormatSpecifier) : ValueConverter = - Basic.withPadding spec (fun (v: obj) -> + Basic.withPadding spec (fun (v: objnull) -> match v with | null -> "" | x -> x.ToString()) @@ -921,7 +921,7 @@ module internal PrintfImpl = match spec.InteropHoleDotNetFormat with | ValueNone -> null | ValueSome fmt -> "{0:" + fmt + "}" - Basic.withPadding spec (fun (vobj: obj) -> + Basic.withPadding spec (fun (vobj: objnull) -> match vobj with | null -> "" | x -> @@ -953,7 +953,7 @@ module internal PrintfImpl = match spec.IsStarWidth, spec.IsStarPrecision with | true, true -> - ValueConverter.Make (fun (vobj: obj) (width: int) (prec: int) -> + ValueConverter.Make (fun (vobj: objnull) (width: int) (prec: int) -> let v = unbox<'T> vobj let opts = { opts with PrintSize = prec } let opts = if not useZeroWidth then { opts with PrintWidth = width} else opts @@ -961,19 +961,19 @@ module internal PrintfImpl = ) | true, false -> - ValueConverter.Make (fun (vobj: obj) (width: int) -> + ValueConverter.Make (fun (vobj: objnull) (width: int) -> let v = unbox<'T> vobj let opts = if not useZeroWidth then { opts with PrintWidth = width} else opts ObjectPrinter.GenericToStringCore(v, opts, bindingFlags)) | false, true -> - ValueConverter.Make (fun (vobj: obj) (prec: int) -> + ValueConverter.Make (fun (vobj: objnull) (prec: int) -> let v = unbox<'T> vobj let opts = { opts with PrintSize = prec } ObjectPrinter.GenericToStringCore(v, opts, bindingFlags) ) | false, false -> - ValueConverter.Make (fun (vobj: obj) -> + ValueConverter.Make (fun (vobj: objnull) -> let v = unbox<'T> vobj ObjectPrinter.GenericToStringCore(v, opts, bindingFlags)) @@ -992,7 +992,7 @@ module internal PrintfImpl = | 's' -> Basic.withPadding spec (unbox >> stringToSafeString) | 'c' -> - Basic.withPadding spec (fun (c: obj) -> (unbox c).ToString()) + Basic.withPadding spec (fun (c: objnull) -> (unbox c).ToString()) | 'M' -> FloatAndDecimal.withPadding spec (fun _ -> "G") "G" // %M ignores precision | 'd' | 'i' | 'u' | 'B' | 'o' | 'x' | 'X' -> @@ -1149,10 +1149,10 @@ module internal PrintfImpl = let argTy = match argTys with null -> typeof | _ -> argTys.[argTys.Length - 1] let conv = getValueConverter argTy spec if isTwoStar then - let convFunc = conv.FuncObj :?> (obj -> int -> int -> string) + let convFunc = conv.FuncObj :?> (objnull -> int -> int -> string) StepStar2 (prefix, convFunc) else - let convFunc = conv.FuncObj :?> (obj -> int -> string) + let convFunc = conv.FuncObj :?> (objnull -> int -> string) StepStar1 (prefix, convFunc) else // For interpolated string format processing, the static types of the '%A' arguments @@ -1162,7 +1162,7 @@ module internal PrintfImpl = let convFunc arg argTy = let mi = mi_GenericToString.MakeGenericMethod [| argTy |] let f = mi.Invoke(null, [| box spec |]) :?> ValueConverter - let f2 = f.FuncObj :?> (obj -> string) + let f2 = f.FuncObj :?> (objnull -> string) f2 arg StepWithTypedArg (prefix, convFunc) @@ -1172,7 +1172,7 @@ module internal PrintfImpl = // are provided via the argument typed extracted from the curried function. They are known on first phase. let argTy = match argTys with null -> typeof | _ -> argTys.[0] let conv = getValueConverter argTy spec - let convFunc = conv.FuncObj :?> (obj -> string) + let convFunc = conv.FuncObj :?> (objnull -> string) StepWithArg (prefix, convFunc) let parseSpec (i: byref) = diff --git a/src/FSharp.Core/printf.fsi b/src/FSharp.Core/printf.fsi index 2e4d009c537..5bbe8405535 100644 --- a/src/FSharp.Core/printf.fsi +++ b/src/FSharp.Core/printf.fsi @@ -31,14 +31,14 @@ type PrintfFormat<'Printer, 'State, 'Residue, 'Result> = /// The types of expressions for %A expression gaps in interpolated string. /// The PrintfFormat containing the formatted result. new: - value: string * captures: obj array * captureTys: Type array -> + value: string * captures: objnull array * captureTys: Type array -> PrintfFormat<'Printer, 'State, 'Residue, 'Result> /// The raw text of the format string. member Value: string /// The captures associated with an interpolated string. - member Captures: obj array + member Captures: objnull array /// The capture types associated with an interpolated string. member CaptureTypes: System.Type array @@ -71,7 +71,7 @@ type PrintfFormat<'Printer, 'State, 'Residue, 'Result, 'Tuple> = /// /// The created format string. new: - value: string * captures: obj array * captureTys: Type array -> + value: string * captures: objnull array * captureTys: Type array -> PrintfFormat<'Printer, 'State, 'Residue, 'Result, 'Tuple> /// Type of a formatting expression. diff --git a/src/FSharp.Core/quotations.fs b/src/FSharp.Core/quotations.fs index 4c71bf0d928..2f90f7a48ee 100644 --- a/src/FSharp.Core/quotations.fs +++ b/src/FSharp.Core/quotations.fs @@ -140,13 +140,13 @@ type Var(name: string, typ: Type, ?isMutable: bool) = override _.GetHashCode() = base.GetHashCode() - override v.Equals(obj: obj) = + override v.Equals(obj: objnull) = match obj with | :? Var as v2 -> System.Object.ReferenceEquals(v, v2) | _ -> false interface System.IComparable with - member v.CompareTo(obj: obj) = + member v.CompareTo(obj: objnull) = match obj with | :? Var as v2 -> if System.Object.ReferenceEquals(v, v2) then @@ -223,15 +223,15 @@ and [] ExprConstInfo = | ForIntegerRangeLoopOp | WhileLoopOp // Arbitrary spliced values - not serialized - | ValueOp of obj * Type * string option - | WithValueOp of obj * Type + | ValueOp of objnull * Type * string option + | WithValueOp of objnull * Type | DefaultValueOp of Type and [] Expr(term: Tree, attribs: Expr list) = member x.Tree = term member x.CustomAttributes = attribs - override x.Equals obj = + override x.Equals(obj: objnull) = match obj with | :? Expr as y -> let rec eq t1 t2 = @@ -2655,7 +2655,7 @@ type Expr with static member Value(value: 'T) = mkValue (box value, typeof<'T>) - static member Value(value: obj, expressionType: Type) = + static member Value(value: objnull, expressionType: Type) = checkNonNull "expressionType" expressionType mkValue (value, expressionType) @@ -2663,7 +2663,7 @@ type Expr with checkNonNull "name" name mkValueWithName (box value, typeof<'T>, name) - static member ValueWithName(value: obj, expressionType: Type, name: string) = + static member ValueWithName(value: objnull, expressionType: Type, name: string) = checkNonNull "expressionType" expressionType checkNonNull "name" name mkValueWithName (value, expressionType, name) @@ -2672,7 +2672,7 @@ type Expr with let raw = mkValueWithDefn (box value, typeof<'T>, definition) new Expr<'T>(raw.Tree, raw.CustomAttributes) - static member WithValue(value: obj, expressionType: Type, definition: Expr) = + static member WithValue(value: objnull, expressionType: Type, definition: Expr) = checkNonNull "expressionType" expressionType mkValueWithDefn (value, expressionType, definition) @@ -2917,7 +2917,7 @@ module DerivedPatterns = module ExprShape = open Patterns - let RebuildShapeCombination (shape: obj, arguments) = + let RebuildShapeCombination (shape: objnull, arguments) = // preserve the attributes let op, attrs = unbox (shape) diff --git a/src/FSharp.Core/quotations.fsi b/src/FSharp.Core/quotations.fsi index ad69f801996..898fe6a362f 100644 --- a/src/FSharp.Core/quotations.fsi +++ b/src/FSharp.Core/quotations.fsi @@ -187,7 +187,7 @@ type Expr = /// member CustomAttributes: Expr list - override Equals: obj: obj -> bool + override Equals: obj: objnull -> bool /// Builds an expression that represents getting the address of a value. /// @@ -1047,7 +1047,7 @@ type Expr = /// /// Evaluates to a quotation with the same structure as <@ 1 @>. /// - static member Value: value: obj * expressionType: Type -> Expr + static member Value: value: objnull * expressionType: Type -> Expr /// Builds an expression that represents a constant value /// @@ -1096,7 +1096,7 @@ type Expr = /// /// Evaluates to a quotation with the same structure as <@ 1 @> and associated information that the name of the value is "name". /// - static member ValueWithName: value: obj * expressionType: Type * name: string -> Expr + static member ValueWithName: value: objnull * expressionType: Type * name: string -> Expr /// Builds an expression that represents a value and its associated reflected definition as a quotation /// @@ -1131,7 +1131,7 @@ type Expr = /// /// Evaluates to a quotation that displays as WithValue (1, Call (None, op_Subtraction, [Value (2), Value (1)])). /// - static member WithValue: value: obj * expressionType: Type * definition: Expr -> Expr + static member WithValue: value: objnull * expressionType: Type * definition: Expr -> Expr /// Builds an expression that represents a variable /// @@ -1709,7 +1709,7 @@ module Patterns = /// /// [] - val (|Value|_|): input: Expr -> (obj * Type) option + val (|Value|_|): input: Expr -> (objnull * Type) option /// An active pattern to recognize expressions that represent a constant value /// @@ -1719,7 +1719,7 @@ module Patterns = /// /// [] - val (|ValueWithName|_|): input: Expr -> (obj * Type * string) option + val (|ValueWithName|_|): input: Expr -> (objnull * Type * string) option /// An active pattern to recognize expressions that are a value with an associated definition /// @@ -1729,7 +1729,7 @@ module Patterns = /// /// [] - val (|WithValue|_|): input: Expr -> (obj * Type * Expr) option + val (|WithValue|_|): input: Expr -> (objnull * Type * Expr) option /// An active pattern to recognize expressions that represent a variable /// @@ -2269,7 +2269,7 @@ module ExprShape = /// /// [] - val (|ShapeVar|ShapeLambda|ShapeCombination|): input: Expr -> Choice + val (|ShapeVar|ShapeLambda|ShapeCombination|): input: Expr -> Choice /// Re-build combination expressions. The first parameter should be an object /// returned by the ShapeCombination case of the active pattern in this module. @@ -2280,4 +2280,4 @@ module ExprShape = /// The rebuilt expression. /// /// - val RebuildShapeCombination: shape: obj * arguments: Expr list -> Expr + val RebuildShapeCombination: shape: objnull * arguments: Expr list -> Expr diff --git a/src/FSharp.Core/reflect.fs b/src/FSharp.Core/reflect.fs index 6b27929933b..f8c8e57d695 100644 --- a/src/FSharp.Core/reflect.fs +++ b/src/FSharp.Core/reflect.fs @@ -47,7 +47,7 @@ module internal Impl = else Type.op_Equality (ty1, ty2) - let func = typedefof<(obj -> obj)> + let func = typedefof<(objnull -> objnull)> let isOptionType typ = equivHeadTypes typ (typeof) @@ -87,7 +87,7 @@ module internal Impl = Expression.Property(Expression.Convert(param, prop.DeclaringType), prop) let expr = - Expression.Lambda>(Expression.Convert(propExpr, typeof), param) + Expression.Lambda>(Expression.Convert(propExpr, typeof), param) expr.Compile() @@ -96,7 +96,7 @@ module internal Impl = let typedParam = Expression.Variable typ let expr = - Expression.Lambda>( + Expression.Lambda>( Expression.Block( [ typedParam ], Expression.Assign(typedParam, Expression.Convert(param, typ)), @@ -115,10 +115,10 @@ module internal Impl = let compileRecordConstructorFunc (ctorInfo: ConstructorInfo) = let ctorParams = ctorInfo.GetParameters() - let paramArray = Expression.Parameter(typeof, "paramArray") + let paramArray = Expression.Parameter(typeof, "paramArray") let expr = - Expression.Lambda>( + Expression.Lambda>( Expression.Convert( Expression.New( ctorInfo, @@ -139,10 +139,10 @@ module internal Impl = let compileUnionCaseConstructorFunc (methodInfo: MethodInfo) = let methodParams = methodInfo.GetParameters() - let paramArray = Expression.Parameter(typeof, "param") + let paramArray = Expression.Parameter(typeof, "param") let expr = - Expression.Lambda>( + Expression.Lambda>( Expression.Convert( Expression.Call( methodInfo, @@ -169,7 +169,7 @@ module internal Impl = | Choice1Of2 info -> Expression.Call(info, Expression.Convert(param, info.DeclaringType)) :> Expression | Choice2Of2 info -> Expression.Property(Expression.Convert(param, info.DeclaringType), info) :> _ - let expr = Expression.Lambda>(tag, param) + let expr = Expression.Lambda>(tag, param) expr.Compile() let compileTupleConstructor tupleEncField getTupleConstructorMethod typ = @@ -192,10 +192,10 @@ module internal Impl = ] ) - let elements = Expression.Parameter(typeof, "elements") + let elements = Expression.Parameter(typeof, "elements") let expr = - Expression.Lambda>( + Expression.Lambda>( Expression.Convert(constituentTuple typ elements 0, typeof), elements ) @@ -246,7 +246,7 @@ module internal Impl = genericArgs.Length let expr = - Expression.Lambda>( + Expression.Lambda>( Expression.Block( [ outputArray ], [ @@ -516,7 +516,7 @@ module internal Impl = let getUnionCaseRecordReader (typ: Type, tag: int, bindingFlags) = let props = fieldsPropsOfUnionCase (typ, tag, bindingFlags) - (fun (obj: obj) -> + (fun (obj: objnull) -> props |> Array.map (fun prop -> prop.GetValue(obj, bindingFlags, null, null, null))) @@ -526,9 +526,9 @@ module internal Impl = let caseTyp = if isNull caseTyp then typ else caseTyp compileRecordOrUnionCaseReaderFunc(caseTyp, props).Invoke - let getUnionTagReader (typ: Type, bindingFlags) : (obj -> int) = + let getUnionTagReader (typ: Type, bindingFlags) : (objnull -> int) = if isOptionType typ then - (fun (obj: obj) -> + (fun (obj: objnull) -> match obj with | null -> 0 | _ -> 1) @@ -536,19 +536,19 @@ module internal Impl = let tagMap = getUnionTypeTagNameMap (typ, bindingFlags) if tagMap.Length <= 1 then - (fun (_obj: obj) -> 0) + (fun (_obj: objnull) -> 0) else match getInstancePropertyReader (typ, "Tag", bindingFlags) with - | Some reader -> (fun (obj: obj) -> reader obj :?> int) + | Some reader -> (fun (obj: objnull) -> reader obj :?> int) | None -> let m2b = typ.GetMethod("GetTag", BindingFlags.Static ||| bindingFlags, null, [| typ |], null) - (fun (obj: obj) -> m2b.Invoke(null, [| obj |]) :?> int) + (fun (obj: objnull) -> m2b.Invoke(null, [| obj |]) :?> int) - let getUnionTagReaderCompiled (typ: Type, bindingFlags) : (obj -> int) = + let getUnionTagReaderCompiled (typ: Type, bindingFlags) : (objnull -> int) = if isOptionType typ then - (fun (obj: obj) -> + (fun (obj: objnull) -> match obj with | null -> 0 | _ -> 1) @@ -556,7 +556,7 @@ module internal Impl = let tagMap = getUnionTypeTagNameMap (typ, bindingFlags) if tagMap.Length <= 1 then - (fun (_obj: obj) -> 0) + (fun (_obj: objnull) -> 0) else match getInstancePropertyInfo (typ, "Tag", bindingFlags) with | null -> @@ -831,7 +831,7 @@ module internal Impl = let getTupleCtor (typ: Type) = let ctor = getTupleConstructorMethod typ - (fun (args: obj array) -> + (fun (args: objnull array) -> ctor.Invoke(BindingFlags.InvokeMethod ||| BindingFlags.Instance ||| BindingFlags.Public, null, args, null)) let getTupleElementAccessors (typ: Type) = @@ -872,7 +872,7 @@ module internal Impl = let tyBenc = etys.[tupleEncField] let maker2 = getTupleConstructor tyBenc - (fun (args: obj array) -> + (fun (args: objnull array) -> let encVal = maker2 args.[tupleEncField..] maker1 (Array.append args.[0 .. tupleEncField - 1] [| encVal |])) @@ -991,7 +991,7 @@ module internal Impl = let getRecordConstructor (typ: Type, bindingFlags) = let ctor = getRecordConstructorMethod (typ, bindingFlags) - (fun (args: obj array) -> + (fun (args: objnull array) -> ctor.Invoke(BindingFlags.InvokeMethod ||| BindingFlags.Instance ||| bindingFlags, null, args, null)) let getRecordConstructorCompiled (typ: Type, bindingFlags) = @@ -1104,7 +1104,7 @@ type UnionCaseInfo(typ: System.Type, tag: int) = override x.GetHashCode() = typ.GetHashCode() + tag - override _.Equals(obj: obj) = + override _.Equals(obj: objnull) = match obj with | :? UnionCaseInfo as uci -> uci.DeclaringType = typ && uci.Tag = tag | _ -> false @@ -1260,11 +1260,11 @@ type FSharpValue = getRecordReader (typ, bindingFlags) record - static member PreComputeRecordFieldReader(info: PropertyInfo) : obj -> obj = + static member PreComputeRecordFieldReader(info: PropertyInfo) : obj -> objnull = checkNonNull "info" info compilePropGetterFunc(info).Invoke - static member PreComputeRecordReader(recordType: Type, ?bindingFlags) : (obj -> obj array) = + static member PreComputeRecordReader(recordType: Type, ?bindingFlags) : (obj -> objnull array) = let bindingFlags = defaultArg bindingFlags BindingFlags.Public checkRecordType ("recordType", recordType, bindingFlags) getRecordReaderCompiled (recordType, bindingFlags) @@ -1279,7 +1279,7 @@ type FSharpValue = checkRecordType ("recordType", recordType, bindingFlags) getRecordConstructorMethod (recordType, bindingFlags) - static member MakeFunction(functionType: Type, implementation: (obj -> obj)) = + static member MakeFunction(functionType: Type, implementation: (objnull -> objnull)) = checkNonNull "functionType" functionType if not (isFunctionType functionType) then @@ -1291,10 +1291,10 @@ type FSharpValue = let dynCloMakerTy = typedefof> let saverTy = dynCloMakerTy.MakeGenericType [| domain; range |] let o = Activator.CreateInstance saverTy - let (f: (obj -> obj) -> obj) = downcast o + let (f: (objnull -> objnull) -> obj) = downcast o f implementation - static member MakeTuple(tupleElements: obj array, tupleType: Type) = + static member MakeTuple(tupleElements: objnull array, tupleType: Type) = checkNonNull "tupleElements" tupleElements checkTupleType ("tupleType", tupleType) getTupleConstructor tupleType tupleElements @@ -1327,7 +1327,7 @@ type FSharpValue = fields.[index] - static member PreComputeTupleReader(tupleType: Type) : (obj -> obj array) = + static member PreComputeTupleReader(tupleType: Type) : (obj -> objnull array) = checkTupleType ("tupleType", tupleType) (compileTupleReader tupleEncField getTupleElementAccessors tupleType).Invoke @@ -1345,7 +1345,7 @@ type FSharpValue = checkTupleType ("tupleType", tupleType) getTupleConstructorInfo tupleType - static member MakeUnion(unionCase: UnionCaseInfo, args: obj array, ?bindingFlags) = + static member MakeUnion(unionCase: UnionCaseInfo, args: objnull array, ?bindingFlags) = let bindingFlags = defaultArg bindingFlags BindingFlags.Public checkNonNull "unionCase" unionCase getUnionCaseConstructor (unionCase.DeclaringType, unionCase.Tag, bindingFlags) args @@ -1360,10 +1360,10 @@ type FSharpValue = checkNonNull "unionCase" unionCase getUnionCaseConstructorMethod (unionCase.DeclaringType, unionCase.Tag, bindingFlags) - static member GetUnionFields(value: obj, unionType: Type, ?bindingFlags) = + static member GetUnionFields(value: objnull, unionType: Type, ?bindingFlags) = let bindingFlags = defaultArg bindingFlags BindingFlags.Public - let ensureType (typ: Type, obj: obj) = + let ensureType (typ: Type, obj: objnull) = match typ with | null -> match obj with @@ -1381,7 +1381,7 @@ type FSharpValue = let flds = getUnionCaseRecordReader (unionType, tag, bindingFlags) value UnionCaseInfo(unionType, tag), flds - static member PreComputeUnionTagReader(unionType: Type, ?bindingFlags) : (obj -> int) = + static member PreComputeUnionTagReader(unionType: Type, ?bindingFlags) : (objnull -> int) = let bindingFlags = defaultArg bindingFlags BindingFlags.Public checkNonNull "unionType" unionType let unionType = getTypeOfReprType (unionType, bindingFlags) @@ -1395,7 +1395,7 @@ type FSharpValue = checkUnionType (unionType, bindingFlags) getUnionTagMemberInfo (unionType, bindingFlags) - static member PreComputeUnionReader(unionCase: UnionCaseInfo, ?bindingFlags) : (obj -> obj array) = + static member PreComputeUnionReader(unionCase: UnionCaseInfo, ?bindingFlags) : (objnull -> objnull array) = let bindingFlags = defaultArg bindingFlags BindingFlags.Public checkNonNull "unionCase" unionCase let typ = unionCase.DeclaringType @@ -1450,7 +1450,7 @@ module FSharpReflectionExtensions = ( recordType: Type, ?allowAccessToPrivateRepresentation - ) : (obj -> obj array) = + ) : (obj -> objnull array) = let bindingFlags = getBindingFlags allowAccessToPrivateRepresentation FSharpValue.PreComputeRecordReader(recordType, bindingFlags) @@ -1462,7 +1462,7 @@ module FSharpReflectionExtensions = let bindingFlags = getBindingFlags allowAccessToPrivateRepresentation FSharpValue.PreComputeRecordConstructorInfo(recordType, bindingFlags) - static member MakeUnion(unionCase: UnionCaseInfo, args: obj array, ?allowAccessToPrivateRepresentation) = + static member MakeUnion(unionCase: UnionCaseInfo, args: objnull array, ?allowAccessToPrivateRepresentation) = let bindingFlags = getBindingFlags allowAccessToPrivateRepresentation FSharpValue.MakeUnion(unionCase, args, bindingFlags) @@ -1478,11 +1478,15 @@ module FSharpReflectionExtensions = let bindingFlags = getBindingFlags allowAccessToPrivateRepresentation FSharpValue.PreComputeUnionTagMemberInfo(unionType, bindingFlags) - static member GetUnionFields(value: obj, unionType: Type, ?allowAccessToPrivateRepresentation) = + static member GetUnionFields(value: objnull, unionType: Type, ?allowAccessToPrivateRepresentation) = let bindingFlags = getBindingFlags allowAccessToPrivateRepresentation FSharpValue.GetUnionFields(value, unionType, bindingFlags) - static member PreComputeUnionTagReader(unionType: Type, ?allowAccessToPrivateRepresentation) : (obj -> int) = + static member PreComputeUnionTagReader + ( + unionType: Type, + ?allowAccessToPrivateRepresentation + ) : (objnull -> int) = let bindingFlags = getBindingFlags allowAccessToPrivateRepresentation FSharpValue.PreComputeUnionTagReader(unionType, bindingFlags) @@ -1490,7 +1494,7 @@ module FSharpReflectionExtensions = ( unionCase: UnionCaseInfo, ?allowAccessToPrivateRepresentation - ) : (obj -> obj array) = + ) : (objnull -> objnull array) = let bindingFlags = getBindingFlags allowAccessToPrivateRepresentation FSharpValue.PreComputeUnionReader(unionCase, bindingFlags) diff --git a/src/FSharp.Core/reflect.fsi b/src/FSharp.Core/reflect.fsi index 9aa76f62a69..e4a5a546677 100644 --- a/src/FSharp.Core/reflect.fsi +++ b/src/FSharp.Core/reflect.fsi @@ -209,7 +209,7 @@ type FSharpValue = /// The field from the record. /// /// - static member GetRecordField: record: obj * info: PropertyInfo -> obj + static member GetRecordField: record: obj * info: PropertyInfo -> objnull /// Precompute a function for reading a particular field from a record. /// Assumes the given type is a RecordType with a field of the given name. @@ -226,7 +226,7 @@ type FSharpValue = /// A function to read the specified field from the record. /// /// - static member PreComputeRecordFieldReader: info: PropertyInfo -> (obj -> obj) + static member PreComputeRecordFieldReader: info: PropertyInfo -> (obj -> objnull) /// Creates an instance of a record type. /// @@ -243,7 +243,7 @@ type FSharpValue = /// static member MakeRecord: [] recordType: Type * - values: obj array * + values: objnull array * ?bindingFlags: BindingFlags -> obj @@ -258,7 +258,7 @@ type FSharpValue = /// The array of fields from the record. /// /// - static member GetRecordFields: record: obj * ?bindingFlags: BindingFlags -> obj array + static member GetRecordFields: record: obj * ?bindingFlags: BindingFlags -> objnull array /// Precompute a function for reading all the fields from a record. The fields are returned in the /// same order as the fields reported by a call to Microsoft.FSharp.Reflection.Type.GetInfo for @@ -282,7 +282,7 @@ type FSharpValue = static member PreComputeRecordReader: [] recordType: Type * ?bindingFlags: BindingFlags -> - (obj -> obj array) + (obj -> objnull array) /// Precompute a function for constructing a record value. /// @@ -300,7 +300,7 @@ type FSharpValue = static member PreComputeRecordConstructor: [] recordType: Type * ?bindingFlags: BindingFlags -> - (obj array -> obj) + (objnull array -> obj) /// Get a ConstructorInfo for a record type /// @@ -324,7 +324,7 @@ type FSharpValue = /// The constructed union case. /// /// - static member MakeUnion: unionCase: UnionCaseInfo * args: obj array * ?bindingFlags: BindingFlags -> obj + static member MakeUnion: unionCase: UnionCaseInfo * args: objnull array * ?bindingFlags: BindingFlags -> objnull /// Identify the union case and its fields for an object /// @@ -343,10 +343,10 @@ type FSharpValue = /// /// static member GetUnionFields: - value: obj * + value: objnull * [] unionType: Type * ?bindingFlags: BindingFlags -> - UnionCaseInfo * obj array + UnionCaseInfo * objnull array /// Assumes the given type is a union type. /// If not, is raised during pre-computation. @@ -363,7 +363,7 @@ type FSharpValue = /// static member PreComputeUnionTagReader: [] unionType: Type * ?bindingFlags: BindingFlags -> - (obj -> int) + (objnull -> int) /// Precompute a property or static method for reading an integer representing the case tag of a union type. /// @@ -387,7 +387,8 @@ type FSharpValue = /// A function to for reading the fields of the given union case. /// /// - static member PreComputeUnionReader: unionCase: UnionCaseInfo * ?bindingFlags: BindingFlags -> (obj -> obj array) + static member PreComputeUnionReader: + unionCase: UnionCaseInfo * ?bindingFlags: BindingFlags -> (objnull -> objnull array) /// Precompute a function for constructing a discriminated union value for a particular union case. /// @@ -398,7 +399,7 @@ type FSharpValue = /// /// static member PreComputeUnionConstructor: - unionCase: UnionCaseInfo * ?bindingFlags: BindingFlags -> (obj array -> obj) + unionCase: UnionCaseInfo * ?bindingFlags: BindingFlags -> (objnull array -> objnull) /// A method that constructs objects of the given case /// @@ -422,7 +423,7 @@ type FSharpValue = /// The fields from the given exception. /// /// - static member GetExceptionFields: exn: obj * ?bindingFlags: BindingFlags -> obj array + static member GetExceptionFields: exn: obj * ?bindingFlags: BindingFlags -> objnull array /// Creates an instance of a tuple type /// @@ -436,7 +437,7 @@ type FSharpValue = /// An instance of the tuple type with the given elements. /// /// - static member MakeTuple: tupleElements: obj array * tupleType: Type -> obj + static member MakeTuple: tupleElements: objnull array * tupleType: Type -> obj /// Reads a field from a tuple value. /// @@ -448,7 +449,7 @@ type FSharpValue = /// The value of the field. /// /// - static member GetTupleField: tuple: obj * index: int -> obj + static member GetTupleField: tuple: obj * index: int -> objnull /// Reads all fields from a tuple. /// @@ -461,7 +462,7 @@ type FSharpValue = /// An array of the fields from the given tuple. /// /// - static member GetTupleFields: tuple: obj -> obj array + static member GetTupleFields: tuple: obj -> objnull array /// Precompute a function for reading the values of a particular tuple type /// @@ -476,7 +477,7 @@ type FSharpValue = /// /// static member PreComputeTupleReader: - [] tupleType: Type -> (obj -> obj array) + [] tupleType: Type -> (obj -> objnull array) /// Gets information that indicates how to read a field of a tuple /// @@ -503,7 +504,7 @@ type FSharpValue = /// /// static member PreComputeTupleConstructor: - [] tupleType: Type -> (obj array -> obj) + [] tupleType: Type -> (objnull array -> obj) /// Gets a method that constructs objects of the given tuple type. /// For small tuples, no additional type will be returned. @@ -535,7 +536,7 @@ type FSharpValue = /// static member MakeFunction: [] functionType: Type * - implementation: (obj -> obj) -> + implementation: (objnull -> objnull) -> obj /// Contains operations associated with constructing and analyzing F# types such as records, unions and tuples @@ -745,7 +746,7 @@ module FSharpReflectionExtensions = /// static member MakeRecord: [] recordType: Type * - values: obj array * + values: objnull array * ?allowAccessToPrivateRepresentation: bool -> obj @@ -764,7 +765,7 @@ module FSharpReflectionExtensions = static member GetRecordFields: [] record: obj * ?allowAccessToPrivateRepresentation: bool -> - obj array + objnull array /// Precompute a function for reading all the fields from a record. The fields are returned in the /// same order as the fields reported by a call to Microsoft.FSharp.Reflection.Type.GetInfo for @@ -788,7 +789,7 @@ module FSharpReflectionExtensions = static member PreComputeRecordReader: [] recordType: Type * ?allowAccessToPrivateRepresentation: bool -> - (obj -> obj array) + (obj -> objnull array) /// Precompute a function for constructing a record value. /// @@ -806,7 +807,7 @@ module FSharpReflectionExtensions = static member PreComputeRecordConstructor: [] recordType: Type * ?allowAccessToPrivateRepresentation: bool -> - (obj array -> obj) + (objnull array -> obj) /// Get a ConstructorInfo for a record type /// @@ -831,7 +832,7 @@ module FSharpReflectionExtensions = /// /// static member MakeUnion: - unionCase: UnionCaseInfo * args: obj array * ?allowAccessToPrivateRepresentation: bool -> obj + unionCase: UnionCaseInfo * args: objnull array * ?allowAccessToPrivateRepresentation: bool -> objnull /// Identify the union case and its fields for an object /// @@ -851,10 +852,10 @@ module FSharpReflectionExtensions = /// /// static member GetUnionFields: - value: obj * + value: objnull * [] unionType: Type * ?allowAccessToPrivateRepresentation: bool -> - UnionCaseInfo * obj array + UnionCaseInfo * objnull array /// Assumes the given type is a union type. /// If not, is raised during pre-computation. @@ -872,7 +873,7 @@ module FSharpReflectionExtensions = static member PreComputeUnionTagReader: [] unionType: Type * ?allowAccessToPrivateRepresentation: bool -> - (obj -> int) + (objnull -> int) /// Precompute a property or static method for reading an integer representing the case tag of a union type. /// @@ -898,7 +899,7 @@ module FSharpReflectionExtensions = /// /// static member PreComputeUnionReader: - unionCase: UnionCaseInfo * ?allowAccessToPrivateRepresentation: bool -> (obj -> obj array) + unionCase: UnionCaseInfo * ?allowAccessToPrivateRepresentation: bool -> (objnull -> objnull array) /// Precompute a function for constructing a discriminated union value for a particular union case. /// @@ -909,7 +910,7 @@ module FSharpReflectionExtensions = /// /// static member PreComputeUnionConstructor: - unionCase: UnionCaseInfo * ?allowAccessToPrivateRepresentation: bool -> (obj array -> obj) + unionCase: UnionCaseInfo * ?allowAccessToPrivateRepresentation: bool -> (objnull array -> objnull) /// A method that constructs objects of the given case /// @@ -934,7 +935,7 @@ module FSharpReflectionExtensions = /// The fields from the given exception. /// /// - static member GetExceptionFields: exn: obj * ?allowAccessToPrivateRepresentation: bool -> obj array + static member GetExceptionFields: exn: obj * ?allowAccessToPrivateRepresentation: bool -> objnull array type FSharpType with diff --git a/src/FSharp.Core/resumable.fs b/src/FSharp.Core/resumable.fs index 24131ea155f..a22b1754021 100644 --- a/src/FSharp.Core/resumable.fs +++ b/src/FSharp.Core/resumable.fs @@ -63,7 +63,7 @@ and ResumptionFunc<'Data> = delegate of byref> -> b and [] ResumptionDynamicInfo<'Data>(initial: ResumptionFunc<'Data>) = member val ResumptionFunc: ResumptionFunc<'Data> = initial with get, set - member val ResumptionData: obj = null with get, set + member val ResumptionData: objnull = null with get, set abstract MoveNext: machine: byref> -> unit abstract SetStateMachine: machine: byref> * machineState: IAsyncStateMachine -> unit diff --git a/src/FSharp.Core/resumable.fsi b/src/FSharp.Core/resumable.fsi index 3cd295f71e4..466301dc36b 100644 --- a/src/FSharp.Core/resumable.fsi +++ b/src/FSharp.Core/resumable.fsi @@ -49,7 +49,7 @@ and member ResumptionFunc: ResumptionFunc<'Data> with get, set /// Additional data associated with the state machine - member ResumptionData: obj with get, set + member ResumptionData: objnull with get, set /// Executes the MoveNext implementation of the state machine abstract MoveNext: machine: byref> -> unit diff --git a/src/FSharp.Core/seqcore.fs b/src/FSharp.Core/seqcore.fs index 68b8c35c48a..89cd432ee9a 100644 --- a/src/FSharp.Core/seqcore.fs +++ b/src/FSharp.Core/seqcore.fs @@ -169,7 +169,7 @@ module internal IEnumerator = f() } - let inline checkNonNull argName arg = + let inline checkNonNull argName (arg: 'T when 'T : null) = if isNull arg then nullArg argName @@ -451,7 +451,7 @@ module RuntimeHelpers = // Enumeration has finished. In this case, we do NOT invoke the exception handlers for the .Dispose() call | None -> disposeOriginal()})) - let CreateEvent (addHandler : 'Delegate -> unit) (removeHandler : 'Delegate -> unit) (createHandler : (obj -> 'Args -> unit) -> 'Delegate ) :IEvent<'Delegate,'Args> = + let CreateEvent (addHandler : 'Delegate -> unit) (removeHandler : 'Delegate -> unit) (createHandler : (objnull -> 'Args -> unit) -> 'Delegate ) :IEvent<'Delegate,'Args> = { new obj() with member x.ToString() = "" interface IEvent<'Delegate,'Args> with diff --git a/src/FSharp.Core/seqcore.fsi b/src/FSharp.Core/seqcore.fsi index e58e1f6ce68..52b4eeb403d 100644 --- a/src/FSharp.Core/seqcore.fsi +++ b/src/FSharp.Core/seqcore.fsi @@ -125,7 +125,7 @@ module RuntimeHelpers = val CreateEvent: addHandler: ('Delegate -> unit) -> removeHandler: ('Delegate -> unit) -> - createHandler: ((obj -> 'Args -> unit) -> 'Delegate) -> + createHandler: ((objnull -> 'Args -> unit) -> 'Delegate) -> Microsoft.FSharp.Control.IEvent<'Delegate, 'Args> /// The F# compiler emits implementations of this type for compiled sequence expressions. diff --git a/src/FSharp.Core/set.fs b/src/FSharp.Core/set.fs index 4efc3fa92df..85fc718c461 100644 --- a/src/FSharp.Core/set.fs +++ b/src/FSharp.Core/set.fs @@ -904,7 +904,7 @@ type Set<[] 'T when 'T: comparison>(comparer: IComparer<' | _ -> false interface System.IComparable with - member this.CompareTo(that: obj) = + member this.CompareTo(that: objnull) = SetTree.compare this.Comparer this.Tree ((that :?> Set<'T>).Tree) interface IStructuralEquatable with diff --git a/src/FSharp.Core/set.fsi b/src/FSharp.Core/set.fsi index b9ba1042945..1be1ad557df 100644 --- a/src/FSharp.Core/set.fsi +++ b/src/FSharp.Core/set.fsi @@ -234,7 +234,7 @@ type Set<[] 'T when 'T: comparison> = interface System.IComparable interface System.Collections.IStructuralEquatable interface IReadOnlyCollection<'T> - override Equals: obj -> bool + override Equals: objnull -> bool #if NETSTANDARD2_1_OR_GREATER /// Contains methods for compiler use related to sets. diff --git a/src/fsi/console.fs b/src/fsi/console.fs index 0c1f056533d..4b26f14c360 100644 --- a/src/fsi/console.fs +++ b/src/fsi/console.fs @@ -8,6 +8,18 @@ open System.Collections.Generic open System.Runtime.InteropServices open FSharp.Compiler.DiagnosticsLogger +[] +module internal ConsoleHelpers = + +#if NO_CHECKNULLS + type MaybeNull<'T when 'T : null> = 'T + + // Shim to match nullness checking library support in preview + let inline (|Null|NonNull|) (x: 'T) : Choice = match x with null -> Null | v -> NonNull v +#else + type MaybeNull<'T when 'T : not null> = 'T | null +#endif + type internal Style = | Prompt | Out @@ -30,24 +42,20 @@ type internal History() = list.Clear() current <- -1 - member _.Add line = - match line with - | null + member _.Add (line: string MaybeNull) = + match line with + | Null | "" -> () - | _ -> list.Add(line) + | NonNull line -> list.Add(line) - member _.AddLast line = - match line with - | null + member _.AddLast (line: string MaybeNull) = + match line with + | Null | "" -> () - | _ -> + | NonNull line -> list.Add(line) current <- list.Count - // Dead code - // member x.First() = current <- 0; x.Current - // member x.Last() = current <- list.Count - 1; x.Current - member x.Previous() = if (list.Count > 0) then current <- ((current - 1) + list.Count) % list.Count diff --git a/tests/AheadOfTime/Trimming/check.ps1 b/tests/AheadOfTime/Trimming/check.ps1 index 028c39a7929..5df1c9f4c2d 100644 --- a/tests/AheadOfTime/Trimming/check.ps1 +++ b/tests/AheadOfTime/Trimming/check.ps1 @@ -1,5 +1,6 @@ function CheckTrim($root, $tfm, $outputfile, $expected_len) { Write-Host "Publish and Execute: ${tfm} - ${root}" + Write-Host "Expecting ${expected_len}" $cwd = Get-Location Set-Location (Join-Path $PSScriptRoot "${root}") @@ -42,7 +43,7 @@ function CheckTrim($root, $tfm, $outputfile, $expected_len) { # error NETSDK1124: Trimming assemblies requires .NET Core 3.0 or higher. # Check net7.0 trimmed assemblies -CheckTrim -root "SelfContained_Trimming_Test" -tfm "net8.0" -outputfile "FSharp.Core.dll" -expected_len 285184 +CheckTrim -root "SelfContained_Trimming_Test" -tfm "net8.0" -outputfile "FSharp.Core.dll" -expected_len 286720 # Check net8.0 trimmed assemblies -CheckTrim -root "StaticLinkedFSharpCore_Trimming_Test" -tfm "net8.0" -outputfile "StaticLinkedFSharpCore_Trimming_Test.dll" -expected_len 8818688 +CheckTrim -root "StaticLinkedFSharpCore_Trimming_Test" -tfm "net8.0" -outputfile "StaticLinkedFSharpCore_Trimming_Test.dll" -expected_len 8819712 diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/misc/compiler_help_output.bsl b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/misc/compiler_help_output.bsl index 8e207799112..a1cb129cc66 100644 --- a/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/misc/compiler_help_output.bsl +++ b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/misc/compiler_help_output.bsl @@ -71,6 +71,7 @@ Copyright (c) Microsoft Corporation. All Rights Reserved. --warn: Set a warning level (0-5) --nowarn: Disable specific warning messages --warnon: Enable specific warnings that may be off by default +--checknulls[+|-] Enable nullness declarations and checks --consolecolors[+|-] Output warning and error messages in color diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs index 1e5b49a1d83..3206e93fcbc 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs @@ -554,8 +554,8 @@ module CustomAttributes_AttributeUsage = (Error 842, Line 20, Col 3, Line 20, Col 14, "This attribute is not valid for use on this language element") (Error 842, Line 21, Col 3, Line 21, Col 18, "This attribute is not valid for use on this language element") (Error 842, Line 22, Col 3, Line 22, Col 17, "This attribute is not valid for use on this language element") - ] - + ] + // SOURCE=AttributeTargetsIsDelegate01.fs # AttributeTargetsIsDelegate01.fs [] let ``AttributeTargetsIsDelegate01_fs`` compilation = diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/MethodsAndProperties.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/MethodsAndProperties.fs index a71f63cbfb9..9722633165d 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/MethodsAndProperties.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/MethodsAndProperties.fs @@ -14,16 +14,23 @@ module MemberDefinitions_MethodsAndProperties = |> withOptions ["--nowarn:988"] |> compile - let verifyCompileAndRun compilation = + let verifyCompileAndRun = verifyCompile >> run + + // SOURCE=PartiallyOverridenProperty.fs + [] + let ``Partially Overriden Property`` compilation = compilation - |> asExe - |> withOptions ["--nowarn:988"] - |> compileAndRun + |> withLangVersionPreview + |> withCheckNulls + |> typecheck + |> shouldSucceed // SOURCE=AbstractProperties01.fs # AbstractProperties01.fs [] let ``AbstractProperties01_fs`` compilation = compilation + |> withLangVersionPreview + |> withCheckNulls |> verifyCompileAndRun |> shouldSucceed diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/PartiallyOverridenProperty.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/PartiallyOverridenProperty.fs new file mode 100644 index 00000000000..472ee4ea8ec --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/PartiallyOverridenProperty.fs @@ -0,0 +1,15 @@ +module MyLib + +type BaseType() = + abstract Msg : string with get,set + default this.Msg + with get() = "" + and set x = printfn "%s" x + +type DerivedType() = + inherit BaseType() + override this.Msg with get() = "getterOnly" + +let d = new DerivedType() +d.Msg <- "" //invoking setter +printfn "%s" d.Msg //invoking getter diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/BindingExpressions/BindingExpressions.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/BindingExpressions/BindingExpressions.fs index 4aa7ff3999a..056350802fe 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/BindingExpressions/BindingExpressions.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/BindingExpressions/BindingExpressions.fs @@ -14,6 +14,12 @@ module BindingExpressions = |> withOptions ["--test:ErrorRanges"] |> compile + let verifyCompileAsExe compilation = + compilation + |> asExe + |> withOptions ["--test:ErrorRanges"] + |> compile + // This test was automatically generated (moved from FSharpQA suite - Conformance/Expressions/ApplicationExpressions/BasicApplication) // SOURCE=AmbigLetBinding.fs # AmbigLetBinding [] @@ -102,11 +108,10 @@ module BindingExpressions = [] let ``in05_fs`` compilation = compilation - |> verifyCompile + |> verifyCompileAsExe |> shouldFail |> withDiagnostics [ (Error 1, Line 12, Col 13, Line 12, Col 14, "The type 'int' does not match the type 'unit'") - (Error 1, Line 12, Col 18, Line 12, Col 24, "Type mismatch. Expecting a\n ''a -> 'b' \nbut given a\n ''a -> unit' \nThe type 'int' does not match the type 'unit'") (Warning 20, Line 13, Col 5, Line 13, Col 10, "The result of this expression has type 'bool' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.") ] @@ -119,7 +124,6 @@ module BindingExpressions = |> shouldFail |> withDiagnostics [ (Error 1, Line 10, Col 9, Line 10, Col 10, "The type 'int' does not match the type 'unit'") - (Error 1, Line 10, Col 14, Line 10, Col 20, "Type mismatch. Expecting a\n ''a -> 'b' \nbut given a\n ''a -> unit' \nThe type 'int' does not match the type 'unit'") ] // SOURCE=MutableLocals01.fs SCFLAGS="--warnon:3180 --optimize+ --test:ErrorRanges" diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/BindingExpressions/in05.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/BindingExpressions/in05.fs index 583f27de4e8..0c386d1676d 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/BindingExpressions/in05.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/BindingExpressions/in05.fs @@ -4,9 +4,9 @@ // I'm adding these cases to make sure we do not accidentally change the behavior from version to version // Eventually, we will deprecated them - and the specs will be updated. //The type 'int' does not match the type 'unit'$ -//Type mismatch\. Expecting a. ''a -> 'b' .but given a. ''a -> unit' .The type 'int' does not match the type 'unit'$ //The result of this expression has type 'bool' and is implicitly ignored\. Consider using 'ignore' to discard this value explicitly, e\.g\. 'expr \|> ignore', or 'let' to bind the result to a name, e\.g\. 'let result = expr'.$ -module E + +module E = let a = 3 in a + 1 |> ignore a + 1 |> ignore diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ForLoop/ForEachOnString01.fs.RealInternalSignatureOff.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ForLoop/ForEachOnString01.fs.RealInternalSignatureOff.il.bsl index 2d3a691ab75..0051f80eb41 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ForLoop/ForEachOnString01.fs.RealInternalSignatureOff.il.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ForLoop/ForEachOnString01.fs.RealInternalSignatureOff.il.bsl @@ -518,7 +518,7 @@ IL_002c: ldloc.3 IL_002d: box [runtime]System.Char IL_0032: call string [runtime]System.String::Format(string, - object) + object) IL_0037: stloc.s V_4 IL_0039: ldstr "%O" IL_003e: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [runtime]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string>::.ctor(string) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ForLoop/ForEachOnString01.fs.RealInternalSignatureOn.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ForLoop/ForEachOnString01.fs.RealInternalSignatureOn.il.bsl index 2d3a691ab75..0051f80eb41 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ForLoop/ForEachOnString01.fs.RealInternalSignatureOn.il.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ForLoop/ForEachOnString01.fs.RealInternalSignatureOn.il.bsl @@ -518,7 +518,7 @@ IL_002c: ldloc.3 IL_002d: box [runtime]System.Char IL_0032: call string [runtime]System.String::Format(string, - object) + object) IL_0037: stloc.s V_4 IL_0039: ldstr "%O" IL_003e: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [runtime]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string>::.ctor(string) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/AnonRecords.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/AnonRecords.fs new file mode 100644 index 00000000000..1178f3e704e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/AnonRecords.fs @@ -0,0 +1,14 @@ +module MyTestModule + +let justInt = 42 +let maybeString : string | null = null +let maybeListOfMaybeString : List<_> | null = [maybeString] + +let giveMeA () = + {| A = maybeString; B = maybeListOfMaybeString; C = justInt|} + +let giveMeB () = + {| A = justInt; B = justInt; C = justInt|} + +let giveMeC () = + {| A = maybeString; B = maybeString; C = maybeString|} \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/AnonRecords.fs.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/AnonRecords.fs.il.net472.bsl new file mode 100644 index 00000000000..9e4cf639944 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/AnonRecords.fs.il.net472.bsl @@ -0,0 +1,876 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 maybeListOfMaybeString@5 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .method public specialname static int32 get_justInt() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.s 42 + IL_0002: ret + } + + .method public specialname static string get_maybeString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } + + .method public specialname static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 get_maybeListOfMaybeString() cil managed + { + + .maxstack 8 + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 MyTestModule::maybeListOfMaybeString@5 + IL_0005: ret + } + + .method public static class '<>f__AnonymousType2430756162`3',int32> giveMeA() cil managed + { + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 04 00 00 00 01 02 02 02 00 00 ) + + .maxstack 8 + IL_0000: call string MyTestModule::get_maybeString() + IL_0005: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 MyTestModule::get_maybeListOfMaybeString() + IL_000a: call int32 MyTestModule::get_justInt() + IL_000f: newobj instance void class '<>f__AnonymousType2430756162`3',int32>::.ctor(!0, + !1, + !2) + IL_0014: ret + } + + .method public static class '<>f__AnonymousType2430756162`3' giveMeB() cil managed + { + + .maxstack 8 + IL_0000: call int32 MyTestModule::get_justInt() + IL_0005: call int32 MyTestModule::get_justInt() + IL_000a: call int32 MyTestModule::get_justInt() + IL_000f: newobj instance void class '<>f__AnonymousType2430756162`3'::.ctor(!0, + !1, + !2) + IL_0014: ret + } + + .method public static class '<>f__AnonymousType2430756162`3' giveMeC() cil managed + { + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 04 00 00 00 01 02 02 02 00 00 ) + + .maxstack 8 + IL_0000: call string MyTestModule::get_maybeString() + IL_0005: call string MyTestModule::get_maybeString() + IL_000a: call string MyTestModule::get_maybeString() + IL_000f: newobj instance void class '<>f__AnonymousType2430756162`3'::.ctor(!0, + !1, + !2) + IL_0014: ret + } + + .method private specialname rtspecialname static void .cctor() cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: stsfld int32 ''.$MyTestModule::init@ + IL_0006: ldsfld int32 ''.$MyTestModule::init@ + IL_000b: pop + IL_000c: ret + } + + .method assembly specialname static void staticInitialization@() cil managed + { + + .maxstack 8 + IL_0000: call string MyTestModule::get_maybeString() + IL_0005: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() + IL_000a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_000f: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 MyTestModule::maybeListOfMaybeString@5 + IL_0014: ret + } + + .property int32 justInt() + { + .get int32 MyTestModule::get_justInt() + } + .property string maybeString() + { + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .get string MyTestModule::get_maybeString() + } + .property class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + maybeListOfMaybeString() + { + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 09 00 00 00 00 00 ) + .get class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 MyTestModule::get_maybeListOfMaybeString() + } +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field static assembly int32 init@ + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method private specialname rtspecialname static void .cctor() cil managed + { + + .maxstack 8 + IL_0000: call void MyTestModule::staticInitialization@() + IL_0005: ret + } + +} + +.class public auto ansi serializable sealed beforefieldinit '<>f__AnonymousType2430756162`3'<'j__TPar','j__TPar','j__TPar'> + extends [runtime]System.Object + implements [runtime]System.Collections.IStructuralComparable, + [runtime]System.IComparable, + class [runtime]System.IComparable`1f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>>, + [runtime]System.Collections.IStructuralEquatable, + class [runtime]System.IEquatable`1f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>> +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 02 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field private !'j__TPar' A@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field private !'j__TPar' B@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field private !'j__TPar' C@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .method public specialname rtspecialname + instance void .ctor(!'j__TPar' A, + !'j__TPar' B, + !'j__TPar' C) cil managed + { + .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 1E 3C 3E 66 5F 5F 41 6E 6F 6E + 79 6D 6F 75 73 54 79 70 65 32 34 33 30 37 35 36 + 31 36 32 60 33 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_000d: ldarg.0 + IL_000e: ldarg.2 + IL_000f: stfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_0014: ldarg.0 + IL_0015: ldarg.3 + IL_0016: stfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_001b: ret + } + + .method public hidebysig specialname instance !'j__TPar' get_A() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_0006: ret + } + + .method public hidebysig specialname instance !'j__TPar' get_B() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_0006: ret + } + + .method public hidebysig specialname instance !'j__TPar' get_C() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_0006: ret + } + + .method public strict virtual instance string ToString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToStringf__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>,string>::Invoke(!0) + IL_0015: ret + } + + .method public hidebysig virtual final instance int32 CompareTo(class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 5 + .locals init (int32 V_0, + int32 V_1) + IL_0000: ldarg.0 + IL_0001: brfalse.s IL_0067 + + IL_0003: ldarg.1 + IL_0004: brfalse.s IL_0065 + + IL_0006: call class [runtime]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_000b: ldarg.0 + IL_000c: ldfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_0011: ldarg.1 + IL_0012: ldfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_0017: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericComparisonWithComparerj__TPar'>(class [runtime]System.Collections.IComparer, + !!0, + !!0) + IL_001c: stloc.0 + IL_001d: ldloc.0 + IL_001e: ldc.i4.0 + IL_001f: bge.s IL_0023 + + IL_0021: ldloc.0 + IL_0022: ret + + IL_0023: ldloc.0 + IL_0024: ldc.i4.0 + IL_0025: ble.s IL_0029 + + IL_0027: ldloc.0 + IL_0028: ret + + IL_0029: call class [runtime]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_002e: ldarg.0 + IL_002f: ldfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_0034: ldarg.1 + IL_0035: ldfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_003a: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericComparisonWithComparerj__TPar'>(class [runtime]System.Collections.IComparer, + !!0, + !!0) + IL_003f: stloc.1 + IL_0040: ldloc.1 + IL_0041: ldc.i4.0 + IL_0042: bge.s IL_0046 + + IL_0044: ldloc.1 + IL_0045: ret + + IL_0046: ldloc.1 + IL_0047: ldc.i4.0 + IL_0048: ble.s IL_004c + + IL_004a: ldloc.1 + IL_004b: ret + + IL_004c: call class [runtime]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0051: ldarg.0 + IL_0052: ldfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_0057: ldarg.1 + IL_0058: ldfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_005d: tail. + IL_005f: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericComparisonWithComparerj__TPar'>(class [runtime]System.Collections.IComparer, + !!0, + !!0) + IL_0064: ret + + IL_0065: ldc.i4.1 + IL_0066: ret + + IL_0067: ldarg.1 + IL_0068: brfalse.s IL_006c + + IL_006a: ldc.i4.m1 + IL_006b: ret + + IL_006c: ldc.i4.0 + IL_006d: ret + } + + .method public hidebysig virtual final instance int32 CompareTo(object obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: unbox.any class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> + IL_0007: tail. + IL_0009: callvirt instance int32 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::CompareTo(class '<>f__AnonymousType2430756162`3') + IL_000e: ret + } + + .method public hidebysig virtual final + instance int32 CompareTo(object obj, + class [runtime]System.Collections.IComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 5 + .locals init (class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> V_0, + class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> V_1, + int32 V_2, + int32 V_3) + IL_0000: ldarg.1 + IL_0001: unbox.any class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: stloc.1 + IL_0009: ldarg.0 + IL_000a: brfalse.s IL_0069 + + IL_000c: ldarg.1 + IL_000d: unbox.any class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> + IL_0012: brfalse.s IL_0067 + + IL_0014: ldarg.2 + IL_0015: ldarg.0 + IL_0016: ldfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_001b: ldloc.1 + IL_001c: ldfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_0021: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericComparisonWithComparerj__TPar'>(class [runtime]System.Collections.IComparer, + !!0, + !!0) + IL_0026: stloc.2 + IL_0027: ldloc.2 + IL_0028: ldc.i4.0 + IL_0029: bge.s IL_002d + + IL_002b: ldloc.2 + IL_002c: ret + + IL_002d: ldloc.2 + IL_002e: ldc.i4.0 + IL_002f: ble.s IL_0033 + + IL_0031: ldloc.2 + IL_0032: ret + + IL_0033: ldarg.2 + IL_0034: ldarg.0 + IL_0035: ldfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_003a: ldloc.1 + IL_003b: ldfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_0040: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericComparisonWithComparerj__TPar'>(class [runtime]System.Collections.IComparer, + !!0, + !!0) + IL_0045: stloc.3 + IL_0046: ldloc.3 + IL_0047: ldc.i4.0 + IL_0048: bge.s IL_004c + + IL_004a: ldloc.3 + IL_004b: ret + + IL_004c: ldloc.3 + IL_004d: ldc.i4.0 + IL_004e: ble.s IL_0052 + + IL_0050: ldloc.3 + IL_0051: ret + + IL_0052: ldarg.2 + IL_0053: ldarg.0 + IL_0054: ldfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_0059: ldloc.1 + IL_005a: ldfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_005f: tail. + IL_0061: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericComparisonWithComparerj__TPar'>(class [runtime]System.Collections.IComparer, + !!0, + !!0) + IL_0066: ret + + IL_0067: ldc.i4.1 + IL_0068: ret + + IL_0069: ldarg.1 + IL_006a: unbox.any class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> + IL_006f: brfalse.s IL_0073 + + IL_0071: ldc.i4.m1 + IL_0072: ret + + IL_0073: ldc.i4.0 + IL_0074: ret + } + + .method public hidebysig virtual final instance int32 GetHashCode(class [runtime]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 7 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: brfalse.s IL_0058 + + IL_0003: ldc.i4.0 + IL_0004: stloc.0 + IL_0005: ldc.i4 0x9e3779b9 + IL_000a: ldarg.1 + IL_000b: ldarg.0 + IL_000c: ldfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_0011: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericHashWithComparerj__TPar'>(class [runtime]System.Collections.IEqualityComparer, + !!0) + IL_0016: ldloc.0 + IL_0017: ldc.i4.6 + IL_0018: shl + IL_0019: ldloc.0 + IL_001a: ldc.i4.2 + IL_001b: shr + IL_001c: add + IL_001d: add + IL_001e: add + IL_001f: stloc.0 + IL_0020: ldc.i4 0x9e3779b9 + IL_0025: ldarg.1 + IL_0026: ldarg.0 + IL_0027: ldfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_002c: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericHashWithComparerj__TPar'>(class [runtime]System.Collections.IEqualityComparer, + !!0) + IL_0031: ldloc.0 + IL_0032: ldc.i4.6 + IL_0033: shl + IL_0034: ldloc.0 + IL_0035: ldc.i4.2 + IL_0036: shr + IL_0037: add + IL_0038: add + IL_0039: add + IL_003a: stloc.0 + IL_003b: ldc.i4 0x9e3779b9 + IL_0040: ldarg.1 + IL_0041: ldarg.0 + IL_0042: ldfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_0047: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericHashWithComparerj__TPar'>(class [runtime]System.Collections.IEqualityComparer, + !!0) + IL_004c: ldloc.0 + IL_004d: ldc.i4.6 + IL_004e: shl + IL_004f: ldloc.0 + IL_0050: ldc.i4.2 + IL_0051: shr + IL_0052: add + IL_0053: add + IL_0054: add + IL_0055: stloc.0 + IL_0056: ldloc.0 + IL_0057: ret + + IL_0058: ldc.i4.0 + IL_0059: ret + } + + .method public hidebysig virtual final instance int32 GetHashCode() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call class [runtime]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() + IL_0006: tail. + IL_0008: callvirt instance int32 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::GetHashCode(class [runtime]System.Collections.IEqualityComparer) + IL_000d: ret + } + + .method public hidebysig instance bool + Equals(class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> obj, + class [runtime]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 5 + .locals init (class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> V_0) + IL_0000: ldarg.0 + IL_0001: brfalse.s IL_004b + + IL_0003: ldarg.1 + IL_0004: brfalse.s IL_0049 + + IL_0006: ldarg.1 + IL_0007: stloc.0 + IL_0008: ldarg.2 + IL_0009: ldarg.0 + IL_000a: ldfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_000f: ldloc.0 + IL_0010: ldfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_0015: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericEqualityWithComparerj__TPar'>(class [runtime]System.Collections.IEqualityComparer, + !!0, + !!0) + IL_001a: brfalse.s IL_0047 + + IL_001c: ldarg.2 + IL_001d: ldarg.0 + IL_001e: ldfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_0023: ldloc.0 + IL_0024: ldfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_0029: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericEqualityWithComparerj__TPar'>(class [runtime]System.Collections.IEqualityComparer, + !!0, + !!0) + IL_002e: brfalse.s IL_0045 + + IL_0030: ldarg.2 + IL_0031: ldarg.0 + IL_0032: ldfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_0037: ldloc.0 + IL_0038: ldfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_003d: tail. + IL_003f: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericEqualityWithComparerj__TPar'>(class [runtime]System.Collections.IEqualityComparer, + !!0, + !!0) + IL_0044: ret + + IL_0045: ldc.i4.0 + IL_0046: ret + + IL_0047: ldc.i4.0 + IL_0048: ret + + IL_0049: ldc.i4.0 + IL_004a: ret + + IL_004b: ldarg.1 + IL_004c: ldnull + IL_004d: cgt.un + IL_004f: ldc.i4.0 + IL_0050: ceq + IL_0052: ret + } + + .method public hidebysig virtual final + instance bool Equals(object obj, + class [runtime]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 5 + .locals init (class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> V_0) + IL_0000: ldarg.1 + IL_0001: isinst class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0015 + + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: ldarg.2 + IL_000d: tail. + IL_000f: callvirt instance bool class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::Equals(class '<>f__AnonymousType2430756162`3', + class [runtime]System.Collections.IEqualityComparer) + IL_0014: ret + + IL_0015: ldc.i4.0 + IL_0016: ret + } + + .method public hidebysig virtual final instance bool Equals(class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 4 + IL_0000: ldarg.0 + IL_0001: brfalse.s IL_0046 + + IL_0003: ldarg.1 + IL_0004: brfalse.s IL_0044 + + IL_0006: ldarg.0 + IL_0007: ldfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_000c: ldarg.1 + IL_000d: ldfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_0012: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericEqualityERj__TPar'>(!!0, + !!0) + IL_0017: brfalse.s IL_0042 + + IL_0019: ldarg.0 + IL_001a: ldfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_001f: ldarg.1 + IL_0020: ldfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_0025: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericEqualityERj__TPar'>(!!0, + !!0) + IL_002a: brfalse.s IL_0040 + + IL_002c: ldarg.0 + IL_002d: ldfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_0032: ldarg.1 + IL_0033: ldfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_0038: tail. + IL_003a: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericEqualityERj__TPar'>(!!0, + !!0) + IL_003f: ret + + IL_0040: ldc.i4.0 + IL_0041: ret + + IL_0042: ldc.i4.0 + IL_0043: ret + + IL_0044: ldc.i4.0 + IL_0045: ret + + IL_0046: ldarg.1 + IL_0047: ldnull + IL_0048: cgt.un + IL_004a: ldc.i4.0 + IL_004b: ceq + IL_004d: ret + } + + .method public hidebysig virtual final instance bool Equals(object obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 4 + .locals init (class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> V_0) + IL_0000: ldarg.1 + IL_0001: isinst class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0014 + + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: tail. + IL_000e: callvirt instance bool class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::Equals(class '<>f__AnonymousType2430756162`3') + IL_0013: ret + + IL_0014: ldc.i4.0 + IL_0015: ret + } + + .property instance !'j__TPar' A() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 ) + .get instance !'j__TPar' '<>f__AnonymousType2430756162`3'::get_A() + } + .property instance !'j__TPar' B() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 01 00 00 00 00 00 ) + .get instance !'j__TPar' '<>f__AnonymousType2430756162`3'::get_B() + } + .property instance !'j__TPar' C() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 02 00 00 00 00 00 ) + .get instance !'j__TPar' '<>f__AnonymousType2430756162`3'::get_C() + } +} + +.class private auto ansi serializable sealed System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes + extends [runtime]System.Enum +{ + .custom instance void [runtime]System.FlagsAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field public specialname rtspecialname int32 value__ + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes All = int32(0xFFFFFFFF) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes None = int32(0x00000000) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicParameterlessConstructor = int32(0x00000001) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicConstructors = int32(0x00000003) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicConstructors = int32(0x00000004) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicMethods = int32(0x00000008) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicMethods = int32(0x00000010) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicFields = int32(0x00000020) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicFields = int32(0x00000040) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicNestedTypes = int32(0x00000080) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicNestedTypes = int32(0x00000100) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicProperties = int32(0x00000200) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicProperties = int32(0x00000400) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicEvents = int32(0x00000800) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicEvents = int32(0x00001000) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes Interfaces = int32(0x00002000) +} + +.class private auto ansi beforefieldinit System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MemberType@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field private class [runtime]System.Type Type@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname + instance void .ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MemberType, + class [runtime]System.Type Type) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::MemberType@ + IL_000d: ldarg.0 + IL_000e: ldarg.2 + IL_000f: stfld class [runtime]System.Type System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::Type@ + IL_0014: ret + } + + .method public hidebysig specialname instance class [runtime]System.Type get_Type() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [runtime]System.Type System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::Type@ + IL_0006: ret + } + + .method public hidebysig specialname instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes get_MemberType() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::MemberType@ + IL_0006: ret + } + + .property instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes + MemberType() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::get_MemberType() + } + .property instance class [runtime]System.Type + Type() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance class [runtime]System.Type System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::get_Type() + } +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8[] NullableFlags + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 scalarByteValue) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldc.i4.1 + IL_0008: newarr [runtime]System.Byte + IL_000d: dup + IL_000e: ldc.i4.0 + IL_000f: ldarg.1 + IL_0010: stelem.i1 + IL_0011: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_0016: ret + } + + .method public specialname rtspecialname instance void .ctor(uint8[] NullableFlags) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_000d: ret + } + +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableContextAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8 Flag + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 Flag) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8 System.Runtime.CompilerServices.NullableContextAttribute::Flag + IL_000d: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/AnonRecords.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/AnonRecords.fs.il.netcore.bsl new file mode 100644 index 00000000000..127fe13bf97 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/AnonRecords.fs.il.netcore.bsl @@ -0,0 +1,719 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 maybeListOfMaybeString@5 + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .method public specialname static int32 get_justInt() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.s 42 + IL_0002: ret + } + + .method public specialname static string get_maybeString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } + + .method public specialname static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 get_maybeListOfMaybeString() cil managed + { + + .maxstack 8 + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 MyTestModule::maybeListOfMaybeString@5 + IL_0005: ret + } + + .method public static class '<>f__AnonymousType2430756162`3',int32> giveMeA() cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 04 00 00 00 01 02 02 02 00 00 ) + + .maxstack 8 + IL_0000: call string MyTestModule::get_maybeString() + IL_0005: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 MyTestModule::get_maybeListOfMaybeString() + IL_000a: call int32 MyTestModule::get_justInt() + IL_000f: newobj instance void class '<>f__AnonymousType2430756162`3',int32>::.ctor(!0, + !1, + !2) + IL_0014: ret + } + + .method public static class '<>f__AnonymousType2430756162`3' giveMeB() cil managed + { + + .maxstack 8 + IL_0000: call int32 MyTestModule::get_justInt() + IL_0005: call int32 MyTestModule::get_justInt() + IL_000a: call int32 MyTestModule::get_justInt() + IL_000f: newobj instance void class '<>f__AnonymousType2430756162`3'::.ctor(!0, + !1, + !2) + IL_0014: ret + } + + .method public static class '<>f__AnonymousType2430756162`3' giveMeC() cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 04 00 00 00 01 02 02 02 00 00 ) + + .maxstack 8 + IL_0000: call string MyTestModule::get_maybeString() + IL_0005: call string MyTestModule::get_maybeString() + IL_000a: call string MyTestModule::get_maybeString() + IL_000f: newobj instance void class '<>f__AnonymousType2430756162`3'::.ctor(!0, + !1, + !2) + IL_0014: ret + } + + .method private specialname rtspecialname static void .cctor() cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: stsfld int32 ''.$MyTestModule::init@ + IL_0006: ldsfld int32 ''.$MyTestModule::init@ + IL_000b: pop + IL_000c: ret + } + + .method assembly specialname static void staticInitialization@() cil managed + { + + .maxstack 8 + IL_0000: call string MyTestModule::get_maybeString() + IL_0005: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() + IL_000a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_000f: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 MyTestModule::maybeListOfMaybeString@5 + IL_0014: ret + } + + .property int32 justInt() + { + .get int32 MyTestModule::get_justInt() + } + .property string maybeString() + { + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .get string MyTestModule::get_maybeString() + } + .property class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + maybeListOfMaybeString() + { + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 09 00 00 00 00 00 ) + .get class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 MyTestModule::get_maybeListOfMaybeString() + } +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field static assembly int32 init@ + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method private specialname rtspecialname static void .cctor() cil managed + { + + .maxstack 8 + IL_0000: call void MyTestModule::staticInitialization@() + IL_0005: ret + } + +} + +.class public auto ansi serializable sealed beforefieldinit '<>f__AnonymousType2430756162`3'<'j__TPar','j__TPar','j__TPar'> + extends [runtime]System.Object + implements [runtime]System.Collections.IStructuralComparable, + [runtime]System.IComparable, + class [runtime]System.IComparable`1f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>>, + [runtime]System.Collections.IStructuralEquatable, + class [runtime]System.IEquatable`1f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>> +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 02 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field private !'j__TPar' A@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field private !'j__TPar' B@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field private !'j__TPar' C@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .method public specialname rtspecialname + instance void .ctor(!'j__TPar' A, + !'j__TPar' B, + !'j__TPar' C) cil managed + { + .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 1E 3C 3E 66 5F 5F 41 6E 6F 6E + 79 6D 6F 75 73 54 79 70 65 32 34 33 30 37 35 36 + 31 36 32 60 33 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_000d: ldarg.0 + IL_000e: ldarg.2 + IL_000f: stfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_0014: ldarg.0 + IL_0015: ldarg.3 + IL_0016: stfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_001b: ret + } + + .method public hidebysig specialname instance !'j__TPar' get_A() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_0006: ret + } + + .method public hidebysig specialname instance !'j__TPar' get_B() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_0006: ret + } + + .method public hidebysig specialname instance !'j__TPar' get_C() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_0006: ret + } + + .method public strict virtual instance string ToString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToStringf__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>,string>::Invoke(!0) + IL_0015: ret + } + + .method public hidebysig virtual final instance int32 CompareTo(class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 5 + .locals init (int32 V_0, + int32 V_1) + IL_0000: ldarg.0 + IL_0001: brfalse.s IL_0067 + + IL_0003: ldarg.1 + IL_0004: brfalse.s IL_0065 + + IL_0006: call class [runtime]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_000b: ldarg.0 + IL_000c: ldfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_0011: ldarg.1 + IL_0012: ldfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_0017: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericComparisonWithComparerj__TPar'>(class [runtime]System.Collections.IComparer, + !!0, + !!0) + IL_001c: stloc.0 + IL_001d: ldloc.0 + IL_001e: ldc.i4.0 + IL_001f: bge.s IL_0023 + + IL_0021: ldloc.0 + IL_0022: ret + + IL_0023: ldloc.0 + IL_0024: ldc.i4.0 + IL_0025: ble.s IL_0029 + + IL_0027: ldloc.0 + IL_0028: ret + + IL_0029: call class [runtime]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_002e: ldarg.0 + IL_002f: ldfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_0034: ldarg.1 + IL_0035: ldfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_003a: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericComparisonWithComparerj__TPar'>(class [runtime]System.Collections.IComparer, + !!0, + !!0) + IL_003f: stloc.1 + IL_0040: ldloc.1 + IL_0041: ldc.i4.0 + IL_0042: bge.s IL_0046 + + IL_0044: ldloc.1 + IL_0045: ret + + IL_0046: ldloc.1 + IL_0047: ldc.i4.0 + IL_0048: ble.s IL_004c + + IL_004a: ldloc.1 + IL_004b: ret + + IL_004c: call class [runtime]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0051: ldarg.0 + IL_0052: ldfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_0057: ldarg.1 + IL_0058: ldfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_005d: tail. + IL_005f: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericComparisonWithComparerj__TPar'>(class [runtime]System.Collections.IComparer, + !!0, + !!0) + IL_0064: ret + + IL_0065: ldc.i4.1 + IL_0066: ret + + IL_0067: ldarg.1 + IL_0068: brfalse.s IL_006c + + IL_006a: ldc.i4.m1 + IL_006b: ret + + IL_006c: ldc.i4.0 + IL_006d: ret + } + + .method public hidebysig virtual final instance int32 CompareTo(object obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: unbox.any class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> + IL_0007: tail. + IL_0009: callvirt instance int32 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::CompareTo(class '<>f__AnonymousType2430756162`3') + IL_000e: ret + } + + .method public hidebysig virtual final + instance int32 CompareTo(object obj, + class [runtime]System.Collections.IComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 5 + .locals init (class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> V_0, + class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> V_1, + int32 V_2, + int32 V_3) + IL_0000: ldarg.1 + IL_0001: unbox.any class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: stloc.1 + IL_0009: ldarg.0 + IL_000a: brfalse.s IL_0069 + + IL_000c: ldarg.1 + IL_000d: unbox.any class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> + IL_0012: brfalse.s IL_0067 + + IL_0014: ldarg.2 + IL_0015: ldarg.0 + IL_0016: ldfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_001b: ldloc.1 + IL_001c: ldfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_0021: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericComparisonWithComparerj__TPar'>(class [runtime]System.Collections.IComparer, + !!0, + !!0) + IL_0026: stloc.2 + IL_0027: ldloc.2 + IL_0028: ldc.i4.0 + IL_0029: bge.s IL_002d + + IL_002b: ldloc.2 + IL_002c: ret + + IL_002d: ldloc.2 + IL_002e: ldc.i4.0 + IL_002f: ble.s IL_0033 + + IL_0031: ldloc.2 + IL_0032: ret + + IL_0033: ldarg.2 + IL_0034: ldarg.0 + IL_0035: ldfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_003a: ldloc.1 + IL_003b: ldfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_0040: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericComparisonWithComparerj__TPar'>(class [runtime]System.Collections.IComparer, + !!0, + !!0) + IL_0045: stloc.3 + IL_0046: ldloc.3 + IL_0047: ldc.i4.0 + IL_0048: bge.s IL_004c + + IL_004a: ldloc.3 + IL_004b: ret + + IL_004c: ldloc.3 + IL_004d: ldc.i4.0 + IL_004e: ble.s IL_0052 + + IL_0050: ldloc.3 + IL_0051: ret + + IL_0052: ldarg.2 + IL_0053: ldarg.0 + IL_0054: ldfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_0059: ldloc.1 + IL_005a: ldfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_005f: tail. + IL_0061: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericComparisonWithComparerj__TPar'>(class [runtime]System.Collections.IComparer, + !!0, + !!0) + IL_0066: ret + + IL_0067: ldc.i4.1 + IL_0068: ret + + IL_0069: ldarg.1 + IL_006a: unbox.any class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> + IL_006f: brfalse.s IL_0073 + + IL_0071: ldc.i4.m1 + IL_0072: ret + + IL_0073: ldc.i4.0 + IL_0074: ret + } + + .method public hidebysig virtual final instance int32 GetHashCode(class [runtime]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 7 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: brfalse.s IL_0058 + + IL_0003: ldc.i4.0 + IL_0004: stloc.0 + IL_0005: ldc.i4 0x9e3779b9 + IL_000a: ldarg.1 + IL_000b: ldarg.0 + IL_000c: ldfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_0011: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericHashWithComparerj__TPar'>(class [runtime]System.Collections.IEqualityComparer, + !!0) + IL_0016: ldloc.0 + IL_0017: ldc.i4.6 + IL_0018: shl + IL_0019: ldloc.0 + IL_001a: ldc.i4.2 + IL_001b: shr + IL_001c: add + IL_001d: add + IL_001e: add + IL_001f: stloc.0 + IL_0020: ldc.i4 0x9e3779b9 + IL_0025: ldarg.1 + IL_0026: ldarg.0 + IL_0027: ldfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_002c: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericHashWithComparerj__TPar'>(class [runtime]System.Collections.IEqualityComparer, + !!0) + IL_0031: ldloc.0 + IL_0032: ldc.i4.6 + IL_0033: shl + IL_0034: ldloc.0 + IL_0035: ldc.i4.2 + IL_0036: shr + IL_0037: add + IL_0038: add + IL_0039: add + IL_003a: stloc.0 + IL_003b: ldc.i4 0x9e3779b9 + IL_0040: ldarg.1 + IL_0041: ldarg.0 + IL_0042: ldfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_0047: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericHashWithComparerj__TPar'>(class [runtime]System.Collections.IEqualityComparer, + !!0) + IL_004c: ldloc.0 + IL_004d: ldc.i4.6 + IL_004e: shl + IL_004f: ldloc.0 + IL_0050: ldc.i4.2 + IL_0051: shr + IL_0052: add + IL_0053: add + IL_0054: add + IL_0055: stloc.0 + IL_0056: ldloc.0 + IL_0057: ret + + IL_0058: ldc.i4.0 + IL_0059: ret + } + + .method public hidebysig virtual final instance int32 GetHashCode() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call class [runtime]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() + IL_0006: tail. + IL_0008: callvirt instance int32 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::GetHashCode(class [runtime]System.Collections.IEqualityComparer) + IL_000d: ret + } + + .method public hidebysig instance bool + Equals(class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> obj, + class [runtime]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 5 + .locals init (class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> V_0) + IL_0000: ldarg.0 + IL_0001: brfalse.s IL_004b + + IL_0003: ldarg.1 + IL_0004: brfalse.s IL_0049 + + IL_0006: ldarg.1 + IL_0007: stloc.0 + IL_0008: ldarg.2 + IL_0009: ldarg.0 + IL_000a: ldfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_000f: ldloc.0 + IL_0010: ldfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_0015: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericEqualityWithComparerj__TPar'>(class [runtime]System.Collections.IEqualityComparer, + !!0, + !!0) + IL_001a: brfalse.s IL_0047 + + IL_001c: ldarg.2 + IL_001d: ldarg.0 + IL_001e: ldfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_0023: ldloc.0 + IL_0024: ldfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_0029: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericEqualityWithComparerj__TPar'>(class [runtime]System.Collections.IEqualityComparer, + !!0, + !!0) + IL_002e: brfalse.s IL_0045 + + IL_0030: ldarg.2 + IL_0031: ldarg.0 + IL_0032: ldfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_0037: ldloc.0 + IL_0038: ldfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_003d: tail. + IL_003f: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericEqualityWithComparerj__TPar'>(class [runtime]System.Collections.IEqualityComparer, + !!0, + !!0) + IL_0044: ret + + IL_0045: ldc.i4.0 + IL_0046: ret + + IL_0047: ldc.i4.0 + IL_0048: ret + + IL_0049: ldc.i4.0 + IL_004a: ret + + IL_004b: ldarg.1 + IL_004c: ldnull + IL_004d: cgt.un + IL_004f: ldc.i4.0 + IL_0050: ceq + IL_0052: ret + } + + .method public hidebysig virtual final + instance bool Equals(object obj, + class [runtime]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 5 + .locals init (class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> V_0) + IL_0000: ldarg.1 + IL_0001: isinst class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0015 + + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: ldarg.2 + IL_000d: tail. + IL_000f: callvirt instance bool class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::Equals(class '<>f__AnonymousType2430756162`3', + class [runtime]System.Collections.IEqualityComparer) + IL_0014: ret + + IL_0015: ldc.i4.0 + IL_0016: ret + } + + .method public hidebysig virtual final instance bool Equals(class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 4 + IL_0000: ldarg.0 + IL_0001: brfalse.s IL_0046 + + IL_0003: ldarg.1 + IL_0004: brfalse.s IL_0044 + + IL_0006: ldarg.0 + IL_0007: ldfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_000c: ldarg.1 + IL_000d: ldfld !0 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::A@ + IL_0012: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericEqualityERj__TPar'>(!!0, + !!0) + IL_0017: brfalse.s IL_0042 + + IL_0019: ldarg.0 + IL_001a: ldfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_001f: ldarg.1 + IL_0020: ldfld !1 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::B@ + IL_0025: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericEqualityERj__TPar'>(!!0, + !!0) + IL_002a: brfalse.s IL_0040 + + IL_002c: ldarg.0 + IL_002d: ldfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_0032: ldarg.1 + IL_0033: ldfld !2 class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::C@ + IL_0038: tail. + IL_003a: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericEqualityERj__TPar'>(!!0, + !!0) + IL_003f: ret + + IL_0040: ldc.i4.0 + IL_0041: ret + + IL_0042: ldc.i4.0 + IL_0043: ret + + IL_0044: ldc.i4.0 + IL_0045: ret + + IL_0046: ldarg.1 + IL_0047: ldnull + IL_0048: cgt.un + IL_004a: ldc.i4.0 + IL_004b: ceq + IL_004d: ret + } + + .method public hidebysig virtual final instance bool Equals(object obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 4 + .locals init (class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> V_0) + IL_0000: ldarg.1 + IL_0001: isinst class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'> + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0014 + + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: tail. + IL_000e: callvirt instance bool class '<>f__AnonymousType2430756162`3'j__TPar',!'j__TPar',!'j__TPar'>::Equals(class '<>f__AnonymousType2430756162`3') + IL_0013: ret + + IL_0014: ldc.i4.0 + IL_0015: ret + } + + .property instance !'j__TPar' A() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 ) + .get instance !'j__TPar' '<>f__AnonymousType2430756162`3'::get_A() + } + .property instance !'j__TPar' B() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 01 00 00 00 00 00 ) + .get instance !'j__TPar' '<>f__AnonymousType2430756162`3'::get_B() + } + .property instance !'j__TPar' C() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 02 00 00 00 00 00 ) + .get instance !'j__TPar' '<>f__AnonymousType2430756162`3'::get_C() + } +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CsharpConsumer.cs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CsharpConsumer.cs new file mode 100644 index 00000000000..0f459a37a79 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CsharpConsumer.cs @@ -0,0 +1,32 @@ +namespace CsharpNamespace +{ +#nullable enable + public static class CsharpClass + { + public static string MyApiWhichHatesNulls(string x) + { + return x.Length.ToString(); + } + + public static string JustUseAllOfItHere() + { + var thisShouldWarn = MyTestModule.nonNullableInputOutputFunc(null); + var thisIsPossiblyNullAndIsOk = MyTestModule.nullableStringInputOutputFunc(thisShouldWarn); + var thereforeThisShouldWarnAgain = MyTestModule.nonNullableInputOutputFunc(thisIsPossiblyNullAndIsOk); + + string? nullString = null; + + var myStructTuple = (nullString,nullString,1,2,3,4); + var thisShouldBeAWarningForSecondTypar = MyTestModule.genericValueTypeTest(myStructTuple); + var thisShouldNotSayAnything = MyTestModule.genericValueTypeTest(("I am not nulll",null,1,2,3,4)); + var thisShouldWarnFor2ndItem = MyTestModule.nonNullableInputOutputFunc(thisShouldNotSayAnything.Item2); + var thisIsOkBecauseItem1IsNotNullable = MyTestModule.nonNullableInputOutputFunc(thisShouldNotSayAnything.Item1); + + var refTuple = MyTestModule.genericRefTypeTest(nullString,nullString,1,2,3,4); + MyTestModule.genericRefTypeTest(refTuple.Item2,refTuple.Item2,1,2,3,4); + + + return MyTestModule.multiArgumentTest(null,null); + } + } +} \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs new file mode 100644 index 00000000000..f289363294b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs @@ -0,0 +1,10 @@ +module MyTestModule + +type Maybe<'T when 'T: not struct> = 'T | null +type MaybeString = string | null + +let curried3Func (a:MaybeString) (b:string) (c:int) = (a,b,c) + +let partiallyAplied (propperString:string) = curried3Func propperString + +let secondOutOfTriple (a,b,c) d e : Maybe<_> = b \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs.il.net472.bsl new file mode 100644 index 00000000000..a01419f0ed0 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs.il.net472.bsl @@ -0,0 +1,204 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class auto ansi serializable sealed nested assembly beforefieldinit partiallyAplied@8 + extends class [FSharp.Core]Microsoft.FSharp.Core.OptimizedClosures/FSharpFunc`3> + { + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field public string propperString + .method assembly specialname rtspecialname instance void .ctor(string propperString) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.OptimizedClosures/FSharpFunc`3>::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld string MyTestModule/partiallyAplied@8::propperString + IL_000d: ret + } + + .method public strict virtual instance class [runtime]System.Tuple`3 + Invoke(string b, + int32 c) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string MyTestModule/partiallyAplied@8::propperString + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: newobj instance void class [runtime]System.Tuple`3::.ctor(!0, + !1, + !2) + IL_000d: ret + } + + } + + .method public static class [runtime]System.Tuple`3 + curried3Func(string a, + string b, + int32 c) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 01 02 01 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: newobj instance void class [runtime]System.Tuple`3::.ctor(!0, + !1, + !2) + IL_0008: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>> partiallyAplied(string propperString) cil managed + { + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 06 00 00 00 01 01 01 01 02 01 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void MyTestModule/partiallyAplied@8::.ctor(string) + IL_0006: ret + } + + .method public static !!b secondOutOfTriple(!!a a, + !!b b, + !!c c, + !!d d, + !!e e) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 03 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + .param type a + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .param type b + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param type c + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .param type d + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .param type e + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [2] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ret + } + +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8[] NullableFlags + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 scalarByteValue) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldc.i4.1 + IL_0008: newarr [runtime]System.Byte + IL_000d: dup + IL_000e: ldc.i4.0 + IL_000f: ldarg.1 + IL_0010: stelem.i1 + IL_0011: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_0016: ret + } + + .method public specialname rtspecialname instance void .ctor(uint8[] NullableFlags) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_000d: ret + } + +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableContextAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8 Flag + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 Flag) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8 System.Runtime.CompilerServices.NullableContextAttribute::Flag + IL_000d: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs.il.netcore.bsl new file mode 100644 index 00000000000..02d5e2cbe40 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs.il.netcore.bsl @@ -0,0 +1,139 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class auto ansi serializable sealed nested assembly beforefieldinit partiallyAplied@8 + extends class [FSharp.Core]Microsoft.FSharp.Core.OptimizedClosures/FSharpFunc`3> + { + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field public string propperString + .method assembly specialname rtspecialname instance void .ctor(string propperString) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.OptimizedClosures/FSharpFunc`3>::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld string MyTestModule/partiallyAplied@8::propperString + IL_000d: ret + } + + .method public strict virtual instance class [runtime]System.Tuple`3 + Invoke(string b, + int32 c) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string MyTestModule/partiallyAplied@8::propperString + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: newobj instance void class [runtime]System.Tuple`3::.ctor(!0, + !1, + !2) + IL_000d: ret + } + + } + + .method public static class [runtime]System.Tuple`3 + curried3Func(string a, + string b, + int32 c) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 01 02 01 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: newobj instance void class [runtime]System.Tuple`3::.ctor(!0, + !1, + !2) + IL_0008: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>> partiallyAplied(string propperString) cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 06 00 00 00 01 01 01 01 02 01 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void MyTestModule/partiallyAplied@8::.ctor(string) + IL_0006: ret + } + + .method public static !!b secondOutOfTriple(!!a a, + !!b b, + !!c c, + !!d d, + !!e e) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 03 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + .param type a + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .param type b + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param type c + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .param type d + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .param type e + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [2] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ret + } + +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomPipe.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomPipe.fs new file mode 100644 index 00000000000..73fe562b29f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomPipe.fs @@ -0,0 +1,3 @@ +module MyTestModule + +let inline myCustomPipeFunc arg func = func arg \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomPipe.fs.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomPipe.fs.il.net472.bsl new file mode 100644 index 00000000000..f057362bee0 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomPipe.fs.il.net472.bsl @@ -0,0 +1,123 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .method public static !!b myassemblyFunc(!!a arg, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 func) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + .param type a + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .param type b + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.0 + IL_0002: tail. + IL_0004: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0009: ret + } + +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8[] NullableFlags + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 scalarByteValue) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldc.i4.1 + IL_0008: newarr [runtime]System.Byte + IL_000d: dup + IL_000e: ldc.i4.0 + IL_000f: ldarg.1 + IL_0010: stelem.i1 + IL_0011: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_0016: ret + } + + .method public specialname rtspecialname instance void .ctor(uint8[] NullableFlags) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_000d: ret + } + +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableContextAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8 Flag + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 Flag) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8 System.Runtime.CompilerServices.NullableContextAttribute::Flag + IL_000d: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomPipe.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomPipe.fs.il.netcore.bsl new file mode 100644 index 00000000000..cb9e545989f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomPipe.fs.il.netcore.bsl @@ -0,0 +1,58 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .method public static !!b myassemblyFunc(!!a arg, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 func) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + .param type a + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .param type b + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.0 + IL_0002: tail. + IL_0004: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0009: ret + } + +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomType.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomType.fs new file mode 100644 index 00000000000..2e52933d1fe --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomType.fs @@ -0,0 +1,25 @@ +module rec MyTestModule + +type MaybeString = string | null +type MaybeMyCustomType = (MyCustomType | null) + +type MyCustomType (x: MaybeString, y: string) = + + static let mutable uglyGlobalMutableString : string = "" + static let mutable uglyGlobalMutableNullableString : MaybeString = null + static let mutable dict : Map = Map.empty + + member val Nullable = x + member val NonNullable = y + member val JustSomeInt = 42 + + static member GiveMeNull() : MaybeString = null + static member GiveMeString() : string = "" + + member this.UnitFunc() = () + member this.GetThis() = this + member this.GetThisOrNull() : MaybeMyCustomType = null + + member this.Item + with get (index) = dict.[index] + and set index value = dict <- dict.Add(index,value) \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomType.fs.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomType.fs.il.net472.bsl new file mode 100644 index 00000000000..1437ae540da --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomType.fs.il.net472.bsl @@ -0,0 +1,369 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class auto ansi serializable nested public Myassembly + extends [runtime]System.Object + { + .custom instance void [runtime]System.Reflection.DefaultMemberAttribute::.ctor(string) = ( 01 00 04 49 74 65 6D 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field static assembly string uglyGlobalMutableString + .field static assembly string uglyGlobalMutableNullableString + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpMap`2 dict + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 01 02 02 00 00 ) + .field assembly string Nullable@ + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .field assembly string NonNullable@ + .field assembly int32 JustSomeInt@ + .field static assembly int32 init@6 + .method public specialname rtspecialname + instance void .ctor(string x, + string y) cil managed + { + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ldarg.0 + IL_0009: ldarg.1 + IL_000a: stfld string MyTestModule/Myassembly::Nullable@ + IL_000f: ldarg.0 + IL_0010: ldarg.2 + IL_0011: stfld string MyTestModule/Myassembly::NonNullable@ + IL_0016: ldarg.0 + IL_0017: ldc.i4.s 42 + IL_0019: stfld int32 MyTestModule/Myassembly::JustSomeInt@ + IL_001e: ret + } + + .method public hidebysig specialname instance string get_Nullable() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string MyTestModule/Myassembly::Nullable@ + IL_0006: ret + } + + .method public hidebysig specialname instance string get_NonNullable() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string MyTestModule/Myassembly::NonNullable@ + IL_0006: ret + } + + .method public hidebysig specialname instance int32 get_JustSomeInt() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 MyTestModule/Myassembly::JustSomeInt@ + IL_0006: ret + } + + .method public static string GiveMeNull() cil managed + { + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } + + .method public static string GiveMeString() cil managed + { + + .maxstack 8 + IL_0000: ldstr "" + IL_0005: ret + } + + .method public hidebysig instance void UnitFunc() cil managed + { + + .maxstack 8 + IL_0000: ret + } + + .method public hidebysig instance class MyTestModule/Myassembly GetThis() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public hidebysig instance class MyTestModule/Myassembly GetThisOrNull() cil managed + { + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } + + .method public hidebysig specialname instance string get_Item(string index) cil managed + { + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: volatile. + IL_0002: ldsfld int32 MyTestModule/Myassembly::init@6 + IL_0007: ldc.i4.4 + IL_0008: bge.s IL_0011 + + IL_000a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::FailStaticInit() + IL_000f: br.s IL_0011 + + IL_0011: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpMap`2 MyTestModule/Myassembly::dict + IL_0016: ldarg.1 + IL_0017: tail. + IL_0019: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpMap`2::get_Item(!0) + IL_001e: ret + } + + .method public hidebysig specialname + instance void set_Item(string index, + string 'value') cil managed + { + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [2] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: volatile. + IL_0002: ldsfld int32 MyTestModule/Myassembly::init@6 + IL_0007: ldc.i4.4 + IL_0008: bge.s IL_0011 + + IL_000a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::FailStaticInit() + IL_000f: br.s IL_0011 + + IL_0011: volatile. + IL_0013: ldsfld int32 MyTestModule/Myassembly::init@6 + IL_0018: ldc.i4.4 + IL_0019: bge.s IL_0022 + + IL_001b: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::FailStaticInit() + IL_0020: br.s IL_0022 + + IL_0022: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpMap`2 MyTestModule/Myassembly::dict + IL_0027: ldarg.1 + IL_0028: ldarg.2 + IL_0029: callvirt instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpMap`2 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpMap`2::Add(!0, + !1) + IL_002e: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpMap`2 MyTestModule/Myassembly::dict + IL_0033: ret + } + + .method private specialname rtspecialname static void .cctor() cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: stsfld int32 ''.$MyTestModule::init@ + IL_0006: ldsfld int32 ''.$MyTestModule::init@ + IL_000b: pop + IL_000c: ret + } + + .method assembly specialname static void staticInitialization@() cil managed + { + + .maxstack 8 + IL_0000: ldstr "" + IL_0005: stsfld string MyTestModule/Myassembly::uglyGlobalMutableString + IL_000a: ldc.i4.2 + IL_000b: volatile. + IL_000d: stsfld int32 MyTestModule/Myassembly::init@6 + IL_0012: ldnull + IL_0013: stsfld string MyTestModule/Myassembly::uglyGlobalMutableNullableString + IL_0018: ldc.i4.3 + IL_0019: volatile. + IL_001b: stsfld int32 MyTestModule/Myassembly::init@6 + IL_0020: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpMap`2 [FSharp.Core]Microsoft.FSharp.Collections.MapModule::Empty() + IL_0025: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpMap`2 MyTestModule/Myassembly::dict + IL_002a: ldc.i4.4 + IL_002b: volatile. + IL_002d: stsfld int32 MyTestModule/Myassembly::init@6 + IL_0032: ret + } + + .property instance string Nullable() + { + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .get instance string MyTestModule/Myassembly::get_Nullable() + } + .property instance string NonNullable() + { + .get instance string MyTestModule/Myassembly::get_NonNullable() + } + .property instance int32 JustSomeInt() + { + .get instance int32 MyTestModule/Myassembly::get_JustSomeInt() + } + .property instance string Item(string) + { + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .set instance void MyTestModule/Myassembly::set_Item(string, + string) + .get instance string MyTestModule/Myassembly::get_Item(string) + } + } + + .method private specialname rtspecialname static void .cctor() cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: stsfld int32 ''.$MyTestModule::init@ + IL_0006: ldsfld int32 ''.$MyTestModule::init@ + IL_000b: pop + IL_000c: ret + } + + .method assembly specialname static void staticInitialization@() cil managed + { + + .maxstack 8 + IL_0000: call void MyTestModule/Myassembly::staticInitialization@() + IL_0005: ret + } + +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field static assembly int32 init@ + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method private specialname rtspecialname static void .cctor() cil managed + { + + .maxstack 8 + IL_0000: call void MyTestModule::staticInitialization@() + IL_0005: ret + } + +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8[] NullableFlags + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 scalarByteValue) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldc.i4.1 + IL_0008: newarr [runtime]System.Byte + IL_000d: dup + IL_000e: ldc.i4.0 + IL_000f: ldarg.1 + IL_0010: stelem.i1 + IL_0011: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_0016: ret + } + + .method public specialname rtspecialname instance void .ctor(uint8[] NullableFlags) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_000d: ret + } + +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableContextAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8 Flag + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 Flag) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8 System.Runtime.CompilerServices.NullableContextAttribute::Flag + IL_000d: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomType.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomType.fs.il.netcore.bsl new file mode 100644 index 00000000000..234a052c5e9 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CustomType.fs.il.netcore.bsl @@ -0,0 +1,304 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class auto ansi serializable nested public Myassembly + extends [runtime]System.Object + { + .custom instance void [runtime]System.Reflection.DefaultMemberAttribute::.ctor(string) = ( 01 00 04 49 74 65 6D 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field static assembly string uglyGlobalMutableString + .field static assembly string uglyGlobalMutableNullableString + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpMap`2 dict + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 01 02 02 00 00 ) + .field assembly string Nullable@ + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .field assembly string NonNullable@ + .field assembly int32 JustSomeInt@ + .field static assembly int32 init@6 + .method public specialname rtspecialname + instance void .ctor(string x, + string y) cil managed + { + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ldarg.0 + IL_0009: ldarg.1 + IL_000a: stfld string MyTestModule/Myassembly::Nullable@ + IL_000f: ldarg.0 + IL_0010: ldarg.2 + IL_0011: stfld string MyTestModule/Myassembly::NonNullable@ + IL_0016: ldarg.0 + IL_0017: ldc.i4.s 42 + IL_0019: stfld int32 MyTestModule/Myassembly::JustSomeInt@ + IL_001e: ret + } + + .method public hidebysig specialname instance string get_Nullable() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string MyTestModule/Myassembly::Nullable@ + IL_0006: ret + } + + .method public hidebysig specialname instance string get_NonNullable() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string MyTestModule/Myassembly::NonNullable@ + IL_0006: ret + } + + .method public hidebysig specialname instance int32 get_JustSomeInt() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 MyTestModule/Myassembly::JustSomeInt@ + IL_0006: ret + } + + .method public static string GiveMeNull() cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } + + .method public static string GiveMeString() cil managed + { + + .maxstack 8 + IL_0000: ldstr "" + IL_0005: ret + } + + .method public hidebysig instance void UnitFunc() cil managed + { + + .maxstack 8 + IL_0000: ret + } + + .method public hidebysig instance class MyTestModule/Myassembly GetThis() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public hidebysig instance class MyTestModule/Myassembly GetThisOrNull() cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } + + .method public hidebysig specialname instance string get_Item(string index) cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: volatile. + IL_0002: ldsfld int32 MyTestModule/Myassembly::init@6 + IL_0007: ldc.i4.4 + IL_0008: bge.s IL_0011 + + IL_000a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::FailStaticInit() + IL_000f: br.s IL_0011 + + IL_0011: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpMap`2 MyTestModule/Myassembly::dict + IL_0016: ldarg.1 + IL_0017: tail. + IL_0019: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpMap`2::get_Item(!0) + IL_001e: ret + } + + .method public hidebysig specialname + instance void set_Item(string index, + string 'value') cil managed + { + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [2] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: volatile. + IL_0002: ldsfld int32 MyTestModule/Myassembly::init@6 + IL_0007: ldc.i4.4 + IL_0008: bge.s IL_0011 + + IL_000a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::FailStaticInit() + IL_000f: br.s IL_0011 + + IL_0011: volatile. + IL_0013: ldsfld int32 MyTestModule/Myassembly::init@6 + IL_0018: ldc.i4.4 + IL_0019: bge.s IL_0022 + + IL_001b: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::FailStaticInit() + IL_0020: br.s IL_0022 + + IL_0022: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpMap`2 MyTestModule/Myassembly::dict + IL_0027: ldarg.1 + IL_0028: ldarg.2 + IL_0029: callvirt instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpMap`2 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpMap`2::Add(!0, + !1) + IL_002e: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpMap`2 MyTestModule/Myassembly::dict + IL_0033: ret + } + + .method private specialname rtspecialname static void .cctor() cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: stsfld int32 ''.$MyTestModule::init@ + IL_0006: ldsfld int32 ''.$MyTestModule::init@ + IL_000b: pop + IL_000c: ret + } + + .method assembly specialname static void staticInitialization@() cil managed + { + + .maxstack 8 + IL_0000: ldstr "" + IL_0005: stsfld string MyTestModule/Myassembly::uglyGlobalMutableString + IL_000a: ldc.i4.2 + IL_000b: volatile. + IL_000d: stsfld int32 MyTestModule/Myassembly::init@6 + IL_0012: ldnull + IL_0013: stsfld string MyTestModule/Myassembly::uglyGlobalMutableNullableString + IL_0018: ldc.i4.3 + IL_0019: volatile. + IL_001b: stsfld int32 MyTestModule/Myassembly::init@6 + IL_0020: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpMap`2 [FSharp.Core]Microsoft.FSharp.Collections.MapModule::Empty() + IL_0025: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpMap`2 MyTestModule/Myassembly::dict + IL_002a: ldc.i4.4 + IL_002b: volatile. + IL_002d: stsfld int32 MyTestModule/Myassembly::init@6 + IL_0032: ret + } + + .property instance string Nullable() + { + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .get instance string MyTestModule/Myassembly::get_Nullable() + } + .property instance string NonNullable() + { + .get instance string MyTestModule/Myassembly::get_NonNullable() + } + .property instance int32 JustSomeInt() + { + .get instance int32 MyTestModule/Myassembly::get_JustSomeInt() + } + .property instance string Item(string) + { + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .set instance void MyTestModule/Myassembly::set_Item(string, + string) + .get instance string MyTestModule/Myassembly::get_Item(string) + } + } + + .method private specialname rtspecialname static void .cctor() cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: stsfld int32 ''.$MyTestModule::init@ + IL_0006: ldsfld int32 ''.$MyTestModule::init@ + IL_000b: pop + IL_000c: ret + } + + .method assembly specialname static void staticInitialization@() cil managed + { + + .maxstack 8 + IL_0000: call void MyTestModule/Myassembly::staticInitialization@() + IL_0005: ret + } + +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field static assembly int32 init@ + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method private specialname rtspecialname static void .cctor() cil managed + { + + .maxstack 8 + IL_0000: call void MyTestModule::staticInitialization@() + IL_0005: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericStructDu.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericStructDu.fs new file mode 100644 index 00000000000..cf72987cafb --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericStructDu.fs @@ -0,0 +1,11 @@ +module TestModule + +[] +type MyStructOption<'T when 'T: not null> = + | MyStructNone + | MyStructSome of nestedGenericField : list> * notNullField2 : string * canBeNullField : (string | null) * notNullField1 : 'T + +let mapStructContents f myOpt = + match myOpt with + | MyStructNone -> MyStructNone + | MyStructSome(ngf,s,ns,x) -> MyStructSome (ngf,s,ns,f x) \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericStructDu.fs.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericStructDu.fs.il.net472.bsl new file mode 100644 index 00000000000..8d49ce9610c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericStructDu.fs.il.net472.bsl @@ -0,0 +1,626 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed TestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class sequential autochar serializable sealed nested public beforefieldinit MyStructOption`1 + extends [runtime]System.ValueType + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoEqualityAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoComparisonAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.StructAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C + 61 79 28 29 2C 6E 71 7D 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 01 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param type T + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class abstract auto ansi sealed nested public Tags + extends [runtime]System.Object + { + .param type T + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field public static literal int32 MyStructNone = int32(0x00000000) + .field public static literal int32 MyStructSome = int32(0x00000001) + } + + .field assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> _nestedGenericField + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field assembly string _notNullField2 + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field assembly string _canBeNullField + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field assembly !T _notNullField1 + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field assembly int32 _tag + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public static valuetype TestModule/MyStructOption`1 get_MyStructNone() cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: newobj instance void valuetype TestModule/MyStructOption`1::.ctor(int32) + IL_0006: ret + } + + .method public hidebysig instance bool get_IsMyStructNone() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance int32 valuetype TestModule/MyStructOption`1::get_Tag() + IL_0006: ldc.i4.0 + IL_0007: ceq + IL_0009: ret + } + + .method public static valuetype TestModule/MyStructOption`1 + NewMyStructSome(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> _nestedGenericField, + string _notNullField2, + string _canBeNullField, + !T _notNullField1) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 01 00 00 00 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 01 01 02 00 00 ) + .param [3] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 5 + .locals init (valuetype TestModule/MyStructOption`1 V_0) + IL_0000: ldloca.s V_0 + IL_0002: initobj valuetype TestModule/MyStructOption`1 + IL_0008: ldloca.s V_0 + IL_000a: ldc.i4.1 + IL_000b: stfld int32 valuetype TestModule/MyStructOption`1::_tag + IL_0010: ldloca.s V_0 + IL_0012: ldarg.0 + IL_0013: stfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> valuetype TestModule/MyStructOption`1::_nestedGenericField + IL_0018: ldloca.s V_0 + IL_001a: ldarg.1 + IL_001b: stfld string valuetype TestModule/MyStructOption`1::_notNullField2 + IL_0020: ldloca.s V_0 + IL_0022: ldarg.2 + IL_0023: stfld string valuetype TestModule/MyStructOption`1::_canBeNullField + IL_0028: ldloca.s V_0 + IL_002a: ldarg.3 + IL_002b: stfld !0 valuetype TestModule/MyStructOption`1::_notNullField1 + IL_0030: ldloc.0 + IL_0031: ret + } + + .method public hidebysig instance bool get_IsMyStructSome() cil managed + { + .custom instance void System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::.ctor(bool, + string[]) = ( 01 00 01 04 00 00 00 0D 6E 6F 74 4E 75 6C 6C 46 + 69 65 6C 64 32 0D 6E 6F 74 4E 75 6C 6C 46 69 65 + 6C 64 31 0E 5F 6E 6F 74 4E 75 6C 6C 46 69 65 6C + 64 32 0E 5F 6E 6F 74 4E 75 6C 6C 46 69 65 6C 64 + 31 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance int32 valuetype TestModule/MyStructOption`1::get_Tag() + IL_0006: ldc.i4.1 + IL_0007: ceq + IL_0009: ret + } + + .method assembly specialname rtspecialname instance void .ctor(int32 _tag) cil managed + { + .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 1B 54 65 73 74 4D 6F 64 75 6C + 65 2B 4D 79 53 74 72 75 63 74 4F 70 74 69 6F 6E + 60 31 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 valuetype TestModule/MyStructOption`1::_tag + IL_0007: ret + } + + .method public hidebysig instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> get_nestedGenericField() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 02 01 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> valuetype TestModule/MyStructOption`1::_nestedGenericField + IL_0006: ret + } + + .method public hidebysig instance string get_notNullField2() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string valuetype TestModule/MyStructOption`1::_notNullField2 + IL_0006: ret + } + + .method public hidebysig instance string get_canBeNullField() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string valuetype TestModule/MyStructOption`1::_canBeNullField + IL_0006: ret + } + + .method public hidebysig instance !T get_notNullField1() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld !0 valuetype TestModule/MyStructOption`1::_notNullField1 + IL_0006: ret + } + + .method public hidebysig instance int32 get_Tag() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 valuetype TestModule/MyStructOption`1::_tag + IL_0006: ret + } + + .method assembly hidebysig specialname instance object __DebugDisplay() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+0.8A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: ldobj valuetype TestModule/MyStructOption`1 + IL_0015: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,string>::Invoke(!0) + IL_001a: ret + } + + .method public strict virtual instance string ToString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,valuetype TestModule/MyStructOption`1>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: ldobj valuetype TestModule/MyStructOption`1 + IL_0015: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,string>::Invoke(!0) + IL_001a: ret + } + + .property instance int32 Tag() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance int32 TestModule/MyStructOption`1::get_Tag() + } + .property valuetype TestModule/MyStructOption`1 + MyStructNone() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get valuetype TestModule/MyStructOption`1 TestModule/MyStructOption`1::get_MyStructNone() + } + .property instance bool IsMyStructNone() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance bool TestModule/MyStructOption`1::get_IsMyStructNone() + } + .property instance bool IsMyStructSome() + { + .custom instance void System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::.ctor(bool, + string[]) = ( 01 00 01 04 00 00 00 0D 6E 6F 74 4E 75 6C 6C 46 + 69 65 6C 64 32 0D 6E 6F 74 4E 75 6C 6C 46 69 65 + 6C 64 31 0E 5F 6E 6F 74 4E 75 6C 6C 46 69 65 6C + 64 32 0E 5F 6E 6F 74 4E 75 6C 6C 46 69 65 6C 64 + 31 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance bool TestModule/MyStructOption`1::get_IsMyStructSome() + } + .property instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> + nestedGenericField() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 01 00 00 00 00 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 02 01 02 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> TestModule/MyStructOption`1::get_nestedGenericField() + } + .property instance string notNullField2() + { + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance string TestModule/MyStructOption`1::get_notNullField2() + } + .property instance string canBeNullField() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 01 00 00 00 02 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance string TestModule/MyStructOption`1::get_canBeNullField() + } + .property instance !T notNullField1() + { + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 01 00 00 00 03 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance !T TestModule/MyStructOption`1::get_notNullField1() + } + } + + .method public static valuetype TestModule/MyStructOption`1 + mapStructContents(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + valuetype TestModule/MyStructOption`1 myOpt) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + .param type a + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param type b + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 02 00 00 00 00 01 00 00 ) + .param [2] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 02 00 00 00 00 01 00 00 ) + + .maxstack 7 + .locals init (valuetype TestModule/MyStructOption`1 V_0, + !!a V_1, + string V_2, + string V_3, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> V_4) + IL_0000: ldarg.1 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call instance int32 valuetype TestModule/MyStructOption`1::get_Tag() + IL_0009: ldc.i4.1 + IL_000a: bne.un.s IL_000e + + IL_000c: br.s IL_0014 + + IL_000e: call valuetype TestModule/MyStructOption`1 valuetype TestModule/MyStructOption`1::get_MyStructNone() + IL_0013: ret + + IL_0014: ldloca.s V_0 + IL_0016: ldfld !0 valuetype TestModule/MyStructOption`1::_notNullField1 + IL_001b: stloc.1 + IL_001c: ldloca.s V_0 + IL_001e: ldfld string valuetype TestModule/MyStructOption`1::_notNullField2 + IL_0023: stloc.2 + IL_0024: ldloca.s V_0 + IL_0026: ldfld string valuetype TestModule/MyStructOption`1::_canBeNullField + IL_002b: stloc.3 + IL_002c: ldloca.s V_0 + IL_002e: ldfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> valuetype TestModule/MyStructOption`1::_nestedGenericField + IL_0033: stloc.s V_4 + IL_0035: ldloc.s V_4 + IL_0037: ldloc.2 + IL_0038: ldloc.3 + IL_0039: ldarg.0 + IL_003a: ldloc.1 + IL_003b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0040: call valuetype TestModule/MyStructOption`1 valuetype TestModule/MyStructOption`1::NewMyStructSome(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1>, + string, + string, + !0) + IL_0045: ret + } + +} + +.class private abstract auto ansi sealed ''.$TestModule + extends [runtime]System.Object +{ +} + +.class private auto ansi serializable sealed System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes + extends [runtime]System.Enum +{ + .custom instance void [runtime]System.FlagsAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field public specialname rtspecialname int32 value__ + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes All = int32(0xFFFFFFFF) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes None = int32(0x00000000) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicParameterlessConstructor = int32(0x00000001) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicConstructors = int32(0x00000003) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicConstructors = int32(0x00000004) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicMethods = int32(0x00000008) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicMethods = int32(0x00000010) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicFields = int32(0x00000020) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicFields = int32(0x00000040) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicNestedTypes = int32(0x00000080) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicNestedTypes = int32(0x00000100) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicProperties = int32(0x00000200) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicProperties = int32(0x00000400) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicEvents = int32(0x00000800) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicEvents = int32(0x00001000) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes Interfaces = int32(0x00002000) +} + +.class private auto ansi beforefieldinit System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MemberType@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field private class [runtime]System.Type Type@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname + instance void .ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MemberType, + class [runtime]System.Type Type) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::MemberType@ + IL_000d: ldarg.0 + IL_000e: ldarg.2 + IL_000f: stfld class [runtime]System.Type System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::Type@ + IL_0014: ret + } + + .method public hidebysig specialname instance class [runtime]System.Type get_Type() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [runtime]System.Type System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::Type@ + IL_0006: ret + } + + .method public hidebysig specialname instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes get_MemberType() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::MemberType@ + IL_0006: ret + } + + .property instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes + MemberType() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::get_MemberType() + } + .property instance class [runtime]System.Type + Type() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance class [runtime]System.Type System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::get_Type() + } +} + +.class private auto ansi beforefieldinit System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private bool ReturnValue@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field private string[] Members@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname + instance void .ctor(bool ReturnValue, + string[] Members) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld bool System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::ReturnValue@ + IL_000d: ldarg.0 + IL_000e: ldarg.2 + IL_000f: stfld string[] System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::Members@ + IL_0014: ret + } + + .method public hidebysig specialname instance string[] get_Members() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string[] System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::Members@ + IL_0006: ret + } + + .method public hidebysig specialname instance bool get_ReturnValue() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld bool System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::ReturnValue@ + IL_0006: ret + } + + .property instance bool ReturnValue() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance bool System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::get_ReturnValue() + } + .property instance string[] Members() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance string[] System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::get_Members() + } +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8[] NullableFlags + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 scalarByteValue) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldc.i4.1 + IL_0008: newarr [runtime]System.Byte + IL_000d: dup + IL_000e: ldc.i4.0 + IL_000f: ldarg.1 + IL_0010: stelem.i1 + IL_0011: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_0016: ret + } + + .method public specialname rtspecialname instance void .ctor(uint8[] NullableFlags) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_000d: ret + } + +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableContextAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8 Flag + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 Flag) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8 System.Runtime.CompilerServices.NullableContextAttribute::Flag + IL_000d: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericStructDu.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericStructDu.fs.il.netcore.bsl new file mode 100644 index 00000000000..43a350944d8 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericStructDu.fs.il.netcore.bsl @@ -0,0 +1,404 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed TestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class sequential autochar serializable sealed nested public beforefieldinit MyStructOption`1 + extends [runtime]System.ValueType + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoEqualityAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoComparisonAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.StructAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C + 61 79 28 29 2C 6E 71 7D 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 01 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param type T + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class abstract auto ansi sealed nested public Tags + extends [runtime]System.Object + { + .param type T + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field public static literal int32 MyStructNone = int32(0x00000000) + .field public static literal int32 MyStructSome = int32(0x00000001) + } + + .field assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> _nestedGenericField + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field assembly string _notNullField2 + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field assembly string _canBeNullField + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field assembly !T _notNullField1 + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field assembly int32 _tag + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public static valuetype TestModule/MyStructOption`1 get_MyStructNone() cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: newobj instance void valuetype TestModule/MyStructOption`1::.ctor(int32) + IL_0006: ret + } + + .method public hidebysig instance bool get_IsMyStructNone() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance int32 valuetype TestModule/MyStructOption`1::get_Tag() + IL_0006: ldc.i4.0 + IL_0007: ceq + IL_0009: ret + } + + .method public static valuetype TestModule/MyStructOption`1 + NewMyStructSome(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> _nestedGenericField, + string _notNullField2, + string _canBeNullField, + !T _notNullField1) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 01 00 00 00 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 01 01 02 00 00 ) + .param [3] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 5 + .locals init (valuetype TestModule/MyStructOption`1 V_0) + IL_0000: ldloca.s V_0 + IL_0002: initobj valuetype TestModule/MyStructOption`1 + IL_0008: ldloca.s V_0 + IL_000a: ldc.i4.1 + IL_000b: stfld int32 valuetype TestModule/MyStructOption`1::_tag + IL_0010: ldloca.s V_0 + IL_0012: ldarg.0 + IL_0013: stfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> valuetype TestModule/MyStructOption`1::_nestedGenericField + IL_0018: ldloca.s V_0 + IL_001a: ldarg.1 + IL_001b: stfld string valuetype TestModule/MyStructOption`1::_notNullField2 + IL_0020: ldloca.s V_0 + IL_0022: ldarg.2 + IL_0023: stfld string valuetype TestModule/MyStructOption`1::_canBeNullField + IL_0028: ldloca.s V_0 + IL_002a: ldarg.3 + IL_002b: stfld !0 valuetype TestModule/MyStructOption`1::_notNullField1 + IL_0030: ldloc.0 + IL_0031: ret + } + + .method public hidebysig instance bool get_IsMyStructSome() cil managed + { + .custom instance void [runtime]System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::.ctor(bool, + string[]) = ( 01 00 01 04 00 00 00 0D 6E 6F 74 4E 75 6C 6C 46 + 69 65 6C 64 32 0D 6E 6F 74 4E 75 6C 6C 46 69 65 + 6C 64 31 0E 5F 6E 6F 74 4E 75 6C 6C 46 69 65 6C + 64 32 0E 5F 6E 6F 74 4E 75 6C 6C 46 69 65 6C 64 + 31 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance int32 valuetype TestModule/MyStructOption`1::get_Tag() + IL_0006: ldc.i4.1 + IL_0007: ceq + IL_0009: ret + } + + .method assembly specialname rtspecialname instance void .ctor(int32 _tag) cil managed + { + .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 1B 54 65 73 74 4D 6F 64 75 6C + 65 2B 4D 79 53 74 72 75 63 74 4F 70 74 69 6F 6E + 60 31 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 valuetype TestModule/MyStructOption`1::_tag + IL_0007: ret + } + + .method public hidebysig instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> get_nestedGenericField() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 02 01 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> valuetype TestModule/MyStructOption`1::_nestedGenericField + IL_0006: ret + } + + .method public hidebysig instance string get_notNullField2() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string valuetype TestModule/MyStructOption`1::_notNullField2 + IL_0006: ret + } + + .method public hidebysig instance string get_canBeNullField() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string valuetype TestModule/MyStructOption`1::_canBeNullField + IL_0006: ret + } + + .method public hidebysig instance !T get_notNullField1() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld !0 valuetype TestModule/MyStructOption`1::_notNullField1 + IL_0006: ret + } + + .method public hidebysig instance int32 get_Tag() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 valuetype TestModule/MyStructOption`1::_tag + IL_0006: ret + } + + .method assembly hidebysig specialname instance object __DebugDisplay() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+0.8A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: ldobj valuetype TestModule/MyStructOption`1 + IL_0015: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,string>::Invoke(!0) + IL_001a: ret + } + + .method public strict virtual instance string ToString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,valuetype TestModule/MyStructOption`1>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: ldobj valuetype TestModule/MyStructOption`1 + IL_0015: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,string>::Invoke(!0) + IL_001a: ret + } + + .property instance int32 Tag() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance int32 TestModule/MyStructOption`1::get_Tag() + } + .property valuetype TestModule/MyStructOption`1 + MyStructNone() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get valuetype TestModule/MyStructOption`1 TestModule/MyStructOption`1::get_MyStructNone() + } + .property instance bool IsMyStructNone() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance bool TestModule/MyStructOption`1::get_IsMyStructNone() + } + .property instance bool IsMyStructSome() + { + .custom instance void [runtime]System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::.ctor(bool, + string[]) = ( 01 00 01 04 00 00 00 0D 6E 6F 74 4E 75 6C 6C 46 + 69 65 6C 64 32 0D 6E 6F 74 4E 75 6C 6C 46 69 65 + 6C 64 31 0E 5F 6E 6F 74 4E 75 6C 6C 46 69 65 6C + 64 32 0E 5F 6E 6F 74 4E 75 6C 6C 46 69 65 6C 64 + 31 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance bool TestModule/MyStructOption`1::get_IsMyStructSome() + } + .property instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> + nestedGenericField() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 01 00 00 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 02 01 02 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> TestModule/MyStructOption`1::get_nestedGenericField() + } + .property instance string notNullField2() + { + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance string TestModule/MyStructOption`1::get_notNullField2() + } + .property instance string canBeNullField() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 01 00 00 00 02 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance string TestModule/MyStructOption`1::get_canBeNullField() + } + .property instance !T notNullField1() + { + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 01 00 00 00 03 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance !T TestModule/MyStructOption`1::get_notNullField1() + } + } + + .method public static valuetype TestModule/MyStructOption`1 + mapStructContents(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + valuetype TestModule/MyStructOption`1 myOpt) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + .param type a + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param type b + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 02 00 00 00 00 01 00 00 ) + .param [2] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 02 00 00 00 00 01 00 00 ) + + .maxstack 7 + .locals init (valuetype TestModule/MyStructOption`1 V_0, + !!a V_1, + string V_2, + string V_3, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> V_4) + IL_0000: ldarg.1 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call instance int32 valuetype TestModule/MyStructOption`1::get_Tag() + IL_0009: ldc.i4.1 + IL_000a: bne.un.s IL_000e + + IL_000c: br.s IL_0014 + + IL_000e: call valuetype TestModule/MyStructOption`1 valuetype TestModule/MyStructOption`1::get_MyStructNone() + IL_0013: ret + + IL_0014: ldloca.s V_0 + IL_0016: ldfld !0 valuetype TestModule/MyStructOption`1::_notNullField1 + IL_001b: stloc.1 + IL_001c: ldloca.s V_0 + IL_001e: ldfld string valuetype TestModule/MyStructOption`1::_notNullField2 + IL_0023: stloc.2 + IL_0024: ldloca.s V_0 + IL_0026: ldfld string valuetype TestModule/MyStructOption`1::_canBeNullField + IL_002b: stloc.3 + IL_002c: ldloca.s V_0 + IL_002e: ldfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> valuetype TestModule/MyStructOption`1::_nestedGenericField + IL_0033: stloc.s V_4 + IL_0035: ldloc.s V_4 + IL_0037: ldloc.2 + IL_0038: ldloc.3 + IL_0039: ldarg.0 + IL_003a: ldloc.1 + IL_003b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0040: call valuetype TestModule/MyStructOption`1 valuetype TestModule/MyStructOption`1::NewMyStructSome(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1>, + string, + string, + !0) + IL_0045: ret + } + +} + +.class private abstract auto ansi sealed ''.$TestModule + extends [runtime]System.Object +{ +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelBindings.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelBindings.fs new file mode 100644 index 00000000000..f3cb30cd05d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelBindings.fs @@ -0,0 +1,8 @@ +module MyTestModule +[] +let nullableLiteral : string | null = "" +let notNullStringField : string = "" +let nullableStringField : string | null = null +let mutable nullableMutableStringField : string | null = null +let nullableInt : System.Nullable = System.Nullable() +let regularInt = 42 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelBindings.fs.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelBindings.fs.il.net472.bsl new file mode 100644 index 00000000000..da49015055d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelBindings.fs.il.net472.bsl @@ -0,0 +1,229 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field public static literal string nullableLiteral = "" + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.LiteralAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field static assembly string nullableMutableStringField@6 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .method public specialname static string get_notNullStringField() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "" + IL_0005: ret + } + + .method public specialname static string get_nullableStringField() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } + + .method public specialname static string get_nullableMutableStringField() cil managed + { + + .maxstack 8 + IL_0000: ldsfld string MyTestModule::nullableMutableStringField@6 + IL_0005: ret + } + + .method public specialname static void set_nullableMutableStringField(string 'value') cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: stsfld string MyTestModule::nullableMutableStringField@6 + IL_0006: ret + } + + .method public specialname static valuetype [runtime]System.Nullable`1 get_nullableInt() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 3 + .locals init (valuetype [runtime]System.Nullable`1 V_0) + IL_0000: ldloc.0 + IL_0001: ret + } + + .method public specialname static int32 get_regularInt() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.s 42 + IL_0002: ret + } + + .method private specialname rtspecialname static void .cctor() cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: stsfld int32 ''.$MyTestModule::init@ + IL_0006: ldsfld int32 ''.$MyTestModule::init@ + IL_000b: pop + IL_000c: ret + } + + .method assembly specialname static void staticInitialization@() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: stsfld string MyTestModule::nullableMutableStringField@6 + IL_0006: ret + } + + .property string notNullStringField() + { + .get string MyTestModule::get_notNullStringField() + } + .property string nullableStringField() + { + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .get string MyTestModule::get_nullableStringField() + } + .property string nullableMutableStringField() + { + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 09 00 00 00 00 00 ) + .set void MyTestModule::set_nullableMutableStringField(string) + .get string MyTestModule::get_nullableMutableStringField() + } + .property valuetype [runtime]System.Nullable`1 + nullableInt() + { + .get valuetype [runtime]System.Nullable`1 MyTestModule::get_nullableInt() + } + .property int32 regularInt() + { + .get int32 MyTestModule::get_regularInt() + } +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field static assembly int32 init@ + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method private specialname rtspecialname static void .cctor() cil managed + { + + .maxstack 8 + IL_0000: call void MyTestModule::staticInitialization@() + IL_0005: ret + } + +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8[] NullableFlags + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 scalarByteValue) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldc.i4.1 + IL_0008: newarr [runtime]System.Byte + IL_000d: dup + IL_000e: ldc.i4.0 + IL_000f: ldarg.1 + IL_0010: stelem.i1 + IL_0011: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_0016: ret + } + + .method public specialname rtspecialname instance void .ctor(uint8[] NullableFlags) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_000d: ret + } + +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableContextAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8 Flag + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 Flag) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8 System.Runtime.CompilerServices.NullableContextAttribute::Flag + IL_000d: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelBindings.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelBindings.fs.il.netcore.bsl new file mode 100644 index 00000000000..16f1a590042 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelBindings.fs.il.netcore.bsl @@ -0,0 +1,164 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field public static literal string nullableLiteral = "" + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.LiteralAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field static assembly string nullableMutableStringField@6 + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .method public specialname static string get_notNullStringField() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "" + IL_0005: ret + } + + .method public specialname static string get_nullableStringField() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } + + .method public specialname static string get_nullableMutableStringField() cil managed + { + + .maxstack 8 + IL_0000: ldsfld string MyTestModule::nullableMutableStringField@6 + IL_0005: ret + } + + .method public specialname static void set_nullableMutableStringField(string 'value') cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: stsfld string MyTestModule::nullableMutableStringField@6 + IL_0006: ret + } + + .method public specialname static valuetype [runtime]System.Nullable`1 get_nullableInt() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 3 + .locals init (valuetype [runtime]System.Nullable`1 V_0) + IL_0000: ldloc.0 + IL_0001: ret + } + + .method public specialname static int32 get_regularInt() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.s 42 + IL_0002: ret + } + + .method private specialname rtspecialname static void .cctor() cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: stsfld int32 ''.$MyTestModule::init@ + IL_0006: ldsfld int32 ''.$MyTestModule::init@ + IL_000b: pop + IL_000c: ret + } + + .method assembly specialname static void staticInitialization@() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: stsfld string MyTestModule::nullableMutableStringField@6 + IL_0006: ret + } + + .property string notNullStringField() + { + .get string MyTestModule::get_notNullStringField() + } + .property string nullableStringField() + { + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .get string MyTestModule::get_nullableStringField() + } + .property string nullableMutableStringField() + { + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 09 00 00 00 00 00 ) + .set void MyTestModule::set_nullableMutableStringField(string) + .get string MyTestModule::get_nullableMutableStringField() + } + .property valuetype [runtime]System.Nullable`1 + nullableInt() + { + .get valuetype [runtime]System.Nullable`1 MyTestModule::get_nullableInt() + } + .property int32 regularInt() + { + .get int32 MyTestModule::get_regularInt() + } +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field static assembly int32 init@ + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method private specialname rtspecialname static void .cctor() cil managed + { + + .maxstack 8 + IL_0000: call void MyTestModule::staticInitialization@() + IL_0005: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctions.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctions.fs new file mode 100644 index 00000000000..5b7efae9b87 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctions.fs @@ -0,0 +1,10 @@ +module MyTestModule + +let nonNullableInputOutputFunc (x:string) = x +let nullableStringInputOutputFunc (x: string | null) = x +let nonNullableIntFunc (x:int) = x +let nullableIntFunc (x:System.Nullable) = x +let genericValueTypeTest (x: struct(string * (string|null) * int * int * int * int)) = x +let genericRefTypeTest (x: string * (string|null) * int * int * int * int) = x +let nestedGenericsTest (x: list | null> | null) = x +let multiArgumentTest (x:string) (y:string | null) = 42 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctions.fs.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctions.fs.il.net472.bsl new file mode 100644 index 00000000000..0461633d8bd --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctions.fs.il.net472.bsl @@ -0,0 +1,216 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .method public static string nonNullableInputOutputFunc(string x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static string nullableStringInputOutputFunc(string x) cil managed + { + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static int32 nonNullableIntFunc(int32 x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static valuetype [runtime]System.Nullable`1 + nullableIntFunc(valuetype [runtime]System.Nullable`1 x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static valuetype [runtime]System.ValueTuple`6 + genericValueTypeTest(valuetype [runtime]System.ValueTuple`6 x) cil managed + { + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 00 01 02 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 00 01 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static class [runtime]System.Tuple`6 + genericRefTypeTest(string x_0, + string x_1, + int32 x_2, + int32 x_3, + int32 x_4, + int32 x_5) cil managed + { + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 01 01 02 00 00 ) + .param [2] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + .locals init (class [runtime]System.Tuple`6 V_0) + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: ldarg.3 + IL_0004: ldarg.s x_4 + IL_0006: ldarg.s x_5 + IL_0008: newobj instance void class [runtime]System.Tuple`6::.ctor(!0, + !1, + !2, + !3, + !4, + !5) + IL_000d: stloc.0 + IL_000e: ldloc.0 + IL_000f: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> + nestedGenericsTest(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> x) cil managed + { + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static int32 multiArgumentTest(string x, + string y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + .param [2] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.s 42 + IL_0002: ret + } + +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8[] NullableFlags + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname + instance void .ctor(uint8 scalarByteValue) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldc.i4.1 + IL_0008: newarr [runtime]System.Byte + IL_000d: dup + IL_000e: ldc.i4.0 + IL_000f: ldarg.1 + IL_0010: stelem.i1 + IL_0011: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_0016: ret + } + + .method public specialname rtspecialname + instance void .ctor(uint8[] NullableFlags) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_000d: ret + } + +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableContextAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8 Flag + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname + instance void .ctor(uint8 Flag) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8 System.Runtime.CompilerServices.NullableContextAttribute::Flag + IL_000d: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctions.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctions.fs.il.netcore.bsl new file mode 100644 index 00000000000..f3e3c40331a --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctions.fs.il.netcore.bsl @@ -0,0 +1,148 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .method public static string nonNullableInputOutputFunc(string x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static string nullableStringInputOutputFunc(string x) cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static int32 nonNullableIntFunc(int32 x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static valuetype [runtime]System.Nullable`1 + nullableIntFunc(valuetype [runtime]System.Nullable`1 x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static valuetype [runtime]System.ValueTuple`6 + genericValueTypeTest(valuetype [runtime]System.ValueTuple`6 x) cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 00 01 02 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 00 01 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static class [runtime]System.Tuple`6 + genericRefTypeTest(string x_0, + string x_1, + int32 x_2, + int32 x_3, + int32 x_4, + int32 x_5) cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 01 01 02 00 00 ) + .param [2] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + .locals init (class [runtime]System.Tuple`6 V_0) + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: ldarg.3 + IL_0004: ldarg.s x_4 + IL_0006: ldarg.s x_5 + IL_0008: newobj instance void class [runtime]System.Tuple`6::.ctor(!0, + !1, + !2, + !3, + !4, + !5) + IL_000d: stloc.0 + IL_000e: ldloc.0 + IL_000f: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> + nestedGenericsTest(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> x) cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static int32 multiArgumentTest(string x, + string y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + .param [2] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.s 42 + IL_0002: ret + } + +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctionsOpt.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctionsOpt.fs new file mode 100644 index 00000000000..5b7efae9b87 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctionsOpt.fs @@ -0,0 +1,10 @@ +module MyTestModule + +let nonNullableInputOutputFunc (x:string) = x +let nullableStringInputOutputFunc (x: string | null) = x +let nonNullableIntFunc (x:int) = x +let nullableIntFunc (x:System.Nullable) = x +let genericValueTypeTest (x: struct(string * (string|null) * int * int * int * int)) = x +let genericRefTypeTest (x: string * (string|null) * int * int * int * int) = x +let nestedGenericsTest (x: list | null> | null) = x +let multiArgumentTest (x:string) (y:string | null) = 42 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctionsOpt.fs.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctionsOpt.fs.il.net472.bsl new file mode 100644 index 00000000000..f4d927102b4 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctionsOpt.fs.il.net472.bsl @@ -0,0 +1,213 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .method public static string nonNullableInputOutputFunc(string x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static string nullableStringInputOutputFunc(string x) cil managed + { + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static int32 nonNullableIntFunc(int32 x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static valuetype [runtime]System.Nullable`1 + nullableIntFunc(valuetype [runtime]System.Nullable`1 x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static valuetype [runtime]System.ValueTuple`6 + genericValueTypeTest(valuetype [runtime]System.ValueTuple`6 x) cil managed + { + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 00 01 02 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 00 01 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static class [runtime]System.Tuple`6 + genericRefTypeTest(string x_0, + string x_1, + int32 x_2, + int32 x_3, + int32 x_4, + int32 x_5) cil managed + { + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 01 01 02 00 00 ) + .param [2] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: ldarg.3 + IL_0004: ldarg.s x_4 + IL_0006: ldarg.s x_5 + IL_0008: newobj instance void class [runtime]System.Tuple`6::.ctor(!0, + !1, + !2, + !3, + !4, + !5) + IL_000d: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> + nestedGenericsTest(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> x) cil managed + { + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static int32 multiArgumentTest(string x, + string y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + .param [2] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.s 42 + IL_0002: ret + } + +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8[] NullableFlags + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname + instance void .ctor(uint8 scalarByteValue) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldc.i4.1 + IL_0008: newarr [runtime]System.Byte + IL_000d: dup + IL_000e: ldc.i4.0 + IL_000f: ldarg.1 + IL_0010: stelem.i1 + IL_0011: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_0016: ret + } + + .method public specialname rtspecialname + instance void .ctor(uint8[] NullableFlags) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_000d: ret + } + +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableContextAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8 Flag + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname + instance void .ctor(uint8 Flag) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8 System.Runtime.CompilerServices.NullableContextAttribute::Flag + IL_000d: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctionsOpt.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctionsOpt.fs.il.netcore.bsl new file mode 100644 index 00000000000..f97a7c36bc5 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ModuleLevelFunctionsOpt.fs.il.netcore.bsl @@ -0,0 +1,145 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .method public static string nonNullableInputOutputFunc(string x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static string nullableStringInputOutputFunc(string x) cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static int32 nonNullableIntFunc(int32 x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static valuetype [runtime]System.Nullable`1 + nullableIntFunc(valuetype [runtime]System.Nullable`1 x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static valuetype [runtime]System.ValueTuple`6 + genericValueTypeTest(valuetype [runtime]System.ValueTuple`6 x) cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 00 01 02 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 00 01 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static class [runtime]System.Tuple`6 + genericRefTypeTest(string x_0, + string x_1, + int32 x_2, + int32 x_3, + int32 x_4, + int32 x_5) cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 01 01 02 00 00 ) + .param [2] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: ldarg.3 + IL_0004: ldarg.s x_4 + IL_0006: ldarg.s x_5 + IL_0008: newobj instance void class [runtime]System.Tuple`6::.ctor(!0, + !1, + !2, + !3, + !4, + !5) + IL_000d: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> + nestedGenericsTest(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> x) cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static int32 multiArgumentTest(string x, + string y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + .param [2] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.s 42 + IL_0002: ret + } + +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullAsTrueValue.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullAsTrueValue.fs new file mode 100644 index 00000000000..043675e4bcc --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullAsTrueValue.fs @@ -0,0 +1,23 @@ +module TestModule + +[] +[] +type MyNullableOption<'T when 'T:null> = + | MyNone + | MySome of value:'T + +let mapPossiblyNullable f myOpt = + match myOpt with + | MyNone -> MyNone + | MySome x -> MySome (f x) + +[] +[] +type MyOptionWhichCannotHaveNullInTheInside<'T when 'T:not null> = + | MyNotNullNone + | MyNotNullSome of value:'T + +let mapNotNullableContents f myOpt = + match myOpt with + | MyNotNullNone -> MyNotNullNone + | MyNotNullSome x -> MyNotNullSome (f x) \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullAsTrueValue.fs.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullAsTrueValue.fs.il.net472.bsl new file mode 100644 index 00000000000..f4977bfcd8d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullAsTrueValue.fs.il.net472.bsl @@ -0,0 +1,656 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed TestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class auto autochar serializable sealed nested public beforefieldinit MyNullableOption`1 + extends [runtime]System.Object + { + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationRepresentationAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilationRepresentationFlags) = ( 01 00 08 00 00 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoEqualityAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoComparisonAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C + 61 79 28 29 2C 6E 71 7D 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 01 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param type T + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .class abstract auto ansi sealed nested public Tags + extends [runtime]System.Object + { + .param type T + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .field public static literal int32 MyNone = int32(0x00000000) + .field public static literal int32 MySome = int32(0x00000001) + } + + .field assembly initonly !T _value + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname instance void .ctor() cil managed + { + .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 E0 07 00 00 1D 54 65 73 74 4D 6F 64 75 6C + 65 2B 4D 79 4E 75 6C 6C 61 62 6C 65 4F 70 74 69 + 6F 6E 60 31 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Object::.ctor() + IL_0006: ret + } + + .method public static class TestModule/MyNullableOption`1 get_MyNone() cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } + + .method public static class TestModule/MyNullableOption`1 NewMySome(!T _value) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void class TestModule/MyNullableOption`1::.ctor(!0) + IL_0006: ret + } + + .method assembly specialname rtspecialname instance void .ctor(!T _value) cil managed + { + .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 1D 54 65 73 74 4D 6F 64 75 6C + 65 2B 4D 79 4E 75 6C 6C 61 62 6C 65 4F 70 74 69 + 6F 6E 60 31 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld !0 class TestModule/MyNullableOption`1::_value + IL_000d: ret + } + + .method public hidebysig instance !T get_value() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld !0 class TestModule/MyNullableOption`1::_value + IL_0006: ret + } + + .method public static int32 GetTag(class TestModule/MyNullableOption`1 A_0) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: brfalse.s IL_0006 + + IL_0003: ldc.i4.1 + IL_0004: br.s IL_0007 + + IL_0006: ldc.i4.0 + IL_0007: ret + } + + .method assembly hidebysig specialname instance object __DebugDisplay() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+0.8A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,string>::Invoke(!0) + IL_0015: ret + } + + .method public strict virtual instance string ToString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,class TestModule/MyNullableOption`1>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,string>::Invoke(!0) + IL_0015: ret + } + + .method public specialname static bool get_IsMyNone(class TestModule/MyNullableOption`1 A_0) cil managed + { + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: ceq + IL_0004: ret + } + + .method public specialname static bool get_IsMySome(class TestModule/MyNullableOption`1 A_0) cil managed + { + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: cgt.un + IL_0004: ret + } + + .property class TestModule/MyNullableOption`1 + MyNone() + { + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get class TestModule/MyNullableOption`1 TestModule/MyNullableOption`1::get_MyNone() + } + .property instance !T 'value'() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 01 00 00 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance !T TestModule/MyNullableOption`1::get_value() + } + .property bool IsMyNone() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 00 00 00 00 00 00 ) + .get bool TestModule/MyNullableOption`1::get_IsMyNone(class TestModule/MyNullableOption`1) + } + .property bool IsMySome() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 00 00 00 00 00 00 ) + .get bool TestModule/MyNullableOption`1::get_IsMySome(class TestModule/MyNullableOption`1) + } + } + + .class auto autochar serializable sealed nested public beforefieldinit MyOptionWhichCannotHaveNullInTheInside`1 + extends [runtime]System.Object + { + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationRepresentationAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilationRepresentationFlags) = ( 01 00 08 00 00 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoEqualityAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoComparisonAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C + 61 79 28 29 2C 6E 71 7D 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 01 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param type T + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class abstract auto ansi sealed nested public Tags + extends [runtime]System.Object + { + .param type T + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field public static literal int32 MyNotNullNone = int32(0x00000000) + .field public static literal int32 MyNotNullSome = int32(0x00000001) + } + + .field assembly initonly !T _value + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname instance void .ctor() cil managed + { + .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 E0 07 00 00 33 54 65 73 74 4D 6F 64 75 6C + 65 2B 4D 79 4F 70 74 69 6F 6E 57 68 69 63 68 43 + 61 6E 6E 6F 74 48 61 76 65 4E 75 6C 6C 49 6E 54 + 68 65 49 6E 73 69 64 65 60 31 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Object::.ctor() + IL_0006: ret + } + + .method public static class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 get_MyNotNullNone() cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } + + .method public static class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 NewMyNotNullSome(!T _value) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void class TestModule/MyOptionWhichCannotHaveNullInTheInside`1::.ctor(!0) + IL_0006: ret + } + + .method assembly specialname rtspecialname instance void .ctor(!T _value) cil managed + { + .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 33 54 65 73 74 4D 6F 64 75 6C + 65 2B 4D 79 4F 70 74 69 6F 6E 57 68 69 63 68 43 + 61 6E 6E 6F 74 48 61 76 65 4E 75 6C 6C 49 6E 54 + 68 65 49 6E 73 69 64 65 60 31 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld !0 class TestModule/MyOptionWhichCannotHaveNullInTheInside`1::_value + IL_000d: ret + } + + .method public hidebysig instance !T get_value() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld !0 class TestModule/MyOptionWhichCannotHaveNullInTheInside`1::_value + IL_0006: ret + } + + .method public static int32 GetTag(class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 A_0) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: brfalse.s IL_0006 + + IL_0003: ldc.i4.1 + IL_0004: br.s IL_0007 + + IL_0006: ldc.i4.0 + IL_0007: ret + } + + .method assembly hidebysig specialname instance object __DebugDisplay() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+0.8A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,string>::Invoke(!0) + IL_0015: ret + } + + .method public strict virtual instance string ToString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,class TestModule/MyOptionWhichCannotHaveNullInTheInside`1>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,string>::Invoke(!0) + IL_0015: ret + } + + .method public specialname static bool get_IsMyNotNullNone(class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 A_0) cil managed + { + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: ceq + IL_0004: ret + } + + .method public specialname static bool get_IsMyNotNullSome(class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 A_0) cil managed + { + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: cgt.un + IL_0004: ret + } + + .property class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 + MyNotNullNone() + { + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 TestModule/MyOptionWhichCannotHaveNullInTheInside`1::get_MyNotNullNone() + } + .property instance !T 'value'() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 01 00 00 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance !T TestModule/MyOptionWhichCannotHaveNullInTheInside`1::get_value() + } + .property bool IsMyNotNullNone() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 00 00 00 00 00 00 ) + .get bool TestModule/MyOptionWhichCannotHaveNullInTheInside`1::get_IsMyNotNullNone(class TestModule/MyOptionWhichCannotHaveNullInTheInside`1) + } + .property bool IsMyNotNullSome() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 00 00 00 00 00 00 ) + .get bool TestModule/MyOptionWhichCannotHaveNullInTheInside`1::get_IsMyNotNullSome(class TestModule/MyOptionWhichCannotHaveNullInTheInside`1) + } + } + + .method public static class TestModule/MyNullableOption`1 + mapPossiblyNullable(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class TestModule/MyNullableOption`1 myOpt) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + .param type a + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param type b + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 4 + .locals init (class TestModule/MyNullableOption`1 V_0, + class TestModule/MyNullableOption`1 V_1, + !!a V_2) + IL_0000: ldarg.1 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: brfalse.s IL_0007 + + IL_0005: br.s IL_0009 + + IL_0007: ldnull + IL_0008: ret + + IL_0009: ldloc.0 + IL_000a: stloc.1 + IL_000b: ldloc.1 + IL_000c: ldfld !0 class TestModule/MyNullableOption`1::_value + IL_0011: stloc.2 + IL_0012: ldarg.0 + IL_0013: ldloc.2 + IL_0014: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0019: call class TestModule/MyNullableOption`1 class TestModule/MyNullableOption`1::NewMySome(!0) + IL_001e: ret + } + + .method public static class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 + mapNotNullableContents(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 myOpt) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + .param type a + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param type b + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + + .maxstack 4 + .locals init (class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 V_0, + class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 V_1, + !!a V_2) + IL_0000: ldarg.1 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: brfalse.s IL_0007 + + IL_0005: br.s IL_0009 + + IL_0007: ldnull + IL_0008: ret + + IL_0009: ldloc.0 + IL_000a: stloc.1 + IL_000b: ldloc.1 + IL_000c: ldfld !0 class TestModule/MyOptionWhichCannotHaveNullInTheInside`1::_value + IL_0011: stloc.2 + IL_0012: ldarg.0 + IL_0013: ldloc.2 + IL_0014: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0019: call class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 class TestModule/MyOptionWhichCannotHaveNullInTheInside`1::NewMyNotNullSome(!0) + IL_001e: ret + } + +} + +.class private abstract auto ansi sealed ''.$TestModule + extends [runtime]System.Object +{ +} + +.class private auto ansi serializable sealed System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes + extends [runtime]System.Enum +{ + .custom instance void [runtime]System.FlagsAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field public specialname rtspecialname int32 value__ + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes All = int32(0xFFFFFFFF) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes None = int32(0x00000000) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicParameterlessConstructor = int32(0x00000001) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicConstructors = int32(0x00000003) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicConstructors = int32(0x00000004) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicMethods = int32(0x00000008) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicMethods = int32(0x00000010) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicFields = int32(0x00000020) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicFields = int32(0x00000040) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicNestedTypes = int32(0x00000080) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicNestedTypes = int32(0x00000100) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicProperties = int32(0x00000200) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicProperties = int32(0x00000400) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicEvents = int32(0x00000800) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicEvents = int32(0x00001000) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes Interfaces = int32(0x00002000) +} + +.class private auto ansi beforefieldinit System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MemberType@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field private class [runtime]System.Type Type@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname + instance void .ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MemberType, + class [runtime]System.Type Type) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::MemberType@ + IL_000d: ldarg.0 + IL_000e: ldarg.2 + IL_000f: stfld class [runtime]System.Type System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::Type@ + IL_0014: ret + } + + .method public hidebysig specialname instance class [runtime]System.Type get_Type() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [runtime]System.Type System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::Type@ + IL_0006: ret + } + + .method public hidebysig specialname instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes get_MemberType() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::MemberType@ + IL_0006: ret + } + + .property instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes + MemberType() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::get_MemberType() + } + .property instance class [runtime]System.Type + Type() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance class [runtime]System.Type System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::get_Type() + } +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8[] NullableFlags + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 scalarByteValue) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldc.i4.1 + IL_0008: newarr [runtime]System.Byte + IL_000d: dup + IL_000e: ldc.i4.0 + IL_000f: ldarg.1 + IL_0010: stelem.i1 + IL_0011: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_0016: ret + } + + .method public specialname rtspecialname instance void .ctor(uint8[] NullableFlags) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_000d: ret + } + +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableContextAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8 Flag + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 Flag) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8 System.Runtime.CompilerServices.NullableContextAttribute::Flag + IL_000d: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullAsTrueValue.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullAsTrueValue.fs.il.netcore.bsl new file mode 100644 index 00000000000..057fa515964 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullAsTrueValue.fs.il.netcore.bsl @@ -0,0 +1,499 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed TestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class auto autochar serializable sealed nested public beforefieldinit MyNullableOption`1 + extends [runtime]System.Object + { + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationRepresentationAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilationRepresentationFlags) = ( 01 00 08 00 00 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoEqualityAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoComparisonAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C + 61 79 28 29 2C 6E 71 7D 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 01 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param type T + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .class abstract auto ansi sealed nested public Tags + extends [runtime]System.Object + { + .param type T + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .field public static literal int32 MyNone = int32(0x00000000) + .field public static literal int32 MySome = int32(0x00000001) + } + + .field assembly initonly !T _value + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname instance void .ctor() cil managed + { + .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 E0 07 00 00 1D 54 65 73 74 4D 6F 64 75 6C + 65 2B 4D 79 4E 75 6C 6C 61 62 6C 65 4F 70 74 69 + 6F 6E 60 31 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Object::.ctor() + IL_0006: ret + } + + .method public static class TestModule/MyNullableOption`1 get_MyNone() cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } + + .method public static class TestModule/MyNullableOption`1 NewMySome(!T _value) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void class TestModule/MyNullableOption`1::.ctor(!0) + IL_0006: ret + } + + .method assembly specialname rtspecialname instance void .ctor(!T _value) cil managed + { + .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 1D 54 65 73 74 4D 6F 64 75 6C + 65 2B 4D 79 4E 75 6C 6C 61 62 6C 65 4F 70 74 69 + 6F 6E 60 31 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld !0 class TestModule/MyNullableOption`1::_value + IL_000d: ret + } + + .method public hidebysig instance !T get_value() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld !0 class TestModule/MyNullableOption`1::_value + IL_0006: ret + } + + .method public static int32 GetTag(class TestModule/MyNullableOption`1 A_0) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: brfalse.s IL_0006 + + IL_0003: ldc.i4.1 + IL_0004: br.s IL_0007 + + IL_0006: ldc.i4.0 + IL_0007: ret + } + + .method assembly hidebysig specialname instance object __DebugDisplay() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+0.8A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,string>::Invoke(!0) + IL_0015: ret + } + + .method public strict virtual instance string ToString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,class TestModule/MyNullableOption`1>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,string>::Invoke(!0) + IL_0015: ret + } + + .method public specialname static bool get_IsMyNone(class TestModule/MyNullableOption`1 A_0) cil managed + { + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: ceq + IL_0004: ret + } + + .method public specialname static bool get_IsMySome(class TestModule/MyNullableOption`1 A_0) cil managed + { + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: cgt.un + IL_0004: ret + } + + .property class TestModule/MyNullableOption`1 + MyNone() + { + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get class TestModule/MyNullableOption`1 TestModule/MyNullableOption`1::get_MyNone() + } + .property instance !T 'value'() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 01 00 00 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance !T TestModule/MyNullableOption`1::get_value() + } + .property bool IsMyNone() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 00 00 00 00 00 00 ) + .get bool TestModule/MyNullableOption`1::get_IsMyNone(class TestModule/MyNullableOption`1) + } + .property bool IsMySome() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 00 00 00 00 00 00 ) + .get bool TestModule/MyNullableOption`1::get_IsMySome(class TestModule/MyNullableOption`1) + } + } + + .class auto autochar serializable sealed nested public beforefieldinit MyOptionWhichCannotHaveNullInTheInside`1 + extends [runtime]System.Object + { + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationRepresentationAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilationRepresentationFlags) = ( 01 00 08 00 00 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoEqualityAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoComparisonAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C + 61 79 28 29 2C 6E 71 7D 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 01 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param type T + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class abstract auto ansi sealed nested public Tags + extends [runtime]System.Object + { + .param type T + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field public static literal int32 MyNotNullNone = int32(0x00000000) + .field public static literal int32 MyNotNullSome = int32(0x00000001) + } + + .field assembly initonly !T _value + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname instance void .ctor() cil managed + { + .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 E0 07 00 00 33 54 65 73 74 4D 6F 64 75 6C + 65 2B 4D 79 4F 70 74 69 6F 6E 57 68 69 63 68 43 + 61 6E 6E 6F 74 48 61 76 65 4E 75 6C 6C 49 6E 54 + 68 65 49 6E 73 69 64 65 60 31 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Object::.ctor() + IL_0006: ret + } + + .method public static class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 get_MyNotNullNone() cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } + + .method public static class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 NewMyNotNullSome(!T _value) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void class TestModule/MyOptionWhichCannotHaveNullInTheInside`1::.ctor(!0) + IL_0006: ret + } + + .method assembly specialname rtspecialname instance void .ctor(!T _value) cil managed + { + .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 33 54 65 73 74 4D 6F 64 75 6C + 65 2B 4D 79 4F 70 74 69 6F 6E 57 68 69 63 68 43 + 61 6E 6E 6F 74 48 61 76 65 4E 75 6C 6C 49 6E 54 + 68 65 49 6E 73 69 64 65 60 31 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld !0 class TestModule/MyOptionWhichCannotHaveNullInTheInside`1::_value + IL_000d: ret + } + + .method public hidebysig instance !T get_value() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld !0 class TestModule/MyOptionWhichCannotHaveNullInTheInside`1::_value + IL_0006: ret + } + + .method public static int32 GetTag(class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 A_0) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: brfalse.s IL_0006 + + IL_0003: ldc.i4.1 + IL_0004: br.s IL_0007 + + IL_0006: ldc.i4.0 + IL_0007: ret + } + + .method assembly hidebysig specialname instance object __DebugDisplay() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+0.8A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,string>::Invoke(!0) + IL_0015: ret + } + + .method public strict virtual instance string ToString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,class TestModule/MyOptionWhichCannotHaveNullInTheInside`1>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,string>::Invoke(!0) + IL_0015: ret + } + + .method public specialname static bool get_IsMyNotNullNone(class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 A_0) cil managed + { + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: ceq + IL_0004: ret + } + + .method public specialname static bool get_IsMyNotNullSome(class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 A_0) cil managed + { + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: cgt.un + IL_0004: ret + } + + .property class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 + MyNotNullNone() + { + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 TestModule/MyOptionWhichCannotHaveNullInTheInside`1::get_MyNotNullNone() + } + .property instance !T 'value'() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 01 00 00 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance !T TestModule/MyOptionWhichCannotHaveNullInTheInside`1::get_value() + } + .property bool IsMyNotNullNone() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 00 00 00 00 00 00 ) + .get bool TestModule/MyOptionWhichCannotHaveNullInTheInside`1::get_IsMyNotNullNone(class TestModule/MyOptionWhichCannotHaveNullInTheInside`1) + } + .property bool IsMyNotNullSome() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 00 00 00 00 00 00 ) + .get bool TestModule/MyOptionWhichCannotHaveNullInTheInside`1::get_IsMyNotNullSome(class TestModule/MyOptionWhichCannotHaveNullInTheInside`1) + } + } + + .method public static class TestModule/MyNullableOption`1 + mapPossiblyNullable(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class TestModule/MyNullableOption`1 myOpt) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + .param type a + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param type b + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 4 + .locals init (class TestModule/MyNullableOption`1 V_0, + class TestModule/MyNullableOption`1 V_1, + !!a V_2) + IL_0000: ldarg.1 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: brfalse.s IL_0007 + + IL_0005: br.s IL_0009 + + IL_0007: ldnull + IL_0008: ret + + IL_0009: ldloc.0 + IL_000a: stloc.1 + IL_000b: ldloc.1 + IL_000c: ldfld !0 class TestModule/MyNullableOption`1::_value + IL_0011: stloc.2 + IL_0012: ldarg.0 + IL_0013: ldloc.2 + IL_0014: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0019: call class TestModule/MyNullableOption`1 class TestModule/MyNullableOption`1::NewMySome(!0) + IL_001e: ret + } + + .method public static class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 + mapNotNullableContents(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 myOpt) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + .param type a + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param type b + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + + .maxstack 4 + .locals init (class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 V_0, + class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 V_1, + !!a V_2) + IL_0000: ldarg.1 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: brfalse.s IL_0007 + + IL_0005: br.s IL_0009 + + IL_0007: ldnull + IL_0008: ret + + IL_0009: ldloc.0 + IL_000a: stloc.1 + IL_000b: ldloc.1 + IL_000c: ldfld !0 class TestModule/MyOptionWhichCannotHaveNullInTheInside`1::_value + IL_0011: stloc.2 + IL_0012: ldarg.0 + IL_0013: ldloc.2 + IL_0014: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0019: call class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 class TestModule/MyOptionWhichCannotHaveNullInTheInside`1::NewMyNotNullSome(!0) + IL_001e: ret + } + +} + +.class private abstract auto ansi sealed ''.$TestModule + extends [runtime]System.Object +{ +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullableInheritance.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullableInheritance.fs new file mode 100644 index 00000000000..19fd926e2fe --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullableInheritance.fs @@ -0,0 +1,24 @@ +module MyTestModule + +open System +open System.Collections.Generic + + +type DerivedWhichAllowsNull() = + inherit ResizeArray() + member x.FirstItem = x[0] + +type DerivedWithoutNull() = + inherit ResizeArray() + member x.FirstItem = x[0] + +type ICanGetAnything<'T> = + abstract member Get : unit -> 'T + +type MyClassImplementingTheSameInterface() = + interface ICanGetAnything with + member x.Get() = null + interface ICanGetAnything>> with + member x.Get() = new ResizeArray<_>() + interface ICanGetAnything | null> with + member x.Get() = null \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullableInheritance.fs.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullableInheritance.fs.il.net472.bsl new file mode 100644 index 00000000000..fbb63d7ff9e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullableInheritance.fs.il.net472.bsl @@ -0,0 +1,275 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public DerivedWhichAllowsNull + extends class [runtime]System.Collections.Generic.List`1 + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 02 00 00 00 01 02 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .method public specialname rtspecialname + instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void class [runtime]System.Collections.Generic.List`1::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method public hidebysig specialname + instance string get_FirstItem() cil managed + { + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + + .maxstack 4 + .locals init (class MyTestModule/DerivedWhichAllowsNull V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldarg.0 + IL_0003: ldc.i4.0 + IL_0004: tail. + IL_0006: callvirt instance !0 class [runtime]System.Collections.Generic.List`1::get_Item(int32) + IL_000b: ret + } + + .property instance string FirstItem() + { + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .get instance string MyTestModule/DerivedWhichAllowsNull::get_FirstItem() + } + } + + .class auto ansi serializable nested public DerivedWithoutNull + extends class [runtime]System.Collections.Generic.List`1 + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .method public specialname rtspecialname + instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void class [runtime]System.Collections.Generic.List`1::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method public hidebysig specialname + instance string get_FirstItem() cil managed + { + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + + .maxstack 4 + .locals init (class MyTestModule/DerivedWithoutNull V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldarg.0 + IL_0003: ldc.i4.0 + IL_0004: tail. + IL_0006: callvirt instance !0 class [runtime]System.Collections.Generic.List`1::get_Item(int32) + IL_000b: ret + } + + .property instance string FirstItem() + { + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .get instance string MyTestModule/DerivedWithoutNull::get_FirstItem() + } + } + + .class interface abstract auto ansi serializable nested public beforefieldinit ICanGetAnything`1 + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param type T + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .method public hidebysig abstract virtual + instance !T Get() cil managed + { + } + + } + + .class auto ansi serializable nested public MyClassImplementingTheSameInterface + extends [runtime]System.Object + implements class MyTestModule/ICanGetAnything`1>, + class MyTestModule/ICanGetAnything`1>>, + class MyTestModule/ICanGetAnything`1 + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .interfaceimpl type class MyTestModule/ICanGetAnything`1> + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 01 02 02 00 00 ) + .interfaceimpl type class MyTestModule/ICanGetAnything`1 + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 02 00 00 00 01 02 00 00 ) + .method public specialname rtspecialname + instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method private hidebysig newslot virtual + instance string 'MyTestModule.ICanGetAnything.Get'() cil managed + { + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .override method instance !0 class MyTestModule/ICanGetAnything`1::Get() + + .maxstack 3 + .locals init (class MyTestModule/MyClassImplementingTheSameInterface V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldnull + IL_0003: ret + } + + .method private hidebysig newslot virtual + instance class [runtime]System.Collections.Generic.List`1> + 'MyTestModule.ICanGetAnything>>.Get'() cil managed + { + .override method instance !0 class MyTestModule/ICanGetAnything`1>>::Get() + + .maxstack 3 + .locals init (class MyTestModule/MyClassImplementingTheSameInterface V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: newobj instance void class [runtime]System.Collections.Generic.List`1>::.ctor() + IL_0007: ret + } + + .method private hidebysig newslot virtual + instance class [runtime]System.Collections.Generic.List`1 + 'MyTestModule.ICanGetAnything>.Get'() cil managed + { + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .override method instance !0 class MyTestModule/ICanGetAnything`1>::Get() + + .maxstack 3 + .locals init (class MyTestModule/MyClassImplementingTheSameInterface V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldnull + IL_0003: ret + } + + } + +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8[] NullableFlags + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname + instance void .ctor(uint8 scalarByteValue) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldc.i4.1 + IL_0008: newarr [runtime]System.Byte + IL_000d: dup + IL_000e: ldc.i4.0 + IL_000f: ldarg.1 + IL_0010: stelem.i1 + IL_0011: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_0016: ret + } + + .method public specialname rtspecialname + instance void .ctor(uint8[] NullableFlags) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_000d: ret + } + +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableContextAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8 Flag + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname + instance void .ctor(uint8 Flag) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8 System.Runtime.CompilerServices.NullableContextAttribute::Flag + IL_000d: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullableInheritance.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullableInheritance.fs.il.netcore.bsl new file mode 100644 index 00000000000..6d3e0775b13 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullableInheritance.fs.il.netcore.bsl @@ -0,0 +1,209 @@ + + + + + +.assembly extern runtime { } +.assembly extern System.Collections +{ + .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) + .ver 8:0:0:0 +} +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public DerivedWhichAllowsNull + extends class [System.Collections]System.Collections.Generic.List`1 + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 02 00 00 00 01 02 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .method public specialname rtspecialname + instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void class [System.Collections]System.Collections.Generic.List`1::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method public hidebysig specialname + instance string get_FirstItem() cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 4 + .locals init (class MyTestModule/DerivedWhichAllowsNull V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldarg.0 + IL_0003: ldc.i4.0 + IL_0004: tail. + IL_0006: callvirt instance !0 class [System.Collections]System.Collections.Generic.List`1::get_Item(int32) + IL_000b: ret + } + + .property instance string FirstItem() + { + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .get instance string MyTestModule/DerivedWhichAllowsNull::get_FirstItem() + } + } + + .class auto ansi serializable nested public DerivedWithoutNull + extends class [System.Collections]System.Collections.Generic.List`1 + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .method public specialname rtspecialname + instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void class [System.Collections]System.Collections.Generic.List`1::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method public hidebysig specialname + instance string get_FirstItem() cil managed + { + + .maxstack 4 + .locals init (class MyTestModule/DerivedWithoutNull V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldarg.0 + IL_0003: ldc.i4.0 + IL_0004: tail. + IL_0006: callvirt instance !0 class [System.Collections]System.Collections.Generic.List`1::get_Item(int32) + IL_000b: ret + } + + .property instance string FirstItem() + { + .get instance string MyTestModule/DerivedWithoutNull::get_FirstItem() + } + } + + .class interface abstract auto ansi serializable nested public beforefieldinit ICanGetAnything`1 + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param type T + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .method public hidebysig abstract virtual + instance !T Get() cil managed + { + } + + } + + .class auto ansi serializable nested public MyClassImplementingTheSameInterface + extends [runtime]System.Object + implements class MyTestModule/ICanGetAnything`1>, + class MyTestModule/ICanGetAnything`1>>, + class MyTestModule/ICanGetAnything`1 + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .interfaceimpl type class MyTestModule/ICanGetAnything`1> + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 01 02 02 00 00 ) + .interfaceimpl type class MyTestModule/ICanGetAnything`1 + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 02 00 00 00 01 02 00 00 ) + .method public specialname rtspecialname + instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method private hidebysig newslot virtual + instance string 'MyTestModule.ICanGetAnything.Get'() cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .override method instance !0 class MyTestModule/ICanGetAnything`1::Get() + + .maxstack 3 + .locals init (class MyTestModule/MyClassImplementingTheSameInterface V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldnull + IL_0003: ret + } + + .method private hidebysig newslot virtual + instance class [System.Collections]System.Collections.Generic.List`1> + 'MyTestModule.ICanGetAnything>>.Get'() cil managed + { + .override method instance !0 class MyTestModule/ICanGetAnything`1>>::Get() + + .maxstack 3 + .locals init (class MyTestModule/MyClassImplementingTheSameInterface V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: newobj instance void class [System.Collections]System.Collections.Generic.List`1>::.ctor() + IL_0007: ret + } + + .method private hidebysig newslot virtual + instance class [System.Collections]System.Collections.Generic.List`1 + 'MyTestModule.ICanGetAnything>.Get'() cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .override method instance !0 class MyTestModule/ICanGetAnything`1>::Get() + + .maxstack 3 + .locals init (class MyTestModule/MyClassImplementingTheSameInterface V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldnull + IL_0003: ret + } + + } + +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullnessMetadata.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullnessMetadata.fs new file mode 100644 index 00000000000..061c6dba9d7 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullnessMetadata.fs @@ -0,0 +1,183 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module EmittedIL.NullnessMetadata + +open Xunit +open FSharp.Test +open FSharp.Test.Compiler + +type Optimize = Optimize | DoNotOptimize + +let verifyCompilation (o:Optimize) compilation = + compilation + |> withLangVersionPreview + |> withOptions ["--checknulls"] + |> (match o with | Optimize -> withOptimize | DoNotOptimize -> withNoOptimize) + |> withNoDebug + |> withNoInterfaceData + |> withNoOptimizationData + |> asLibrary + |> verifyILBaseline + +[] +let ``Nullable attr for module bindings`` compilation = + compilation + |> verifyCompilation DoNotOptimize + +[] +let ``Nullable attr for module functions`` compilation = + compilation + |> verifyCompilation DoNotOptimize + +[] +let ``Nullable attr for module functions optimize`` compilation = + compilation + |> verifyCompilation Optimize + +[] +let ``Nullable attr for curriedFunc optimize`` compilation = + compilation + |> verifyCompilation Optimize + +[] +let ``Nullable attr for anon records`` compilation = + compilation + |> verifyCompilation DoNotOptimize + +[] +let ``Nullable attr for records`` compilation = + compilation + |> verifyCompilation DoNotOptimize + +[] +let ``Nullable attr for ref DUs`` compilation = + compilation + |> verifyCompilation DoNotOptimize + +[] +let ``Nullable attr for struct DUs`` compilation = + compilation + |> verifyCompilation DoNotOptimize + +[] +let ``Nullable attr for custom type`` compilation = + compilation + |> verifyCompilation DoNotOptimize + +[] +let ``Nullable attr for Option clones`` compilation = + compilation + |> verifyCompilation DoNotOptimize + +[] +let ``Generic struct DU`` compilation = + compilation + |> verifyCompilation DoNotOptimize + +[] +let ``Nullable inheritance`` compilation = + compilation + |> verifyCompilation DoNotOptimize + +[] +let ``Custom pipe`` compilation = + compilation + |> verifyCompilation DoNotOptimize + +[] +let ``SupportsNull`` compilation = + compilation + |> withNoWarn 52 + |> verifyCompilation DoNotOptimize + + +module Interop = + open System.IO + + let fsharpLibCreator = + FSharp + >> asLibrary + >> withLangVersionPreview + >> withName "MyFSharpLib" + >> withOptions ["--checknulls"] + + let csharpLibCompile fsLibReference = + CSharp + >> withReferences [fsLibReference] + >> withCSharpLanguageVersion CSharpLanguageVersion.Preview + >> asLibrary + >> withName "CsharpAppConsumingNullness" + >> compile + + let FsharpFromFile filename = + Path.Combine(__SOURCE_DIRECTORY__, filename) + |> File.ReadAllText + |> fsharpLibCreator + + [] + let ``Csharp understands Fsharp-produced struct unions via IsXXX flow analysis`` () = + let csharpCode = """ +#nullable enable +public class C { + public void M() { + var data = MyTestModule.MyStructDU.A; + if(data.IsA){ + string thisMustWarn = data.nonNullableString; + string? thisIsOk = data.nonNullableString; + string? thisIsAlsoOk = data.nullableString; + System.Console.Write(thisMustWarn + thisIsOk + thisIsAlsoOk); + } else if(data.IsB){ + string thisMustBeOK = data.nonNullableString; + System.Console.Write(thisMustBeOK.Length); + } else if (data.IsC){ + string evenThoughItIsC_ThisMustStillFailBecauseFieldIsNullable = data.nullableString; + System.Console.Write(evenThoughItIsC_ThisMustStillFailBecauseFieldIsNullable.Length); + } + + var thisCreationIsBad = MyTestModule.MyStructDU.NewB(null); + var thisCreationIsFine = MyTestModule.MyStructDU.NewC(null); + + System.Console.Write(thisCreationIsBad.ToString() + thisCreationIsFine.ToString() ); + } +}""" + csharpCode + |> csharpLibCompile (FsharpFromFile "StructDU.fs") + |> withDiagnostics [ + Warning 8600, Line 6, Col 35, Line 6, Col 57, "Converting null literal or possible null value to non-nullable type." + Warning 8600, Line 14, Col 78, Line 14, Col 97, "Converting null literal or possible null value to non-nullable type." + Warning 8602, Line 15, Col 34, Line 15, Col 89, "Dereference of a possibly null reference." + Warning 8625, Line 18, Col 62, Line 18, Col 66, "Cannot convert null literal to non-nullable reference type."] + + [] + let ``Csharp code understands Fsharp-produced generics`` () = + let fsharpcode = """ +module MyFSharpLib +let stringTupleInOut(x:struct(string * string|null)) = x """ + let fsLib = fsharpLibCreator fsharpcode + let csharpCode = """ +#nullable enable +public class C { + public void M() { + string? nullString = null; + MyFSharpLib.stringTupleInOut(("a good string here",nullString)); + } +}""" + csharpCode + |> csharpLibCompile fsLib + |> withDiagnostics [] + + [] + let ``Csharp code can work with annotated FSharp module`` () = + Path.Combine(__SOURCE_DIRECTORY__,"CsharpConsumer.cs") + |> File.ReadAllText + |> csharpLibCompile (FsharpFromFile "ModuleLevelFunctions.fs") + |> shouldFail + |> withDiagnostics [ + Error 29, Line 28, Col 20, Line 28, Col 61, "Cannot implicitly convert type 'int' to 'string'" + Warning 8625, Line 12, Col 74, Line 12, Col 78, "Cannot convert null literal to non-nullable reference type." + Warning 8604, Line 14, Col 88, Line 14, Col 113, "Possible null reference argument for parameter 'x' in 'string MyTestModule.nonNullableInputOutputFunc(string x)'." + Warning 8620, Line 19, Col 88, Line 19, Col 101, "Argument of type '(string?, string?, int, int, int, int)' cannot be used for parameter 'x' of type '(string, string?, int, int, int, int)' in '(string, string?, int, int, int, int) MyTestModule.genericValueTypeTest((string, string?, int, int, int, int) x)' due to differences in the nullability of reference types." + Warning 8604, Line 21, Col 84, Line 21, Col 114, "Possible null reference argument for parameter 'x' in 'string MyTestModule.nonNullableInputOutputFunc(string x)'." + Warning 8604, Line 24, Col 60, Line 24, Col 70, "Possible null reference argument for parameter 'x_0' in 'Tuple MyTestModule.genericRefTypeTest(string x_0, string? x_1, int x_2, int x_3, int x_4, int x_5)'." + Warning 8604, Line 25, Col 45, Line 25, Col 59, "Possible null reference argument for parameter 'x_0' in 'Tuple MyTestModule.genericRefTypeTest(string x_0, string? x_1, int x_2, int x_3, int x_4, int x_5)'." + Warning 8625, Line 28, Col 51, Line 28, Col 55, "Cannot convert null literal to non-nullable reference type."] \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/Records.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/Records.fs new file mode 100644 index 00000000000..2a2c7a09b7e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/Records.fs @@ -0,0 +1,25 @@ +module MyTestModule + +let maybeString : string | null = null + +[] +type MyRecord<'X,'Y,'Z when 'Y:null and 'Z:not null> = + { + JustInt : int + NullInt : System.Nullable + JustString : string + NullableString : string | null + GenericNormalField : 'X + GenericNullableField : 'Y + GenericNotNullField : 'Z } + +let createAnInstance () = + { + JustInt = 42 + NullInt = System.Nullable.op_Implicit(42) + JustString = "" + NullableString = null + GenericNormalField = 42 + GenericNullableField = maybeString + GenericNotNullField = ""} + \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/Records.fs.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/Records.fs.il.net472.bsl new file mode 100644 index 00000000000..14108f77f92 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/Records.fs.il.net472.bsl @@ -0,0 +1,449 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class auto ansi serializable sealed nested public beforefieldinit MyRecord`3 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoComparisonAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoEqualityAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 02 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param type X + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .param type Y + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param type Z + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field assembly int32 JustInt@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field assembly valuetype [runtime]System.Nullable`1 NullInt@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field assembly string JustString@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field assembly string NullableString@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .field assembly !X GenericNormalField@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field assembly !Y GenericNullableField@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field assembly !Z GenericNotNullField@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .method public hidebysig specialname instance int32 get_JustInt() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 class MyTestModule/MyRecord`3::JustInt@ + IL_0006: ret + } + + .method public hidebysig specialname + instance valuetype [runtime]System.Nullable`1 + get_NullInt() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld valuetype [runtime]System.Nullable`1 class MyTestModule/MyRecord`3::NullInt@ + IL_0006: ret + } + + .method public hidebysig specialname instance string get_JustString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string class MyTestModule/MyRecord`3::JustString@ + IL_0006: ret + } + + .method public hidebysig specialname instance string get_NullableString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string class MyTestModule/MyRecord`3::NullableString@ + IL_0006: ret + } + + .method public hidebysig specialname instance !X get_GenericNormalField() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld !0 class MyTestModule/MyRecord`3::GenericNormalField@ + IL_0006: ret + } + + .method public hidebysig specialname instance !Y get_GenericNullableField() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld !1 class MyTestModule/MyRecord`3::GenericNullableField@ + IL_0006: ret + } + + .method public hidebysig specialname instance !Z get_GenericNotNullField() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld !2 class MyTestModule/MyRecord`3::GenericNotNullField@ + IL_0006: ret + } + + .method public specialname rtspecialname + instance void .ctor(int32 justInt, + valuetype [runtime]System.Nullable`1 nullInt, + string justString, + string nullableString, + !X genericNormalField, + !Y genericNullableField, + !Z genericNotNullField) cil managed + { + .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 17 4D 79 54 65 73 74 4D 6F 64 + 75 6C 65 2B 4D 79 52 65 63 6F 72 64 60 33 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld int32 class MyTestModule/MyRecord`3::JustInt@ + IL_000d: ldarg.0 + IL_000e: ldarg.2 + IL_000f: stfld valuetype [runtime]System.Nullable`1 class MyTestModule/MyRecord`3::NullInt@ + IL_0014: ldarg.0 + IL_0015: ldarg.3 + IL_0016: stfld string class MyTestModule/MyRecord`3::JustString@ + IL_001b: ldarg.0 + IL_001c: ldarg.s nullableString + IL_001e: stfld string class MyTestModule/MyRecord`3::NullableString@ + IL_0023: ldarg.0 + IL_0024: ldarg.s genericNormalField + IL_0026: stfld !0 class MyTestModule/MyRecord`3::GenericNormalField@ + IL_002b: ldarg.0 + IL_002c: ldarg.s genericNullableField + IL_002e: stfld !1 class MyTestModule/MyRecord`3::GenericNullableField@ + IL_0033: ldarg.0 + IL_0034: ldarg.s genericNotNullField + IL_0036: stfld !2 class MyTestModule/MyRecord`3::GenericNotNullField@ + IL_003b: ret + } + + .method public strict virtual instance string ToString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,class MyTestModule/MyRecord`3>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,string>::Invoke(!0) + IL_0015: ret + } + + .property instance int32 JustInt() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 ) + .get instance int32 MyTestModule/MyRecord`3::get_JustInt() + } + .property instance valuetype [runtime]System.Nullable`1 + NullInt() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 01 00 00 00 00 00 ) + .get instance valuetype [runtime]System.Nullable`1 MyTestModule/MyRecord`3::get_NullInt() + } + .property instance string JustString() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 02 00 00 00 00 00 ) + .get instance string MyTestModule/MyRecord`3::get_JustString() + } + .property instance string NullableString() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 03 00 00 00 00 00 ) + .get instance string MyTestModule/MyRecord`3::get_NullableString() + } + .property instance !X GenericNormalField() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 04 00 00 00 00 00 ) + .get instance !X MyTestModule/MyRecord`3::get_GenericNormalField() + } + .property instance !Y GenericNullableField() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 05 00 00 00 00 00 ) + .get instance !Y MyTestModule/MyRecord`3::get_GenericNullableField() + } + .property instance !Z GenericNotNullField() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 06 00 00 00 00 00 ) + .get instance !Z MyTestModule/MyRecord`3::get_GenericNotNullField() + } + } + + .method public specialname static string get_maybeString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } + + .method public static class MyTestModule/MyRecord`3 createAnInstance() cil managed + { + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 01 02 01 00 00 ) + + .maxstack 9 + IL_0000: ldc.i4.s 42 + IL_0002: ldc.i4.s 42 + IL_0004: call valuetype [runtime]System.Nullable`1 valuetype [runtime]System.Nullable`1::op_Implicit(!0) + IL_0009: ldstr "" + IL_000e: ldnull + IL_000f: ldc.i4.s 42 + IL_0011: call string MyTestModule::get_maybeString() + IL_0016: ldstr "" + IL_001b: newobj instance void class MyTestModule/MyRecord`3::.ctor(int32, + valuetype [runtime]System.Nullable`1, + string, + string, + !0, + !1, + !2) + IL_0020: ret + } + + .property string maybeString() + { + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .get string MyTestModule::get_maybeString() + } +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ +} + +.class private auto ansi serializable sealed System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes + extends [runtime]System.Enum +{ + .custom instance void [runtime]System.FlagsAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field public specialname rtspecialname int32 value__ + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes All = int32(0xFFFFFFFF) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes None = int32(0x00000000) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicParameterlessConstructor = int32(0x00000001) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicConstructors = int32(0x00000003) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicConstructors = int32(0x00000004) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicMethods = int32(0x00000008) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicMethods = int32(0x00000010) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicFields = int32(0x00000020) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicFields = int32(0x00000040) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicNestedTypes = int32(0x00000080) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicNestedTypes = int32(0x00000100) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicProperties = int32(0x00000200) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicProperties = int32(0x00000400) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicEvents = int32(0x00000800) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicEvents = int32(0x00001000) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes Interfaces = int32(0x00002000) +} + +.class private auto ansi beforefieldinit System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MemberType@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field private class [runtime]System.Type Type@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname + instance void .ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MemberType, + class [runtime]System.Type Type) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::MemberType@ + IL_000d: ldarg.0 + IL_000e: ldarg.2 + IL_000f: stfld class [runtime]System.Type System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::Type@ + IL_0014: ret + } + + .method public hidebysig specialname instance class [runtime]System.Type get_Type() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [runtime]System.Type System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::Type@ + IL_0006: ret + } + + .method public hidebysig specialname instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes get_MemberType() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::MemberType@ + IL_0006: ret + } + + .property instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes + MemberType() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::get_MemberType() + } + .property instance class [runtime]System.Type + Type() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance class [runtime]System.Type System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::get_Type() + } +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8[] NullableFlags + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 scalarByteValue) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldc.i4.1 + IL_0008: newarr [runtime]System.Byte + IL_000d: dup + IL_000e: ldc.i4.0 + IL_000f: ldarg.1 + IL_0010: stelem.i1 + IL_0011: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_0016: ret + } + + .method public specialname rtspecialname instance void .ctor(uint8[] NullableFlags) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_000d: ret + } + +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableContextAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8 Flag + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 Flag) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8 System.Runtime.CompilerServices.NullableContextAttribute::Flag + IL_000d: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/Records.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/Records.fs.il.netcore.bsl new file mode 100644 index 00000000000..46f7f58bdc6 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/Records.fs.il.netcore.bsl @@ -0,0 +1,292 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class auto ansi serializable sealed nested public beforefieldinit MyRecord`3 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoComparisonAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoEqualityAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 02 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param type X + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .param type Y + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param type Z + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .field assembly int32 JustInt@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field assembly valuetype [runtime]System.Nullable`1 NullInt@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field assembly string JustString@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field assembly string NullableString@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .field assembly !X GenericNormalField@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field assembly !Y GenericNullableField@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field assembly !Z GenericNotNullField@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .method public hidebysig specialname instance int32 get_JustInt() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 class MyTestModule/MyRecord`3::JustInt@ + IL_0006: ret + } + + .method public hidebysig specialname + instance valuetype [runtime]System.Nullable`1 + get_NullInt() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld valuetype [runtime]System.Nullable`1 class MyTestModule/MyRecord`3::NullInt@ + IL_0006: ret + } + + .method public hidebysig specialname instance string get_JustString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string class MyTestModule/MyRecord`3::JustString@ + IL_0006: ret + } + + .method public hidebysig specialname instance string get_NullableString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string class MyTestModule/MyRecord`3::NullableString@ + IL_0006: ret + } + + .method public hidebysig specialname instance !X get_GenericNormalField() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld !0 class MyTestModule/MyRecord`3::GenericNormalField@ + IL_0006: ret + } + + .method public hidebysig specialname instance !Y get_GenericNullableField() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld !1 class MyTestModule/MyRecord`3::GenericNullableField@ + IL_0006: ret + } + + .method public hidebysig specialname instance !Z get_GenericNotNullField() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld !2 class MyTestModule/MyRecord`3::GenericNotNullField@ + IL_0006: ret + } + + .method public specialname rtspecialname + instance void .ctor(int32 justInt, + valuetype [runtime]System.Nullable`1 nullInt, + string justString, + string nullableString, + !X genericNormalField, + !Y genericNullableField, + !Z genericNotNullField) cil managed + { + .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 17 4D 79 54 65 73 74 4D 6F 64 + 75 6C 65 2B 4D 79 52 65 63 6F 72 64 60 33 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld int32 class MyTestModule/MyRecord`3::JustInt@ + IL_000d: ldarg.0 + IL_000e: ldarg.2 + IL_000f: stfld valuetype [runtime]System.Nullable`1 class MyTestModule/MyRecord`3::NullInt@ + IL_0014: ldarg.0 + IL_0015: ldarg.3 + IL_0016: stfld string class MyTestModule/MyRecord`3::JustString@ + IL_001b: ldarg.0 + IL_001c: ldarg.s nullableString + IL_001e: stfld string class MyTestModule/MyRecord`3::NullableString@ + IL_0023: ldarg.0 + IL_0024: ldarg.s genericNormalField + IL_0026: stfld !0 class MyTestModule/MyRecord`3::GenericNormalField@ + IL_002b: ldarg.0 + IL_002c: ldarg.s genericNullableField + IL_002e: stfld !1 class MyTestModule/MyRecord`3::GenericNullableField@ + IL_0033: ldarg.0 + IL_0034: ldarg.s genericNotNullField + IL_0036: stfld !2 class MyTestModule/MyRecord`3::GenericNotNullField@ + IL_003b: ret + } + + .method public strict virtual instance string ToString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,class MyTestModule/MyRecord`3>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,string>::Invoke(!0) + IL_0015: ret + } + + .property instance int32 JustInt() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 ) + .get instance int32 MyTestModule/MyRecord`3::get_JustInt() + } + .property instance valuetype [runtime]System.Nullable`1 + NullInt() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 01 00 00 00 00 00 ) + .get instance valuetype [runtime]System.Nullable`1 MyTestModule/MyRecord`3::get_NullInt() + } + .property instance string JustString() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 02 00 00 00 00 00 ) + .get instance string MyTestModule/MyRecord`3::get_JustString() + } + .property instance string NullableString() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 03 00 00 00 00 00 ) + .get instance string MyTestModule/MyRecord`3::get_NullableString() + } + .property instance !X GenericNormalField() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 04 00 00 00 00 00 ) + .get instance !X MyTestModule/MyRecord`3::get_GenericNormalField() + } + .property instance !Y GenericNullableField() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 05 00 00 00 00 00 ) + .get instance !Y MyTestModule/MyRecord`3::get_GenericNullableField() + } + .property instance !Z GenericNotNullField() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 06 00 00 00 00 00 ) + .get instance !Z MyTestModule/MyRecord`3::get_GenericNotNullField() + } + } + + .method public specialname static string get_maybeString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } + + .method public static class MyTestModule/MyRecord`3 createAnInstance() cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 01 02 01 00 00 ) + + .maxstack 9 + IL_0000: ldc.i4.s 42 + IL_0002: ldc.i4.s 42 + IL_0004: call valuetype [runtime]System.Nullable`1 valuetype [runtime]System.Nullable`1::op_Implicit(!0) + IL_0009: ldstr "" + IL_000e: ldnull + IL_000f: ldc.i4.s 42 + IL_0011: call string MyTestModule::get_maybeString() + IL_0016: ldstr "" + IL_001b: newobj instance void class MyTestModule/MyRecord`3::.ctor(int32, + valuetype [runtime]System.Nullable`1, + string, + string, + !0, + !1, + !2) + IL_0020: ret + } + + .property string maybeString() + { + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .get string MyTestModule::get_maybeString() + } +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ReferenceDU.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ReferenceDU.fs new file mode 100644 index 00000000000..01c56c32109 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ReferenceDU.fs @@ -0,0 +1,18 @@ +module MyTestModule + +[] +type MyDu = + | JustLabel + | JustInt of int + | MaybeString of (string | null) + +let giveMeLabel () = JustLabel + +let createMaybeString (innerValue:string|null) = MaybeString innerValue + +let processNullableDu (x : (MyDu | null)) : string | null = + match x with + | null -> null + | JustLabel -> null + | JustInt x -> string x + | MaybeString x -> x \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ReferenceDU.fs.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ReferenceDU.fs.il.net472.bsl new file mode 100644 index 00000000000..0a8ff69084c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ReferenceDU.fs.il.net472.bsl @@ -0,0 +1,747 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) + .ver 2:1:0:0 +} +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class abstract auto autochar serializable nested public beforefieldinit MyDu + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoComparisonAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoEqualityAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C + 61 79 28 29 2C 6E 71 7D 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 01 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class abstract auto ansi sealed nested public Tags + extends [runtime]System.Object + { + .field public static literal int32 JustLabel = int32(0x00000000) + .field public static literal int32 JustInt = int32(0x00000001) + .field public static literal int32 MaybeString = int32(0x00000002) + } + + .class auto ansi serializable nested assembly beforefieldinit specialname _JustLabel + extends MyTestModule/MyDu + { + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerTypeProxyAttribute::.ctor(class [runtime]System.Type) = ( 01 00 2B 4D 79 54 65 73 74 4D 6F 64 75 6C 65 2B + 4D 79 44 75 2B 5F 4A 75 73 74 4C 61 62 65 6C 40 + 44 65 62 75 67 54 79 70 65 50 72 6F 78 79 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C + 61 79 28 29 2C 6E 71 7D 00 00 ) + .method assembly specialname rtspecialname instance void .ctor() cil managed + { + .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 11 4D 79 54 65 73 74 4D 6F 64 + 75 6C 65 2B 4D 79 44 75 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void MyTestModule/MyDu::.ctor() + IL_0006: ret + } + + } + + .class auto ansi serializable nested public beforefieldinit specialname JustInt + extends MyTestModule/MyDu + { + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerTypeProxyAttribute::.ctor(class [runtime]System.Type) = ( 01 00 28 4D 79 54 65 73 74 4D 6F 64 75 6C 65 2B + 4D 79 44 75 2B 4A 75 73 74 49 6E 74 40 44 65 62 + 75 67 54 79 70 65 50 72 6F 78 79 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C + 61 79 28 29 2C 6E 71 7D 00 00 ) + .field assembly initonly int32 item + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname instance void .ctor(int32 item) cil managed + { + .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 11 4D 79 54 65 73 74 4D 6F 64 + 75 6C 65 2B 4D 79 44 75 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void MyTestModule/MyDu::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld int32 MyTestModule/MyDu/JustInt::item + IL_000d: ret + } + + .method public hidebysig instance int32 get_Item() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 MyTestModule/MyDu/JustInt::item + IL_0006: ret + } + + .property instance int32 Item() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 01 00 00 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance int32 MyTestModule/MyDu/JustInt::get_Item() + } + } + + .class auto ansi serializable nested public beforefieldinit specialname MaybeString + extends MyTestModule/MyDu + { + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerTypeProxyAttribute::.ctor(class [runtime]System.Type) = ( 01 00 2C 4D 79 54 65 73 74 4D 6F 64 75 6C 65 2B + 4D 79 44 75 2B 4D 61 79 62 65 53 74 72 69 6E 67 + 40 44 65 62 75 67 54 79 70 65 50 72 6F 78 79 00 + 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C + 61 79 28 29 2C 6E 71 7D 00 00 ) + .field assembly initonly string item + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname instance void .ctor(string item) cil managed + { + .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 11 4D 79 54 65 73 74 4D 6F 64 + 75 6C 65 2B 4D 79 44 75 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void MyTestModule/MyDu::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld string MyTestModule/MyDu/MaybeString::item + IL_000d: ret + } + + .method public hidebysig instance string get_Item() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string MyTestModule/MyDu/MaybeString::item + IL_0006: ret + } + + .property instance string Item() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 02 00 00 00 00 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance string MyTestModule/MyDu/MaybeString::get_Item() + } + } + + .class auto ansi nested assembly beforefieldinit specialname _JustLabel@DebugTypeProxy + extends [runtime]System.Object + { + .field assembly class MyTestModule/MyDu/_JustLabel _obj + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(class MyTestModule/MyDu/_JustLabel obj) cil managed + { + .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 11 4D 79 54 65 73 74 4D 6F 64 + 75 6C 65 2B 4D 79 44 75 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld class MyTestModule/MyDu/_JustLabel MyTestModule/MyDu/_JustLabel@DebugTypeProxy::_obj + IL_000d: ret + } + + } + + .class auto ansi nested assembly beforefieldinit specialname JustInt@DebugTypeProxy + extends [runtime]System.Object + { + .field assembly class MyTestModule/MyDu/JustInt _obj + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(class MyTestModule/MyDu/JustInt obj) cil managed + { + .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 11 4D 79 54 65 73 74 4D 6F 64 + 75 6C 65 2B 4D 79 44 75 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld class MyTestModule/MyDu/JustInt MyTestModule/MyDu/JustInt@DebugTypeProxy::_obj + IL_000d: ret + } + + .method public hidebysig instance int32 get_Item() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class MyTestModule/MyDu/JustInt MyTestModule/MyDu/JustInt@DebugTypeProxy::_obj + IL_0006: ldfld int32 MyTestModule/MyDu/JustInt::item + IL_000b: ret + } + + .property instance int32 Item() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 01 00 00 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance int32 MyTestModule/MyDu/JustInt@DebugTypeProxy::get_Item() + } + } + + .class auto ansi nested assembly beforefieldinit specialname MaybeString@DebugTypeProxy + extends [runtime]System.Object + { + .field assembly class MyTestModule/MyDu/MaybeString _obj + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(class MyTestModule/MyDu/MaybeString obj) cil managed + { + .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 11 4D 79 54 65 73 74 4D 6F 64 + 75 6C 65 2B 4D 79 44 75 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld class MyTestModule/MyDu/MaybeString MyTestModule/MyDu/MaybeString@DebugTypeProxy::_obj + IL_000d: ret + } + + .method public hidebysig instance string get_Item() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class MyTestModule/MyDu/MaybeString MyTestModule/MyDu/MaybeString@DebugTypeProxy::_obj + IL_0006: ldfld string MyTestModule/MyDu/MaybeString::item + IL_000b: ret + } + + .property instance string Item() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 02 00 00 00 00 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance string MyTestModule/MyDu/MaybeString@DebugTypeProxy::get_Item() + } + } + + .field static assembly initonly class MyTestModule/MyDu _unique_JustLabel + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method private specialname rtspecialname static void .cctor() cil managed + { + + .maxstack 8 + IL_0000: newobj instance void MyTestModule/MyDu/_JustLabel::.ctor() + IL_0005: stsfld class MyTestModule/MyDu MyTestModule/MyDu::_unique_JustLabel + IL_000a: ret + } + + .method assembly specialname rtspecialname instance void .ctor() cil managed + { + .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 E0 07 00 00 11 4D 79 54 65 73 74 4D 6F 64 + 75 6C 65 2B 4D 79 44 75 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Object::.ctor() + IL_0006: ret + } + + .method public static class MyTestModule/MyDu get_JustLabel() cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldsfld class MyTestModule/MyDu MyTestModule/MyDu::_unique_JustLabel + IL_0005: ret + } + + .method public hidebysig instance bool get_IsJustLabel() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: isinst MyTestModule/MyDu/_JustLabel + IL_0006: ldnull + IL_0007: cgt.un + IL_0009: ret + } + + .method public static class MyTestModule/MyDu NewJustInt(int32 item) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void MyTestModule/MyDu/JustInt::.ctor(int32) + IL_0006: ret + } + + .method public hidebysig instance bool get_IsJustInt() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: isinst MyTestModule/MyDu/JustInt + IL_0006: ldnull + IL_0007: cgt.un + IL_0009: ret + } + + .method public static class MyTestModule/MyDu NewMaybeString(string item) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 02 00 00 00 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void MyTestModule/MyDu/MaybeString::.ctor(string) + IL_0006: ret + } + + .method public hidebysig instance bool get_IsMaybeString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: isinst MyTestModule/MyDu/MaybeString + IL_0006: ldnull + IL_0007: cgt.un + IL_0009: ret + } + + .method public hidebysig instance int32 get_Tag() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: isinst MyTestModule/MyDu/MaybeString + IL_0006: brfalse.s IL_000b + + IL_0008: ldc.i4.2 + IL_0009: br.s IL_0017 + + IL_000b: ldarg.0 + IL_000c: isinst MyTestModule/MyDu/JustInt + IL_0011: brfalse.s IL_0016 + + IL_0013: ldc.i4.1 + IL_0014: br.s IL_0017 + + IL_0016: ldc.i4.0 + IL_0017: ret + } + + .method assembly hidebysig specialname instance object __DebugDisplay() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+0.8A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0015: ret + } + + .method public strict virtual instance string ToString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,class MyTestModule/MyDu>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0015: ret + } + + .property instance int32 Tag() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance int32 MyTestModule/MyDu::get_Tag() + } + .property class MyTestModule/MyDu JustLabel() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get class MyTestModule/MyDu MyTestModule/MyDu::get_JustLabel() + } + .property instance bool IsJustLabel() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance bool MyTestModule/MyDu::get_IsJustLabel() + } + .property instance bool IsJustInt() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance bool MyTestModule/MyDu::get_IsJustInt() + } + .property instance bool IsMaybeString() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance bool MyTestModule/MyDu::get_IsMaybeString() + } + } + + .method public static class MyTestModule/MyDu giveMeLabel() cil managed + { + + .maxstack 8 + IL_0000: call class MyTestModule/MyDu MyTestModule/MyDu::get_JustLabel() + IL_0005: ret + } + + .method public static class MyTestModule/MyDu createMaybeString(string innerValue) cil managed + { + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call class MyTestModule/MyDu MyTestModule/MyDu::NewMaybeString(string) + IL_0006: ret + } + + .method public static string processNullableDu(class MyTestModule/MyDu x) cil managed + { + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 5 + .locals init (class MyTestModule/MyDu V_0, + class MyTestModule/MyDu V_1, + class MyTestModule/MyDu/JustInt V_2, + int32 V_3, + int32 V_4, + class MyTestModule/MyDu/MaybeString V_5, + string V_6) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: brfalse.s IL_0019 + + IL_0005: ldloc.0 + IL_0006: stloc.1 + IL_0007: ldloc.1 + IL_0008: isinst MyTestModule/MyDu/JustInt + IL_000d: brtrue.s IL_001d + + IL_000f: ldloc.1 + IL_0010: isinst MyTestModule/MyDu/MaybeString + IL_0015: brtrue.s IL_0048 + + IL_0017: br.s IL_001b + + IL_0019: ldnull + IL_001a: ret + + IL_001b: ldnull + IL_001c: ret + + IL_001d: ldloc.0 + IL_001e: castclass MyTestModule/MyDu/JustInt + IL_0023: stloc.2 + IL_0024: ldloc.2 + IL_0025: ldfld int32 MyTestModule/MyDu/JustInt::item + IL_002a: stloc.3 + IL_002b: ldloc.3 + IL_002c: stloc.s V_4 + IL_002e: ldloc.s V_4 + IL_0030: box [runtime]System.Int32 + IL_0035: unbox.any [runtime]System.IFormattable + IL_003a: ldnull + IL_003b: call class [netstandard]System.Globalization.CultureInfo [netstandard]System.Globalization.CultureInfo::get_InvariantCulture() + IL_0040: tail. + IL_0042: callvirt instance string [netstandard]System.IFormattable::ToString(string, + class [netstandard]System.IFormatProvider) + IL_0047: ret + + IL_0048: ldloc.0 + IL_0049: castclass MyTestModule/MyDu/MaybeString + IL_004e: stloc.s V_5 + IL_0050: ldloc.s V_5 + IL_0052: ldfld string MyTestModule/MyDu/MaybeString::item + IL_0057: stloc.s V_6 + IL_0059: ldloc.s V_6 + IL_005b: ret + } + +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ +} + +.class private auto ansi serializable sealed System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes + extends [runtime]System.Enum +{ + .custom instance void [runtime]System.FlagsAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field public specialname rtspecialname int32 value__ + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes All = int32(0xFFFFFFFF) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes None = int32(0x00000000) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicParameterlessConstructor = int32(0x00000001) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicConstructors = int32(0x00000003) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicConstructors = int32(0x00000004) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicMethods = int32(0x00000008) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicMethods = int32(0x00000010) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicFields = int32(0x00000020) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicFields = int32(0x00000040) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicNestedTypes = int32(0x00000080) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicNestedTypes = int32(0x00000100) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicProperties = int32(0x00000200) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicProperties = int32(0x00000400) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicEvents = int32(0x00000800) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicEvents = int32(0x00001000) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes Interfaces = int32(0x00002000) +} + +.class private auto ansi beforefieldinit System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MemberType@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field private class [runtime]System.Type Type@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname + instance void .ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MemberType, + class [runtime]System.Type Type) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::MemberType@ + IL_000d: ldarg.0 + IL_000e: ldarg.2 + IL_000f: stfld class [runtime]System.Type System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::Type@ + IL_0014: ret + } + + .method public hidebysig specialname instance class [runtime]System.Type get_Type() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [runtime]System.Type System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::Type@ + IL_0006: ret + } + + .method public hidebysig specialname instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes get_MemberType() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::MemberType@ + IL_0006: ret + } + + .property instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes + MemberType() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::get_MemberType() + } + .property instance class [runtime]System.Type + Type() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance class [runtime]System.Type System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::get_Type() + } +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8[] NullableFlags + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 scalarByteValue) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldc.i4.1 + IL_0008: newarr [runtime]System.Byte + IL_000d: dup + IL_000e: ldc.i4.0 + IL_000f: ldarg.1 + IL_0010: stelem.i1 + IL_0011: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_0016: ret + } + + .method public specialname rtspecialname instance void .ctor(uint8[] NullableFlags) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_000d: ret + } + +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableContextAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8 Flag + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 Flag) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8 System.Runtime.CompilerServices.NullableContextAttribute::Flag + IL_000d: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ReferenceDU.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ReferenceDU.fs.il.netcore.bsl new file mode 100644 index 00000000000..c946d58421f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ReferenceDU.fs.il.netcore.bsl @@ -0,0 +1,590 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) + .ver 2:1:0:0 +} +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class abstract auto autochar serializable nested public beforefieldinit MyDu + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoComparisonAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoEqualityAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C + 61 79 28 29 2C 6E 71 7D 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 01 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class abstract auto ansi sealed nested public Tags + extends [runtime]System.Object + { + .field public static literal int32 JustLabel = int32(0x00000000) + .field public static literal int32 JustInt = int32(0x00000001) + .field public static literal int32 MaybeString = int32(0x00000002) + } + + .class auto ansi serializable nested assembly beforefieldinit specialname _JustLabel + extends MyTestModule/MyDu + { + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerTypeProxyAttribute::.ctor(class [runtime]System.Type) = ( 01 00 2B 4D 79 54 65 73 74 4D 6F 64 75 6C 65 2B + 4D 79 44 75 2B 5F 4A 75 73 74 4C 61 62 65 6C 40 + 44 65 62 75 67 54 79 70 65 50 72 6F 78 79 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C + 61 79 28 29 2C 6E 71 7D 00 00 ) + .method assembly specialname rtspecialname instance void .ctor() cil managed + { + .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 11 4D 79 54 65 73 74 4D 6F 64 + 75 6C 65 2B 4D 79 44 75 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void MyTestModule/MyDu::.ctor() + IL_0006: ret + } + + } + + .class auto ansi serializable nested public beforefieldinit specialname JustInt + extends MyTestModule/MyDu + { + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerTypeProxyAttribute::.ctor(class [runtime]System.Type) = ( 01 00 28 4D 79 54 65 73 74 4D 6F 64 75 6C 65 2B + 4D 79 44 75 2B 4A 75 73 74 49 6E 74 40 44 65 62 + 75 67 54 79 70 65 50 72 6F 78 79 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C + 61 79 28 29 2C 6E 71 7D 00 00 ) + .field assembly initonly int32 item + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname instance void .ctor(int32 item) cil managed + { + .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 11 4D 79 54 65 73 74 4D 6F 64 + 75 6C 65 2B 4D 79 44 75 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void MyTestModule/MyDu::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld int32 MyTestModule/MyDu/JustInt::item + IL_000d: ret + } + + .method public hidebysig instance int32 get_Item() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 MyTestModule/MyDu/JustInt::item + IL_0006: ret + } + + .property instance int32 Item() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 01 00 00 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance int32 MyTestModule/MyDu/JustInt::get_Item() + } + } + + .class auto ansi serializable nested public beforefieldinit specialname MaybeString + extends MyTestModule/MyDu + { + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerTypeProxyAttribute::.ctor(class [runtime]System.Type) = ( 01 00 2C 4D 79 54 65 73 74 4D 6F 64 75 6C 65 2B + 4D 79 44 75 2B 4D 61 79 62 65 53 74 72 69 6E 67 + 40 44 65 62 75 67 54 79 70 65 50 72 6F 78 79 00 + 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C + 61 79 28 29 2C 6E 71 7D 00 00 ) + .field assembly initonly string item + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname instance void .ctor(string item) cil managed + { + .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 11 4D 79 54 65 73 74 4D 6F 64 + 75 6C 65 2B 4D 79 44 75 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void MyTestModule/MyDu::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld string MyTestModule/MyDu/MaybeString::item + IL_000d: ret + } + + .method public hidebysig instance string get_Item() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string MyTestModule/MyDu/MaybeString::item + IL_0006: ret + } + + .property instance string Item() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 02 00 00 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance string MyTestModule/MyDu/MaybeString::get_Item() + } + } + + .class auto ansi nested assembly beforefieldinit specialname _JustLabel@DebugTypeProxy + extends [runtime]System.Object + { + .field assembly class MyTestModule/MyDu/_JustLabel _obj + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(class MyTestModule/MyDu/_JustLabel obj) cil managed + { + .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 11 4D 79 54 65 73 74 4D 6F 64 + 75 6C 65 2B 4D 79 44 75 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld class MyTestModule/MyDu/_JustLabel MyTestModule/MyDu/_JustLabel@DebugTypeProxy::_obj + IL_000d: ret + } + + } + + .class auto ansi nested assembly beforefieldinit specialname JustInt@DebugTypeProxy + extends [runtime]System.Object + { + .field assembly class MyTestModule/MyDu/JustInt _obj + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(class MyTestModule/MyDu/JustInt obj) cil managed + { + .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 11 4D 79 54 65 73 74 4D 6F 64 + 75 6C 65 2B 4D 79 44 75 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld class MyTestModule/MyDu/JustInt MyTestModule/MyDu/JustInt@DebugTypeProxy::_obj + IL_000d: ret + } + + .method public hidebysig instance int32 get_Item() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class MyTestModule/MyDu/JustInt MyTestModule/MyDu/JustInt@DebugTypeProxy::_obj + IL_0006: ldfld int32 MyTestModule/MyDu/JustInt::item + IL_000b: ret + } + + .property instance int32 Item() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 01 00 00 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance int32 MyTestModule/MyDu/JustInt@DebugTypeProxy::get_Item() + } + } + + .class auto ansi nested assembly beforefieldinit specialname MaybeString@DebugTypeProxy + extends [runtime]System.Object + { + .field assembly class MyTestModule/MyDu/MaybeString _obj + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(class MyTestModule/MyDu/MaybeString obj) cil managed + { + .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 11 4D 79 54 65 73 74 4D 6F 64 + 75 6C 65 2B 4D 79 44 75 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld class MyTestModule/MyDu/MaybeString MyTestModule/MyDu/MaybeString@DebugTypeProxy::_obj + IL_000d: ret + } + + .method public hidebysig instance string get_Item() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class MyTestModule/MyDu/MaybeString MyTestModule/MyDu/MaybeString@DebugTypeProxy::_obj + IL_0006: ldfld string MyTestModule/MyDu/MaybeString::item + IL_000b: ret + } + + .property instance string Item() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 02 00 00 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance string MyTestModule/MyDu/MaybeString@DebugTypeProxy::get_Item() + } + } + + .field static assembly initonly class MyTestModule/MyDu _unique_JustLabel + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method private specialname rtspecialname static void .cctor() cil managed + { + + .maxstack 8 + IL_0000: newobj instance void MyTestModule/MyDu/_JustLabel::.ctor() + IL_0005: stsfld class MyTestModule/MyDu MyTestModule/MyDu::_unique_JustLabel + IL_000a: ret + } + + .method assembly specialname rtspecialname instance void .ctor() cil managed + { + .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 E0 07 00 00 11 4D 79 54 65 73 74 4D 6F 64 + 75 6C 65 2B 4D 79 44 75 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Object::.ctor() + IL_0006: ret + } + + .method public static class MyTestModule/MyDu get_JustLabel() cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldsfld class MyTestModule/MyDu MyTestModule/MyDu::_unique_JustLabel + IL_0005: ret + } + + .method public hidebysig instance bool get_IsJustLabel() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: isinst MyTestModule/MyDu/_JustLabel + IL_0006: ldnull + IL_0007: cgt.un + IL_0009: ret + } + + .method public static class MyTestModule/MyDu NewJustInt(int32 item) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void MyTestModule/MyDu/JustInt::.ctor(int32) + IL_0006: ret + } + + .method public hidebysig instance bool get_IsJustInt() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: isinst MyTestModule/MyDu/JustInt + IL_0006: ldnull + IL_0007: cgt.un + IL_0009: ret + } + + .method public static class MyTestModule/MyDu NewMaybeString(string item) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 02 00 00 00 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void MyTestModule/MyDu/MaybeString::.ctor(string) + IL_0006: ret + } + + .method public hidebysig instance bool get_IsMaybeString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: isinst MyTestModule/MyDu/MaybeString + IL_0006: ldnull + IL_0007: cgt.un + IL_0009: ret + } + + .method public hidebysig instance int32 get_Tag() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: isinst MyTestModule/MyDu/MaybeString + IL_0006: brfalse.s IL_000b + + IL_0008: ldc.i4.2 + IL_0009: br.s IL_0017 + + IL_000b: ldarg.0 + IL_000c: isinst MyTestModule/MyDu/JustInt + IL_0011: brfalse.s IL_0016 + + IL_0013: ldc.i4.1 + IL_0014: br.s IL_0017 + + IL_0016: ldc.i4.0 + IL_0017: ret + } + + .method assembly hidebysig specialname instance object __DebugDisplay() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+0.8A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0015: ret + } + + .method public strict virtual instance string ToString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,class MyTestModule/MyDu>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0015: ret + } + + .property instance int32 Tag() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance int32 MyTestModule/MyDu::get_Tag() + } + .property class MyTestModule/MyDu JustLabel() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get class MyTestModule/MyDu MyTestModule/MyDu::get_JustLabel() + } + .property instance bool IsJustLabel() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance bool MyTestModule/MyDu::get_IsJustLabel() + } + .property instance bool IsJustInt() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance bool MyTestModule/MyDu::get_IsJustInt() + } + .property instance bool IsMaybeString() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance bool MyTestModule/MyDu::get_IsMaybeString() + } + } + + .method public static class MyTestModule/MyDu giveMeLabel() cil managed + { + + .maxstack 8 + IL_0000: call class MyTestModule/MyDu MyTestModule/MyDu::get_JustLabel() + IL_0005: ret + } + + .method public static class MyTestModule/MyDu createMaybeString(string innerValue) cil managed + { + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call class MyTestModule/MyDu MyTestModule/MyDu::NewMaybeString(string) + IL_0006: ret + } + + .method public static string processNullableDu(class MyTestModule/MyDu x) cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 5 + .locals init (class MyTestModule/MyDu V_0, + class MyTestModule/MyDu V_1, + class MyTestModule/MyDu/JustInt V_2, + int32 V_3, + int32 V_4, + class MyTestModule/MyDu/MaybeString V_5, + string V_6) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: brfalse.s IL_0019 + + IL_0005: ldloc.0 + IL_0006: stloc.1 + IL_0007: ldloc.1 + IL_0008: isinst MyTestModule/MyDu/JustInt + IL_000d: brtrue.s IL_001d + + IL_000f: ldloc.1 + IL_0010: isinst MyTestModule/MyDu/MaybeString + IL_0015: brtrue.s IL_0048 + + IL_0017: br.s IL_001b + + IL_0019: ldnull + IL_001a: ret + + IL_001b: ldnull + IL_001c: ret + + IL_001d: ldloc.0 + IL_001e: castclass MyTestModule/MyDu/JustInt + IL_0023: stloc.2 + IL_0024: ldloc.2 + IL_0025: ldfld int32 MyTestModule/MyDu/JustInt::item + IL_002a: stloc.3 + IL_002b: ldloc.3 + IL_002c: stloc.s V_4 + IL_002e: ldloc.s V_4 + IL_0030: box [runtime]System.Int32 + IL_0035: unbox.any [runtime]System.IFormattable + IL_003a: ldnull + IL_003b: call class [netstandard]System.Globalization.CultureInfo [netstandard]System.Globalization.CultureInfo::get_InvariantCulture() + IL_0040: tail. + IL_0042: callvirt instance string [netstandard]System.IFormattable::ToString(string, + class [netstandard]System.IFormatProvider) + IL_0047: ret + + IL_0048: ldloc.0 + IL_0049: castclass MyTestModule/MyDu/MaybeString + IL_004e: stloc.s V_5 + IL_0050: ldloc.s V_5 + IL_0052: ldfld string MyTestModule/MyDu/MaybeString::item + IL_0057: stloc.s V_6 + IL_0059: ldloc.s V_6 + IL_005b: ret + } + +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/StructDU.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/StructDU.fs new file mode 100644 index 00000000000..2571094f73f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/StructDU.fs @@ -0,0 +1,13 @@ +module MyTestModule + +[] +[] +type MyStructDU = + | A + | B of nonNullableString:string // Tricky as the field WILL be null for tags other than B + | C of nullableString:(string | null) // The field behind this is always nullable + +let getVal x = + match x with + | C text -> text + | _ -> failwith "fail" \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/StructDU.fs.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/StructDU.fs.il.net472.bsl new file mode 100644 index 00000000000..83c9e539fa5 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/StructDU.fs.il.net472.bsl @@ -0,0 +1,578 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class sequential autochar serializable sealed nested public beforefieldinit Myassembly + extends [runtime]System.ValueType + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoComparisonAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoEqualityAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.StructAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C + 61 79 28 29 2C 6E 71 7D 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 01 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class abstract auto ansi sealed nested public Tags + extends [runtime]System.Object + { + .field public static literal int32 A = int32(0x00000000) + .field public static literal int32 B = int32(0x00000001) + .field public static literal int32 C = int32(0x00000002) + } + + .field assembly string _nonNullableString + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field assembly string _nullableString + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field assembly int32 _tag + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public static valuetype MyTestModule/Myassembly + get_A() cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: newobj instance void MyTestModule/Myassembly::.ctor(int32) + IL_0006: ret + } + + .method public hidebysig instance bool + get_IsA() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance int32 MyTestModule/Myassembly::get_Tag() + IL_0006: ldc.i4.0 + IL_0007: ceq + IL_0009: ret + } + + .method public static valuetype MyTestModule/Myassembly + NewB(string _nonNullableString) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 01 00 00 00 00 00 ) + + .maxstack 2 + .locals init (valuetype MyTestModule/Myassembly V_0) + IL_0000: ldloca.s V_0 + IL_0002: initobj MyTestModule/Myassembly + IL_0008: ldloca.s V_0 + IL_000a: ldc.i4.1 + IL_000b: stfld int32 MyTestModule/Myassembly::_tag + IL_0010: ldloca.s V_0 + IL_0012: ldarg.0 + IL_0013: stfld string MyTestModule/Myassembly::_nonNullableString + IL_0018: ldloc.0 + IL_0019: ret + } + + .method public hidebysig instance bool + get_IsB() cil managed + { + .custom instance void System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::.ctor(bool, + string[]) = ( 01 00 01 02 00 00 00 11 6E 6F 6E 4E 75 6C 6C 61 + 62 6C 65 53 74 72 69 6E 67 12 5F 6E 6F 6E 4E 75 + 6C 6C 61 62 6C 65 53 74 72 69 6E 67 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance int32 MyTestModule/Myassembly::get_Tag() + IL_0006: ldc.i4.1 + IL_0007: ceq + IL_0009: ret + } + + .method public static valuetype MyTestModule/Myassembly + NewC(string _nullableString) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 02 00 00 00 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 2 + .locals init (valuetype MyTestModule/Myassembly V_0) + IL_0000: ldloca.s V_0 + IL_0002: initobj MyTestModule/Myassembly + IL_0008: ldloca.s V_0 + IL_000a: ldc.i4.2 + IL_000b: stfld int32 MyTestModule/Myassembly::_tag + IL_0010: ldloca.s V_0 + IL_0012: ldarg.0 + IL_0013: stfld string MyTestModule/Myassembly::_nullableString + IL_0018: ldloc.0 + IL_0019: ret + } + + .method public hidebysig instance bool + get_IsC() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance int32 MyTestModule/Myassembly::get_Tag() + IL_0006: ldc.i4.2 + IL_0007: ceq + IL_0009: ret + } + + .method assembly specialname rtspecialname + instance void .ctor(int32 _tag) cil managed + { + .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 17 4D 79 54 65 73 74 4D 6F 64 + 75 6C 65 2B 4D 79 53 74 72 75 63 74 44 55 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 MyTestModule/Myassembly::_tag + IL_0007: ret + } + + .method public hidebysig instance string + get_nonNullableString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string MyTestModule/Myassembly::_nonNullableString + IL_0006: ret + } + + .method public hidebysig instance string + get_nullableString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string MyTestModule/Myassembly::_nullableString + IL_0006: ret + } + + .method public hidebysig instance int32 + get_Tag() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 MyTestModule/Myassembly::_tag + IL_0006: ret + } + + .method assembly hidebysig specialname + instance object __DebugDisplay() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+0.8A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: ldobj MyTestModule/Myassembly + IL_0015: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001a: ret + } + + .method public strict virtual instance string + ToString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,valuetype MyTestModule/Myassembly>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: ldobj MyTestModule/Myassembly + IL_0015: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001a: ret + } + + .property instance int32 Tag() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance int32 MyTestModule/Myassembly::get_Tag() + } + .property valuetype MyTestModule/Myassembly + A() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get valuetype MyTestModule/Myassembly MyTestModule/Myassembly::get_A() + } + .property instance bool IsA() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance bool MyTestModule/Myassembly::get_IsA() + } + .property instance bool IsB() + { + .custom instance void System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::.ctor(bool, + string[]) = ( 01 00 01 02 00 00 00 11 6E 6F 6E 4E 75 6C 6C 61 + 62 6C 65 53 74 72 69 6E 67 12 5F 6E 6F 6E 4E 75 + 6C 6C 61 62 6C 65 53 74 72 69 6E 67 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance bool MyTestModule/Myassembly::get_IsB() + } + .property instance bool IsC() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance bool MyTestModule/Myassembly::get_IsC() + } + .property instance string nonNullableString() + { + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 01 00 00 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance string MyTestModule/Myassembly::get_nonNullableString() + } + .property instance string nullableString() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 02 00 00 00 00 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance string MyTestModule/Myassembly::get_nullableString() + } + } + + .method public static string getVal(valuetype MyTestModule/Myassembly x) cil managed + { + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 3 + .locals init (valuetype MyTestModule/Myassembly V_0, + string V_1, + string V_2) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call instance int32 MyTestModule/Myassembly::get_Tag() + IL_0009: ldc.i4.2 + IL_000a: bne.un.s IL_0016 + + IL_000c: ldloca.s V_0 + IL_000e: ldfld string MyTestModule/Myassembly::_nullableString + IL_0013: stloc.1 + IL_0014: ldloc.1 + IL_0015: ret + + IL_0016: ldstr "fail" + IL_001b: stloc.2 + IL_001c: ldloc.2 + IL_001d: call class [runtime]System.Exception [FSharp.Core]Microsoft.FSharp.Core.Operators::Failure(string) + IL_0022: throw + } + +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ +} + +.class private auto ansi serializable sealed System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes + extends [runtime]System.Enum +{ + .custom instance void [runtime]System.FlagsAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field public specialname rtspecialname int32 value__ + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes All = int32(0xFFFFFFFF) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes None = int32(0x00000000) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicParameterlessConstructor = int32(0x00000001) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicConstructors = int32(0x00000003) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicConstructors = int32(0x00000004) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicMethods = int32(0x00000008) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicMethods = int32(0x00000010) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicFields = int32(0x00000020) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicFields = int32(0x00000040) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicNestedTypes = int32(0x00000080) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicNestedTypes = int32(0x00000100) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicProperties = int32(0x00000200) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicProperties = int32(0x00000400) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes PublicEvents = int32(0x00000800) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes NonPublicEvents = int32(0x00001000) + .field public static literal valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes Interfaces = int32(0x00002000) +} + +.class private auto ansi beforefieldinit System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MemberType@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field private class [runtime]System.Type Type@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname + instance void .ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MemberType, + class [runtime]System.Type Type) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::MemberType@ + IL_000d: ldarg.0 + IL_000e: ldarg.2 + IL_000f: stfld class [runtime]System.Type System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::Type@ + IL_0014: ret + } + + .method public hidebysig specialname instance class [runtime]System.Type + get_Type() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [runtime]System.Type System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::Type@ + IL_0006: ret + } + + .method public hidebysig specialname instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes + get_MemberType() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::MemberType@ + IL_0006: ret + } + + .property instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes + MemberType() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::get_MemberType() + } + .property instance class [runtime]System.Type + Type() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance class [runtime]System.Type System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::get_Type() + } +} + +.class private auto ansi beforefieldinit System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private bool ReturnValue@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field private string[] Members@ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname + instance void .ctor(bool ReturnValue, + string[] Members) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld bool System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::ReturnValue@ + IL_000d: ldarg.0 + IL_000e: ldarg.2 + IL_000f: stfld string[] System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::Members@ + IL_0014: ret + } + + .method public hidebysig specialname instance string[] + get_Members() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string[] System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::Members@ + IL_0006: ret + } + + .method public hidebysig specialname instance bool + get_ReturnValue() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld bool System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::ReturnValue@ + IL_0006: ret + } + + .property instance bool ReturnValue() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance bool System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::get_ReturnValue() + } + .property instance string[] Members() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance string[] System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::get_Members() + } +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8[] NullableFlags + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname + instance void .ctor(uint8 scalarByteValue) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldc.i4.1 + IL_0008: newarr [runtime]System.Byte + IL_000d: dup + IL_000e: ldc.i4.0 + IL_000f: ldarg.1 + IL_0010: stelem.i1 + IL_0011: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_0016: ret + } + + .method public specialname rtspecialname + instance void .ctor(uint8[] NullableFlags) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_000d: ret + } + +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableContextAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8 Flag + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname + instance void .ctor(uint8 Flag) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8 System.Runtime.CompilerServices.NullableContextAttribute::Flag + IL_000d: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/StructDU.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/StructDU.fs.il.netcore.bsl new file mode 100644 index 00000000000..3832bab72b8 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/StructDU.fs.il.netcore.bsl @@ -0,0 +1,349 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class sequential autochar serializable sealed nested public beforefieldinit Myassembly + extends [runtime]System.ValueType + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoComparisonAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoEqualityAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.StructAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C + 61 79 28 29 2C 6E 71 7D 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 01 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .class abstract auto ansi sealed nested public Tags + extends [runtime]System.Object + { + .field public static literal int32 A = int32(0x00000000) + .field public static literal int32 B = int32(0x00000001) + .field public static literal int32 C = int32(0x00000002) + } + + .field assembly string _nonNullableString + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field assembly string _nullableString + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field assembly int32 _tag + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public static valuetype MyTestModule/Myassembly + get_A() cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: newobj instance void MyTestModule/Myassembly::.ctor(int32) + IL_0006: ret + } + + .method public hidebysig instance bool + get_IsA() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance int32 MyTestModule/Myassembly::get_Tag() + IL_0006: ldc.i4.0 + IL_0007: ceq + IL_0009: ret + } + + .method public static valuetype MyTestModule/Myassembly + NewB(string _nonNullableString) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 01 00 00 00 00 00 ) + + .maxstack 2 + .locals init (valuetype MyTestModule/Myassembly V_0) + IL_0000: ldloca.s V_0 + IL_0002: initobj MyTestModule/Myassembly + IL_0008: ldloca.s V_0 + IL_000a: ldc.i4.1 + IL_000b: stfld int32 MyTestModule/Myassembly::_tag + IL_0010: ldloca.s V_0 + IL_0012: ldarg.0 + IL_0013: stfld string MyTestModule/Myassembly::_nonNullableString + IL_0018: ldloc.0 + IL_0019: ret + } + + .method public hidebysig instance bool + get_IsB() cil managed + { + .custom instance void [runtime]System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::.ctor(bool, + string[]) = ( 01 00 01 02 00 00 00 11 6E 6F 6E 4E 75 6C 6C 61 + 62 6C 65 53 74 72 69 6E 67 12 5F 6E 6F 6E 4E 75 + 6C 6C 61 62 6C 65 53 74 72 69 6E 67 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance int32 MyTestModule/Myassembly::get_Tag() + IL_0006: ldc.i4.1 + IL_0007: ceq + IL_0009: ret + } + + .method public static valuetype MyTestModule/Myassembly + NewC(string _nullableString) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 02 00 00 00 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 2 + .locals init (valuetype MyTestModule/Myassembly V_0) + IL_0000: ldloca.s V_0 + IL_0002: initobj MyTestModule/Myassembly + IL_0008: ldloca.s V_0 + IL_000a: ldc.i4.2 + IL_000b: stfld int32 MyTestModule/Myassembly::_tag + IL_0010: ldloca.s V_0 + IL_0012: ldarg.0 + IL_0013: stfld string MyTestModule/Myassembly::_nullableString + IL_0018: ldloc.0 + IL_0019: ret + } + + .method public hidebysig instance bool + get_IsC() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance int32 MyTestModule/Myassembly::get_Tag() + IL_0006: ldc.i4.2 + IL_0007: ceq + IL_0009: ret + } + + .method assembly specialname rtspecialname + instance void .ctor(int32 _tag) cil managed + { + .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, + class [runtime]System.Type) = ( 01 00 60 06 00 00 17 4D 79 54 65 73 74 4D 6F 64 + 75 6C 65 2B 4D 79 53 74 72 75 63 74 44 55 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 MyTestModule/Myassembly::_tag + IL_0007: ret + } + + .method public hidebysig instance string + get_nonNullableString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string MyTestModule/Myassembly::_nonNullableString + IL_0006: ret + } + + .method public hidebysig instance string + get_nullableString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld string MyTestModule/Myassembly::_nullableString + IL_0006: ret + } + + .method public hidebysig instance int32 + get_Tag() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 MyTestModule/Myassembly::_tag + IL_0006: ret + } + + .method assembly hidebysig specialname + instance object __DebugDisplay() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+0.8A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: ldobj MyTestModule/Myassembly + IL_0015: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001a: ret + } + + .method public strict virtual instance string + ToString() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%+A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,valuetype MyTestModule/Myassembly>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: ldobj MyTestModule/Myassembly + IL_0015: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001a: ret + } + + .property instance int32 Tag() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance int32 MyTestModule/Myassembly::get_Tag() + } + .property valuetype MyTestModule/Myassembly + A() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get valuetype MyTestModule/Myassembly MyTestModule/Myassembly::get_A() + } + .property instance bool IsA() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance bool MyTestModule/Myassembly::get_IsA() + } + .property instance bool IsB() + { + .custom instance void [runtime]System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::.ctor(bool, + string[]) = ( 01 00 01 02 00 00 00 11 6E 6F 6E 4E 75 6C 6C 61 + 62 6C 65 53 74 72 69 6E 67 12 5F 6E 6F 6E 4E 75 + 6C 6C 61 62 6C 65 53 74 72 69 6E 67 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance bool MyTestModule/Myassembly::get_IsB() + } + .property instance bool IsC() + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance bool MyTestModule/Myassembly::get_IsC() + } + .property instance string nonNullableString() + { + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 01 00 00 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance string MyTestModule/Myassembly::get_nonNullableString() + } + .property instance string nullableString() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 02 00 00 00 00 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance string MyTestModule/Myassembly::get_nullableString() + } + } + + .method public static string getVal(valuetype MyTestModule/Myassembly x) cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 3 + .locals init (valuetype MyTestModule/Myassembly V_0, + string V_1, + string V_2) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call instance int32 MyTestModule/Myassembly::get_Tag() + IL_0009: ldc.i4.2 + IL_000a: bne.un.s IL_0016 + + IL_000c: ldloca.s V_0 + IL_000e: ldfld string MyTestModule/Myassembly::_nullableString + IL_0013: stloc.1 + IL_0014: ldloc.1 + IL_0015: ret + + IL_0016: ldstr "fail" + IL_001b: stloc.2 + IL_001c: ldloc.2 + IL_001d: call class [runtime]System.Exception [FSharp.Core]Microsoft.FSharp.Core.Operators::Failure(string) + IL_0022: throw + } + +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/SupportsNull.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/SupportsNull.fs new file mode 100644 index 00000000000..ca7cc4d98bc --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/SupportsNull.fs @@ -0,0 +1,43 @@ +module MyTestModule + +let iCanProduceNullSometimes (arg:'a) : 'a = + let mutable cache = null + + if (System.DateTime.Now.Hour = 7) then + cache <- arg + + if (System.DateTime.Now.Hour = 7) then + null + else + arg + +let iPatternMatchOnArg arg = + match arg with + | null -> "null" + | _ -> "not null" + +let iAcceptNullPartiallyInferedFromUnderscore(arg: _ | null) = 0 + +let iAcceptNullPartiallyInferedFromNamedTypar(arg: 'a | null) = 0 + +let iAcceptNullWithNullAnnotation(arg: 'a | null when 'a: not struct) = + if isNull arg then + 1 + else + 0 + +let iAcceptNullExplicitAnnotation(arg: 'T when 'T:null) = + if isNull arg then + 1 + else + 0 + + +let fullyInferedTestCase arg1 arg2 = + System.Console.Write(iAcceptNullPartiallyInferedFromUnderscore arg1) + let maybeNull = iCanProduceNullSometimes arg2 + maybeNull + +let structShouldBeAllowedHere arg = + let boxed : obj | null = box arg + iAcceptNullPartiallyInferedFromUnderscore boxed \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/SupportsNull.fs.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/SupportsNull.fs.il.net472.bsl new file mode 100644 index 00000000000..74d4cc4fc1e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/SupportsNull.fs.il.net472.bsl @@ -0,0 +1,276 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .method public static !!a iCanProduceNullSometimes(!!a arg) cil managed + { + .param type a + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 4 + .locals init (!!a V_0, + valuetype [runtime]System.DateTime V_1, + valuetype [runtime]System.DateTime V_2, + !!a V_3) + IL_0000: call valuetype [runtime]System.DateTime [runtime]System.DateTime::get_Now() + IL_0005: stloc.1 + IL_0006: ldloca.s V_1 + IL_0008: call instance int32 [runtime]System.DateTime::get_Hour() + IL_000d: ldc.i4.7 + IL_000e: bne.un.s IL_0014 + + IL_0010: ldarg.0 + IL_0011: stloc.0 + IL_0012: br.s IL_0014 + + IL_0014: call valuetype [runtime]System.DateTime [runtime]System.DateTime::get_Now() + IL_0019: stloc.2 + IL_001a: ldloca.s V_2 + IL_001c: call instance int32 [runtime]System.DateTime::get_Hour() + IL_0021: ldc.i4.7 + IL_0022: bne.un.s IL_0026 + + IL_0024: ldloc.3 + IL_0025: ret + + IL_0026: ldarg.0 + IL_0027: ret + } + + .method public static string iPatternMatchOnArg(!!a arg) cil managed + { + .param type a + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: box !!a + IL_0006: brfalse.s IL_000a + + IL_0008: br.s IL_0010 + + IL_000a: ldstr "null" + IL_000f: ret + + IL_0010: ldstr "not null" + IL_0015: ret + } + + .method public static int32 iAcceptNullPartiallyInferedFromUnderscore(!!a arg) cil managed + { + .param type a + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: ret + } + + .method public static int32 iAcceptNullPartiallyInferedFromNamedTypar(!!a arg) cil managed + { + .param type a + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: ret + } + + .method public static int32 iAcceptNullWithNullAnnotation(!!a arg) cil managed + { + .param type a + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 3 + .locals init (!!a V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: box !!a + IL_0008: brtrue.s IL_000d + + IL_000a: ldc.i4.1 + IL_000b: br.s IL_000e + + IL_000d: ldc.i4.0 + IL_000e: brfalse.s IL_0012 + + IL_0010: ldc.i4.1 + IL_0011: ret + + IL_0012: ldc.i4.0 + IL_0013: ret + } + + .method public static int32 iAcceptNullExplicitAnnotation(!!T arg) cil managed + { + .param type T + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 3 + .locals init (!!T V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: box !!T + IL_0008: brtrue.s IL_000d + + IL_000a: ldc.i4.1 + IL_000b: br.s IL_000e + + IL_000d: ldc.i4.0 + IL_000e: brfalse.s IL_0012 + + IL_0010: ldc.i4.1 + IL_0011: ret + + IL_0012: ldc.i4.0 + IL_0013: ret + } + + .method public static !!b fullyInferedTestCase(!!a arg1, + !!b arg2) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + .param type a + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param type b + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 3 + .locals init (!!b V_0) + IL_0000: ldarg.0 + IL_0001: call int32 MyTestModule::iAcceptNullPartiallyInferedFromUnderscore(!!0) + IL_0006: call void [runtime]System.Console::Write(int32) + IL_000b: ldarg.1 + IL_000c: call !!0 MyTestModule::iCanProduceNullSometimes(!!0) + IL_0011: stloc.0 + IL_0012: ldloc.0 + IL_0013: ret + } + + .method public static int32 structShouldBeAllowedHere(!!a arg) cil managed + { + .param type a + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + + .maxstack 3 + .locals init (object V_0) + IL_0000: ldarg.0 + IL_0001: box !!a + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: call int32 MyTestModule::iAcceptNullPartiallyInferedFromUnderscore(!!0) + IL_000d: ret + } + +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8[] NullableFlags + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 scalarByteValue) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldc.i4.1 + IL_0008: newarr [runtime]System.Byte + IL_000d: dup + IL_000e: ldc.i4.0 + IL_000f: ldarg.1 + IL_0010: stelem.i1 + IL_0011: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_0016: ret + } + + .method public specialname rtspecialname instance void .ctor(uint8[] NullableFlags) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_000d: ret + } + +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableContextAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8 Flag + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 Flag) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8 System.Runtime.CompilerServices.NullableContextAttribute::Flag + IL_000d: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/SupportsNull.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/SupportsNull.fs.il.netcore.bsl new file mode 100644 index 00000000000..8c5236b881b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/SupportsNull.fs.il.netcore.bsl @@ -0,0 +1,212 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly extern runtime { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .method public static !!a iCanProduceNullSometimes(!!a arg) cil managed + { + .param type a + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 4 + .locals init (!!a V_0, + valuetype [runtime]System.DateTime V_1, + valuetype [runtime]System.DateTime V_2, + !!a V_3) + IL_0000: call valuetype [runtime]System.DateTime [runtime]System.DateTime::get_Now() + IL_0005: stloc.1 + IL_0006: ldloca.s V_1 + IL_0008: call instance int32 [runtime]System.DateTime::get_Hour() + IL_000d: ldc.i4.7 + IL_000e: bne.un.s IL_0014 + + IL_0010: ldarg.0 + IL_0011: stloc.0 + IL_0012: br.s IL_0014 + + IL_0014: call valuetype [runtime]System.DateTime [runtime]System.DateTime::get_Now() + IL_0019: stloc.2 + IL_001a: ldloca.s V_2 + IL_001c: call instance int32 [runtime]System.DateTime::get_Hour() + IL_0021: ldc.i4.7 + IL_0022: bne.un.s IL_0026 + + IL_0024: ldloc.3 + IL_0025: ret + + IL_0026: ldarg.0 + IL_0027: ret + } + + .method public static string iPatternMatchOnArg(!!a arg) cil managed + { + .param type a + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: box !!a + IL_0006: brfalse.s IL_000a + + IL_0008: br.s IL_0010 + + IL_000a: ldstr "null" + IL_000f: ret + + IL_0010: ldstr "not null" + IL_0015: ret + } + + .method public static int32 iAcceptNullPartiallyInferedFromUnderscore(!!a arg) cil managed + { + .param type a + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: ret + } + + .method public static int32 iAcceptNullPartiallyInferedFromNamedTypar(!!a arg) cil managed + { + .param type a + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: ret + } + + .method public static int32 iAcceptNullWithNullAnnotation(!!a arg) cil managed + { + .param type a + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 3 + .locals init (!!a V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: box !!a + IL_0008: brtrue.s IL_000d + + IL_000a: ldc.i4.1 + IL_000b: br.s IL_000e + + IL_000d: ldc.i4.0 + IL_000e: brfalse.s IL_0012 + + IL_0010: ldc.i4.1 + IL_0011: ret + + IL_0012: ldc.i4.0 + IL_0013: ret + } + + .method public static int32 iAcceptNullExplicitAnnotation(!!T arg) cil managed + { + .param type T + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 3 + .locals init (!!T V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: box !!T + IL_0008: brtrue.s IL_000d + + IL_000a: ldc.i4.1 + IL_000b: br.s IL_000e + + IL_000d: ldc.i4.0 + IL_000e: brfalse.s IL_0012 + + IL_0010: ldc.i4.1 + IL_0011: ret + + IL_0012: ldc.i4.0 + IL_0013: ret + } + + .method public static !!b fullyInferedTestCase(!!a arg1, + !!b arg2) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + .param type a + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param type b + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 3 + .locals init (!!b V_0) + IL_0000: ldarg.0 + IL_0001: call int32 MyTestModule::iAcceptNullPartiallyInferedFromUnderscore(!!0) + IL_0006: call void [runtime]System.Console::Write(int32) + IL_000b: ldarg.1 + IL_000c: call !!0 MyTestModule::iCanProduceNullSometimes(!!0) + IL_0011: stloc.0 + IL_0012: ldloc.0 + IL_0013: ret + } + + .method public static int32 structShouldBeAllowedHere(!!a arg) cil managed + { + .param type a + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + + .maxstack 3 + .locals init (object V_0) + IL_0000: ldarg.0 + IL_0001: box !!a + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: call int32 MyTestModule::iAcceptNullPartiallyInferedFromUnderscore(!!0) + IL_000d: ret + } + +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/TupleElimination.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/TupleElimination.fs index 5c77f15f552..d14b6d2240c 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/TupleElimination.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/TupleElimination.fs @@ -7,6 +7,9 @@ open FSharp.Test.Compiler module ``TupleElimination`` = + + let compile cu = cu |> withCheckNulls |> withLangVersionPreview |> compile + [] let ``Sequence expressions with potential side effects do not prevent tuple elimination``() = FSharp """ @@ -90,12 +93,12 @@ public static Tuple v() valuetype [runtime]System.DateTime V_1, int32 V_2) IL_0000: ldstr "" - IL_0005: callvirt instance string [runtime]System.Object::ToString() + IL_0005: callvirt instance string [runtime]System.String::ToString() IL_000a: stloc.0 IL_000b: call valuetype [runtime]System.DateTime [runtime]System.DateTime::get_Now() IL_0010: stloc.1 IL_0011: ldstr "3" - IL_0016: callvirt instance string [runtime]System.Object::ToString() + IL_0016: callvirt instance string [runtime]System.String::ToString() IL_001b: stloc.0 IL_001c: call int32 TupleElimination::f() IL_0021: stloc.2 @@ -133,12 +136,12 @@ public static int w() int32 V_2, class [runtime]System.Tuple`2 V_3) IL_0000: ldstr "" - IL_0005: callvirt instance string [runtime]System.Object::ToString() + IL_0005: callvirt instance string [runtime]System.String::ToString() IL_000a: stloc.0 IL_000b: call valuetype [runtime]System.DateTime [runtime]System.DateTime::get_Now() IL_0010: stloc.1 IL_0011: ldstr "3" - IL_0016: callvirt instance string [runtime]System.Object::ToString() + IL_0016: callvirt instance string [runtime]System.String::ToString() IL_001b: stloc.0 IL_001c: call int32 TupleElimination::f() IL_0021: stloc.2 @@ -179,12 +182,12 @@ public static int x() valuetype [runtime]System.DateTime V_1, int32 V_2) IL_0000: ldstr "" - IL_0005: callvirt instance string [runtime]System.Object::ToString() + IL_0005: callvirt instance string [runtime]System.String::ToString() IL_000a: stloc.0 IL_000b: call valuetype [runtime]System.DateTime [runtime]System.DateTime::get_Now() IL_0010: stloc.1 IL_0011: ldstr "3" - IL_0016: callvirt instance string [runtime]System.Object::ToString() + IL_0016: callvirt instance string [runtime]System.String::ToString() IL_001b: stloc.0 IL_001c: call int32 TupleElimination::f() IL_0021: stloc.2 @@ -347,12 +350,12 @@ public static int z() int32 V_3, int32 V_4) IL_0000: ldstr "" - IL_0005: callvirt instance string [runtime]System.Object::ToString() + IL_0005: callvirt instance string [runtime]System.String::ToString() IL_000a: stloc.1 IL_000b: call valuetype [runtime]System.DateTime [runtime]System.DateTime::get_Now() IL_0010: stloc.2 IL_0011: ldstr "3" - IL_0016: callvirt instance string [runtime]System.Object::ToString() + IL_0016: callvirt instance string [runtime]System.String::ToString() IL_001b: stloc.1 IL_001c: ldc.i4.2 IL_001d: call int32 TupleElimination::f() @@ -574,7 +577,7 @@ public static int y() IL_000b: brfalse.s IL_0027 IL_000d: ldstr "" - IL_0012: callvirt instance string [runtime]System.Object::ToString() + IL_0012: callvirt instance string [runtime]System.String::ToString() IL_0017: stloc.3 IL_0018: ldc.i4.1 IL_0019: stloc.0 @@ -621,7 +624,7 @@ public static int y() IL_005a: br.s IL_0095 IL_005c: ldstr "" - IL_0061: callvirt instance string [runtime]System.Object::ToString() + IL_0061: callvirt instance string [runtime]System.String::ToString() IL_0066: stloc.3 IL_0067: ldc.i4.6 IL_0068: stloc.0 diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeEqualsMissingTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeEqualsMissingTests.fs index 13d596019de..e0eb2e11b74 100644 --- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeEqualsMissingTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeEqualsMissingTests.fs @@ -6,16 +6,16 @@ open Xunit open FSharp.Test open FSharp.Compiler.Diagnostics +// Disabled this test, see https://github.com/dotnet/fsharp/commit/98dc1b09fa1ff15176998dc2d28c5b5c8d0f80b1#r43542750 +//module ``Type definition missing equals`` = -module ``Type definition missing equals`` = - - [] - let ``Missing equals in DU``() = - CompilerAssert.TypeCheckSingleError - """ -type X | A | B - """ - FSharpDiagnosticSeverity.Error - 10 - (2, 8, 2, 9) - "Unexpected symbol '|' in type definition. Expected '=' or other token." +// [] +// let ``Missing equals in DU``() = +// CompilerAssert.TypeCheckSingleError +// """ +// type X | A | B +// """ +// FSharpDiagnosticSeverity.Error +// 10 +// (2, 8, 2, 9) +// "Unexpected symbol '|' in type definition. Expected '=' or other token." diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index aa343573791..3cbbe3ef3c5 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -175,6 +175,7 @@ + @@ -235,6 +236,10 @@ + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/FSharpChecker/TransparentCompiler.fs b/tests/FSharp.Compiler.ComponentTests/FSharpChecker/TransparentCompiler.fs index cb3f9cece44..cacbec09c2c 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharpChecker/TransparentCompiler.fs +++ b/tests/FSharp.Compiler.ComponentTests/FSharpChecker/TransparentCompiler.fs @@ -475,7 +475,6 @@ type ProjectRequest = ProjectAction * AsyncReplyChannel type FuzzingEvent = StartedChecking | FinishedChecking of bool | AbortedChecking of string | ModifiedImplFile | ModifiedSigFile -[] type SignatureFiles = Yes = 1 | No = 2 | Some = 3 let fuzzingTest seed (project: SyntheticProject) = task { diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DiscriminatedUnionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DiscriminatedUnionTests.fs index 6d2d0d24c28..0daad0e2f28 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/DiscriminatedUnionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/DiscriminatedUnionTests.fs @@ -65,6 +65,7 @@ if foo.IsA then failwith "Should not be A" |> compileExeAndRun |> shouldSucceed + [] let ``Is* discriminated union properties with backticks are visible, proper values are returned`` () = Fsx """ @@ -146,6 +147,7 @@ let isFoo = foo.IsFoo |> withErrorMessage "The type 'Foo' does not define the field, constructor or member 'IsFoo'. Maybe you want one of the following: Foo" + [] let ``Is* discriminated union properties are unavailable on union case with lang version 8`` () = Fsx """ diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs index 3d2333ec9a4..a4732bcb18a 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs @@ -89,7 +89,7 @@ let x = "a" |> _.ToString () """ 'string -> 'a' but given a 'unit -> string' -The type 'string' does not match the type 'unit'""" ] +The type 'unit' does not match the type 'string'""" ] [] let ``Underscore Dot Curried Function With Arguments - NonAtomic`` () = diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableCsharpImportTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableCsharpImportTests.fs new file mode 100644 index 00000000000..c477417e75a --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableCsharpImportTests.fs @@ -0,0 +1,229 @@ +module Language.NullableCSharpImport + +open Xunit +open FSharp.Test +open FSharp.Test.Compiler + +let withStrictNullness cu = + cu + |> withLangVersionPreview + |> withCheckNulls + |> withWarnOn 3261 + |> withOptions ["--warnaserror+"] + +let typeCheckWithStrictNullness cu = + cu + |> withStrictNullness + |> typecheck + + +[] +let ``Passing null to IlGenerator BeginCatchBlock is fine`` () = + FSharp """module MyLibrary +open System.Reflection.Emit +open System + +let mutable logRefEmitCalls = true + +type ILGenerator with + member ilG.BeginCatchBlockAndLog (ty: Type | null) = + if logRefEmitCalls then + printfn "ilg%d.BeginCatchBlock(%A)" (abs <| hash ilG) ty + + ilG.BeginCatchBlock ty + +let doSomethingAboutIt (ilg:ILGenerator) = + ilg.BeginCatchBlockAndLog(null) +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Consuming C# generic API which allows struct and yet uses question mark on the typar`` () = + FSharp """module MyLibrary +let ec = + { new System.Collections.Generic.IEqualityComparer with + member this.Equals(x, y) = (x+0) = (y+0) + member this.GetHashCode(obj) = obj * 2} +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``TypeBuilder CreateTypeInfo with an upcast`` () = + FSharp """module MyLibrary +open System +open System.Reflection.Emit + +let createType (typB:TypeBuilder) : Type= + typB.CreateTypeInfo() :> Type +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``CurrentDomain ProcessExit add to event`` () = + FSharp """module MyLibrary +open System + +do System.AppDomain.CurrentDomain.ProcessExit |> Event.add (fun args -> failwith $"{args.GetHashCode()}") +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Consuming C# extension methods which allow nullable this`` () = + FSharp """module MyLibrary + +open System + +let asMemoryOnNonNull : Memory = + let bytes = [|0uy..11uy|] + let memory = bytes.AsMemory() + memory + +let asMemoryOnNull : Memory = + let bytes : (byte[]) | null = null + let memory = bytes.AsMemory() + memory +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Consuming LinkedList First and Last should warn about nullness`` () = + FSharp """module MyLibrary + +let ll = new System.Collections.Generic.LinkedList() +let x:System.Collections.Generic.LinkedListNode = ll.Last +let y:System.Collections.Generic.LinkedListNode = ll.First +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics + [ Error 3261, Line 4, Col 59, Line 4, Col 66, "Nullness warning: The types 'System.Collections.Generic.LinkedListNode' and 'System.Collections.Generic.LinkedListNode | null' do not have compatible nullability." + Error 3261, Line 4, Col 59, Line 4, Col 66, "Nullness warning: The types 'System.Collections.Generic.LinkedListNode' and 'System.Collections.Generic.LinkedListNode | null' do not have equivalent nullability." + Error 3261, Line 5, Col 59, Line 5, Col 67, "Nullness warning: The types 'System.Collections.Generic.LinkedListNode' and 'System.Collections.Generic.LinkedListNode | null' do not have compatible nullability." + Error 3261, Line 5, Col 59, Line 5, Col 67, "Nullness warning: The types 'System.Collections.Generic.LinkedListNode' and 'System.Collections.Generic.LinkedListNode | null' do not have equivalent nullability."] + +[] +let ``Nullable directory info show warn on prop access`` () = + FSharp """module MyLibrary +open System.IO +open System + +let d : DirectoryInfo | null = null +let s : string = d.Name // should warn here!! +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics [Error 3261, Line 6, Col 18, Line 6, Col 24, "Nullness warning: The types 'DirectoryInfo' and 'DirectoryInfo | null' do not have compatible nullability."] + +[] +let ``Consumption of netstandard2 BCL api which is not annotated`` () = + FSharp """module MyLibrary +open System.Reflection + +[] +type PublicKey = + | PublicKey of byte[] + | PublicKeyToken of byte[] + +let FromAssemblyName (aname: AssemblyName) = + match aname.GetPublicKey() with + | Null + | NonNull [||] -> + match aname.GetPublicKeyToken() with + | Null + | NonNull [||] -> None + | NonNull bytes -> Some(PublicKeyToken bytes) + | NonNull bytes -> Some(PublicKey bytes)""" + |> asLibrary + |> asNetStandard20 + |> typeCheckWithStrictNullness + |> shouldSucceed + + +[] +let ``Consumption of nullable C# - no generics, just strings in methods and fields`` () = + let csharpLib = + CSharp """ + #nullable enable + namespace Nullables { + public class NullableClass { + // Fields with nullable type + public static string NotNullField; + // Fields with non-nullable type + public static string? MaybeNullField; + // Methods which return nullable string + public static string? ReturnsNullableStringNoParams() { return null; } + public static string? ReturnsNullableString1NullableParam(string? _) { return null; } + public static string? ReturnsNullableString1NonNullableParam(string _) { return null; } + public static string? ReturnsNullableString2NullableParams(string? _, string? __) { return null; } + public static string? ReturnsNullableString2NonNullableParams(string _, string __) { return null; } + public static string? ReturnsNullableString1Nullable1NonNullableParam(string? _, string __) { return null; } + + // Methods which return non-nullable string + public static string ReturnsNonNullableStringNoParams() { return ""; } + public static string ReturnsNonNullableString1NullableParam(string? _) { return ""; } + public static string ReturnsNonNullableString1NonNullableParam(string _) { return ""; } + public static string ReturnsNonNullableString2NullableParams(string? _, string? __) { return ""; } + public static string ReturnsNonNullableString2NonNullableParams(string _, string __) { return ""; } + public static string ReturnsNonNullableString1Nullable1NonNullableParam(string? _, string __) { return ""; } + } + }""" |> withName "csNullableLib" + + FSharp """ + module FSNullable + open Nullables + + let nullablestrNoParams : string = NullableClass.ReturnsNullableStringNoParams() // Error here, line 5 + let nonNullableStrNoParams : string | null = NullableClass.ReturnsNonNullableStringNoParams() + let nullablestrNoParamsCorrectlyAnnotated : string | null = NullableClass.ReturnsNullableStringNoParams() + let nonNullableStrNoParamsCorrectlyAnnotated : string = NullableClass.ReturnsNonNullableStringNoParams() + let notNullField : string = NullableClass.NotNullField + let maybeNullField : string | null = NullableClass.MaybeNullField + let maybeNullField2 : string | null = NullableClass.NotNullField + + + let notNullField2 : string = NullableClass.MaybeNullField // Error here, line 14 + NullableClass.MaybeNullField <- null + NullableClass.NotNullField <- null // Error here, line 16 + + let notNullArg : string = "hello" + let maybeNullArg : string | null = "there" + + let nullableParamOk1 = NullableClass.ReturnsNullableString1NullableParam(notNullArg) + let nullableParamOk2 = NullableClass.ReturnsNullableString1NullableParam(maybeNullArg) + + let nonNullParamCallPass = NullableClass.ReturnsNullableString1NonNullableParam(notNullArg) + let nonNullParamCallFail = NullableClass.ReturnsNullableString1NonNullableParam(maybeNullArg) // Error here, 25 + + let mixedParams1 = NullableClass.ReturnsNullableString1Nullable1NonNullableParam(notNullArg,notNullArg) + let mixedParams2 = NullableClass.ReturnsNullableString1Nullable1NonNullableParam(maybeNullArg,maybeNullArg) // Error here, 28 + let mixedParams3 = NullableClass.ReturnsNullableString1Nullable1NonNullableParam(maybeNullArg,notNullArg) + let mixedParams4 = NullableClass.ReturnsNullableString1Nullable1NonNullableParam(notNullArg,maybeNullArg) // Error here, 30 + + + """ + |> asLibrary + |> withReferences [csharpLib] + |> withStrictNullness + |> compile + |> shouldFail + |> withDiagnostics [ + Error 3261, Line 5, Col 40, Line 5, Col 85, "Nullness warning: The types 'string' and 'string | null' do not have compatible nullability." + Error 3261, Line 5, Col 40, Line 5, Col 85, "Nullness warning: The types 'string' and 'string | null' do not have equivalent nullability." + Error 3261, Line 14, Col 34, Line 14, Col 62, "Nullness warning: The types 'string' and 'string | null' do not have equivalent nullability." + Error 3261, Line 16, Col 35, Line 16, Col 39, "Nullness warning: The type 'string' does not support 'null'." + Error 3261, Line 25, Col 85, Line 25, Col 97, "Nullness warning: The types 'string' and 'string | null' do not have equivalent nullability." + Error 3261, Line 28, Col 99, Line 28, Col 111, "Nullness warning: The types 'string' and 'string | null' do not have equivalent nullability." + Error 3261, Line 30, Col 97, Line 30, Col 109, "Nullness warning: The types 'string' and 'string | null' do not have equivalent nullability."] + diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableLibraryConstructsTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableLibraryConstructsTests.fs new file mode 100644 index 00000000000..790c4cfd395 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableLibraryConstructsTests.fs @@ -0,0 +1,59 @@ +module Language.NullableLibraryConstructs + +open Xunit +open FSharp.Test +open FSharp.Test.Compiler + +let typeCheckWithStrictNullness cu = + cu + |> withLangVersionPreview + |> withCheckNulls + |> withWarnOn 3261 + |> withOptions ["--warnaserror+"] + |> typecheck + +[] +let ``Can unsafely forgive null using Unchecked nonNull function`` () = + FSharp """module MyLibrary + +let readAllLines (reader:System.IO.StreamReader) : seq = + seq { + while not reader.EndOfStream do + reader.ReadLine() |> Unchecked.nonNull + } +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Can unsafely forgive null using Unchecked NonNullQuick active pattern`` () = + FSharp """module MyLibrary + +let readAllLines (reader:System.IO.StreamReader) : seq = + seq { + while not reader.EndOfStream do + match reader.ReadLine() with + | Unchecked.NonNullQuick line -> yield line + } +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Can concat two maybe null strings`` () = + FSharp """module MyLibrary + +let addStrings (x:string | null) (y:string) : string = + + let s2 = x + x + let s3 = y + y + let s4 = y + x + let s4string : string = s4 + + s4 +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs new file mode 100644 index 00000000000..7c57afabd98 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs @@ -0,0 +1,902 @@ +module Language.NullableReferenceTypes + +open Xunit +open FSharp.Test.Compiler + +let withNullnessOptions cu = + cu + |> withLangVersionPreview + |> withCheckNulls + |> withWarnOn 3261 + |> withWarnOn 3262 + |> withOptions ["--warnaserror+"] + +let typeCheckWithStrictNullness cu = + cu + |> withNullnessOptions + |> typecheck + +[] +let ``Cannot pass possibly null value to a strict function``() = + FSharp """ +module MyLib +let strictFunc(x:string) = () +let nonStrictFunc(x:string | null) = strictFunc(x) + """ + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics [ + Error 3261, Line 4, Col 49, Line 4, Col 50, "Nullness warning: The types 'string' and 'string | null' do not have equivalent nullability."] + +[] +[] +[] +[] +[ fileExists")>] +[ fileExists")>] +[] +[] +[ System.IO.File.Exists")>] +[ System.IO.File.Exists")>] +[] +let ``Calling a nullAllowing API can still infer a withoutNull type``(functionCall) = + FSharp $""" +module MyLib + +let myStrictFunc(x: string) = x.GetHashCode() +let fileExists (path:string|null) = true + +let myStringReturningFunc (path) = + let ex = {functionCall} + myStrictFunc(path) + """ + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +//[] +// TODO Tomas - as of now, this does not bring the desired result +let ``Type inference with underscore or null`` () = + FSharp $""" +module MyLib + +let myFunc (path: _ | null) = + System.IO.File.Exists(path) + """ + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Type inference SystemIOFileExists`` () = + FSharp $""" +module MyLib + +let test() = + let maybeString : string | null = null + System.IO.File.Exists(maybeString) + +let myFunc path : string = + let exists = path |> System.IO.File.Exists + path + """ + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Type inference fsharp func`` () = + FSharp $"""module MyLib + +let fileExists (path:string|null) = true +let myStringReturningFunc (pathArg) : string = + let ex = pathArg |> fileExists + pathArg + """ + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + + +// P1: inline or not +// P2: type annotation for function argument +// P3: type annotation for cache +let MutableBindingAnnotationCombinations = + [| + for functionInlineFlag in ["" + "inline"] do + for xArg in ["" + ":'T" + ":'T|null" + ": _" + ": _|null" + ": string|null" + ": string"] do + // No annotation or _ must work all the time + for cacheArg in ["" + ": _"] do + yield [|functionInlineFlag :> obj; xArg :> obj; cacheArg :> obj|] + + // If we have a named type, the same one must work for cache binding as well + if xArg.Contains("'T") || xArg.Contains("string|null") then + yield [|functionInlineFlag :> obj; xArg :> obj; xArg :> obj|] + + // If we have a type WithNull, using _|null should infer the exact same type + if xArg.Contains("|null") || xArg.Contains("string") then + yield [|functionInlineFlag :> obj; xArg :> obj; ":_|null" :> obj|] + + if xArg = ":'T" then + for guard in [" when 'T:null" + " when 'T:null and 'T:not struct"] do + yield [|functionInlineFlag :> obj; (xArg + guard) :> obj; "" :> obj|] + + if xArg = ":'T|null" then + for guard in [" when 'T:not struct" + " when 'T:not null" + " when 'T:not struct and 'T:not null"] do + yield [|functionInlineFlag :> obj; (xArg + guard) :> obj; "" :> obj|] + |] + +[] +[] +let ``Mutable binding with a null literal`` inln xArg cache = + FSharp $"""module MyLib + +let %s{inln} f (x %s{xArg}) = + let mutable cache %s{cache} = null + cache <- x + + match cache with + | null -> failwith "It was null" + | c -> c + """ + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Mutable string binding initially assigned to null should not need type annotation``() = + FSharp """ +module MyLib + + +let name = "abc" +let mutable cache = null +cache <- name + """ + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Mutable string binding assigned to null and matched againts null``() = + FSharp """ +module MyLib + +let whatEver() = + let mutable x = null + x <- "abc" + x + + +(* This is a comment +let name = "abc" +let mutable cache = null +cache <- name + +match cache with +| null -> () +| c -> ()*) + + """ + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Mutable cache binding initially assigned to null should not need type annotation``() = + FSharp """ +module MyLib +open System.Collections.Concurrent +open System + +let mkCacheInt32 () = + let mutable topLevelCache = null + + fun f (idx: int32) -> + let cache = + match topLevelCache with + | null -> + let v = ConcurrentDictionary(Environment.ProcessorCount, 11) + topLevelCache <- v + v + | v -> v + + match cache.TryGetValue idx with + | true, res -> res + | _ -> + let res = f idx + cache[idx] <- res + res + + """ + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Can infer underscore or null``() = + FSharp """ +module MyLib +let iAcceptNullPartiallyInfered(arg: _ | null) = 42 +let iHaveMissingContraint(arg: 'a | null) = 42 + """ + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Invalid usages of WithNull syntax``() = + FSharp """ +module MyLib +let f1(x: option | null) = () +let f2(x: int | null) = () +let f3(x: ('a*'b) | null) = () +let f4(x: option<'a> | null) = () +let f5(x: ('a | null) when 'a:struct) = () +let f6(x: 'a | null when 'a:null) = () + """ + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics + [ Error 3261, Line 3, Col 11, Line 3, Col 32, "Nullness warning: The type 'string option' uses 'null' as a representation value but a non-null type is expected." + Error 3260, Line 4, Col 11, Line 4, Col 21, "The type 'int' does not support a nullness qualitification." + Error 43, Line 4, Col 11, Line 4, Col 21, "A generic construct requires that the type 'int' have reference semantics, but it does not, i.e. it is a struct" + Error 3260, Line 5, Col 11, Line 5, Col 25, "The type '('a * 'b)' does not support a nullness qualitification." + Error 3261, Line 6, Col 11, Line 6, Col 28, "Nullness warning: The type ''a option' uses 'null' as a representation value but a non-null type is expected." + Error 43, Line 7, Col 28, Line 7, Col 37, "The constraints 'struct' and 'not struct' are inconsistent" + Error 43, Line 8, Col 26, Line 8, Col 33, "The constraints 'null' and 'not null' are inconsistent"] + +[] +let ``Boolean literal to string is not nullable`` () = + FSharp """module MyLibrary +let onlyWantNotNullString(x:string) = () + +let processBool () : string = + onlyWantNotNullString (true.ToString()) + onlyWantNotNullString (false.ToString()) + + true.ToString() +""" + |> asLibrary + |> withNoWarn 52 // The value has been copied to ensure the original is not mutated... + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Boolean to string is not nullable`` () = + FSharp """module MyLibrary +let onlyWantNotNullString(x:string) = () + +let processBool (b:bool) : string = + let asString = b.ToString() + asString +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Printing a nullable string should pass`` () = + FSharp """module MyLibrary +let maybeNull : string | null = null +let nonNullString = "abc" +let printedValueNotNull = sprintf "This is not null: %s" nonNullString +let printedValueNull = sprintf "This is null: %s" maybeNull +let interpolated = $"This is fine %s{maybeNull}" +let interpolatedAnnotatedNotNull = $"This is fine %s{nonNullString}" +let interpolatedAnnotatedNullable = $"This is not null %s{maybeNull}" +let interpolateNullLiteral = $"This is not null %s{null}" +let sprintfnNullLiteral = sprintf "This is null: %s" null +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + + +[] +let ``Printing a nullable object should pass`` () = + FSharp """module MyLibrary +let maybeNull : string | null = null +let maybeUri : System.Uri | null = null +let okString = "abc" +let printViaO = sprintf "This is null: %O and this is null %O and this is not null %O" maybeNull maybeUri okString +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + + +[] +let ``Printing a nullable array via percent A should pass`` () = + FSharp """module MyLibrary +let maybeArray : ((string array) | null) = null +let arrayOfMaybes : ((string | null) array ) = [|null|] +let printViaA = sprintf "This is null: %A and this has null inside %A" maybeArray arrayOfMaybes +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Type inference with sprintfn`` () = + FSharp """module MyLibrary +let needsString(x:string) = () + +let myTopFunction inferedVal = + printfn "This is it %s" inferedVal // There was a regression infering this to be (string | null) + needsString inferedVal +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``WhatIf the format itself is null`` () = + FSharp """module MyLibrary +[] +let thisCannotBeAFormat : string | null = null +[] +let maybeLiteral : string | null = "abc" +[] +let maybeLiteralWithHole : string | null = "Look at me %s" +[] +let notNullLiteral : string = "abc" +let doStuff() = + printfn notNullLiteral + printfn maybeLiteral + printfn maybeLiteralWithHole thisCannotBeAFormat +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Match null on two strings`` () = + FSharp """module MyLibrary +let len2r (str1: string | null) (str2: string | null) = + match str1, str2 with + | null, _ -> -1 + | _, null -> -1 + | s1, s2 -> s1.Length + s2.Length +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +[] +[] +[] +[] +[] +[] +let ``Eliminate nullness after matching`` (tp) = + FSharp $"""module MyLibrary + +let myFunction (input : string | null) : string = + match input with + | {tp} -> "" + | nonNullString -> nonNullString +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +[] +[] +let ``Eliminate tupled nullness after matching`` (tp) = + FSharp $"""module MyLibrary + +let myFunction (input1 : string | null) (input2 : string | null): (string*string) = + match input1,input2 with + | {tp} -> "","" + | nns1,nns2 -> nns1,nns2 +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + + +[] +[] +[] +[] +[] +[] +[] +let ``Should NOT eliminate tupled nullness after matching`` (tp) = + FSharp $"""module MyLibrary + +let myFunction (input1 : string | null) (input2 : string | null): (string*string) = + match input1,input2 with + | %s{tp} -> "","" + | nns1,nns2 -> nns1,nns2 +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withErrorCode 3261 + +[] +let ``Eliminate aliased nullness after matching`` () = + FSharp $"""module MyLibrary + +type Maybe<'T when 'T:not struct> = 'T | null + +let myFunction (input : string Maybe) : string = + match input with + | null -> "" + | nonNullString -> nonNullString +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``WithNull used on anon type`` () = + FSharp """module MyLibrary + +let maybeAnon : _ | null = {|Hello="there"|} +let maybeAnon2 : {|Hello:string|} | null = null +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics + [ Error 3260, Line 4, Col 18, Line 4, Col 41, "The type '{| Hello: string |}' does not support a nullness qualitification." + Error 3261, Line 4, Col 44, Line 4, Col 48, "Nullness warning: The type '{| Hello: string |}' does not support 'null'."] + + +[] +let ``WithNull on a DU`` () = + FSharp """module MyLibrary + +type MyDu = A | B + + +let strictFunc(arg: 'x when 'x : not null) = + printfn "%A" arg + arg + +let looseFunc(arg: _ | null) = arg + +strictFunc(A) |> ignore +looseFunc(A) |> ignore + +let maybeDu : _ | null = MyDu.A +let maybeDu2 : _ | null = null + +strictFunc(maybeDu) |> ignore +strictFunc(maybeDu2) |> ignore + +looseFunc(maybeDu2) |> ignore +looseFunc(maybeDu2) |> ignore + +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics [ + Error 3261, Line 18, Col 12, Line 18, Col 19, "Nullness warning: The type 'MyDu | null' supports 'null' but a non-null type is expected." + Error 3261, Line 19, Col 12, Line 19, Col 20, "Nullness warning: The type ''a | null' supports 'null' but a non-null type is expected."] + +[] +let ``Strict func handling of obj type`` () = + FSharp """module MyLibrary +let strictFunc(arg: 'x when 'x : not null) = printfn "%s" (arg.ToString()) + +strictFunc("hi") |> ignore +strictFunc({|Anon=5|}) |> ignore +strictFunc(null:obj) |> ignore +strictFunc(null:(obj|null)) |> ignore +strictFunc(null:(string|null)) |> ignore + """ + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics + [ Error 3261, Line 6, Col 12, Line 6, Col 16, "Nullness warning: The type 'obj' does not support 'null'." + Error 3261, Line 7, Col 12, Line 7, Col 27, "Nullness warning: The type 'obj | null' supports 'null' but a non-null type is expected." + Error 3261, Line 8, Col 12, Line 8, Col 30, "Nullness warning: The type 'string | null' supports 'null' but a non-null type is expected."] + + + +[] +let ``Strict func null literal`` () = + FSharp """module MyLibrary +let strictFunc(arg: 'x when 'x : not null) = printfn "%s" (arg.ToString()) + +strictFunc(null) |> ignore """ + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics + [ Error 43, Line 4, Col 12, Line 4, Col 16, "The constraints 'null' and 'not null' are inconsistent"] + +[] +let ``Strict func null literal2`` () = + FSharp """module MyLibrary +let strictFunc(arg: 'x when 'x : not null) = printfn "%s" (arg.ToString()) + +strictFunc(null) |> ignore +strictFunc({|Anon=5|}) |> ignore +strictFunc("hi") |> ignore """ + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics + [ Error 43, Line 4, Col 12, Line 4, Col 16, "The constraints 'null' and 'not null' are inconsistent"] + +[] +let ``Supports null in generic code`` () = + FSharp """module MyLibrary +let myGenericFunction p = + match p with + | null -> () + | p -> printfn "%s" (p.ToString()) + +[] +type X(p:int) = + member _.P = p + +let myValOfX : X = null + +myGenericFunction "HiThere" +myGenericFunction ("HiThere":string | null) +myGenericFunction (System.DateTime.Now) +myGenericFunction 123 +myGenericFunction myValOfX + +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics + [Error 3261, Line 13, Col 19, Line 13, Col 28, "Nullness warning: The type 'string' does not support 'null'." + Error 3261, Line 15, Col 20, Line 15, Col 39, "Nullness warning: The type 'System.DateTime' does not support 'null'." + Error 3261, Line 16, Col 19, Line 16, Col 22, "Nullness warning: The type 'int' does not support 'null'."] + +[] +let ``Null assignment in generic code`` () = + FSharp """module MyLibrary +let myNullReturningFunction p = + let mutable x = p + x <- null + x + +[] +type X(p:int) = + member _.P = p + +type Y (p:int) = + member _.P = p + +let myValOfX : X = null +let myValOfY : Y = Unchecked.defaultof + +myNullReturningFunction "HiThere" |> ignore +myNullReturningFunction ("HiThere":string | null) |> ignore +myNullReturningFunction (System.DateTime.Now) |> ignore +myNullReturningFunction {|Anon=42|} |> ignore +myNullReturningFunction (1,2,3) |> ignore +myNullReturningFunction myValOfX |> ignore +myNullReturningFunction myValOfY |> ignore + +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics + [Error 3261, Line 17, Col 25, Line 17, Col 34, "Nullness warning: The type 'string' does not support 'null'." + Error 3261, Line 19, Col 26, Line 19, Col 45, "Nullness warning: The type 'System.DateTime' does not support 'null'." + Error 3261, Line 20, Col 25, Line 20, Col 36, "Nullness warning: The type '{| Anon: 'a |}' does not support 'null'." + Error 3261, Line 21, Col 26, Line 21, Col 31, "Nullness warning: The type '('a * 'b * 'c)' does not support 'null'." + Error 3261, Line 23, Col 25, Line 23, Col 33, "Nullness warning: The type 'Y' does not support 'null'."] + +[] +let ``Nullnesss support for F# types`` () = + FSharp """module MyLibrary +type MyDu = A | B +type MyRecord = {X:int;Y:string} + +let strictFunc(arg: 'x when 'x : not null) = + printfn "%A" arg + arg + +let looseFunc(arg: _ | null) = arg + +strictFunc(A) |> ignore +strictFunc({X=1;Y="a"}) |> ignore +strictFunc({|ZZ=15;YZ="a"|}) |> ignore +strictFunc((1,2,3)) |> ignore + +looseFunc(A) |> ignore +looseFunc({X=1;Y="a"}) |> ignore +looseFunc({|ZZ=15;YZ="a"|}) |> ignore +looseFunc((1,2,3)) |> ignore + +strictFunc(null) |> ignore +looseFunc(null) |> ignore + +let maybeDu : _ | null = MyDu.A +let maybeRecd : MyRecord | null = {X=1;Y="a"} +let maybeAnon : _ | null = {|Hello="there"|} +let maybeTuple : (int*int) | null = null + +strictFunc(maybeDu) |> ignore +strictFunc(maybeRecd) |> ignore +strictFunc(maybeAnon) |> ignore +strictFunc(maybeTuple) |> ignore + +looseFunc(maybeDu) |> ignore +looseFunc(maybeRecd) |> ignore +looseFunc(maybeAnon) |> ignore +looseFunc(maybeTuple) |> ignore + +type Maybe<'T> = 'T | null +let maybeTuple2 : Maybe = null +strictFunc(maybeTuple2) |> ignore +looseFunc(maybeTuple2) |> ignore +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics + [ Error 43, Line 21, Col 12, Line 21, Col 16, "The constraints 'null' and 'not null' are inconsistent" + Error 3260, Line 27, Col 18, Line 27, Col 34, "The type '(int * int)' does not support a nullness qualitification." + Error 3261, Line 27, Col 37, Line 27, Col 41, "Nullness warning: The type '(int * int)' does not support 'null'." + Error 3261, Line 29, Col 12, Line 29, Col 19, "Nullness warning: The type 'MyDu | null' supports 'null' but a non-null type is expected." + Error 3261, Line 30, Col 12, Line 30, Col 21, "Nullness warning: The type 'MyRecord | null' supports 'null' but a non-null type is expected." + Error 3261, Line 40, Col 36, Line 40, Col 40, "Nullness warning: The type 'Maybe' does not support 'null'."] + +[] +let ``Static member on Record with null arg`` () = + FSharp """module MyLibrary + +type MyRecord = {X:string;Y:int} + with static member Create(x:string) = {X=x;Y = 42} + +let thisWorks = MyRecord.Create("xx") +let thisShouldWarn = MyRecord.Create(null) +let maybeNull : string | null = "abc" +let thisShouldAlsoWarn = MyRecord.Create(maybeNull) +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics + [Error 3261, Line 7, Col 38, Line 7, Col 42, "Nullness warning: The type 'string' does not support 'null'." + Error 3261, Line 9, Col 42, Line 9, Col 51, "Nullness warning: The types 'string' and 'string | null' do not have equivalent nullability."] + + +[] +let ``Option ofObj should remove nullness when used in a function`` () = + FSharp """module MyLibrary +let processOpt2 (s: string | null) : string option = Option.ofObj s""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Option ofObj should remove nullness when piping`` () = + FSharp """module MyLibrary +let processOpt (s: string | null) : string option = + let stringOpt = Option.ofObj s + stringOpt +let processOpt3 (s: string | null) : string option = s |> Option.ofObj +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Option ofObj called in a useless way raises warning`` () = + FSharp """module MyLibrary + +let processOpt1 (s: string) = Option.ofObj s +let processOpt2 (s: string) : option = + Option.ofObj s +let processOpt3 (s: string) : string option = + let sOpt = Option.ofObj s + sOpt +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics + [ Error 3262, Line 3, Col 44, Line 3, Col 45, "Value known to be without null passed to a function meant for nullables: You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value." + Error 3262, Line 5, Col 18, Line 5, Col 19, "Value known to be without null passed to a function meant for nullables: You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value." + Error 3262, Line 7, Col 29, Line 7, Col 30, "Value known to be without null passed to a function meant for nullables: You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value."] + + +[] +let ``Option ofObj called on a string literal`` () = + FSharp """module MyLibrary +let whatIsThis = Option.ofObj "abc123" +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withErrorCodes [3262] + +[] +let ``Option ofObj for PathGetDirectoryName`` () = + FSharp """module MyLibrary +open System.IO + +let dirName = Path.GetDirectoryName "" +let whatIsThis1 = Option.ofObj dirName +let whatIsThis2 = Option.ofObj ( Path.GetDirectoryName "" ) +let whatIsThis3 = Option.ofObj ("" |> Path.GetDirectoryName ) // Warnings were happening at this line only +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Option ofObj with fully annotated nullsupportive func`` () = + FSharp """module MyLibrary + +let nullSupportiveFunc (x: string | null) : string | null = x +let maybePath : string | null = null +let whatIsThis3 = Option.ofObj (maybePath |> nullSupportiveFunc) +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Option ofObj with calling id inside`` () = + FSharp """module MyLibrary + +let maybePath : string | null = null +let whatIsThis5 = Option.ofObj (id maybePath) +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Useless null pattern match`` () = + FSharp """module MyLibrary + +let clearlyNotNull = "42" +let mappedVal = + match clearlyNotNull with + | null -> 42 + | _ -> 43 +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics [Error 3261, Line 6, Col 7, Line 6, Col 11, "Nullness warning: The type 'string' does not support 'null'."] + +[] +let ``Useless usage of nonNull utility from fscore`` () = + FSharp """module MyLibrary + +let clearlyNotNull = "42" +let mappedVal = nonNull clearlyNotNull +let maybeNull : string | null = null +let mappedMaybe = nonNull maybeNull +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics [Error 3262, Line 4, Col 25, Line 4, Col 39, "Value known to be without null passed to a function meant for nullables: You can remove this `nonNull` assertion."] + +[] +let ``Regression: Useless usage in nested calls`` () = + FSharp """module MyLibrary +open System.IO + +let meTry = Option.ofObj (Path.GetDirectoryName "") +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + + +[] +let ``Useless usage of null active patterns from fscore`` () = + FSharp """module MyLibrary + +let clearlyNotNull = "42" +let mapped1 = + match clearlyNotNull with + | NonNullQuick safe -> safe + +let mapped2 = + match clearlyNotNull with + |Null -> 0 + |NonNull _ -> 1 +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics + [ Error 3262, Line 6, Col 7, Line 6, Col 24, "Value known to be without null passed to a function meant for nullables: You can remove this |NonNullQuick| pattern usage." + Error 3262, Line 10, Col 6, Line 10, Col 10, "Value known to be without null passed to a function meant for nullables: You can remove this |Null|NonNull| pattern usage." + Error 3262, Line 11, Col 6, Line 11, Col 15, "Value known to be without null passed to a function meant for nullables: You can remove this |Null|NonNull| pattern usage."] + +[] +let ``Obj can be passed to not null constrained methods`` () = + FSharp """module MyLibrary + +let objVal:(obj | null) = box 42 + + +let mappableFunc = + match objVal with + |Null -> 42 + |NonNull o -> o.GetHashCode() +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Importing and processing contravariant interfaces`` () = + + FSharp """module MyLibrary + +open System +open System.Collections.Concurrent +open System.Collections.Generic + + +let cmp1 : IEqualityComparer = StringComparer.Ordinal +let cmp2 : IEqualityComparer = StringComparer.Ordinal +let stringHash = cmp2.GetHashCode("abc") +let nullHash = cmp2.GetHashCode(null) +let nullEquals = cmp2.Equals("abc", null) + +let dict = ConcurrentDictionary (StringComparer.Ordinal) +dict["ok"] <- 42 + +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + + +[] +let ``Notnull constraint and inline annotated value`` () = + FSharp """module MyLibrary +open System + +let f3 (x: 'T when 'T : not null) = 1 + +let v3 = f3 (null: obj) +let v4 = f3 (null: String | null) +let v5 = f3 (Some 1) + +let w3 = (null: obj) |> f3 +let w4 = (null: String | null) |> f3 + +let v3WithNull = f3 (null: obj | null) +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics + [ Error 3261, Line 6, Col 14, Line 6, Col 18, "Nullness warning: The type 'obj' does not support 'null'." + Error 3261, Line 7, Col 14, Line 7, Col 33, "Nullness warning: The type 'String | null' supports 'null' but a non-null type is expected." + Error 3261, Line 8, Col 14, Line 8, Col 20, "Nullness warning: The type ''a option' uses 'null' as a representation value but a non-null type is expected." + Error 3261, Line 10, Col 11, Line 10, Col 15, "Nullness warning: The type 'obj' does not support 'null'." + Error 3261, Line 11, Col 35, Line 11, Col 37, "Nullness warning: The type 'String | null' supports 'null' but a non-null type is expected." + Error 3261, Line 13, Col 22, Line 13, Col 38, "Nullness warning: The type 'obj | null' supports 'null' but a non-null type is expected."] \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs new file mode 100644 index 00000000000..e6398675a01 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs @@ -0,0 +1,125 @@ +module Language.NullableRegressions + +open Xunit +open FSharp.Test +open FSharp.Test.Compiler + +let withVersionAndCheckNulls (version,checknulls) cu = + cu + |> withLangVersion version + |> withWarnOn 3261 + |> withOptions ["--warnaserror+"] + |> if checknulls then withCheckNulls else id + + +[] +[] +[] +[] +let ``Micro compilation`` langVersion checknulls = + + FsFromPath (__SOURCE_DIRECTORY__ ++ "micro.fsi") + |> withAdditionalSourceFile (SourceFromPath (__SOURCE_DIRECTORY__ ++ "micro.fs")) + |> withLangVersion langVersion + |> fun x -> + if checknulls then + x |> withCheckNulls |> withDefines ["CHECKNULLS"] + else x + |> compile + |> shouldSucceed + +[] +let ``Existing positive v8 disabled`` compilation = + compilation + |> withVersionAndCheckNulls ("8.0",false) + |> verifyBaseline + +[] +let ``Existing positive vPreview disabled`` compilation = + compilation + |> withVersionAndCheckNulls ("preview",false) + |> verifyBaseline + +[] +let ``Existing positive vPreview enabled`` compilation = + compilation + |> withVersionAndCheckNulls ("preview",true) + |> verifyBaseline + +[] +let ``Existing negative v8 disabled`` compilation = + compilation + |> withVersionAndCheckNulls ("8.0",false) + |> verifyBaseline + +[] +let ``Existing negative vPreview disabled`` compilation = + compilation + |> withVersionAndCheckNulls ("preview",false) + |> verifyBaseline + +[] +let ``Existing negative vPreview enabled`` compilation = + compilation + |> withVersionAndCheckNulls ("preview",true) + |> verifyBaseline + +[] +let ``Library functions nullness disabled`` compilation = + compilation + |> withVersionAndCheckNulls ("preview",false) + |> verifyBaseline + +[] +let ``Library functions nullness enabled`` compilation = + compilation + |> withVersionAndCheckNulls ("preview",true) + |> verifyBaseline + +[] +let ``With new nullness syntax nullness disabled`` compilation = + compilation + |> withVersionAndCheckNulls ("preview",false) + |> verifyBaseline + +[] +let ``DefaultValueBug when checknulls is disabled`` compilation = + compilation + |> withVersionAndCheckNulls ("preview",false) + |> verifyBaseline + +[] +let ``With new nullness syntax nullness enabled`` compilation = + compilation + |> withVersionAndCheckNulls ("preview",true) + |> verifyBaseline + + + +[] +[] +[] +[] +[] +[] +[] +let ``DefaultValue regression`` (version,checknulls,fullCompile) = + FSharp $""" +module MyLib + +[] +type C7 = + [] + val mutable Whoops : (int -> int) {if version="preview" then " | null" else ""} // no warnings in checknulls+ + """ + |> asLibrary + |> withVersionAndCheckNulls (version,checknulls) + |> (if fullCompile then compile else typecheck) + |> fun x -> + if checknulls then + x |> shouldSucceed + else + x + |> shouldFail + |> withDiagnostics + [(Error 444, Line 7, Col 17, Line 7, Col 23, "The type of a field using the 'DefaultValue' attribute must admit default initialization, i.e. have 'null' as a proper value or be a struct type whose fields all admit default initialization. You can use 'DefaultValue(false)' to disable this check")] diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs new file mode 100644 index 00000000000..2f46eb0370e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs @@ -0,0 +1,52 @@ +module ExistingNegative + +open System +open System.Diagnostics +open System.Runtime.CompilerServices + +module NullConstraintTests = + type C<'T when 'T : null>() = class end + + let f1 (y : C< (int * int) >) = y // This gave an error in F# 4.5 and we expect it to continue to give an error + + let f2 (y : C) = y // This gave an error in F# 4.5 and we expect it to continue to give an error + + let f3 (y : C int>) = y // This gave an error in F# 4.5 and we expect it to continue to give an error + +module DefaultValueTests = + + module StructExamples = + [] + type C1 = + [] + val mutable Whoops : String // expect an error if checknulls is on + + [] + type C4a = + [] + val mutable Whoops : int list // This gave an error in F# 4.5 and we expect it to continue to give an error + + [] + type C5 = + [] + val mutable Whoops : int * int // This gave an error in F# 4.5 and we expect it to continue to give an error + + [] + type C6 = + [] + val mutable Whoops : int -> int // This gave an error in F# 4.5 and we expect it to continue to give an error + + module ClassExamples = + + type C4a = + [] + val mutable Whoops : int list // Should have given an error in F# 4.5 but didn't. Expect a corrective error if checknulls is on + + type C5 = + [] + val mutable Whoops : int * int // Should have given an error in F# 4.5 but didn't. Expect a corrective error if checknulls is on + + type C6 = + [] + val mutable Whoops : int -> int // Should have given an error in F# 4.5 but didn't. Expect a corrective error if checknulls is on + diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs.checknulls_on.err.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs.checknulls_on.err.bsl new file mode 100644 index 00000000000..cada047d442 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs.checknulls_on.err.bsl @@ -0,0 +1,10 @@ +existing-negative.fs (10,17)-(10,33) typecheck error Nullness warning: The type '(int * int)' does not support 'null'. +existing-negative.fs (12,17)-(12,28) typecheck error Nullness warning: The type 'int list' does not support 'null'. +existing-negative.fs (14,17)-(14,30) typecheck error Nullness warning: The type '(int -> int)' does not support 'null'. +existing-negative.fs (22,25)-(22,31) typecheck error The type of a field using the 'DefaultValue' attribute must admit default initialization, i.e. have 'null' as a proper value or be a struct type whose fields all admit default initialization. You can use 'DefaultValue(false)' to disable this check +existing-negative.fs (27,25)-(27,31) typecheck error The type of a field using the 'DefaultValue' attribute must admit default initialization, i.e. have 'null' as a proper value or be a struct type whose fields all admit default initialization. You can use 'DefaultValue(false)' to disable this check +existing-negative.fs (32,25)-(32,31) typecheck error The type of a field using the 'DefaultValue' attribute must admit default initialization, i.e. have 'null' as a proper value or be a struct type whose fields all admit default initialization. You can use 'DefaultValue(false)' to disable this check +existing-negative.fs (37,25)-(37,31) typecheck error The type of a field using the 'DefaultValue' attribute must admit default initialization, i.e. have 'null' as a proper value or be a struct type whose fields all admit default initialization. You can use 'DefaultValue(false)' to disable this check +existing-negative.fs (43,25)-(43,31) typecheck error The type of a field using the 'DefaultValue' attribute must admit default initialization, i.e. have 'null' as a proper value or be a struct type whose fields all admit default initialization. You can use 'DefaultValue(false)' to disable this check +existing-negative.fs (47,25)-(47,31) typecheck error The type of a field using the 'DefaultValue' attribute must admit default initialization, i.e. have 'null' as a proper value or be a struct type whose fields all admit default initialization. You can use 'DefaultValue(false)' to disable this check +existing-negative.fs (51,25)-(51,31) typecheck error The type of a field using the 'DefaultValue' attribute must admit default initialization, i.e. have 'null' as a proper value or be a struct type whose fields all admit default initialization. You can use 'DefaultValue(false)' to disable this check \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs.nullness_disabled.err.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs.nullness_disabled.err.bsl new file mode 100644 index 00000000000..eaffe804e94 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs.nullness_disabled.err.bsl @@ -0,0 +1,3 @@ +existing-negative.fs (10,17)-(10,33) typecheck error The type '(int * int)' does not have 'null' as a proper value +existing-negative.fs (12,17)-(12,28) typecheck error The type 'int list' does not have 'null' as a proper value +existing-negative.fs (14,17)-(14,30) typecheck error The type '(int -> int)' does not have 'null' as a proper value \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-positive.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-positive.fs new file mode 100644 index 00000000000..727a1a8b69d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-positive.fs @@ -0,0 +1,69 @@ +module ExistingPositive +open System +open System.Diagnostics +open System.Runtime.CompilerServices + +module Extractions0a = + + let x = null + let result = (x = "") //The type 'string' does not support 'null'. + +module Extractions0b = + + let x = null + let f (x: 'T, y: 'T) = () + let result = f (x, "") //The type 'string' does not support 'null'. + +module Extractions0d = + + let x = null + let f<'T when 'T : null> (x: 'T, y: 'T) = () + let result = f (x, "") //The type 'string' does not support 'null'. + +module Basics = + let x1 : String = null // expect a warning when checknulls is on + let x4 : String = "" + +module Basics2 = + let f1 () = null + let f8 () : String = null // expect a warning when checknulls is on + +type C(s: String) = + member __.Value = s + +module InteropBasics = + let s0 = String.Concat("a","b") + let s1 : String = String.Concat("a","c") + let test1() = String.Concat("a","d") + let test2(s1:String, s2: String) = String.Concat(s1,s2) + let test3() = String( [| 'a' |] ) + let test4() = System.AppDomain.CurrentDomain + let test5 : System.AppDomain = System.AppDomain.CurrentDomain + +System.Console.WriteLine("a") +System.Console.WriteLine("a", (null: obj[])) // expect a warning when checknulls is on + +let f0 line = + let add (s:String) = () + match line with + | null | "" -> () //The type 'string' does not support 'null'. + | _ -> add line + +module NullConstraintTests = + type C<'T when 'T : null>() = class end + + let f3 (y : C) = y // expect a warning when checknulls is on + +module DefaultValueTests = + + module StructExamples = + + [] + type C2 = + [] + val mutable Whoops : String // expect no warning or error under any configuration + + module ClassExamples = + type C2 = + [] + val mutable Whoops : String // expect no warning or error under any configuration diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-positive.fs.checknulls_on.err.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-positive.fs.checknulls_on.err.bsl new file mode 100644 index 00000000000..82848eae396 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-positive.fs.checknulls_on.err.bsl @@ -0,0 +1,8 @@ +existing-positive.fs (9,23)-(9,25) typecheck error Nullness warning: The type 'string' does not support 'null'. +existing-positive.fs (15,24)-(15,26) typecheck error Nullness warning: The type 'string' does not support 'null'. +existing-positive.fs (21,24)-(21,26) typecheck error Nullness warning: The type 'string' does not support 'null'. +existing-positive.fs (24,23)-(24,27) typecheck error Nullness warning: The type 'String' does not support 'null'. +existing-positive.fs (29,26)-(29,30) typecheck error Nullness warning: The type 'String' does not support 'null'. +existing-positive.fs (44,32)-(44,36) typecheck error Nullness warning: The type 'obj array' does not support 'null'. +existing-positive.fs (49,14)-(49,16) typecheck error Nullness warning: The type 'string' does not support 'null'. +existing-positive.fs (55,17)-(55,26) typecheck error Nullness warning: The type 'String' does not support 'null'. \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-positive.fs.nullness_disabled.err.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-positive.fs.nullness_disabled.err.bsl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs new file mode 100644 index 00000000000..03dc226b725 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs @@ -0,0 +1,41 @@ +module LibraryFunctions + +open System + +let x4 : string = "plain string" +let x5 = nonNull ("": string | null) // Should not give a Nullness warning +let x6 = nonNull "" // **Expected to give a Nullness warning +let x7 = nonNull "" +let _x7 : String = x7 +let x8 = nonNull Array.empty +let x9 = nonNull [| "" |] +let x10 = nonNullV (Nullable(3)) +let x11 = try nonNullV (Nullable()) with :? System.NullReferenceException -> 10 +let x12 = nullV +let x13 = nullV +let x14 = withNullV 6L +let x15 : String | null = withNull x4 // This should not warn (is OK if typar is passed, this is wrong) +let x15a : String | null = withNull "" // This should not warn (is OK if typar is passed, this is wrong) +let x15b : String | null = withNull x4 +let x15c : String | null = withNull x4 // **Expected to give a Nullness warning +let x16 : Nullable = withNullV 3 + +let y0 = isNull null // Should not give a Nullness warning (obj) +let y1 = isNull (null: obj | null) // Should not give a Nullness warning +let y1b = isNull (null: String | null) // Should not give a Nullness warning +let y2 = isNull "" // **Expected to give a Nullness warning - type instantiation of a nullable type is non-nullable String +let y9 = isNull "" // **Expected to give a Nullness warning - type instantiation of a nullable type is non-nullable String +let y10 = isNull "" // Should not give a Nullness warning. +// Not yet allowed +//let f7 () : 'T | null when 'T : struct = null +let f7b () : Nullable<'T> = nullV + +let f0b (line:string | null) = + let add (s:String) = () + match line with + | null -> () + | _ -> add (line) // warning expected + +let add (s:String) = () +let f0c line = + add (nonNull "") \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs.checknulls_on.err.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs.checknulls_on.err.bsl new file mode 100644 index 00000000000..a74b139264c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs.checknulls_on.err.bsl @@ -0,0 +1,13 @@ +library-functions.fs (6,27)-(6,29) typecheck error Value known to be without null passed to a function meant for nullables: You can remove this `nonNull` assertion. +library-functions.fs (7,10)-(7,17) typecheck error Nullness warning: The type 'String | null' supports 'null' but a non-null type is expected. +library-functions.fs (7,33)-(7,35) typecheck error Value known to be without null passed to a function meant for nullables: You can remove this `nonNull` assertion. +library-functions.fs (8,18)-(8,20) typecheck error Value known to be without null passed to a function meant for nullables: You can remove this `nonNull` assertion. +library-functions.fs (10,28)-(10,39) typecheck error Value known to be without null passed to a function meant for nullables: You can remove this `nonNull` assertion. +library-functions.fs (11,18)-(11,26) typecheck error Value known to be without null passed to a function meant for nullables: You can remove this `nonNull` assertion. +library-functions.fs (17,27)-(17,38) typecheck error Nullness warning: The types 'String' and 'String | null' do not have equivalent nullability. +library-functions.fs (18,28)-(18,39) typecheck error Nullness warning: The types 'String' and 'String | null' do not have equivalent nullability. +library-functions.fs (20,28)-(20,36) typecheck error Nullness warning: The type 'String | null' supports 'null' but a non-null type is expected. +library-functions.fs (26,17)-(26,19) typecheck error Nullness warning: The type 'string' does not support 'null'. +library-functions.fs (27,10)-(27,16) typecheck error Nullness warning: The type 'String' does not support 'null'. +library-functions.fs (37,17)-(37,21) typecheck error Nullness warning: The types 'String' and 'string | null' do not have equivalent nullability. +library-functions.fs (41,26)-(41,28) typecheck error Value known to be without null passed to a function meant for nullables: You can remove this `nonNull` assertion. \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs.nullness_disabled.err.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs.nullness_disabled.err.bsl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/micro.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/micro.fs new file mode 100644 index 00000000000..a0027c2d0a9 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/micro.fs @@ -0,0 +1,13 @@ + +module M + +let isNotNull (value: 'T) = + match value with + | null -> false + | _ -> true + +#if CHECKNULLS +let s: System.String | null = null +#else +let s: System.String = null +#endif \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/micro.fsi b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/micro.fsi new file mode 100644 index 00000000000..25271ae6d7e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/micro.fsi @@ -0,0 +1,3 @@ + +module M +val isNotNull: value: 'T -> bool when 'T : null \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/positive-defaultValue-bug.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/positive-defaultValue-bug.fs new file mode 100644 index 00000000000..f4b7c1b03d2 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/positive-defaultValue-bug.fs @@ -0,0 +1,13 @@ +module EnabledPositive +open System + +module NotNullConstraint = + let f3 (x: 'T when 'T : not null) = 1 + let v5 = f3 (Some 1) // Expect to give a warning + //let w5 = (Some 1) |> f3 // Expect to give a warning + + +[] +type C4b = + [] + val mutable Whoops : FSharp.Collections.List | null // expect no warning \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/positive-defaultValue-bug.fs.nullness_disabled.err.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/positive-defaultValue-bug.fs.nullness_disabled.err.bsl new file mode 100644 index 00000000000..22970adc345 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/positive-defaultValue-bug.fs.nullness_disabled.err.bsl @@ -0,0 +1,2 @@ +positive-defaultValue-bug.fs (6,18)-(6,24) typecheck error Nullness warning: The type ''a option' uses 'null' as a representation value but a non-null type is expected. +positive-defaultValue-bug.fs (13,17)-(13,23) typecheck error The type of a field using the 'DefaultValue' attribute must admit default initialization, i.e. have 'null' as a proper value or be a struct type whose fields all admit default initialization. You can use 'DefaultValue(false)' to disable this check \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs new file mode 100644 index 00000000000..8f2efd0e02d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs @@ -0,0 +1,237 @@ +module EnabledPositive +open System +module Basics = + let x2 : String | null = null // expect no warning in any configuration + let x3 : String | null = "a" // expect no warning in any configuration + +module NotNullConstraint = + let f3 (x: 'T when 'T : not null) = 1 + let v1 = f3 1 + let v2 = f3 "a" + let v3 = f3 (null: obj) // Expect no warning in any configuration - warnings about 'obj' and nulls are suppressed + let v4 = f3 (null: String | null) // Expect to give a warning + let v5 = f3 (Some 1) // Expect to give a warning + + let w1 = 1 |> f3 + let w2 = "a" |> f3 + let w3 = (null: obj) |> f3 // Expect no warning in any configuration - warnings about 'obj' and nulls are suppressed + let w4 = (null: String | null) |> f3 // Expect to give a warning + let w5 = (Some 1) |> f3 // Expect to give a warning + +module MemberBasics = + type C() = + member x.P = 1 + member x.M() = 2 + + let c : C | null = C() + let v1 = c.P // Expected to give a warning + let v2 = c.M() // Expected to give a warning + let f1 = c.M // Expected to give a warning + + +module Basics2 = + let f1 () = null + + let f2 () : String | null = null + + let f3 () : 'T | null = null + + let f4 () : 'T | null when 'T : not struct = null + + let f5 () : 'T when 'T : not struct and 'T : null = null + + let f8 () : String = null // Expected to give a Nullness warning + + +type C(s: String) = + member __.Value = s + + +// This give a warning since 'T is not known to be reference type non-null +let f<'T when 'T: not null and 'T: not struct > (x: 'T | null, y: 'T | null) = () + +module Extractions0c = + + let x = null + let f<'T when 'T : not null and 'T: not struct> (x: 'T | null, y: 'T | null) = () + let s : String = "" + let result = f (x, s) // expect no warning in any configuration + +module Extractions0e = + + let x = null + let f<'T when 'T : not null and 'T: not struct> (x: 'T | null, y: 'T | null) = () + let result = f (x, "") // expect no warning in any configuration + +module Extractions1 = + + let mutable x : _ | null = null + x <- "" // expect no warning + +//let f<'T when 'T : not struct> (x: 'T | null) = 1 +module InteropBasics = + let s0 = String.Concat("a","b") + let s1 : String = String.Concat("a","c") + let test1() = String.Concat("a","d") + let test2(s1:String, s2: String) = String.Concat(s1,s2) + let test3() = String( [| 'a' |] ) + let test4() = System.AppDomain.CurrentDomain + let test5 : System.AppDomain = System.AppDomain.CurrentDomain + +type KonsoleWithNulls = + static member WriteLine(s: String | null) = Console.WriteLine(s) + static member WriteLine(fmt: String, arg1: String | null) = Console.WriteLine(fmt, arg1) + static member WriteLine(fmt: String, [] args: (obj | null)[] | null) = Console.WriteLine(fmt, args) + static member WriteLineC(s: C | null) = Console.WriteLine(s.Value) + static member WriteLineC(fmt: C | null, arg1: C | null) = Console.WriteLine(fmt.Value, arg1.Value) + +module KonsoleWithNullsModule = + let WriteLine(s: String | null) = Console.WriteLine(s) + let WriteLine2(fmt: String, arg1: String | null) = Console.WriteLine(fmt, arg1) + let WriteLineC(s: C | null) = Console.WriteLine(s.Value) + let WriteLineC2(fmt: C | null, arg1: C | null) = Console.WriteLine(fmt.Value, arg1.Value) + +module KonsoleWithNullsModule2 = + let WriteLine (x : string | null) = KonsoleWithNullsModule.WriteLine x + let WriteLine2 (fmt: string, arg1: string | null) = KonsoleWithNullsModule.WriteLine2(fmt, arg1) + let WriteLineC(s: _ | null) = KonsoleWithNullsModule.WriteLineC(s) + let WriteLineC2(fmt: _ , arg1: _ | null) = KonsoleWithNullsModule.WriteLineC2(fmt, arg1) + +type KonsoleNoNulls = + static member WriteLine(s: String) = Console.WriteLine(s) + static member WriteLine(fmt: String, arg1: String | null) = Console.WriteLine(fmt, arg1) + static member WriteLine(fmt: String, [] args: obj[]) = Console.WriteLine(fmt, args) + static member WriteLineC(s: C) = Console.WriteLine(s.Value) + static member WriteLineC(fmt: C, arg1: C) = Console.WriteLine(fmt.Value, arg1.Value) + +module KonsoleNoNullsModule = + let WriteLine(s: String) = Console.WriteLine(s) + let WriteLine2(fmt: String, arg1: String) = Console.WriteLine(fmt, arg1) + let WriteLineC(s: C) = Console.WriteLine(s.Value) + let WriteLineC2(fmt: C, arg1: C) = Console.WriteLine(fmt.Value, arg1.Value) + +module KonsoleNoNullsModule2 = + let WriteLine x = KonsoleNoNullsModule.WriteLine x + let WriteLine2 (fmt, arg1) = KonsoleNoNullsModule.WriteLine2(fmt, arg1) + let WriteLineC(s) = KonsoleNoNullsModule.WriteLineC(s) + let WriteLineC2(fmt, arg1) = KonsoleNoNullsModule.WriteLineC2(fmt, arg1) + +System.Console.WriteLine("a") +System.Console.WriteLine("a", (null: obj[])) // Expected to give a Nullness warning + +KonsoleWithNulls.WriteLine("Hello world") +KonsoleWithNulls.WriteLine(null) // WRONG: gives an incorrect Nullness warning for String | null and String | null +KonsoleWithNulls.WriteLine("Hello","world") +KonsoleWithNulls.WriteLine("Hello","world","there") // // WRONG: gives an incorrect Nullness warning for String | null and String | null + +KonsoleNoNulls.WriteLine("Hello world") +try + KonsoleNoNulls.WriteLine(null) // Expected to give a Nullness warning +with :? System.ArgumentNullException -> () +KonsoleNoNulls.WriteLine("Hello","world") +//KonsoleNoNulls.WriteLine("Hello",null) // CHECK ME +try + KonsoleNoNulls.WriteLine(null, "World") // Expected to give a Nullness warning +with :? System.ArgumentNullException -> () + +KonsoleWithNullsModule.WriteLine("Hello world") +try + KonsoleWithNullsModule.WriteLine(null) +with :? System.ArgumentNullException -> () +KonsoleWithNullsModule.WriteLine2("Hello","world") +KonsoleWithNullsModule.WriteLine2("Hello",null) +try + KonsoleWithNullsModule.WriteLine2(null,"world") +with :? System.ArgumentNullException -> () + +KonsoleWithNullsModule2.WriteLine("Hello world") +try + KonsoleWithNullsModule2.WriteLine(null) +with :? System.ArgumentNullException -> () +KonsoleWithNullsModule2.WriteLine2("Hello","world") +KonsoleWithNullsModule2.WriteLine2("Hello",null) +try + KonsoleWithNullsModule2.WriteLine2(null,"world") +with :? System.ArgumentNullException -> () + +KonsoleNoNullsModule.WriteLine("Hello world") +try + KonsoleNoNullsModule.WriteLine(null) // Expected to give a Nullness warning +with :? System.ArgumentNullException -> () +KonsoleNoNullsModule.WriteLine2("Hello","world") +KonsoleNoNullsModule.WriteLine2("Hello",null) // Expected to give a Nullness warning +try + KonsoleNoNullsModule.WriteLine2(null,"world") // Expected to give a Nullness warning +with :? System.ArgumentNullException -> () + +//------------------------------------- + +// Param array cases + +KonsoleNoNulls.WriteLine("Hello","world","there") +KonsoleWithNulls.WriteLine("Hello","world",null) // Expected to give a Nullness warning +KonsoleNoNulls.WriteLine("Hello","world",null) // Expected to give a Nullness warning +System.Console.WriteLine("a", (null: obj[] | null)) +System.Console.WriteLine("a", (null: (obj | null)[] | null)) + +//------- +// random stuff + +let f0 line = + let add (s:String) = () + match line with + | null | "" -> () + | _ -> add line // Exected to give a nullness warning + +module NullConstraintTests = + type C<'T when 'T : null>() = class end + + let f3 (y : C) = y // Expect a Nullness warning + + let f4 (y : C) = y // No warning expected + + let f5 (y : C | null>) = y // No warning expected + + let f6 (y : C | null>) = y // No warning expected, lexing/parsing should succeed + +module DefaultValueTests = + + + module StructExamples = + [] + type C2 = + [] + val mutable Whoops : String // expect no warning + + [] + type C3 = + [] + val mutable Whoops : String | null // expect no warning + + [] + type C4b = + [] + val mutable Whoops : FSharp.Collections.List | null // expect no warning + + [] + type C7 = + [] + val mutable Whoops : (int -> int) | null // expect no warning + + module ClassExamples = + + type C2 = + [] + val mutable Whoops : String // expect no warning + + type C3 = + [] + val mutable Whoops : String | null // expect no warning + + type C4b = + [] + val mutable Whoops : int FSharp.Collections.List | null // expect no warning + + type C7 = + [] + val mutable Whoops : (int -> int) | null // expect no warning diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.checknulls_on.err.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.checknulls_on.err.bsl new file mode 100644 index 00000000000..5154ce43e79 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.checknulls_on.err.bsl @@ -0,0 +1,35 @@ +using-nullness-syntax-positive.fs (11,18)-(11,22) typecheck error Nullness warning: The type 'obj' does not support 'null'. +using-nullness-syntax-positive.fs (12,18)-(12,37) typecheck error Nullness warning: The type 'String | null' supports 'null' but a non-null type is expected. +using-nullness-syntax-positive.fs (13,18)-(13,24) typecheck error Nullness warning: The type ''a option' uses 'null' as a representation value but a non-null type is expected. +using-nullness-syntax-positive.fs (17,15)-(17,19) typecheck error Nullness warning: The type 'obj' does not support 'null'. +using-nullness-syntax-positive.fs (18,39)-(18,41) typecheck error Nullness warning: The type 'String | null' supports 'null' but a non-null type is expected. +using-nullness-syntax-positive.fs (19,26)-(19,28) typecheck error Nullness warning: The type 'int option' uses 'null' as a representation value but a non-null type is expected. +using-nullness-syntax-positive.fs (27,14)-(27,17) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (27,14)-(27,17) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (28,14)-(28,19) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (28,14)-(28,19) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (29,14)-(29,17) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (29,14)-(29,17) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (43,26)-(43,30) typecheck error Nullness warning: The type 'String' does not support 'null'. +using-nullness-syntax-positive.fs (85,63)-(85,70) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (85,63)-(85,70) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (86,81)-(86,90) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (86,81)-(86,90) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (86,92)-(86,102) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (86,92)-(86,102) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (91,53)-(91,60) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (91,53)-(91,60) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (92,72)-(92,81) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (92,72)-(92,81) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (92,83)-(92,93) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (92,83)-(92,93) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (120,32)-(120,36) typecheck error Nullness warning: The type 'obj array' does not support 'null'. +using-nullness-syntax-positive.fs (129,4)-(129,34) typecheck error Nullness warning: The type 'String' does not support 'null'. +using-nullness-syntax-positive.fs (134,5)-(134,44) typecheck error Nullness warning: The type 'String' does not support 'null'. +using-nullness-syntax-positive.fs (144,39)-(144,43) typecheck error Nullness warning: The type 'String' does not support 'null'. +using-nullness-syntax-positive.fs (154,40)-(154,44) typecheck error Nullness warning: The type 'string' does not support 'null'. +using-nullness-syntax-positive.fs (159,36)-(159,40) typecheck error Nullness warning: The type 'String' does not support 'null'. +using-nullness-syntax-positive.fs (162,41)-(162,45) typecheck error Nullness warning: The type 'String' does not support 'null'. +using-nullness-syntax-positive.fs (164,37)-(164,41) typecheck error Nullness warning: The type 'String' does not support 'null'. +using-nullness-syntax-positive.fs (183,14)-(183,16) typecheck error Nullness warning: The type 'string' does not support 'null'. +using-nullness-syntax-positive.fs (189,17)-(189,26) typecheck error Nullness warning: The type 'String' does not support 'null'. \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.nullness_disabled.err.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.nullness_disabled.err.bsl new file mode 100644 index 00000000000..cd596951cfe --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.nullness_disabled.err.bsl @@ -0,0 +1,4 @@ +using-nullness-syntax-positive.fs (13,18)-(13,24) typecheck error Nullness warning: The type ''a option' uses 'null' as a representation value but a non-null type is expected. +using-nullness-syntax-positive.fs (19,26)-(19,28) typecheck error Nullness warning: The type 'int option' uses 'null' as a representation value but a non-null type is expected. +using-nullness-syntax-positive.fs (214,25)-(214,31) typecheck error The type of a field using the 'DefaultValue' attribute must admit default initialization, i.e. have 'null' as a proper value or be a struct type whose fields all admit default initialization. You can use 'DefaultValue(false)' to disable this check +using-nullness-syntax-positive.fs (219,25)-(219,31) typecheck error The type of a field using the 'DefaultValue' attribute must admit default initialization, i.e. have 'null' as a proper value or be a struct type whose fields all admit default initialization. You can use 'DefaultValue(false)' to disable this check \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Miscellaneous/MigratedCoreTests.fs b/tests/FSharp.Compiler.ComponentTests/Miscellaneous/MigratedCoreTests.fs index e92ef88592c..1b524fe445a 100644 --- a/tests/FSharp.Compiler.ComponentTests/Miscellaneous/MigratedCoreTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Miscellaneous/MigratedCoreTests.fs @@ -78,11 +78,11 @@ let ``auto-widen-minimal``() = [] let ``auto-widen-version-preview-warns-on``() = - singleVersionedNegTestAux "core/auto-widen/preview" ["--warnon:3388";"--warnon:3389";"--warnon:3395";"--warnaserror+";"--define:NEGATIVE"] LangVersion.Preview "test" + singleVersionedNegTestAux "core/auto-widen/preview" ["--warnon:3388";"--warnon:3389";"--warnon:3395";"--warnaserror+";"--define:NEGATIVE"] LangVersion.V80 "test" [] let ``auto-widen-version-preview-default-warns``() = - singleVersionedNegTestAux "core/auto-widen/preview-default-warns" ["--warnaserror+";"--define:NEGATIVE"] LangVersion.Preview "test" + singleVersionedNegTestAux "core/auto-widen/preview-default-warns" ["--warnaserror+";"--define:NEGATIVE"] LangVersion.V80 "test" [] let ``comprehensions-FSC_DEBUG`` () = singleTestBuildAndRun "core/comprehensions" FSC_DEBUG diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl index 63a16671bca..2d010b9f985 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl @@ -7,6 +7,23 @@ ! AssemblyReference: System.Reflection.Emit.ILGeneration ! AssemblyReference: System.Reflection.Metadata ! AssemblyReference: netstandard +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: j__TPar IntImplIdx +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: j__TPar get_IntImplIdx() +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: j__TPar IntfIdx +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: j__TPar get_IntfIdx() +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: j__TPar TypeIdx +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: j__TPar get_TypeIdx() +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: Boolean Equals(<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]) +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: Boolean Equals(<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar], System.Collections.IEqualityComparer) +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: Boolean Equals(System.Object) +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: Int32 CompareTo(<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]) +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: Int32 CompareTo(System.Object) +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: Int32 CompareTo(System.Object, System.Collections.IComparer) +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: Int32 GetHashCode() +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: Int32 GetHashCode(System.Collections.IEqualityComparer) +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: System.String ToString() +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: Void .ctor(j__TPar, j__TPar, j__TPar) FSharp.Compiler.AbstractIL.IL+ILArgConvention+Tags: Int32 CDecl FSharp.Compiler.AbstractIL.IL+ILArgConvention+Tags: Int32 Default FSharp.Compiler.AbstractIL.IL+ILArgConvention+Tags: Int32 FastCall @@ -301,6 +318,24 @@ FSharp.Compiler.AbstractIL.IL+ILAttribute: Int32 get_Tag() FSharp.Compiler.AbstractIL.IL+ILAttribute: System.String ToString() FSharp.Compiler.AbstractIL.IL+ILAttributes: ILAttribute[] AsArray() FSharp.Compiler.AbstractIL.IL+ILAttributes: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILAttribute] AsList() +FSharp.Compiler.AbstractIL.IL+ILAttributesStored+Given: ILAttributes Item +FSharp.Compiler.AbstractIL.IL+ILAttributesStored+Given: ILAttributes get_Item() +FSharp.Compiler.AbstractIL.IL+ILAttributesStored+Reader: Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,FSharp.Compiler.AbstractIL.IL+ILAttribute[]] Item +FSharp.Compiler.AbstractIL.IL+ILAttributesStored+Reader: Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,FSharp.Compiler.AbstractIL.IL+ILAttribute[]] get_Item() +FSharp.Compiler.AbstractIL.IL+ILAttributesStored+Tags: Int32 Given +FSharp.Compiler.AbstractIL.IL+ILAttributesStored+Tags: Int32 Reader +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: Boolean IsGiven +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: Boolean IsReader +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: Boolean get_IsGiven() +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: Boolean get_IsReader() +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: FSharp.Compiler.AbstractIL.IL+ILAttributesStored+Given +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: FSharp.Compiler.AbstractIL.IL+ILAttributesStored+Reader +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: FSharp.Compiler.AbstractIL.IL+ILAttributesStored+Tags +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: ILAttributes GetCustomAttrs(Int32) +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: ILAttributesStored NewGiven(ILAttributes) +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: ILAttributesStored NewReader(Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,FSharp.Compiler.AbstractIL.IL+ILAttribute[]]) +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: Int32 Tag +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: Int32 get_Tag() FSharp.Compiler.AbstractIL.IL+ILAttributesStored: System.String ToString() FSharp.Compiler.AbstractIL.IL+ILCallingConv: Boolean Equals(ILCallingConv) FSharp.Compiler.AbstractIL.IL+ILCallingConv: Boolean Equals(ILCallingConv, System.Collections.IEqualityComparer) @@ -398,10 +433,14 @@ FSharp.Compiler.AbstractIL.IL+ILEventDef: Boolean get_IsRTSpecialName() FSharp.Compiler.AbstractIL.IL+ILEventDef: Boolean get_IsSpecialName() FSharp.Compiler.AbstractIL.IL+ILEventDef: ILAttributes CustomAttrs FSharp.Compiler.AbstractIL.IL+ILEventDef: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILEventDef: ILAttributesStored CustomAttrsStored +FSharp.Compiler.AbstractIL.IL+ILEventDef: ILAttributesStored get_CustomAttrsStored() FSharp.Compiler.AbstractIL.IL+ILEventDef: ILMethodRef AddMethod FSharp.Compiler.AbstractIL.IL+ILEventDef: ILMethodRef RemoveMethod FSharp.Compiler.AbstractIL.IL+ILEventDef: ILMethodRef get_AddMethod() FSharp.Compiler.AbstractIL.IL+ILEventDef: ILMethodRef get_RemoveMethod() +FSharp.Compiler.AbstractIL.IL+ILEventDef: Int32 MetadataIndex +FSharp.Compiler.AbstractIL.IL+ILEventDef: Int32 get_MetadataIndex() FSharp.Compiler.AbstractIL.IL+ILEventDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodRef] OtherMethods FSharp.Compiler.AbstractIL.IL+ILEventDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodRef] get_OtherMethods() FSharp.Compiler.AbstractIL.IL+ILEventDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodRef] FireMethod @@ -453,10 +492,14 @@ FSharp.Compiler.AbstractIL.IL+ILFieldDef: Boolean get_IsStatic() FSharp.Compiler.AbstractIL.IL+ILFieldDef: Boolean get_NotSerialized() FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILAttributes CustomAttrs FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILAttributesStored CustomAttrsStored +FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILAttributesStored get_CustomAttrsStored() FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILMemberAccess Access FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILMemberAccess get_Access() FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILType FieldType FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILType get_FieldType() +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Int32 MetadataIndex +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Int32 get_MetadataIndex() FSharp.Compiler.AbstractIL.IL+ILFieldDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldInit] LiteralValue FSharp.Compiler.AbstractIL.IL+ILFieldDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldInit] get_LiteralValue() FSharp.Compiler.AbstractIL.IL+ILFieldDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILNativeType] Marshal @@ -775,6 +818,8 @@ FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsVirtual() FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsZeroInit() FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILAttributes CustomAttrs FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILAttributesStored CustomAttrsStored +FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILAttributesStored get_CustomAttrsStored() FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILCallingConv CallingConv FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILCallingConv get_CallingConv() FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILCallingSignature GetCallingSignature() @@ -787,7 +832,9 @@ FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILReturn get_Return() FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILSecurityDecls SecurityDecls FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILSecurityDecls get_SecurityDecls() FSharp.Compiler.AbstractIL.IL+ILMethodDef: Int32 MaxStack +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Int32 MetadataIndex FSharp.Compiler.AbstractIL.IL+ILMethodDef: Int32 get_MaxStack() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Int32 get_MetadataIndex() FSharp.Compiler.AbstractIL.IL+ILMethodDef: MethodBody Body FSharp.Compiler.AbstractIL.IL+ILMethodDef: MethodBody get_Body() FSharp.Compiler.AbstractIL.IL+ILMethodDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef] GenericParams @@ -1247,10 +1294,14 @@ FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Boolean get_IsRTSpecialName() FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Boolean get_IsSpecialName() FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILAttributes CustomAttrs FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILAttributesStored CustomAttrsStored +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILAttributesStored get_CustomAttrsStored() FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILThisConvention CallingConv FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILThisConvention get_CallingConv() FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILType PropertyType FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILType get_PropertyType() +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Int32 MetadataIndex +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Int32 get_MetadataIndex() FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] Args FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] get_Args() FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldInit] Init @@ -1513,6 +1564,8 @@ FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean get_IsStruct() FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean get_IsStructOrEnum() FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILAttributes CustomAttrs FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILAttributesStored CustomAttrsStored +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILAttributesStored get_CustomAttrsStored() FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILDefaultPInvokeEncoding Encoding FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILDefaultPInvokeEncoding get_Encoding() FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILEventDefs Events @@ -1527,25 +1580,29 @@ FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILPropertyDefs Properties FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILPropertyDefs get_Properties() FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILSecurityDecls SecurityDecls FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILSecurityDecls get_SecurityDecls() -FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDef With(Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.TypeAttributes], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType]], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef]], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType]], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodImplDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILEventDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILPropertyDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeDefAdditionalFlags], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILAttributesStored], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILSecurityDecls]) +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDef With(Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.TypeAttributes], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType]], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef]], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType]], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodImplDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILEventDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILPropertyDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeDefAdditionalFlags], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILAttributes], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILSecurityDecls], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.AbstractIL.IL+ILAttributesStored,System.Int32]]]]) FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefAccess Access FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefAccess get_Access() FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefLayout Layout FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefLayout get_Layout() FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefs NestedTypes FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefs get_NestedTypes() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Int32 MetadataIndex +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Int32 get_MetadataIndex() FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef] GenericParams FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef] get_GenericParams() FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] Implements FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] get_Implements() FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType] Extends FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType] get_Extends() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.AbstractIL.IL+ILAttributesStored,System.Int32]]] ImplementsCustomAttrs +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.AbstractIL.IL+ILAttributesStored,System.Int32]]] get_ImplementsCustomAttrs() FSharp.Compiler.AbstractIL.IL+ILTypeDef: System.Reflection.TypeAttributes Attributes FSharp.Compiler.AbstractIL.IL+ILTypeDef: System.Reflection.TypeAttributes get_Attributes() FSharp.Compiler.AbstractIL.IL+ILTypeDef: System.String Name FSharp.Compiler.AbstractIL.IL+ILTypeDef: System.String ToString() FSharp.Compiler.AbstractIL.IL+ILTypeDef: System.String get_Name() -FSharp.Compiler.AbstractIL.IL+ILTypeDef: Void .ctor(System.String, System.Reflection.TypeAttributes, ILTypeDefLayout, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType], ILMethodDefs, ILTypeDefs, ILFieldDefs, ILMethodImplDefs, ILEventDefs, ILPropertyDefs, ILTypeDefAdditionalFlags, ILSecurityDecls, ILAttributesStored) +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Void .ctor(System.String, System.Reflection.TypeAttributes, ILTypeDefLayout, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.AbstractIL.IL+ILAttributesStored,System.Int32]]], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType], ILMethodDefs, ILTypeDefs, ILFieldDefs, ILMethodImplDefs, ILEventDefs, ILPropertyDefs, ILTypeDefAdditionalFlags, ILSecurityDecls, ILAttributes) FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess+Nested: ILMemberAccess Item FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess+Nested: ILMemberAccess get_Item() FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess+Tags: Int32 Nested @@ -5560,21 +5617,25 @@ FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpField,FSharp.Compiler.Symbols.FSharpType]] |Field|_|(FSharp.Compiler.Symbols.FSharpSymbol) FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[FSharp.Compiler.Symbols.FSharpEntity,FSharp.Compiler.Symbols.FSharpEntity,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpType]]] |FSharpEntity|_|(FSharp.Compiler.Symbols.FSharpSymbol) FSharp.Compiler.Symbols.FSharpType: Boolean Equals(System.Object) +FSharp.Compiler.Symbols.FSharpType: Boolean HasNullAnnotation FSharp.Compiler.Symbols.FSharpType: Boolean HasTypeDefinition FSharp.Compiler.Symbols.FSharpType: Boolean IsAbbreviation FSharp.Compiler.Symbols.FSharpType: Boolean IsAnonRecordType FSharp.Compiler.Symbols.FSharpType: Boolean IsFunctionType FSharp.Compiler.Symbols.FSharpType: Boolean IsGenericParameter FSharp.Compiler.Symbols.FSharpType: Boolean IsMeasureType +FSharp.Compiler.Symbols.FSharpType: Boolean IsNullAmbivalent FSharp.Compiler.Symbols.FSharpType: Boolean IsStructTupleType FSharp.Compiler.Symbols.FSharpType: Boolean IsTupleType FSharp.Compiler.Symbols.FSharpType: Boolean IsUnresolved +FSharp.Compiler.Symbols.FSharpType: Boolean get_HasNullAnnotation() FSharp.Compiler.Symbols.FSharpType: Boolean get_HasTypeDefinition() FSharp.Compiler.Symbols.FSharpType: Boolean get_IsAbbreviation() FSharp.Compiler.Symbols.FSharpType: Boolean get_IsAnonRecordType() FSharp.Compiler.Symbols.FSharpType: Boolean get_IsFunctionType() FSharp.Compiler.Symbols.FSharpType: Boolean get_IsGenericParameter() FSharp.Compiler.Symbols.FSharpType: Boolean get_IsMeasureType() +FSharp.Compiler.Symbols.FSharpType: Boolean get_IsNullAmbivalent() FSharp.Compiler.Symbols.FSharpType: Boolean get_IsStructTupleType() FSharp.Compiler.Symbols.FSharpType: Boolean get_IsTupleType() FSharp.Compiler.Symbols.FSharpType: Boolean get_IsUnresolved() @@ -5925,6 +5986,18 @@ FSharp.Compiler.Syntax.ParsedHashDirective: Microsoft.FSharp.Collections.FSharpL FSharp.Compiler.Syntax.ParsedHashDirective: System.String ToString() FSharp.Compiler.Syntax.ParsedHashDirective: System.String get_ident() FSharp.Compiler.Syntax.ParsedHashDirective: System.String ident +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Ident: FSharp.Compiler.Syntax.Ident get_value() +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Ident: FSharp.Compiler.Syntax.Ident value +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Ident: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Ident: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Int32: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Int32: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Int32: Int32 get_value() +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Int32: Int32 value +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+LongIdent: FSharp.Compiler.Syntax.SynLongIdent get_value() +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+LongIdent: FSharp.Compiler.Syntax.SynLongIdent value +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+LongIdent: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+LongIdent: FSharp.Compiler.Text.Range range FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier: FSharp.Compiler.Text.Range get_range() FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier: FSharp.Compiler.Text.Range range FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier: System.String constant @@ -5937,14 +6010,29 @@ FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: FSharp.Compiler.Text. FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: FSharp.Compiler.Text.Range range FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: System.String get_value() FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: System.String value +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Tags: Int32 Ident +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Tags: Int32 Int32 +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Tags: Int32 LongIdent FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Tags: Int32 SourceIdentifier FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Tags: Int32 String +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean IsIdent +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean IsInt32 +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean IsLongIdent FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean IsSourceIdentifier FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean IsString +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean get_IsIdent() +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean get_IsInt32() +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean get_IsLongIdent() FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean get_IsSourceIdentifier() FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean get_IsString() +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument NewIdent(FSharp.Compiler.Syntax.Ident, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument NewInt32(Int32, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument NewLongIdent(FSharp.Compiler.Syntax.SynLongIdent, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument NewSourceIdentifier(System.String, System.String, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument NewString(System.String, FSharp.Compiler.Syntax.SynStringKind, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Ident +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Int32 +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+LongIdent FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Tags @@ -9041,6 +9129,8 @@ FSharp.Compiler.Syntax.SynType+StaticConstantNamed: FSharp.Compiler.Syntax.SynTy FSharp.Compiler.Syntax.SynType+StaticConstantNamed: FSharp.Compiler.Syntax.SynType value FSharp.Compiler.Syntax.SynType+StaticConstantNamed: FSharp.Compiler.Text.Range get_range() FSharp.Compiler.Syntax.SynType+StaticConstantNamed: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynType+StaticConstantNull: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynType+StaticConstantNull: FSharp.Compiler.Text.Range range FSharp.Compiler.Syntax.SynType+Tags: Int32 Anon FSharp.Compiler.Syntax.SynType+Tags: Int32 AnonRecd FSharp.Compiler.Syntax.SynType+Tags: Int32 App @@ -9058,9 +9148,11 @@ FSharp.Compiler.Syntax.SynType+Tags: Int32 SignatureParameter FSharp.Compiler.Syntax.SynType+Tags: Int32 StaticConstant FSharp.Compiler.Syntax.SynType+Tags: Int32 StaticConstantExpr FSharp.Compiler.Syntax.SynType+Tags: Int32 StaticConstantNamed +FSharp.Compiler.Syntax.SynType+Tags: Int32 StaticConstantNull FSharp.Compiler.Syntax.SynType+Tags: Int32 Tuple FSharp.Compiler.Syntax.SynType+Tags: Int32 Var FSharp.Compiler.Syntax.SynType+Tags: Int32 WithGlobalConstraints +FSharp.Compiler.Syntax.SynType+Tags: Int32 WithNull FSharp.Compiler.Syntax.SynType+Tuple: Boolean get_isStruct() FSharp.Compiler.Syntax.SynType+Tuple: Boolean isStruct FSharp.Compiler.Syntax.SynType+Tuple: FSharp.Compiler.Text.Range get_range() @@ -9077,6 +9169,12 @@ FSharp.Compiler.Syntax.SynType+WithGlobalConstraints: FSharp.Compiler.Text.Range FSharp.Compiler.Syntax.SynType+WithGlobalConstraints: FSharp.Compiler.Text.Range range FSharp.Compiler.Syntax.SynType+WithGlobalConstraints: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeConstraint] constraints FSharp.Compiler.Syntax.SynType+WithGlobalConstraints: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeConstraint] get_constraints() +FSharp.Compiler.Syntax.SynType+WithNull: Boolean ambivalent +FSharp.Compiler.Syntax.SynType+WithNull: Boolean get_ambivalent() +FSharp.Compiler.Syntax.SynType+WithNull: FSharp.Compiler.Syntax.SynType get_innerType() +FSharp.Compiler.Syntax.SynType+WithNull: FSharp.Compiler.Syntax.SynType innerType +FSharp.Compiler.Syntax.SynType+WithNull: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynType+WithNull: FSharp.Compiler.Text.Range range FSharp.Compiler.Syntax.SynType: Boolean IsAnon FSharp.Compiler.Syntax.SynType: Boolean IsAnonRecd FSharp.Compiler.Syntax.SynType: Boolean IsApp @@ -9094,9 +9192,11 @@ FSharp.Compiler.Syntax.SynType: Boolean IsSignatureParameter FSharp.Compiler.Syntax.SynType: Boolean IsStaticConstant FSharp.Compiler.Syntax.SynType: Boolean IsStaticConstantExpr FSharp.Compiler.Syntax.SynType: Boolean IsStaticConstantNamed +FSharp.Compiler.Syntax.SynType: Boolean IsStaticConstantNull FSharp.Compiler.Syntax.SynType: Boolean IsTuple FSharp.Compiler.Syntax.SynType: Boolean IsVar FSharp.Compiler.Syntax.SynType: Boolean IsWithGlobalConstraints +FSharp.Compiler.Syntax.SynType: Boolean IsWithNull FSharp.Compiler.Syntax.SynType: Boolean get_IsAnon() FSharp.Compiler.Syntax.SynType: Boolean get_IsAnonRecd() FSharp.Compiler.Syntax.SynType: Boolean get_IsApp() @@ -9114,9 +9214,11 @@ FSharp.Compiler.Syntax.SynType: Boolean get_IsSignatureParameter() FSharp.Compiler.Syntax.SynType: Boolean get_IsStaticConstant() FSharp.Compiler.Syntax.SynType: Boolean get_IsStaticConstantExpr() FSharp.Compiler.Syntax.SynType: Boolean get_IsStaticConstantNamed() +FSharp.Compiler.Syntax.SynType: Boolean get_IsStaticConstantNull() FSharp.Compiler.Syntax.SynType: Boolean get_IsTuple() FSharp.Compiler.Syntax.SynType: Boolean get_IsVar() FSharp.Compiler.Syntax.SynType: Boolean get_IsWithGlobalConstraints() +FSharp.Compiler.Syntax.SynType: Boolean get_IsWithNull() FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewAnon(FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewAnonRecd(Boolean, Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.Syntax.Ident,FSharp.Compiler.Syntax.SynType]], FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewApp(FSharp.Compiler.Syntax.SynType, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Boolean, FSharp.Compiler.Text.Range) @@ -9134,9 +9236,11 @@ FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewSignatureParam FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewStaticConstant(FSharp.Compiler.Syntax.SynConst, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewStaticConstantExpr(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewStaticConstantNamed(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewStaticConstantNull(FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewTuple(Boolean, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTupleTypeSegment], FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewVar(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewWithGlobalConstraints(FSharp.Compiler.Syntax.SynType, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeConstraint], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewWithNull(FSharp.Compiler.Syntax.SynType, Boolean, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+Anon FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+AnonRecd FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+App @@ -9154,10 +9258,12 @@ FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+SignatureParamete FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+StaticConstant FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+StaticConstantExpr FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+StaticConstantNamed +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+StaticConstantNull FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+Tags FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+Tuple FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+Var FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+WithGlobalConstraints +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+WithNull FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Text.Range Range FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Text.Range get_Range() FSharp.Compiler.Syntax.SynType: Int32 Tag @@ -9172,6 +9278,7 @@ FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparIsEquatable FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparIsReferenceType FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparIsUnmanaged FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparIsValueType +FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparNotSupportsNull FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparSubtypeOfType FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparSupportsMember FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparSupportsNull @@ -9217,6 +9324,10 @@ FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsValueType: FSharp.Compiler. FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsValueType: FSharp.Compiler.Syntax.SynTypar typar FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsValueType: FSharp.Compiler.Text.Range get_range() FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsValueType: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparNotSupportsNull: FSharp.Compiler.Syntax.SynTypar genericName +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparNotSupportsNull: FSharp.Compiler.Syntax.SynTypar get_genericName() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparNotSupportsNull: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparNotSupportsNull: FSharp.Compiler.Text.Range range FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSubtypeOfType: FSharp.Compiler.Syntax.SynTypar get_typar() FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSubtypeOfType: FSharp.Compiler.Syntax.SynTypar typar FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSubtypeOfType: FSharp.Compiler.Syntax.SynType get_typeName() @@ -9242,6 +9353,7 @@ FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparIsEquatable FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparIsReferenceType FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparIsUnmanaged FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparIsValueType +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparNotSupportsNull FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparSubtypeOfType FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparSupportsMember FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparSupportsNull @@ -9254,6 +9366,7 @@ FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparIsEquatable() FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparIsReferenceType() FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparIsUnmanaged() FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparIsValueType() +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparNotSupportsNull() FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparSubtypeOfType() FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparSupportsMember() FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparSupportsNull() @@ -9266,6 +9379,7 @@ FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstrai FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparIsReferenceType(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparIsUnmanaged(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparIsValueType(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparNotSupportsNull(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparSubtypeOfType(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparSupportsMember(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynMemberSig, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparSupportsNull(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Text.Range) @@ -9279,6 +9393,7 @@ FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstrai FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsReferenceType FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsUnmanaged FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsValueType +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparNotSupportsNull FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSubtypeOfType FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSupportsMember FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSupportsNull diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl index e8647e3f6ba..4dd172f9462 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl @@ -7,6 +7,23 @@ ! AssemblyReference: System.Reflection.Emit.ILGeneration ! AssemblyReference: System.Reflection.Metadata ! AssemblyReference: netstandard +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: j__TPar IntImplIdx +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: j__TPar get_IntImplIdx() +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: j__TPar IntfIdx +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: j__TPar get_IntfIdx() +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: j__TPar TypeIdx +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: j__TPar get_TypeIdx() +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: Boolean Equals(<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]) +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: Boolean Equals(<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar], System.Collections.IEqualityComparer) +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: Boolean Equals(System.Object) +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: Int32 CompareTo(<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]) +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: Int32 CompareTo(System.Object) +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: Int32 CompareTo(System.Object, System.Collections.IComparer) +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: Int32 GetHashCode() +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: Int32 GetHashCode(System.Collections.IEqualityComparer) +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: System.String ToString() +<>f__AnonymousType10003411232265`3[j__TPar,j__TPar,j__TPar]: Void .ctor(j__TPar, j__TPar, j__TPar) FSharp.Compiler.AbstractIL.IL+ILArgConvention+Tags: Int32 CDecl FSharp.Compiler.AbstractIL.IL+ILArgConvention+Tags: Int32 Default FSharp.Compiler.AbstractIL.IL+ILArgConvention+Tags: Int32 FastCall @@ -301,6 +318,24 @@ FSharp.Compiler.AbstractIL.IL+ILAttribute: Int32 get_Tag() FSharp.Compiler.AbstractIL.IL+ILAttribute: System.String ToString() FSharp.Compiler.AbstractIL.IL+ILAttributes: ILAttribute[] AsArray() FSharp.Compiler.AbstractIL.IL+ILAttributes: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILAttribute] AsList() +FSharp.Compiler.AbstractIL.IL+ILAttributesStored+Given: ILAttributes Item +FSharp.Compiler.AbstractIL.IL+ILAttributesStored+Given: ILAttributes get_Item() +FSharp.Compiler.AbstractIL.IL+ILAttributesStored+Reader: Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,FSharp.Compiler.AbstractIL.IL+ILAttribute[]] Item +FSharp.Compiler.AbstractIL.IL+ILAttributesStored+Reader: Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,FSharp.Compiler.AbstractIL.IL+ILAttribute[]] get_Item() +FSharp.Compiler.AbstractIL.IL+ILAttributesStored+Tags: Int32 Given +FSharp.Compiler.AbstractIL.IL+ILAttributesStored+Tags: Int32 Reader +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: Boolean IsGiven +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: Boolean IsReader +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: Boolean get_IsGiven() +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: Boolean get_IsReader() +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: FSharp.Compiler.AbstractIL.IL+ILAttributesStored+Given +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: FSharp.Compiler.AbstractIL.IL+ILAttributesStored+Reader +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: FSharp.Compiler.AbstractIL.IL+ILAttributesStored+Tags +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: ILAttributes GetCustomAttrs(Int32) +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: ILAttributesStored NewGiven(ILAttributes) +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: ILAttributesStored NewReader(Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,FSharp.Compiler.AbstractIL.IL+ILAttribute[]]) +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: Int32 Tag +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: Int32 get_Tag() FSharp.Compiler.AbstractIL.IL+ILAttributesStored: System.String ToString() FSharp.Compiler.AbstractIL.IL+ILCallingConv: Boolean Equals(ILCallingConv) FSharp.Compiler.AbstractIL.IL+ILCallingConv: Boolean Equals(ILCallingConv, System.Collections.IEqualityComparer) @@ -398,10 +433,14 @@ FSharp.Compiler.AbstractIL.IL+ILEventDef: Boolean get_IsRTSpecialName() FSharp.Compiler.AbstractIL.IL+ILEventDef: Boolean get_IsSpecialName() FSharp.Compiler.AbstractIL.IL+ILEventDef: ILAttributes CustomAttrs FSharp.Compiler.AbstractIL.IL+ILEventDef: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILEventDef: ILAttributesStored CustomAttrsStored +FSharp.Compiler.AbstractIL.IL+ILEventDef: ILAttributesStored get_CustomAttrsStored() FSharp.Compiler.AbstractIL.IL+ILEventDef: ILMethodRef AddMethod FSharp.Compiler.AbstractIL.IL+ILEventDef: ILMethodRef RemoveMethod FSharp.Compiler.AbstractIL.IL+ILEventDef: ILMethodRef get_AddMethod() FSharp.Compiler.AbstractIL.IL+ILEventDef: ILMethodRef get_RemoveMethod() +FSharp.Compiler.AbstractIL.IL+ILEventDef: Int32 MetadataIndex +FSharp.Compiler.AbstractIL.IL+ILEventDef: Int32 get_MetadataIndex() FSharp.Compiler.AbstractIL.IL+ILEventDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodRef] OtherMethods FSharp.Compiler.AbstractIL.IL+ILEventDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodRef] get_OtherMethods() FSharp.Compiler.AbstractIL.IL+ILEventDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodRef] FireMethod @@ -453,10 +492,14 @@ FSharp.Compiler.AbstractIL.IL+ILFieldDef: Boolean get_IsStatic() FSharp.Compiler.AbstractIL.IL+ILFieldDef: Boolean get_NotSerialized() FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILAttributes CustomAttrs FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILAttributesStored CustomAttrsStored +FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILAttributesStored get_CustomAttrsStored() FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILMemberAccess Access FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILMemberAccess get_Access() FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILType FieldType FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILType get_FieldType() +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Int32 MetadataIndex +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Int32 get_MetadataIndex() FSharp.Compiler.AbstractIL.IL+ILFieldDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldInit] LiteralValue FSharp.Compiler.AbstractIL.IL+ILFieldDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldInit] get_LiteralValue() FSharp.Compiler.AbstractIL.IL+ILFieldDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILNativeType] Marshal @@ -775,6 +818,8 @@ FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsVirtual() FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsZeroInit() FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILAttributes CustomAttrs FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILAttributesStored CustomAttrsStored +FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILAttributesStored get_CustomAttrsStored() FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILCallingConv CallingConv FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILCallingConv get_CallingConv() FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILCallingSignature GetCallingSignature() @@ -787,7 +832,9 @@ FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILReturn get_Return() FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILSecurityDecls SecurityDecls FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILSecurityDecls get_SecurityDecls() FSharp.Compiler.AbstractIL.IL+ILMethodDef: Int32 MaxStack +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Int32 MetadataIndex FSharp.Compiler.AbstractIL.IL+ILMethodDef: Int32 get_MaxStack() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Int32 get_MetadataIndex() FSharp.Compiler.AbstractIL.IL+ILMethodDef: MethodBody Body FSharp.Compiler.AbstractIL.IL+ILMethodDef: MethodBody get_Body() FSharp.Compiler.AbstractIL.IL+ILMethodDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef] GenericParams @@ -1247,10 +1294,14 @@ FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Boolean get_IsRTSpecialName() FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Boolean get_IsSpecialName() FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILAttributes CustomAttrs FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILAttributesStored CustomAttrsStored +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILAttributesStored get_CustomAttrsStored() FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILThisConvention CallingConv FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILThisConvention get_CallingConv() FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILType PropertyType FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILType get_PropertyType() +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Int32 MetadataIndex +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Int32 get_MetadataIndex() FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] Args FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] get_Args() FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldInit] Init @@ -1513,6 +1564,8 @@ FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean get_IsStruct() FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean get_IsStructOrEnum() FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILAttributes CustomAttrs FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILAttributesStored CustomAttrsStored +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILAttributesStored get_CustomAttrsStored() FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILDefaultPInvokeEncoding Encoding FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILDefaultPInvokeEncoding get_Encoding() FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILEventDefs Events @@ -1527,25 +1580,29 @@ FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILPropertyDefs Properties FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILPropertyDefs get_Properties() FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILSecurityDecls SecurityDecls FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILSecurityDecls get_SecurityDecls() -FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDef With(Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.TypeAttributes], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType]], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef]], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType]], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodImplDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILEventDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILPropertyDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeDefAdditionalFlags], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILAttributesStored], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILSecurityDecls]) +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDef With(Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.TypeAttributes], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType]], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef]], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType]], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodImplDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILEventDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILPropertyDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeDefAdditionalFlags], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILAttributes], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILSecurityDecls], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.AbstractIL.IL+ILAttributesStored,System.Int32]]]]) FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefAccess Access FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefAccess get_Access() FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefLayout Layout FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefLayout get_Layout() FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefs NestedTypes FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefs get_NestedTypes() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Int32 MetadataIndex +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Int32 get_MetadataIndex() FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef] GenericParams FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef] get_GenericParams() FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] Implements FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] get_Implements() FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType] Extends FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType] get_Extends() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.AbstractIL.IL+ILAttributesStored,System.Int32]]] ImplementsCustomAttrs +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.AbstractIL.IL+ILAttributesStored,System.Int32]]] get_ImplementsCustomAttrs() FSharp.Compiler.AbstractIL.IL+ILTypeDef: System.Reflection.TypeAttributes Attributes FSharp.Compiler.AbstractIL.IL+ILTypeDef: System.Reflection.TypeAttributes get_Attributes() FSharp.Compiler.AbstractIL.IL+ILTypeDef: System.String Name FSharp.Compiler.AbstractIL.IL+ILTypeDef: System.String ToString() FSharp.Compiler.AbstractIL.IL+ILTypeDef: System.String get_Name() -FSharp.Compiler.AbstractIL.IL+ILTypeDef: Void .ctor(System.String, System.Reflection.TypeAttributes, ILTypeDefLayout, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType], ILMethodDefs, ILTypeDefs, ILFieldDefs, ILMethodImplDefs, ILEventDefs, ILPropertyDefs, ILTypeDefAdditionalFlags, ILSecurityDecls, ILAttributesStored) +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Void .ctor(System.String, System.Reflection.TypeAttributes, ILTypeDefLayout, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.AbstractIL.IL+ILAttributesStored,System.Int32]]], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType], ILMethodDefs, ILTypeDefs, ILFieldDefs, ILMethodImplDefs, ILEventDefs, ILPropertyDefs, ILTypeDefAdditionalFlags, ILSecurityDecls, ILAttributes) FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess+Nested: ILMemberAccess Item FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess+Nested: ILMemberAccess get_Item() FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess+Tags: Int32 Nested @@ -5595,21 +5652,25 @@ FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpField,FSharp.Compiler.Symbols.FSharpType]] |Field|_|(FSharp.Compiler.Symbols.FSharpSymbol) FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[FSharp.Compiler.Symbols.FSharpEntity,FSharp.Compiler.Symbols.FSharpEntity,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpType]]] |FSharpEntity|_|(FSharp.Compiler.Symbols.FSharpSymbol) FSharp.Compiler.Symbols.FSharpType: Boolean Equals(System.Object) +FSharp.Compiler.Symbols.FSharpType: Boolean HasNullAnnotation FSharp.Compiler.Symbols.FSharpType: Boolean HasTypeDefinition FSharp.Compiler.Symbols.FSharpType: Boolean IsAbbreviation FSharp.Compiler.Symbols.FSharpType: Boolean IsAnonRecordType FSharp.Compiler.Symbols.FSharpType: Boolean IsFunctionType FSharp.Compiler.Symbols.FSharpType: Boolean IsGenericParameter FSharp.Compiler.Symbols.FSharpType: Boolean IsMeasureType +FSharp.Compiler.Symbols.FSharpType: Boolean IsNullAmbivalent FSharp.Compiler.Symbols.FSharpType: Boolean IsStructTupleType FSharp.Compiler.Symbols.FSharpType: Boolean IsTupleType FSharp.Compiler.Symbols.FSharpType: Boolean IsUnresolved +FSharp.Compiler.Symbols.FSharpType: Boolean get_HasNullAnnotation() FSharp.Compiler.Symbols.FSharpType: Boolean get_HasTypeDefinition() FSharp.Compiler.Symbols.FSharpType: Boolean get_IsAbbreviation() FSharp.Compiler.Symbols.FSharpType: Boolean get_IsAnonRecordType() FSharp.Compiler.Symbols.FSharpType: Boolean get_IsFunctionType() FSharp.Compiler.Symbols.FSharpType: Boolean get_IsGenericParameter() FSharp.Compiler.Symbols.FSharpType: Boolean get_IsMeasureType() +FSharp.Compiler.Symbols.FSharpType: Boolean get_IsNullAmbivalent() FSharp.Compiler.Symbols.FSharpType: Boolean get_IsStructTupleType() FSharp.Compiler.Symbols.FSharpType: Boolean get_IsTupleType() FSharp.Compiler.Symbols.FSharpType: Boolean get_IsUnresolved() @@ -9103,6 +9164,8 @@ FSharp.Compiler.Syntax.SynType+StaticConstantNamed: FSharp.Compiler.Syntax.SynTy FSharp.Compiler.Syntax.SynType+StaticConstantNamed: FSharp.Compiler.Syntax.SynType value FSharp.Compiler.Syntax.SynType+StaticConstantNamed: FSharp.Compiler.Text.Range get_range() FSharp.Compiler.Syntax.SynType+StaticConstantNamed: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynType+StaticConstantNull: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynType+StaticConstantNull: FSharp.Compiler.Text.Range range FSharp.Compiler.Syntax.SynType+Tags: Int32 Anon FSharp.Compiler.Syntax.SynType+Tags: Int32 AnonRecd FSharp.Compiler.Syntax.SynType+Tags: Int32 App @@ -9120,9 +9183,11 @@ FSharp.Compiler.Syntax.SynType+Tags: Int32 SignatureParameter FSharp.Compiler.Syntax.SynType+Tags: Int32 StaticConstant FSharp.Compiler.Syntax.SynType+Tags: Int32 StaticConstantExpr FSharp.Compiler.Syntax.SynType+Tags: Int32 StaticConstantNamed +FSharp.Compiler.Syntax.SynType+Tags: Int32 StaticConstantNull FSharp.Compiler.Syntax.SynType+Tags: Int32 Tuple FSharp.Compiler.Syntax.SynType+Tags: Int32 Var FSharp.Compiler.Syntax.SynType+Tags: Int32 WithGlobalConstraints +FSharp.Compiler.Syntax.SynType+Tags: Int32 WithNull FSharp.Compiler.Syntax.SynType+Tuple: Boolean get_isStruct() FSharp.Compiler.Syntax.SynType+Tuple: Boolean isStruct FSharp.Compiler.Syntax.SynType+Tuple: FSharp.Compiler.Text.Range get_range() @@ -9139,6 +9204,12 @@ FSharp.Compiler.Syntax.SynType+WithGlobalConstraints: FSharp.Compiler.Text.Range FSharp.Compiler.Syntax.SynType+WithGlobalConstraints: FSharp.Compiler.Text.Range range FSharp.Compiler.Syntax.SynType+WithGlobalConstraints: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeConstraint] constraints FSharp.Compiler.Syntax.SynType+WithGlobalConstraints: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeConstraint] get_constraints() +FSharp.Compiler.Syntax.SynType+WithNull: Boolean ambivalent +FSharp.Compiler.Syntax.SynType+WithNull: Boolean get_ambivalent() +FSharp.Compiler.Syntax.SynType+WithNull: FSharp.Compiler.Syntax.SynType get_innerType() +FSharp.Compiler.Syntax.SynType+WithNull: FSharp.Compiler.Syntax.SynType innerType +FSharp.Compiler.Syntax.SynType+WithNull: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynType+WithNull: FSharp.Compiler.Text.Range range FSharp.Compiler.Syntax.SynType: Boolean IsAnon FSharp.Compiler.Syntax.SynType: Boolean IsAnonRecd FSharp.Compiler.Syntax.SynType: Boolean IsApp @@ -9156,9 +9227,11 @@ FSharp.Compiler.Syntax.SynType: Boolean IsSignatureParameter FSharp.Compiler.Syntax.SynType: Boolean IsStaticConstant FSharp.Compiler.Syntax.SynType: Boolean IsStaticConstantExpr FSharp.Compiler.Syntax.SynType: Boolean IsStaticConstantNamed +FSharp.Compiler.Syntax.SynType: Boolean IsStaticConstantNull FSharp.Compiler.Syntax.SynType: Boolean IsTuple FSharp.Compiler.Syntax.SynType: Boolean IsVar FSharp.Compiler.Syntax.SynType: Boolean IsWithGlobalConstraints +FSharp.Compiler.Syntax.SynType: Boolean IsWithNull FSharp.Compiler.Syntax.SynType: Boolean get_IsAnon() FSharp.Compiler.Syntax.SynType: Boolean get_IsAnonRecd() FSharp.Compiler.Syntax.SynType: Boolean get_IsApp() @@ -9176,9 +9249,11 @@ FSharp.Compiler.Syntax.SynType: Boolean get_IsSignatureParameter() FSharp.Compiler.Syntax.SynType: Boolean get_IsStaticConstant() FSharp.Compiler.Syntax.SynType: Boolean get_IsStaticConstantExpr() FSharp.Compiler.Syntax.SynType: Boolean get_IsStaticConstantNamed() +FSharp.Compiler.Syntax.SynType: Boolean get_IsStaticConstantNull() FSharp.Compiler.Syntax.SynType: Boolean get_IsTuple() FSharp.Compiler.Syntax.SynType: Boolean get_IsVar() FSharp.Compiler.Syntax.SynType: Boolean get_IsWithGlobalConstraints() +FSharp.Compiler.Syntax.SynType: Boolean get_IsWithNull() FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewAnon(FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewAnonRecd(Boolean, Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.Syntax.Ident,FSharp.Compiler.Syntax.SynType]], FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewApp(FSharp.Compiler.Syntax.SynType, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Boolean, FSharp.Compiler.Text.Range) @@ -9196,9 +9271,11 @@ FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewSignatureParam FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewStaticConstant(FSharp.Compiler.Syntax.SynConst, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewStaticConstantExpr(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewStaticConstantNamed(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewStaticConstantNull(FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewTuple(Boolean, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTupleTypeSegment], FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewVar(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewWithGlobalConstraints(FSharp.Compiler.Syntax.SynType, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeConstraint], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewWithNull(FSharp.Compiler.Syntax.SynType, Boolean, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+Anon FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+AnonRecd FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+App @@ -9216,10 +9293,12 @@ FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+SignatureParamete FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+StaticConstant FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+StaticConstantExpr FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+StaticConstantNamed +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+StaticConstantNull FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+Tags FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+Tuple FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+Var FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+WithGlobalConstraints +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+WithNull FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Text.Range Range FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Text.Range get_Range() FSharp.Compiler.Syntax.SynType: Int32 Tag @@ -9234,6 +9313,7 @@ FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparIsEquatable FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparIsReferenceType FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparIsUnmanaged FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparIsValueType +FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparNotSupportsNull FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparSubtypeOfType FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparSupportsMember FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparSupportsNull @@ -9279,6 +9359,10 @@ FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsValueType: FSharp.Compiler. FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsValueType: FSharp.Compiler.Syntax.SynTypar typar FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsValueType: FSharp.Compiler.Text.Range get_range() FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsValueType: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparNotSupportsNull: FSharp.Compiler.Syntax.SynTypar genericName +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparNotSupportsNull: FSharp.Compiler.Syntax.SynTypar get_genericName() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparNotSupportsNull: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparNotSupportsNull: FSharp.Compiler.Text.Range range FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSubtypeOfType: FSharp.Compiler.Syntax.SynTypar get_typar() FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSubtypeOfType: FSharp.Compiler.Syntax.SynTypar typar FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSubtypeOfType: FSharp.Compiler.Syntax.SynType get_typeName() @@ -9304,6 +9388,7 @@ FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparIsEquatable FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparIsReferenceType FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparIsUnmanaged FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparIsValueType +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparNotSupportsNull FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparSubtypeOfType FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparSupportsMember FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparSupportsNull @@ -9316,6 +9401,7 @@ FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparIsEquatable() FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparIsReferenceType() FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparIsUnmanaged() FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparIsValueType() +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparNotSupportsNull() FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparSubtypeOfType() FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparSupportsMember() FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparSupportsNull() @@ -9328,6 +9414,7 @@ FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstrai FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparIsReferenceType(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparIsUnmanaged(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparIsValueType(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparNotSupportsNull(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparSubtypeOfType(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparSupportsMember(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynMemberSig, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparSupportsNull(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Text.Range) @@ -9341,6 +9428,7 @@ FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstrai FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsReferenceType FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsUnmanaged FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsValueType +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparNotSupportsNull FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSubtypeOfType FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSupportsMember FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSupportsNull diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj index d0af2696e3b..18a5b4d696b 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj @@ -75,6 +75,12 @@ + + + SyntaxTreeTestSource\%(RecursiveDir)\%(Extension)\%(Filename)%(Extension) + + + diff --git a/tests/FSharp.Compiler.Service.Tests/ModuleReaderCancellationTests.fs b/tests/FSharp.Compiler.Service.Tests/ModuleReaderCancellationTests.fs index 8038cb8ad38..59391934fd2 100644 --- a/tests/FSharp.Compiler.Service.Tests/ModuleReaderCancellationTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/ModuleReaderCancellationTests.fs @@ -115,10 +115,10 @@ type PreTypeDefData = mkILMethods [] let typeAttributes = TypeAttributes.Public - - ILTypeDef(this.Name, typeAttributes, ILTypeDefLayout.Auto, [], [], - None, methodsDefs, mkILTypeDefs [], mkILFields [], emptyILMethodImpls, mkILEvents [], mkILProperties [], - ILTypeDefAdditionalFlags.None, emptyILSecurityDecls, emptyILCustomAttrsStored) + let customAttrs = mkILCustomAttrs [] + ILTypeDef(this.Name, typeAttributes, ILTypeDefLayout.Auto, [], None, [], + None, methodsDefs, mkILTypeDefs [], mkILFields [], emptyILMethodImpls, mkILEvents [], mkILProperties [], ILTypeDefAdditionalFlags.None, + emptyILSecurityDecls, customAttrs) type PreTypeDef(data: PreTypeDefData) = let typeDef = data.TypeDef diff --git a/tests/FSharp.Compiler.Service.Tests/PatternMatchCompilationTests.fs b/tests/FSharp.Compiler.Service.Tests/PatternMatchCompilationTests.fs index 2defa8e9e2f..4ae43434099 100644 --- a/tests/FSharp.Compiler.Service.Tests/PatternMatchCompilationTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/PatternMatchCompilationTests.fs @@ -314,12 +314,12 @@ match box 1 with """ assertHasSymbolUsages (List.map string ['a'..'j']) checkResults dumpDiagnostics checkResults |> shouldEqual [ - "(5,34--5,35): The type 'obj' does not support the operator '+'" - "(5,32--5,33): The type 'obj' does not support the operator '+'" - "(7,45--7,46): The type 'obj' does not match the type 'uint64'" - "(7,43--7,44): The type 'obj' does not match the type 'uint64'" - "(8,43--8,44): The type 'obj' does not match the type 'int8'" - "(8,41--8,42): The type 'obj' does not match the type 'int8'" + "(5,34--5,35): The type 'objnull' does not support the operator '+'" + "(5,32--5,33): The type 'objnull' does not support the operator '+'" + "(7,45--7,46): The type 'objnull' does not match the type 'uint64'" + "(7,43--7,44): The type 'objnull' does not match the type 'uint64'" + "(8,43--8,44): The type 'objnull' does not match the type 'int8'" + "(8,41--8,42): The type 'objnull' does not match the type 'int8'" "(3,6--3,11): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." ] @@ -755,7 +755,7 @@ Some x |> eq """ assertHasSymbolUsages (List.map string ['a'..'z']) checkResults dumpDiagnostics checkResults |> shouldEqual [ - "(11,25--11,26): This expression was expected to have type\u001d 'int' \u001dbut here has type\u001d 'obj'"; + "(11,25--11,26): This expression was expected to have type\u001d 'int' \u001dbut here has type\u001d 'objnull'"; "(28,6--28,24): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)."; "(26,6--26,12): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)."; "(24,6--24,12): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)."; @@ -955,8 +955,8 @@ Some "" |> eq // No more type checks after the above line? """ assertHasSymbolUsages (Set.toList validSet) checkResults dumpDiagnostics checkResults |> shouldEqual [ - "(27,2--27,14): This expression was expected to have type\u001d 'obj' \u001dbut here has type\u001d 'struct ('a * 'b)'"; - "(52,2--52,13): This expression was expected to have type\u001d 'obj' \u001dbut here has type\u001d 'AAA'"; + "(27,2--27,14): This expression was expected to have type\u001d 'objnull' \u001dbut here has type\u001d 'struct ('a * 'b)'"; + "(52,2--52,13): This expression was expected to have type\u001d 'objnull' \u001dbut here has type\u001d 'AAA'"; "(26,6--26,24): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)."; "(24,6--24,12): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)."; "(22,6--22,12): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)."; @@ -1037,10 +1037,10 @@ Some "" |> eq """ assertHasSymbolUsages (set ['a'..'y'] - set [ 'm'..'r' ] |> Set.map string |> Set.toList) checkResults dumpDiagnostics checkResults |> shouldEqual [ - "(19,2--19,4): This expression was expected to have type\u001d 'obj' \u001dbut here has type\u001d 'int'"; - "(21,2--21,7): This expression was expected to have type\u001d 'obj' \u001dbut here has type\u001d 'bool'"; - "(23,2--23,6): This expression was expected to have type\u001d 'obj' \u001dbut here has type\u001d 'bool'"; - "(28,28--28,29): The type 'obj' does not match the type 'int'"; + "(19,2--19,4): This expression was expected to have type\u001d 'objnull' \u001dbut here has type\u001d 'int'"; + "(21,2--21,7): This expression was expected to have type\u001d 'objnull' \u001dbut here has type\u001d 'bool'"; + "(23,2--23,6): This expression was expected to have type\u001d 'objnull' \u001dbut here has type\u001d 'bool'"; + "(28,28--28,29): The type 'objnull' does not match the type 'int'"; "(41,5--41,6): The value or constructor 'm' is not defined."; "(42,5--42,6): The value or constructor 'n' is not defined."; "(43,5--43,6): The value or constructor 'o' is not defined."; diff --git a/tests/FSharp.Compiler.Service.Tests/expected-help-output.bsl b/tests/FSharp.Compiler.Service.Tests/expected-help-output.bsl index 8f80673a9ba..f6d8f432cd2 100644 --- a/tests/FSharp.Compiler.Service.Tests/expected-help-output.bsl +++ b/tests/FSharp.Compiler.Service.Tests/expected-help-output.bsl @@ -109,6 +109,8 @@ --nowarn: Disable specific warning messages --warnon: Enable specific warnings that may be off by default +--checknulls[+|-] Enable nullness declarations and + checks --consolecolors[+|-] Output warning and error messages in color diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl index def2dea16c8..cccdc677da3 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl @@ -1747,7 +1747,10 @@ Microsoft.FSharp.Core.Operators+Unchecked: Boolean Equals[T](T, T) Microsoft.FSharp.Core.Operators+Unchecked: Int32 Compare[T](T, T) Microsoft.FSharp.Core.Operators+Unchecked: Int32 Hash[T](T) Microsoft.FSharp.Core.Operators+Unchecked: T DefaultOf[T]() +Microsoft.FSharp.Core.Operators+Unchecked: T NonNullQuickPattern[T](T) +Microsoft.FSharp.Core.Operators+Unchecked: T NonNull[T](T) Microsoft.FSharp.Core.Operators+Unchecked: T Unbox[T](System.Object) +Microsoft.FSharp.Core.Operators: Boolean IsNullV[T](System.Nullable`1[T]) Microsoft.FSharp.Core.Operators: Boolean IsNull[T](T) Microsoft.FSharp.Core.Operators: Boolean Not(Boolean) Microsoft.FSharp.Core.Operators: Boolean op_Equality[T](T, T) @@ -1783,6 +1786,8 @@ Microsoft.FSharp.Core.Operators: Int64 ToInt64[T](T) Microsoft.FSharp.Core.Operators: IntPtr ToIntPtr$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.IntPtr], T) Microsoft.FSharp.Core.Operators: IntPtr ToIntPtr[T](T) Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Collections.FSharpList`1[T] op_Append[T](Microsoft.FSharp.Collections.FSharpList`1[T], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpChoice`2[Microsoft.FSharp.Core.Unit,T] NullMatchPattern[T](T) +Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpChoice`2[Microsoft.FSharp.Core.Unit,T] NullValueMatchPattern[T](System.Nullable`1[T]) Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpFunc`2[T1,T3] op_ComposeLeft[T2,T3,T1](Microsoft.FSharp.Core.FSharpFunc`2[T2,T3], Microsoft.FSharp.Core.FSharpFunc`2[T1,T2]) Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpFunc`2[T1,T3] op_ComposeRight[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,T2], Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]) Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpOption`1[System.String] FailurePattern(System.Exception) @@ -1812,6 +1817,8 @@ Microsoft.FSharp.Core.Operators: System.Exception Failure(System.String) Microsoft.FSharp.Core.Operators: System.IO.TextReader ConsoleIn[T]() Microsoft.FSharp.Core.Operators: System.IO.TextWriter ConsoleError[T]() Microsoft.FSharp.Core.Operators: System.IO.TextWriter ConsoleOut[T]() +Microsoft.FSharp.Core.Operators: System.Nullable`1[T] NullV[T]() +Microsoft.FSharp.Core.Operators: System.Nullable`1[T] WithNullV[T](T) Microsoft.FSharp.Core.Operators: System.Object Box[T](T) Microsoft.FSharp.Core.Operators: System.RuntimeMethodHandle MethodHandleOf[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]) Microsoft.FSharp.Core.Operators: System.String NameOf[T](T) @@ -1835,6 +1842,8 @@ Microsoft.FSharp.Core.Operators: T Cos[T](T) Microsoft.FSharp.Core.Operators: T Cosh$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) Microsoft.FSharp.Core.Operators: T Cosh[T](T) Microsoft.FSharp.Core.Operators: T DefaultArg[T](Microsoft.FSharp.Core.FSharpOption`1[T], T) +Microsoft.FSharp.Core.Operators: T DefaultIfNullV[T](T, System.Nullable`1[T]) +Microsoft.FSharp.Core.Operators: T DefaultIfNull[T](T, T) Microsoft.FSharp.Core.Operators: T DefaultValueArg[T](Microsoft.FSharp.Core.FSharpValueOption`1[T], T) Microsoft.FSharp.Core.Operators: T Exit[T](Int32) Microsoft.FSharp.Core.Operators: T Exp$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) @@ -1852,6 +1861,11 @@ Microsoft.FSharp.Core.Operators: T Log10[T](T) Microsoft.FSharp.Core.Operators: T Log[T](T) Microsoft.FSharp.Core.Operators: T Max[T](T, T) Microsoft.FSharp.Core.Operators: T Min[T](T, T) +Microsoft.FSharp.Core.Operators: T NonNullQuickPattern[T](T) +Microsoft.FSharp.Core.Operators: T NonNullQuickValuePattern[T](System.Nullable`1[T]) +Microsoft.FSharp.Core.Operators: T NonNullV[T](System.Nullable`1[T]) +Microsoft.FSharp.Core.Operators: T NonNull[T](T) +Microsoft.FSharp.Core.Operators: T NullArgCheck[T](System.String, T) Microsoft.FSharp.Core.Operators: T NullArg[T](System.String) Microsoft.FSharp.Core.Operators: T PowInteger$W[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, Int32) Microsoft.FSharp.Core.Operators: T PowInteger[T](T, Int32) @@ -1871,6 +1885,7 @@ Microsoft.FSharp.Core.Operators: T Tanh[T](T) Microsoft.FSharp.Core.Operators: T Truncate$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) Microsoft.FSharp.Core.Operators: T Truncate[T](T) Microsoft.FSharp.Core.Operators: T Unbox[T](System.Object) +Microsoft.FSharp.Core.Operators: T WithNull[T](T) Microsoft.FSharp.Core.Operators: T op_BitwiseAnd$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, T) Microsoft.FSharp.Core.Operators: T op_BitwiseAnd[T](T, T) Microsoft.FSharp.Core.Operators: T op_BitwiseOr$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, T) @@ -2091,6 +2106,9 @@ Microsoft.FSharp.Core.ValueOption: TState Fold[T,TState](Microsoft.FSharp.Core.F Microsoft.FSharp.Core.ValueOption: T[] ToArray[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) Microsoft.FSharp.Core.ValueOption: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpValueOption`1[T]) Microsoft.FSharp.Core.VolatileFieldAttribute: Void .ctor() +Microsoft.FSharp.Core.WarnOnWithoutNullArgumentAttribute: System.String WarningMessage +Microsoft.FSharp.Core.WarnOnWithoutNullArgumentAttribute: System.String get_WarningMessage() +Microsoft.FSharp.Core.WarnOnWithoutNullArgumentAttribute: Void .ctor(System.String) Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Byte] ToByte$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Byte], System.Nullable`1[T]) Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Byte] ToByte[T](System.Nullable`1[T]) Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Byte] ToUInt8$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Byte], System.Nullable`1[T]) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl index e1864618be6..3da2e0a5a4d 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl @@ -1786,7 +1786,10 @@ Microsoft.FSharp.Core.Operators+Unchecked: Boolean Equals[T](T, T) Microsoft.FSharp.Core.Operators+Unchecked: Int32 Compare[T](T, T) Microsoft.FSharp.Core.Operators+Unchecked: Int32 Hash[T](T) Microsoft.FSharp.Core.Operators+Unchecked: T DefaultOf[T]() +Microsoft.FSharp.Core.Operators+Unchecked: T NonNullQuickPattern[T](T) +Microsoft.FSharp.Core.Operators+Unchecked: T NonNull[T](T) Microsoft.FSharp.Core.Operators+Unchecked: T Unbox[T](System.Object) +Microsoft.FSharp.Core.Operators: Boolean IsNullV[T](System.Nullable`1[T]) Microsoft.FSharp.Core.Operators: Boolean IsNull[T](T) Microsoft.FSharp.Core.Operators: Boolean Not(Boolean) Microsoft.FSharp.Core.Operators: Boolean op_Equality[T](T, T) @@ -1822,6 +1825,8 @@ Microsoft.FSharp.Core.Operators: Int64 ToInt64[T](T) Microsoft.FSharp.Core.Operators: IntPtr ToIntPtr$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.IntPtr], T) Microsoft.FSharp.Core.Operators: IntPtr ToIntPtr[T](T) Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Collections.FSharpList`1[T] op_Append[T](Microsoft.FSharp.Collections.FSharpList`1[T], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpChoice`2[Microsoft.FSharp.Core.Unit,T] NullMatchPattern[T](T) +Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpChoice`2[Microsoft.FSharp.Core.Unit,T] NullValueMatchPattern[T](System.Nullable`1[T]) Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpFunc`2[T1,T3] op_ComposeLeft[T2,T3,T1](Microsoft.FSharp.Core.FSharpFunc`2[T2,T3], Microsoft.FSharp.Core.FSharpFunc`2[T1,T2]) Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpFunc`2[T1,T3] op_ComposeRight[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,T2], Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]) Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpOption`1[System.String] FailurePattern(System.Exception) @@ -1851,6 +1856,8 @@ Microsoft.FSharp.Core.Operators: System.Exception Failure(System.String) Microsoft.FSharp.Core.Operators: System.IO.TextReader ConsoleIn[T]() Microsoft.FSharp.Core.Operators: System.IO.TextWriter ConsoleError[T]() Microsoft.FSharp.Core.Operators: System.IO.TextWriter ConsoleOut[T]() +Microsoft.FSharp.Core.Operators: System.Nullable`1[T] NullV[T]() +Microsoft.FSharp.Core.Operators: System.Nullable`1[T] WithNullV[T](T) Microsoft.FSharp.Core.Operators: System.Object Box[T](T) Microsoft.FSharp.Core.Operators: System.String NameOf[T](T) Microsoft.FSharp.Core.Operators: System.String ToString[T](T) @@ -1873,6 +1880,8 @@ Microsoft.FSharp.Core.Operators: T Cos[T](T) Microsoft.FSharp.Core.Operators: T Cosh$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) Microsoft.FSharp.Core.Operators: T Cosh[T](T) Microsoft.FSharp.Core.Operators: T DefaultArg[T](Microsoft.FSharp.Core.FSharpOption`1[T], T) +Microsoft.FSharp.Core.Operators: T DefaultIfNullV[T](T, System.Nullable`1[T]) +Microsoft.FSharp.Core.Operators: T DefaultIfNull[T](T, T) Microsoft.FSharp.Core.Operators: T DefaultValueArg[T](Microsoft.FSharp.Core.FSharpValueOption`1[T], T) Microsoft.FSharp.Core.Operators: T Exit[T](Int32) Microsoft.FSharp.Core.Operators: T Exp$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) @@ -1890,6 +1899,11 @@ Microsoft.FSharp.Core.Operators: T Log10[T](T) Microsoft.FSharp.Core.Operators: T Log[T](T) Microsoft.FSharp.Core.Operators: T Max[T](T, T) Microsoft.FSharp.Core.Operators: T Min[T](T, T) +Microsoft.FSharp.Core.Operators: T NonNullQuickPattern[T](T) +Microsoft.FSharp.Core.Operators: T NonNullQuickValuePattern[T](System.Nullable`1[T]) +Microsoft.FSharp.Core.Operators: T NonNullV[T](System.Nullable`1[T]) +Microsoft.FSharp.Core.Operators: T NonNull[T](T) +Microsoft.FSharp.Core.Operators: T NullArgCheck[T](System.String, T) Microsoft.FSharp.Core.Operators: T NullArg[T](System.String) Microsoft.FSharp.Core.Operators: T PowInteger$W[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, Int32) Microsoft.FSharp.Core.Operators: T PowInteger[T](T, Int32) @@ -1909,6 +1923,7 @@ Microsoft.FSharp.Core.Operators: T Tanh[T](T) Microsoft.FSharp.Core.Operators: T Truncate$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) Microsoft.FSharp.Core.Operators: T Truncate[T](T) Microsoft.FSharp.Core.Operators: T Unbox[T](System.Object) +Microsoft.FSharp.Core.Operators: T WithNull[T](T) Microsoft.FSharp.Core.Operators: T op_BitwiseAnd$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, T) Microsoft.FSharp.Core.Operators: T op_BitwiseAnd[T](T, T) Microsoft.FSharp.Core.Operators: T op_BitwiseOr$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, T) @@ -2129,6 +2144,9 @@ Microsoft.FSharp.Core.ValueOption: TState Fold[T,TState](Microsoft.FSharp.Core.F Microsoft.FSharp.Core.ValueOption: T[] ToArray[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) Microsoft.FSharp.Core.ValueOption: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpValueOption`1[T]) Microsoft.FSharp.Core.VolatileFieldAttribute: Void .ctor() +Microsoft.FSharp.Core.WarnOnWithoutNullArgumentAttribute: System.String WarningMessage +Microsoft.FSharp.Core.WarnOnWithoutNullArgumentAttribute: System.String get_WarningMessage() +Microsoft.FSharp.Core.WarnOnWithoutNullArgumentAttribute: Void .ctor(System.String) Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Byte] ToByte$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Byte], System.Nullable`1[T]) Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Byte] ToByte[T](System.Nullable`1[T]) Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Byte] ToUInt8$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Byte], System.Nullable`1[T]) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl index 5fa4760b53e..902d117b840 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl @@ -1748,7 +1748,10 @@ Microsoft.FSharp.Core.Operators+Unchecked: Boolean Equals[T](T, T) Microsoft.FSharp.Core.Operators+Unchecked: Int32 Compare[T](T, T) Microsoft.FSharp.Core.Operators+Unchecked: Int32 Hash[T](T) Microsoft.FSharp.Core.Operators+Unchecked: T DefaultOf[T]() +Microsoft.FSharp.Core.Operators+Unchecked: T NonNullQuickPattern[T](T) +Microsoft.FSharp.Core.Operators+Unchecked: T NonNull[T](T) Microsoft.FSharp.Core.Operators+Unchecked: T Unbox[T](System.Object) +Microsoft.FSharp.Core.Operators: Boolean IsNullV[T](System.Nullable`1[T]) Microsoft.FSharp.Core.Operators: Boolean IsNull[T](T) Microsoft.FSharp.Core.Operators: Boolean Not(Boolean) Microsoft.FSharp.Core.Operators: Boolean op_Equality[T](T, T) @@ -1784,6 +1787,8 @@ Microsoft.FSharp.Core.Operators: Int64 ToInt64[T](T) Microsoft.FSharp.Core.Operators: IntPtr ToIntPtr$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.IntPtr], T) Microsoft.FSharp.Core.Operators: IntPtr ToIntPtr[T](T) Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Collections.FSharpList`1[T] op_Append[T](Microsoft.FSharp.Collections.FSharpList`1[T], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpChoice`2[Microsoft.FSharp.Core.Unit,T] NullMatchPattern[T](T) +Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpChoice`2[Microsoft.FSharp.Core.Unit,T] NullValueMatchPattern[T](System.Nullable`1[T]) Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpFunc`2[T1,T3] op_ComposeLeft[T2,T3,T1](Microsoft.FSharp.Core.FSharpFunc`2[T2,T3], Microsoft.FSharp.Core.FSharpFunc`2[T1,T2]) Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpFunc`2[T1,T3] op_ComposeRight[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,T2], Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]) Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpOption`1[System.String] FailurePattern(System.Exception) @@ -1813,6 +1818,8 @@ Microsoft.FSharp.Core.Operators: System.Exception Failure(System.String) Microsoft.FSharp.Core.Operators: System.IO.TextReader ConsoleIn[T]() Microsoft.FSharp.Core.Operators: System.IO.TextWriter ConsoleError[T]() Microsoft.FSharp.Core.Operators: System.IO.TextWriter ConsoleOut[T]() +Microsoft.FSharp.Core.Operators: System.Nullable`1[T] NullV[T]() +Microsoft.FSharp.Core.Operators: System.Nullable`1[T] WithNullV[T](T) Microsoft.FSharp.Core.Operators: System.Object Box[T](T) Microsoft.FSharp.Core.Operators: System.RuntimeMethodHandle MethodHandleOf[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]) Microsoft.FSharp.Core.Operators: System.String NameOf[T](T) @@ -1836,6 +1843,8 @@ Microsoft.FSharp.Core.Operators: T Cos[T](T) Microsoft.FSharp.Core.Operators: T Cosh$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) Microsoft.FSharp.Core.Operators: T Cosh[T](T) Microsoft.FSharp.Core.Operators: T DefaultArg[T](Microsoft.FSharp.Core.FSharpOption`1[T], T) +Microsoft.FSharp.Core.Operators: T DefaultIfNullV[T](T, System.Nullable`1[T]) +Microsoft.FSharp.Core.Operators: T DefaultIfNull[T](T, T) Microsoft.FSharp.Core.Operators: T DefaultValueArg[T](Microsoft.FSharp.Core.FSharpValueOption`1[T], T) Microsoft.FSharp.Core.Operators: T Exit[T](Int32) Microsoft.FSharp.Core.Operators: T Exp$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) @@ -1853,6 +1862,11 @@ Microsoft.FSharp.Core.Operators: T Log10[T](T) Microsoft.FSharp.Core.Operators: T Log[T](T) Microsoft.FSharp.Core.Operators: T Max[T](T, T) Microsoft.FSharp.Core.Operators: T Min[T](T, T) +Microsoft.FSharp.Core.Operators: T NonNullQuickPattern[T](T) +Microsoft.FSharp.Core.Operators: T NonNullQuickValuePattern[T](System.Nullable`1[T]) +Microsoft.FSharp.Core.Operators: T NonNullV[T](System.Nullable`1[T]) +Microsoft.FSharp.Core.Operators: T NonNull[T](T) +Microsoft.FSharp.Core.Operators: T NullArgCheck[T](System.String, T) Microsoft.FSharp.Core.Operators: T NullArg[T](System.String) Microsoft.FSharp.Core.Operators: T PowInteger$W[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, Int32) Microsoft.FSharp.Core.Operators: T PowInteger[T](T, Int32) @@ -1872,6 +1886,7 @@ Microsoft.FSharp.Core.Operators: T Tanh[T](T) Microsoft.FSharp.Core.Operators: T Truncate$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) Microsoft.FSharp.Core.Operators: T Truncate[T](T) Microsoft.FSharp.Core.Operators: T Unbox[T](System.Object) +Microsoft.FSharp.Core.Operators: T WithNull[T](T) Microsoft.FSharp.Core.Operators: T op_BitwiseAnd$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, T) Microsoft.FSharp.Core.Operators: T op_BitwiseAnd[T](T, T) Microsoft.FSharp.Core.Operators: T op_BitwiseOr$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, T) @@ -2092,6 +2107,9 @@ Microsoft.FSharp.Core.ValueOption: TState Fold[T,TState](Microsoft.FSharp.Core.F Microsoft.FSharp.Core.ValueOption: T[] ToArray[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) Microsoft.FSharp.Core.ValueOption: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpValueOption`1[T]) Microsoft.FSharp.Core.VolatileFieldAttribute: Void .ctor() +Microsoft.FSharp.Core.WarnOnWithoutNullArgumentAttribute: System.String WarningMessage +Microsoft.FSharp.Core.WarnOnWithoutNullArgumentAttribute: System.String get_WarningMessage() +Microsoft.FSharp.Core.WarnOnWithoutNullArgumentAttribute: Void .ctor(System.String) Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Byte] ToByte$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Byte], System.Nullable`1[T]) Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Byte] ToByte[T](System.Nullable`1[T]) Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Byte] ToUInt8$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Byte], System.Nullable`1[T]) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl index ea111e99abf..aafb3256de6 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl @@ -1789,7 +1789,10 @@ Microsoft.FSharp.Core.Operators+Unchecked: Boolean Equals[T](T, T) Microsoft.FSharp.Core.Operators+Unchecked: Int32 Compare[T](T, T) Microsoft.FSharp.Core.Operators+Unchecked: Int32 Hash[T](T) Microsoft.FSharp.Core.Operators+Unchecked: T DefaultOf[T]() +Microsoft.FSharp.Core.Operators+Unchecked: T NonNullQuickPattern[T](T) +Microsoft.FSharp.Core.Operators+Unchecked: T NonNull[T](T) Microsoft.FSharp.Core.Operators+Unchecked: T Unbox[T](System.Object) +Microsoft.FSharp.Core.Operators: Boolean IsNullV[T](System.Nullable`1[T]) Microsoft.FSharp.Core.Operators: Boolean IsNull[T](T) Microsoft.FSharp.Core.Operators: Boolean Not(Boolean) Microsoft.FSharp.Core.Operators: Boolean op_Equality[T](T, T) @@ -1825,6 +1828,8 @@ Microsoft.FSharp.Core.Operators: Int64 ToInt64[T](T) Microsoft.FSharp.Core.Operators: IntPtr ToIntPtr$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.IntPtr], T) Microsoft.FSharp.Core.Operators: IntPtr ToIntPtr[T](T) Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Collections.FSharpList`1[T] op_Append[T](Microsoft.FSharp.Collections.FSharpList`1[T], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpChoice`2[Microsoft.FSharp.Core.Unit,T] NullMatchPattern[T](T) +Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpChoice`2[Microsoft.FSharp.Core.Unit,T] NullValueMatchPattern[T](System.Nullable`1[T]) Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpFunc`2[T1,T3] op_ComposeLeft[T2,T3,T1](Microsoft.FSharp.Core.FSharpFunc`2[T2,T3], Microsoft.FSharp.Core.FSharpFunc`2[T1,T2]) Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpFunc`2[T1,T3] op_ComposeRight[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,T2], Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]) Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpOption`1[System.String] FailurePattern(System.Exception) @@ -1854,6 +1859,8 @@ Microsoft.FSharp.Core.Operators: System.Exception Failure(System.String) Microsoft.FSharp.Core.Operators: System.IO.TextReader ConsoleIn[T]() Microsoft.FSharp.Core.Operators: System.IO.TextWriter ConsoleError[T]() Microsoft.FSharp.Core.Operators: System.IO.TextWriter ConsoleOut[T]() +Microsoft.FSharp.Core.Operators: System.Nullable`1[T] NullV[T]() +Microsoft.FSharp.Core.Operators: System.Nullable`1[T] WithNullV[T](T) Microsoft.FSharp.Core.Operators: System.Object Box[T](T) Microsoft.FSharp.Core.Operators: System.String NameOf[T](T) Microsoft.FSharp.Core.Operators: System.String ToString[T](T) @@ -1876,6 +1883,8 @@ Microsoft.FSharp.Core.Operators: T Cos[T](T) Microsoft.FSharp.Core.Operators: T Cosh$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) Microsoft.FSharp.Core.Operators: T Cosh[T](T) Microsoft.FSharp.Core.Operators: T DefaultArg[T](Microsoft.FSharp.Core.FSharpOption`1[T], T) +Microsoft.FSharp.Core.Operators: T DefaultIfNullV[T](T, System.Nullable`1[T]) +Microsoft.FSharp.Core.Operators: T DefaultIfNull[T](T, T) Microsoft.FSharp.Core.Operators: T DefaultValueArg[T](Microsoft.FSharp.Core.FSharpValueOption`1[T], T) Microsoft.FSharp.Core.Operators: T Exit[T](Int32) Microsoft.FSharp.Core.Operators: T Exp$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) @@ -1893,6 +1902,11 @@ Microsoft.FSharp.Core.Operators: T Log10[T](T) Microsoft.FSharp.Core.Operators: T Log[T](T) Microsoft.FSharp.Core.Operators: T Max[T](T, T) Microsoft.FSharp.Core.Operators: T Min[T](T, T) +Microsoft.FSharp.Core.Operators: T NonNullQuickPattern[T](T) +Microsoft.FSharp.Core.Operators: T NonNullQuickValuePattern[T](System.Nullable`1[T]) +Microsoft.FSharp.Core.Operators: T NonNullV[T](System.Nullable`1[T]) +Microsoft.FSharp.Core.Operators: T NonNull[T](T) +Microsoft.FSharp.Core.Operators: T NullArgCheck[T](System.String, T) Microsoft.FSharp.Core.Operators: T NullArg[T](System.String) Microsoft.FSharp.Core.Operators: T PowInteger$W[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, Int32) Microsoft.FSharp.Core.Operators: T PowInteger[T](T, Int32) @@ -1912,6 +1926,7 @@ Microsoft.FSharp.Core.Operators: T Tanh[T](T) Microsoft.FSharp.Core.Operators: T Truncate$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) Microsoft.FSharp.Core.Operators: T Truncate[T](T) Microsoft.FSharp.Core.Operators: T Unbox[T](System.Object) +Microsoft.FSharp.Core.Operators: T WithNull[T](T) Microsoft.FSharp.Core.Operators: T op_BitwiseAnd$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, T) Microsoft.FSharp.Core.Operators: T op_BitwiseAnd[T](T, T) Microsoft.FSharp.Core.Operators: T op_BitwiseOr$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, T) @@ -2132,6 +2147,9 @@ Microsoft.FSharp.Core.ValueOption: TState Fold[T,TState](Microsoft.FSharp.Core.F Microsoft.FSharp.Core.ValueOption: T[] ToArray[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) Microsoft.FSharp.Core.ValueOption: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpValueOption`1[T]) Microsoft.FSharp.Core.VolatileFieldAttribute: Void .ctor() +Microsoft.FSharp.Core.WarnOnWithoutNullArgumentAttribute: System.String WarningMessage +Microsoft.FSharp.Core.WarnOnWithoutNullArgumentAttribute: System.String get_WarningMessage() +Microsoft.FSharp.Core.WarnOnWithoutNullArgumentAttribute: Void .ctor(System.String) Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Byte] ToByte$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Byte], System.Nullable`1[T]) Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Byte] ToByte[T](System.Nullable`1[T]) Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Byte] ToUInt8$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Byte], System.Nullable`1[T]) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/OptionModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/OptionModule.fs index cecad68f233..9a566f5361d 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/OptionModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/OptionModule.fs @@ -131,7 +131,7 @@ type OptionModule() = member this.OfToObj() = Assert.True( Option.toObj (Some "3") = "3") Assert.True( Option.toObj (Some "") = "") - Assert.True( Option.toObj (Some null) = null) + Assert.True( Option.toObj (Some null) = null) // TODO NULLNESS: this type annotation should not be needed Assert.True( Option.toObj None = null) Assert.True( Option.ofObj "3" = Some "3") diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs index a9275d15f99..4a2d52ef4d4 100644 --- a/tests/FSharp.Test.Utilities/Compiler.fs +++ b/tests/FSharp.Test.Utilities/Compiler.fs @@ -480,6 +480,9 @@ module rec Compiler = | FS fs -> FS { fs with OutputDirectory = path } | _ -> failwith "withOutputDirectory is only supported on F#" + let withCheckNulls (cUnit: CompilationUnit) : CompilationUnit = + withOptionsHelper ["--checknulls+"] "checknulls is only supported in F#" cUnit + let withBufferWidth (width: int)(cUnit: CompilationUnit) : CompilationUnit = withOptionsHelper [ $"--bufferwidth:{width}" ] "withBufferWidth is only supported on F#" cUnit @@ -1605,6 +1608,7 @@ Actual: | null -> () | _ when expectedContent = actualErrors -> () | _ -> File.WriteAllText(path, actualErrors) + //File.WriteAllText(path, actualErrors) match Assert.shouldBeSameMultilineStringSets expectedContent actualErrors with | None -> () diff --git a/tests/FSharp.Test.Utilities/ILChecker.fs b/tests/FSharp.Test.Utilities/ILChecker.fs index a1a45a3bc4f..7b2cdc7b95e 100644 --- a/tests/FSharp.Test.Utilities/ILChecker.fs +++ b/tests/FSharp.Test.Utilities/ILChecker.fs @@ -72,6 +72,10 @@ module ILChecker = |> unifyRuntimeAssemblyName |> unifyImageBase + let stripManagedResources (text: string) = + let result = Regex.Replace(text, "\.mresource public .*\r?\n{\s*}\r?\n", "", RegexOptions.Multiline) + result + // This lets the same test be used when targeting both netfx and netcore. let unifyNetStandardVersions (text: string) = text.Replace(".ver 2:0:0:0", ".ver 2:1:0:0") @@ -84,6 +88,7 @@ module ILChecker = |> stripComments |> unifyingAssemblyNames |> unifyMethodLine + |> stripManagedResources |> unifyNetStandardVersions |> unifyResourceBlock @@ -120,6 +125,7 @@ module ILChecker = let prepareLines (s: string) = s.Split('\n') + // Skip emitted managed resources |> Array.map(fun e -> e.Trim('\r')) |> Array.skipWhile(String.IsNullOrWhiteSpace) |> Array.rev diff --git a/tests/fsharp/Compiler/Regressions/NullableOptionalRegressionTests.fs b/tests/fsharp/Compiler/Regressions/NullableOptionalRegressionTests.fs index 87f55ac4cce..4b4ffb4b349 100644 --- a/tests/fsharp/Compiler/Regressions/NullableOptionalRegressionTests.fs +++ b/tests/fsharp/Compiler/Regressions/NullableOptionalRegressionTests.fs @@ -8,7 +8,8 @@ open FSharp.Test.Compiler [] module NullableOptionalRegressionTests = - [] + //Disabled, see RFC for nullable + //[] let ``Should compile with generic overloaded nullable methods``() = Fsx """ open System diff --git a/tests/fsharp/core/printing/output.1000.stdout.bsl b/tests/fsharp/core/printing/output.1000.stdout.bsl index f780a746484..cf1e86cdebf 100644 --- a/tests/fsharp/core/printing/output.1000.stdout.bsl +++ b/tests/fsharp/core/printing/output.1000.stdout.bsl @@ -1539,7 +1539,7 @@ module Test4343e = val dB: D = D(2) val dAB: D * D * D list = (D(1), D(2), [D(1); D(2)]) val dC: D = D(True) - val boxed_dABC: obj list = [D(1); D(2); D(True)] + val boxed_dABC: objnull list = [D(1); D(2); D(True)] type F1 = inherit System.Windows.Forms.Form interface System.IDisposable diff --git a/tests/fsharp/core/printing/output.200.stdout.bsl b/tests/fsharp/core/printing/output.200.stdout.bsl index fdf12045d2d..56e536c67fe 100644 --- a/tests/fsharp/core/printing/output.200.stdout.bsl +++ b/tests/fsharp/core/printing/output.200.stdout.bsl @@ -784,7 +784,7 @@ module Test4343e = val dB: D = D(2) val dAB: D * D * D list = (D(1), D(2), [D(1); D(2)]) val dC: D = D(True) - val boxed_dABC: obj list = [D(1); D(2); D(True)] + val boxed_dABC: objnull list = [D(1); D(2); D(True)] type F1 = inherit System.Windows.Forms.Form interface System.IDisposable diff --git a/tests/fsharp/core/printing/output.47.stdout.bsl b/tests/fsharp/core/printing/output.47.stdout.bsl index 088a6f21e4e..d88710bef2d 100644 --- a/tests/fsharp/core/printing/output.47.stdout.bsl +++ b/tests/fsharp/core/printing/output.47.stdout.bsl @@ -5084,7 +5084,7 @@ module Test4343e = val dB: D = D(2) val dAB: D * D * D list = (D(1), D(2), [D(1); D(2)]) val dC: D = D(True) - val boxed_dABC: obj list = [D(1); D(2); D(True)] + val boxed_dABC: objnull list = [D(1); D(2); D(True)] type F1 = inherit System.Windows.Forms.Form interface System.IDisposable diff --git a/tests/fsharp/core/printing/output.multiemit.stdout.bsl b/tests/fsharp/core/printing/output.multiemit.stdout.bsl index b2af7d4f2dc..8285e548f75 100644 --- a/tests/fsharp/core/printing/output.multiemit.stdout.bsl +++ b/tests/fsharp/core/printing/output.multiemit.stdout.bsl @@ -5086,7 +5086,7 @@ module Test4343e = val dB: D = D(2) val dAB: D * D * D list = (D(1), D(2), [D(1); D(2)]) val dC: D = D(True) - val boxed_dABC: obj list = [D(1); D(2); D(True)] + val boxed_dABC: objnull list = [D(1); D(2); D(True)] type F1 = inherit System.Windows.Forms.Form interface System.IDisposable diff --git a/tests/fsharp/core/printing/output.off.stdout.bsl b/tests/fsharp/core/printing/output.off.stdout.bsl index 56edaec8d22..38b3c24ebfc 100644 --- a/tests/fsharp/core/printing/output.off.stdout.bsl +++ b/tests/fsharp/core/printing/output.off.stdout.bsl @@ -570,7 +570,7 @@ module Test4343e = val dB: D val dAB: D * D * D list val dC: D - val boxed_dABC: obj list + val boxed_dABC: objnull list type F1 = inherit System.Windows.Forms.Form interface System.IDisposable diff --git a/tests/fsharp/core/printing/output.stdout.bsl b/tests/fsharp/core/printing/output.stdout.bsl index b2af7d4f2dc..8285e548f75 100644 --- a/tests/fsharp/core/printing/output.stdout.bsl +++ b/tests/fsharp/core/printing/output.stdout.bsl @@ -5086,7 +5086,7 @@ module Test4343e = val dB: D = D(2) val dAB: D * D * D list = (D(1), D(2), [D(1); D(2)]) val dC: D = D(True) - val boxed_dABC: obj list = [D(1); D(2); D(True)] + val boxed_dABC: objnull list = [D(1); D(2); D(True)] type F1 = inherit System.Windows.Forms.Form interface System.IDisposable diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index 30c2e3b40d6..e8af104e2c7 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -36,8 +36,45 @@ let testConfig = getTestsDirectory >> testConfig [] module CoreTests = + #if !NETCOREAPP -// This test stays in FsharpSuite for a later migration phases, it uses hardcoded #r to a C# compiled cslib.dll inside + [] + let ``subtype-langversion-preview-checknulls`` () = + let cfg = testConfig "core/subtype" + + use testOkFile = fileguard cfg "test.ok" + + fsc cfg "%s -o:test-checknulls.exe -g --langversion:preview --checknulls" cfg.fsc_flags ["test.fsx"] + + exec cfg ("." ++ "test-checknulls.exe") "" + + testOkFile.CheckExists() + + [] + let ``subtype-langversion-preview-no-checknulls`` () = + let cfg = testConfig "core/subtype" + + use testOkFile = fileguard cfg "test.ok" + + fsc cfg "%s -o:test-no-checknulls.exe -g --langversion:preview --checknulls-" cfg.fsc_flags ["test.fsx"] + + exec cfg ("." ++ "test-no-checknulls.exe") "" + + testOkFile.CheckExists() + + [] + let ``subtype-langversion-46`` () = + let cfg = testConfig "core/subtype" + + use testOkFile = fileguard cfg "test.ok" + + fsc cfg "%s -o:test-langversion-46.exe -g --langversion:4.6" cfg.fsc_flags ["test.fsx"] + + exec cfg ("." ++ "test-langversion-46.exe") "" + + testOkFile.CheckExists() + + // This test stays in FsharpSuite for a later migration phases, it uses hardcoded #r to a C# compiled cslib.dll inside [] let ``quotes-FSC-FSC_DEBUG`` () = singleTestBuildAndRun "core/quotes" FSC_DEBUG @@ -956,6 +993,31 @@ module CoreTests = [] let ``libtest-FSC_NETFX_TEST_ROUNDTRIP_AS_DLL`` () = singleTestBuildAndRun "core/libtest" FSC_NETFX_TEST_ROUNDTRIP_AS_DLL + [] + let ``libtest-langversion-preview-checknulls`` () = + let cfg = testConfig "core/libtest" + + use testOkFile = fileguard cfg "test.ok" + + fsc cfg "%s -o:test-checknulls.exe -g --langversion:preview --checknulls" cfg.fsc_flags ["test.fsx"] + + exec cfg ("." ++ "test-checknulls.exe") "" + + testOkFile.CheckExists() + + + [] + let ``libtest-langversion-46`` () = + let cfg = testConfig "core/libtest" + + use testOkFile = fileguard cfg "test.ok" + + fsc cfg "%s -o:test-langversion-46.exe -g --langversion:4.6" cfg.fsc_flags ["test.fsx"] + + exec cfg ("." ++ "test-langversion-46.exe") "" + + testOkFile.CheckExists() + [] let ``no-warn-2003-tests`` () = // see https://github.com/dotnet/fsharp/issues/3139 diff --git a/tests/fsharp/typecheck/sigs/neg04.bsl b/tests/fsharp/typecheck/sigs/neg04.bsl index ab0c018eb80..d077d480f01 100644 --- a/tests/fsharp/typecheck/sigs/neg04.bsl +++ b/tests/fsharp/typecheck/sigs/neg04.bsl @@ -30,10 +30,16 @@ neg04.fs(47,30,47,51): typecheck error FS0001: Type mismatch. Expecting a ''a seq -> 'n' but given a ''o list -> 'p' -The type ''a seq' does not match the type ''n list' +The type ''a list' does not match the type ''b seq' neg04.fs(47,49,47,51): typecheck error FS0784: This numeric literal requires that a module 'NumericLiteralN' defining functions FromZero, FromOne, FromInt32, FromInt64 and FromString be in scope +neg04.fs(47,30,47,51): typecheck error FS0001: Type mismatch. Expecting a + ''a seq -> 'n' +but given a + ''o list -> 'p' +The type ''a list' does not match the type ''c seq' + neg04.fs(61,25,61,40): typecheck error FS0001: This expression was expected to have type 'ClassType1' but here has type diff --git a/tests/fsharp/typecheck/sigs/neg06.bsl b/tests/fsharp/typecheck/sigs/neg06.bsl index 54b3c5d84e5..d55e3e948d2 100644 --- a/tests/fsharp/typecheck/sigs/neg06.bsl +++ b/tests/fsharp/typecheck/sigs/neg06.bsl @@ -16,30 +16,16 @@ neg06.fs(37,6,37,29): typecheck error FS0954: This type definition involves an i neg06.fs(37,6,37,29): typecheck error FS0912: This declaration element is not permitted in an augmentation -neg06.fs(37,6,37,29): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation - neg06.fs(42,6,42,30): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation neg06.fs(46,5,46,29): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation neg06.fs(42,6,42,30): typecheck error FS0912: This declaration element is not permitted in an augmentation -neg06.fs(42,6,42,30): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation - -neg06.fs(46,5,46,29): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation - neg06.fs(53,10,53,19): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation neg06.fs(60,10,60,20): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation -neg06.fs(60,10,60,20): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation - -neg06.fs(60,10,60,20): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation - -neg06.fs(64,9,64,19): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation - -neg06.fs(64,9,64,19): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation - neg06.fs(64,9,64,19): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation neg06.fs(75,10,75,19): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation @@ -48,8 +34,6 @@ neg06.fs(80,10,80,25): typecheck error FS0953: This type definition involves an neg06.fs(90,10,90,11): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation -neg06.fs(90,10,90,11): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - neg06.fs(94,10,94,11): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation neg06.fs(99,10,99,11): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation @@ -58,26 +42,12 @@ neg06.fs(100,9,100,10): typecheck error FS0035: This construct is deprecated: Th neg06.fs(104,10,104,11): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation -neg06.fs(104,10,104,11): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - -neg06.fs(108,10,108,11): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - neg06.fs(108,10,108,11): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation neg06.fs(112,10,112,11): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation neg06.fs(117,10,117,11): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation -neg06.fs(117,10,117,11): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - -neg06.fs(117,10,117,11): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - -neg06.fs(118,9,118,10): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - -neg06.fs(118,9,118,10): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - -neg06.fs(118,9,118,10): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - neg06.fs(118,9,118,10): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation neg06.fs(118,9,118,10): typecheck error FS0035: This construct is deprecated: This type abbreviation has one or more declared type parameters that do not appear in the type being abbreviated. Type abbreviations must use all declared type parameters in the type being abbreviated. Consider removing one or more type parameters, or use a concrete type definition that wraps an underlying type, such as 'type C<'a> = C of ...'. diff --git a/tests/fsharp/typecheck/sigs/neg07.bsl b/tests/fsharp/typecheck/sigs/neg07.bsl index 5b28d3e7afb..3a32ac5abb8 100644 --- a/tests/fsharp/typecheck/sigs/neg07.bsl +++ b/tests/fsharp/typecheck/sigs/neg07.bsl @@ -1,8 +1,6 @@ neg07.fs(7,10,7,29): typecheck error FS0049: Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. -neg07.fs(7,10,7,29): typecheck error FS0049: Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. - neg07.fs(24,13,24,23): typecheck error FS0039: The value or constructor 'UnionCase1' is not defined. Maybe you want one of the following: X.UnionCase1 @@ -27,16 +25,18 @@ neg07.fs(46,15,46,27): typecheck error FS0039: The record label 'RecordLabel1' i neg07.fs(46,33,46,45): typecheck error FS0039: The record label 'RecordLabel2' is not defined. Maybe you want one of the following: R.RecordLabel2 -neg07.fs(47,17,47,55): typecheck error FS0025: Incomplete pattern matches on this expression. -neg07.fs(47,59,47,60): typecheck error FS0039: The value or constructor 'a' is not defined. -neg07.fs(47,63,47,64): typecheck error FS0039: The value or constructor 'b' is not defined. - neg07.fs(47,19,47,31): typecheck error FS0039: The record label 'RecordLabel1' is not defined. Maybe you want one of the following: R.RecordLabel1 neg07.fs(47,37,47,49): typecheck error FS0039: The record label 'RecordLabel2' is not defined. Maybe you want one of the following: R.RecordLabel2 +neg07.fs(47,59,47,60): typecheck error FS0039: The value or constructor 'a' is not defined. + +neg07.fs(47,63,47,64): typecheck error FS0039: The value or constructor 'b' is not defined. + +neg07.fs(47,17,47,55): typecheck error FS0025: Incomplete pattern matches on this expression. + neg07.fs(57,10,57,17): typecheck error FS1196: The 'UseNullAsTrueValue' attribute flag may only be used with union types that have one nullary case and at least one non-nullary case neg07.fs(64,10,64,18): typecheck error FS1196: The 'UseNullAsTrueValue' attribute flag may only be used with union types that have one nullary case and at least one non-nullary case diff --git a/tests/fsharp/typecheck/sigs/neg106.bsl b/tests/fsharp/typecheck/sigs/neg106.bsl index b683af334ee..feb58523b1f 100644 --- a/tests/fsharp/typecheck/sigs/neg106.bsl +++ b/tests/fsharp/typecheck/sigs/neg106.bsl @@ -172,11 +172,3 @@ neg106.fs(147,34,147,44): typecheck error FS1204: This construct is for use in t neg106.fs(148,34,148,44): typecheck error FS1204: This construct is for use in the FSharp.Core library and should not be used directly neg106.fs(149,34,149,44): typecheck error FS1204: This construct is for use in the FSharp.Core library and should not be used directly - -neg106.fs(146,34,146,47): typecheck error FS1204: This construct is for use in the FSharp.Core library and should not be used directly - -neg106.fs(147,34,147,44): typecheck error FS1204: This construct is for use in the FSharp.Core library and should not be used directly - -neg106.fs(148,34,148,44): typecheck error FS1204: This construct is for use in the FSharp.Core library and should not be used directly - -neg106.fs(149,34,149,44): typecheck error FS1204: This construct is for use in the FSharp.Core library and should not be used directly diff --git a/tests/fsharp/typecheck/sigs/neg106.vsbsl b/tests/fsharp/typecheck/sigs/neg106.vsbsl index b683af334ee..feb58523b1f 100644 --- a/tests/fsharp/typecheck/sigs/neg106.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg106.vsbsl @@ -172,11 +172,3 @@ neg106.fs(147,34,147,44): typecheck error FS1204: This construct is for use in t neg106.fs(148,34,148,44): typecheck error FS1204: This construct is for use in the FSharp.Core library and should not be used directly neg106.fs(149,34,149,44): typecheck error FS1204: This construct is for use in the FSharp.Core library and should not be used directly - -neg106.fs(146,34,146,47): typecheck error FS1204: This construct is for use in the FSharp.Core library and should not be used directly - -neg106.fs(147,34,147,44): typecheck error FS1204: This construct is for use in the FSharp.Core library and should not be used directly - -neg106.fs(148,34,148,44): typecheck error FS1204: This construct is for use in the FSharp.Core library and should not be used directly - -neg106.fs(149,34,149,44): typecheck error FS1204: This construct is for use in the FSharp.Core library and should not be used directly diff --git a/tests/fsharp/typecheck/sigs/neg111.bsl b/tests/fsharp/typecheck/sigs/neg111.bsl index c5048f7c299..9ad833b8054 100644 --- a/tests/fsharp/typecheck/sigs/neg111.bsl +++ b/tests/fsharp/typecheck/sigs/neg111.bsl @@ -1,8 +1,6 @@ neg111.fs(2,552,2,557): typecheck error FS0039: The type 'fail1' is not defined. -neg111.fs(2,552,2,557): typecheck error FS0039: The type 'fail1' is not defined. - neg111.fs(3,624,3,629): typecheck error FS0039: The value or constructor 'fail2' is not defined. Maybe you want one of the following: Failure failwith diff --git a/tests/fsharp/typecheck/sigs/neg112.bsl b/tests/fsharp/typecheck/sigs/neg112.bsl index 23711fb3b4d..59b02d90e0c 100644 --- a/tests/fsharp/typecheck/sigs/neg112.bsl +++ b/tests/fsharp/typecheck/sigs/neg112.bsl @@ -2,5 +2,3 @@ neg112.fs(20,49,20,62): typecheck error FS0001: A type parameter is missing a constraint 'when (Tuple or ^options) : (static member TupleMap: ^options * Tuple -> (('item -> ^value) -> ^values))' neg112.fs(20,31,20,39): typecheck error FS0043: A type parameter is missing a constraint 'when (Tuple or ^options) : (static member TupleMap: ^options * Tuple -> (('item -> ^value) -> ^values))' - -neg112.fs(20,31,20,39): typecheck error FS0043: A type parameter is missing a constraint 'when (Tuple or ^options) : (static member TupleMap: ^options * Tuple -> (('item -> ^value) -> ^values))' diff --git a/tests/fsharp/typecheck/sigs/neg119b.bsl b/tests/fsharp/typecheck/sigs/neg119b.bsl index 7a445f3ea7f..414486b9017 100644 --- a/tests/fsharp/typecheck/sigs/neg119b.bsl +++ b/tests/fsharp/typecheck/sigs/neg119b.bsl @@ -1,11 +1,12 @@ -neg119b.fs(40,9,40,17): typecheck error FS0030: Value restriction: The value 'res2n3n4' has an inferred generic type - val res2n3n4: ^_a when (^_b or Applicatives.ZipList or ^_a) : (static member (<*>) : ^_b * Applicatives.ZipList -> ^_a) and (^_c or obj or ^_b) : (static member (<*>) : ^_c * obj -> ^_b) and (Applicatives.Ap or ^_c) : (static member Return: ^_c * Applicatives.Ap -> ((int -> int -> int) -> ^_c)) -However, values cannot have generic type variables like '_a in "let x: '_a". You can do one of the following: -- Define it as a simple data term like an integer literal, a string literal or a union case like "let x = 1" -- Add an explicit type annotation like "let x : int" -- Use the value as a non-generic type in later code for type inference like "do x" -or if you still want type-dependent results, you can define 'res2n3n4' as a function instead by doing either: -- Add a unit parameter like "let x()" -- Write explicit type parameters like "let x<'a>". -This error is because a let binding without parameters defines a value, not a function. Values cannot be generic because reading a value is assumed to result in the same everywhere but generic type parameters may invalidate this assumption by enabling type-dependent results. +neg119b.fs(40,20,40,22): typecheck error FS0071: Type constraint mismatch when applying the default type 'obj' for a type inference variable. No overloads match for method 'Return'. + +Known return type: ((int -> int -> int) -> obj) + +Known type parameters: < obj , Applicatives.Ap > + +Available overloads: + - static member Applicatives.Ap.Return: 'a seq * Ap: Applicatives.Ap -> ('a -> 'a seq) // Argument at index 1 doesn't match + - static member Applicatives.Ap.Return: ('r -> 'a) * Ap: Applicatives.Ap -> (('a -> 'r -> 'a2) -> 'a3 -> 'a -> 'r -> 'a2) // Argument at index 1 doesn't match + - static member Applicatives.Ap.Return: System.Tuple<'a> * Ap: Applicatives.Ap -> ('a -> System.Tuple<'a>) // Argument at index 1 doesn't match + - static member Applicatives.Ap.Return: r: ^R * obj -> ('a1 -> ^R) when ^R: (static member Return: 'a1 -> ^R) // Argument 'r' doesn't match Consider adding further type constraints diff --git a/tests/fsharp/typecheck/sigs/neg133.bsl b/tests/fsharp/typecheck/sigs/neg133.bsl index 23bf916f031..4a20d5c9a87 100644 --- a/tests/fsharp/typecheck/sigs/neg133.bsl +++ b/tests/fsharp/typecheck/sigs/neg133.bsl @@ -20,5 +20,3 @@ neg133.fs(63,7,63,14): typecheck error FS0026: This rule will never be matched neg133.fs(69,7,69,16): typecheck error FS0026: This rule will never be matched neg133.fs(76,10,76,11): typecheck error FS0957: One or more of the declared type parameters for this type extension have a missing or wrong type constraint not matching the original type constraints on 'A<_,_,_>' - -neg133.fs(76,10,76,11): typecheck error FS0957: One or more of the declared type parameters for this type extension have a missing or wrong type constraint not matching the original type constraints on 'A<_,_,_>' diff --git a/tests/fsharp/typecheck/sigs/neg15.bsl b/tests/fsharp/typecheck/sigs/neg15.bsl index 055ddf9fcc3..3089124970c 100644 --- a/tests/fsharp/typecheck/sigs/neg15.bsl +++ b/tests/fsharp/typecheck/sigs/neg15.bsl @@ -15,10 +15,6 @@ neg15.fs(110,17,110,45): typecheck error FS0491: The member or object constructo neg15.fs(111,17,111,52): typecheck error FS1092: The type 'PrivateRecordType' is not accessible from this code location -neg15.fs(111,17,111,52): typecheck error FS1092: The type 'PrivateRecordType' is not accessible from this code location - -neg15.fs(112,18,112,78): typecheck error FS1093: The union cases or fields of the type 'RecordTypeWithPrivateRepresentation' are not accessible from this code location - neg15.fs(112,18,112,78): typecheck error FS1093: The union cases or fields of the type 'RecordTypeWithPrivateRepresentation' are not accessible from this code location neg15.fs(113,17,113,76): typecheck error FS1093: The union cases or fields of the type 'RecordTypeWithPrivateRepresentation' are not accessible from this code location diff --git a/tests/fsharp/typecheck/sigs/neg16.bsl b/tests/fsharp/typecheck/sigs/neg16.bsl index b3f777bea39..9cb22ec9c0a 100644 --- a/tests/fsharp/typecheck/sigs/neg16.bsl +++ b/tests/fsharp/typecheck/sigs/neg16.bsl @@ -3,8 +3,6 @@ neg16.fs(7,13,7,16): typecheck error FS0644: Namespaces cannot contain extension neg16.fs(23,10,23,11): typecheck error FS0935: Types with the 'AllowNullLiteral' attribute may only inherit from or implement types which also allow the use of the null literal -neg16.fs(23,10,23,11): typecheck error FS0935: Types with the 'AllowNullLiteral' attribute may only inherit from or implement types which also allow the use of the null literal - neg16.fs(35,10,35,11): typecheck error FS0934: Records, union, abbreviations and struct types cannot have the 'AllowNullLiteral' attribute neg16.fs(38,10,38,11): typecheck error FS0934: Records, union, abbreviations and struct types cannot have the 'AllowNullLiteral' attribute diff --git a/tests/fsharp/typecheck/sigs/neg20.bsl b/tests/fsharp/typecheck/sigs/neg20.bsl index 2f69e52310e..8f6822eb135 100644 --- a/tests/fsharp/typecheck/sigs/neg20.bsl +++ b/tests/fsharp/typecheck/sigs/neg20.bsl @@ -90,19 +90,19 @@ neg20.fs(108,12,108,16): typecheck error FS0001: Type mismatch. Expecting a 'B * B -> 'a' but given a 'A * A -> Data' -The type 'B' does not match the type 'A' +The type 'A' does not match the type 'B' neg20.fs(109,12,109,16): typecheck error FS0001: Type mismatch. Expecting a 'A * B -> 'a' but given a 'A * A -> Data' -The type 'B' does not match the type 'A' +The type 'A' does not match the type 'B' neg20.fs(110,12,110,16): typecheck error FS0001: Type mismatch. Expecting a 'B * A -> 'a' but given a 'A * A -> Data' -The type 'B' does not match the type 'A' +The type 'A' does not match the type 'B' neg20.fs(128,19,128,22): typecheck error FS0001: This expression was expected to have type 'string' @@ -147,7 +147,7 @@ neg20.fs(167,13,167,31): typecheck error FS0502: The member or object constructo neg20.fs(182,14,182,31): typecheck error FS0041: No overloads match for method 'M'. -Known types of arguments: string * obj +Known types of arguments: string * objnull Available overloads: - static member C2.M: fmt: string * [] args: int array -> string // Argument 'args' doesn't match @@ -156,22 +156,12 @@ Available overloads: neg20.fs(183,29,183,34): typecheck error FS0001: This expression was expected to have type 'int' but here has type - 'obj' - -neg20.fs(183,29,183,34): typecheck error FS0001: This expression was expected to have type - 'int' -but here has type - 'obj' + 'objnull' neg20.fs(183,35,183,40): typecheck error FS0001: This expression was expected to have type 'int' but here has type - 'obj' - -neg20.fs(183,35,183,40): typecheck error FS0001: This expression was expected to have type - 'int' -but here has type - 'obj' + 'objnull' neg20.fs(183,14,183,41): typecheck error FS0193: Type constraint mismatch. The type 'string' @@ -182,26 +172,16 @@ is not compatible with type neg20.fs(184,28,184,33): typecheck error FS0001: This expression was expected to have type 'int' but here has type - 'obj' - -neg20.fs(184,28,184,33): typecheck error FS0001: This expression was expected to have type - 'int' -but here has type - 'obj' + 'objnull' neg20.fs(184,34,184,39): typecheck error FS0001: This expression was expected to have type 'int' but here has type - 'obj' - -neg20.fs(184,34,184,39): typecheck error FS0001: This expression was expected to have type - 'int' -but here has type - 'obj' + 'objnull' neg20.fs(188,14,188,31): typecheck error FS0041: No overloads match for method 'M'. -Known types of arguments: string * obj +Known types of arguments: string * objnull Available overloads: - static member C3.M: fmt: string * [] args: string array -> string // Argument 'args' doesn't match @@ -210,22 +190,12 @@ Available overloads: neg20.fs(189,29,189,34): typecheck error FS0001: This expression was expected to have type 'string' but here has type - 'obj' - -neg20.fs(189,29,189,34): typecheck error FS0001: This expression was expected to have type - 'string' -but here has type - 'obj' - -neg20.fs(189,35,189,40): typecheck error FS0001: This expression was expected to have type - 'string' -but here has type - 'obj' + 'objnull' neg20.fs(189,35,189,40): typecheck error FS0001: This expression was expected to have type 'string' but here has type - 'obj' + 'objnull' neg20.fs(189,14,189,41): typecheck error FS0193: Type constraint mismatch. The type 'string' @@ -236,22 +206,12 @@ is not compatible with type neg20.fs(190,28,190,33): typecheck error FS0001: This expression was expected to have type 'string' but here has type - 'obj' - -neg20.fs(190,28,190,33): typecheck error FS0001: This expression was expected to have type - 'string' -but here has type - 'obj' + 'objnull' neg20.fs(190,34,190,39): typecheck error FS0001: This expression was expected to have type 'string' but here has type - 'obj' - -neg20.fs(190,34,190,39): typecheck error FS0001: This expression was expected to have type - 'string' -but here has type - 'obj' + 'objnull' neg20.fs(195,5,195,10): typecheck error FS0842: This attribute is not valid for use on this language element diff --git a/tests/fsharp/typecheck/sigs/neg29.bsl b/tests/fsharp/typecheck/sigs/neg29.bsl index dd2d49ffda1..5f75bb8cdb0 100644 --- a/tests/fsharp/typecheck/sigs/neg29.bsl +++ b/tests/fsharp/typecheck/sigs/neg29.bsl @@ -1,8 +1,8 @@ neg29.fs(5,19,6,16): parse error FS0010: Incomplete structured construct at or before this point in type name. Expected '>' or other token. -neg29.fs(9,1,9,1): parse error FS0010: Incomplete structured construct at or before this point in implementation file - neg29.fs(6,19,6,20): parse error FS0010: Unexpected symbol '(' in expression neg29.fs(6,18,6,19): parse error FS3156: Unexpected token '>' or incomplete expression + +neg29.fs(9,1,9,1): parse error FS0010: Incomplete structured construct at or before this point in implementation file diff --git a/tests/fsharp/typecheck/sigs/neg30.bsl b/tests/fsharp/typecheck/sigs/neg30.bsl index b57ca6bcb82..67f4ba2cd53 100644 --- a/tests/fsharp/typecheck/sigs/neg30.bsl +++ b/tests/fsharp/typecheck/sigs/neg30.bsl @@ -23,8 +23,4 @@ neg30.fs(63,13,63,27): typecheck error FS0001: A generic construct requires that neg30.fs(71,12,71,35): typecheck error FS0120: hello! -neg30.fs(71,12,71,35): typecheck error FS0120: hello! - -neg30.fs(71,12,71,35): typecheck error FS0120: hello! - neg30.fs(78,13,78,37): typecheck error FS10021: hello! diff --git a/tests/fsharp/typecheck/sigs/neg32.bsl b/tests/fsharp/typecheck/sigs/neg32.bsl index 09e6050c790..50625a4882d 100644 --- a/tests/fsharp/typecheck/sigs/neg32.bsl +++ b/tests/fsharp/typecheck/sigs/neg32.bsl @@ -45,10 +45,6 @@ neg32.fs(59,4,59,33): typecheck error FS0671: A property cannot have explicit ty neg32.fs(62,10,62,12): typecheck error FS0039: The type parameter 'T is not defined. -neg32.fs(62,10,62,12): typecheck error FS0039: The type parameter 'T is not defined. - -neg32.fs(65,11,65,13): typecheck error FS0039: The type parameter 'T is not defined. - neg32.fs(65,11,65,13): typecheck error FS0039: The type parameter 'T is not defined. neg32.fs(69,65,69,86): typecheck error FS0033: The non-generic type 'System.EventArgs' does not expect any type arguments, but here is given 1 type argument(s) diff --git a/tests/fsharp/typecheck/sigs/neg48.bsl b/tests/fsharp/typecheck/sigs/neg48.bsl index 4d9e739cc0d..a6f0847486c 100644 --- a/tests/fsharp/typecheck/sigs/neg48.bsl +++ b/tests/fsharp/typecheck/sigs/neg48.bsl @@ -9,50 +9,28 @@ neg48.fs(52,21,52,26): typecheck error FS0023: The member 'Item2' can not be def neg48.fs(56,16,56,20): typecheck error FS0023: The member 'Tags' can not be defined because the name 'Tags' clashes with the generated type 'Tags' in this type or module -neg48.fs(56,16,56,20): typecheck error FS0023: The member 'Tags' can not be defined because the name 'Tags' clashes with the generated type 'Tags' in this type or module - -neg48.fs(60,21,60,25): typecheck error FS0023: The member 'Tags' can not be defined because the name 'Tags' clashes with the generated type 'Tags' in this type or module - neg48.fs(60,21,60,25): typecheck error FS0023: The member 'Tags' can not be defined because the name 'Tags' clashes with the generated type 'Tags' in this type or module neg48.fs(64,16,64,19): typecheck error FS0023: The member 'Tag' can not be defined because the name 'Tag' clashes with the generated property 'Tag' in this type or module -neg48.fs(64,16,64,19): typecheck error FS0023: The member 'Tag' can not be defined because the name 'Tag' clashes with the generated property 'Tag' in this type or module - neg48.fs(68,16,68,20): typecheck error FS0023: The member 'Item' can not be defined because the name 'Item' clashes with the generated property 'Item' in this type or module neg48.fs(72,21,72,25): typecheck error FS0023: The member 'Item' can not be defined because the name 'Item' clashes with the generated property 'Item' in this type or module neg48.fs(76,16,76,20): typecheck error FS0023: The member 'Tags' can not be defined because the name 'Tags' clashes with the generated type 'Tags' in this type or module -neg48.fs(76,16,76,20): typecheck error FS0023: The member 'Tags' can not be defined because the name 'Tags' clashes with the generated type 'Tags' in this type or module - neg48.fs(80,21,80,25): typecheck error FS0023: The member 'Tags' can not be defined because the name 'Tags' clashes with the generated type 'Tags' in this type or module -neg48.fs(80,21,80,25): typecheck error FS0023: The member 'Tags' can not be defined because the name 'Tags' clashes with the generated type 'Tags' in this type or module - -neg48.fs(84,16,84,19): typecheck error FS0023: The member 'Tag' can not be defined because the name 'Tag' clashes with the generated property 'Tag' in this type or module - neg48.fs(84,16,84,19): typecheck error FS0023: The member 'Tag' can not be defined because the name 'Tag' clashes with the generated property 'Tag' in this type or module neg48.fs(88,21,88,24): typecheck error FS0023: The member 'Tag' can not be defined because the name 'Tag' clashes with the generated property 'Tag' in this type or module -neg48.fs(88,21,88,24): typecheck error FS0023: The member 'Tag' can not be defined because the name 'Tag' clashes with the generated property 'Tag' in this type or module - -neg48.fs(92,16,92,20): typecheck error FS0023: The member 'Tags' can not be defined because the name 'Tags' clashes with the generated type 'Tags' in this type or module - neg48.fs(92,16,92,20): typecheck error FS0023: The member 'Tags' can not be defined because the name 'Tags' clashes with the generated type 'Tags' in this type or module neg48.fs(96,16,96,19): typecheck error FS0023: The member 'Tag' can not be defined because the name 'Tag' clashes with the generated property 'Tag' in this type or module -neg48.fs(96,16,96,19): typecheck error FS0023: The member 'Tag' can not be defined because the name 'Tag' clashes with the generated property 'Tag' in this type or module - -neg48.fs(102,16,102,19): typecheck error FS0023: The member 'Tag' can not be defined because the name 'Tag' clashes with the generated property 'Tag' in this type or module - neg48.fs(102,16,102,19): typecheck error FS0023: The member 'Tag' can not be defined because the name 'Tag' clashes with the generated property 'Tag' in this type or module neg48.fs(105,16,105,20): typecheck error FS0023: The member 'Tags' can not be defined because the name 'Tags' clashes with the generated type 'Tags' in this type or module -neg48.fs(105,16,105,20): typecheck error FS0023: The member 'Tags' can not be defined because the name 'Tags' clashes with the generated type 'Tags' in this type or module - neg48.fs(108,16,108,20): typecheck error FS0023: The member 'Item' can not be defined because the name 'Item' clashes with the generated property 'Item' in this type or module diff --git a/tests/fsharp/typecheck/sigs/neg63.bsl b/tests/fsharp/typecheck/sigs/neg63.bsl index 194fbe88771..300565f5df2 100644 --- a/tests/fsharp/typecheck/sigs/neg63.bsl +++ b/tests/fsharp/typecheck/sigs/neg63.bsl @@ -16,5 +16,3 @@ neg63.fs(18,6,18,7): typecheck error FS3209: The address of the variable 'x' or neg63.fs(26,6,26,10): typecheck error FS3209: The address of the variable 'addr' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope. neg63.fs(30,24,30,25): typecheck error FS3232: Struct members cannot return the address of fields of the struct by reference - -neg63.fs(30,24,30,25): typecheck error FS3232: Struct members cannot return the address of fields of the struct by reference diff --git a/tests/fsharp/typecheck/sigs/neg64.vsbsl b/tests/fsharp/typecheck/sigs/neg64.vsbsl index 0b2bac35a59..e9578dc3735 100644 --- a/tests/fsharp/typecheck/sigs/neg64.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg64.vsbsl @@ -1,4 +1,2 @@ neg64.fsx(32,32,32,33): parse error FS0010: Unexpected symbol ')' in if/then/else expression - -neg64.fsx(32,32,32,33): parse error FS0010: Unexpected symbol ')' in if/then/else expression diff --git a/tests/fsharp/typecheck/sigs/neg66.vsbsl b/tests/fsharp/typecheck/sigs/neg66.vsbsl index 9c5184da298..0c27ea51528 100644 --- a/tests/fsharp/typecheck/sigs/neg66.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg66.vsbsl @@ -1,6 +1,4 @@ neg66.fsx(43,4,43,5): parse error FS0010: Unexpected symbol ')' in definition. Expected incomplete structured construct at or before this point or other token. -neg66.fsx(43,4,43,5): parse error FS0010: Unexpected symbol ')' in definition. Expected incomplete structured construct at or before this point or other token. - neg66.fsx(30,1,38,33): typecheck error FS0003: This value is not a function and cannot be applied. diff --git a/tests/fsharp/typecheck/sigs/neg67.vsbsl b/tests/fsharp/typecheck/sigs/neg67.vsbsl index 9d8da15b935..6f2922050be 100644 --- a/tests/fsharp/typecheck/sigs/neg67.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg67.vsbsl @@ -7,14 +7,6 @@ neg67.fsx(42,17,42,34): parse error FS0597: Successive arguments should be separ neg67.fsx(42,35,42,36): parse error FS0010: Unexpected symbol '}' in definition. Expected incomplete structured construct at or before this point or other token. -neg67.fsx(41,36,41,37): parse error FS0010: Incomplete structured construct at or before this point in expression. Expected '}' or other token. - -neg67.fsx(41,15,41,16): parse error FS0604: Unmatched '{' - -neg67.fsx(42,17,42,34): parse error FS0597: Successive arguments should be separated by spaces or tupled, and arguments involving function or method applications should be parenthesized - -neg67.fsx(42,35,42,36): parse error FS0010: Unexpected symbol '}' in definition. Expected incomplete structured construct at or before this point or other token. - neg67.fsx(41,9,41,14): typecheck error FS0193: Type constraint mismatch. The type 'Async' is not compatible with type diff --git a/tests/fsharp/typecheck/sigs/neg68.vsbsl b/tests/fsharp/typecheck/sigs/neg68.vsbsl index 15966211aa0..b55d58ee143 100644 --- a/tests/fsharp/typecheck/sigs/neg68.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg68.vsbsl @@ -1,8 +1,6 @@ neg68.fsx(71,46,71,47): parse error FS0010: Unexpected symbol ')' in binding. Expected incomplete structured construct at or before this point or other token. -neg68.fsx(71,46,71,47): parse error FS0010: Unexpected symbol ')' in binding. Expected incomplete structured construct at or before this point or other token. - neg68.fsx(123,40,123,41): typecheck error FS0001: The type 'bool' does not match the type 'float<'u>' neg68.fsx(123,38,123,39): typecheck error FS0043: The type 'bool' does not match the type 'float<'u>' diff --git a/tests/fsharp/typecheck/sigs/neg69.vsbsl b/tests/fsharp/typecheck/sigs/neg69.vsbsl index 4fa46496f65..75e44001573 100644 --- a/tests/fsharp/typecheck/sigs/neg69.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg69.vsbsl @@ -1,6 +1,3 @@ -neg69.fsx(87,6,87,12): typecheck error FS0912: This declaration element is not permitted in an augmentation - -neg69.fsx(87,6,87,12): typecheck error FS0929: This type requires a definition neg69.fsx(88,43,88,44): parse error FS1241: Expected type argument or static argument @@ -98,98 +95,6 @@ To continue using non-conforming indentation, pass the '--strict-indentation-' f neg69.fsx(242,1,242,3): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (221:1). Try indenting this further. To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. -neg69.fsx(88,43,88,44): parse error FS1241: Expected type argument or static argument - -neg69.fsx(88,44,88,45): parse error FS0010: Unexpected symbol '>' in type definition. Expected '=' or other token. - -neg69.fsx(94,5,94,8): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (93:5). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(94,5,94,8): parse error FS0010: Unexpected keyword 'let' or 'use' in implementation file - -neg69.fsx(95,5,95,8): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (94:5). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(96,5,96,8): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (95:5). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(98,5,98,11): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (96:5). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(98,19,98,20): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (96:5). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(99,5,99,11): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (96:5). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(100,5,100,11): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (96:5). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(101,5,101,11): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (96:5). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(102,5,102,11): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (96:5). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(104,5,104,14): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (96:5). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(113,1,113,5): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (96:5). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(168,1,168,4): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (96:5). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(170,1,170,4): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (168:1). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(171,1,171,4): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (170:1). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(172,1,172,4): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (171:1). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(173,1,173,4): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (172:1). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(174,1,174,4): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (173:1). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(176,1,176,4): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (174:1). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(177,1,177,4): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (176:1). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(178,1,178,4): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (177:1). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(180,1,180,4): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (178:1). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(181,1,181,4): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (180:1). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(182,1,182,4): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (181:1). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(183,1,183,4): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (182:1). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(185,1,185,4): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (183:1). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(194,1,194,4): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (185:1). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(203,1,203,4): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (194:1). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(212,1,212,4): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (203:1). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. - -neg69.fsx(221,1,221,4): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (212:1). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. +neg69.fsx(87,6,87,12): typecheck error FS0929: This type requires a definition -neg69.fsx(242,1,242,3): parse error FS0058: Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (221:1). Try indenting this further. -To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7. +neg69.fsx(87,6,87,12): typecheck error FS0912: This declaration element is not permitted in an augmentation diff --git a/tests/fsharp/typecheck/sigs/neg70.vsbsl b/tests/fsharp/typecheck/sigs/neg70.vsbsl index 5103887eb35..16c15ba3780 100644 --- a/tests/fsharp/typecheck/sigs/neg70.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg70.vsbsl @@ -1,4 +1,2 @@ neg70.fsx(109,64,109,65): parse error FS0010: Unexpected symbol ')' in binding. Expected incomplete structured construct at or before this point or other token. - -neg70.fsx(109,64,109,65): parse error FS0010: Unexpected symbol ')' in binding. Expected incomplete structured construct at or before this point or other token. diff --git a/tests/fsharp/typecheck/sigs/neg71.vsbsl b/tests/fsharp/typecheck/sigs/neg71.vsbsl index 433b951a1d9..b50d91e15e0 100644 --- a/tests/fsharp/typecheck/sigs/neg71.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg71.vsbsl @@ -7,14 +7,6 @@ neg71.fsx(230,1,230,13): parse error FS0010: Unexpected identifier in member def neg71.fsx(128,5,128,81): parse info FS3520: XML comment is not placed on a valid language element. -neg71.fsx(110,43,110,44): parse error FS0010: Unexpected symbol ')' in expression. Expected incomplete structured construct at or before this point or other token. - -neg71.fsx(166,24,168,1): parse error FS0010: Incomplete structured construct at or before this point in member definition. Expected incomplete structured construct at or before this point, 'end' or other token. - -neg71.fsx(230,1,230,13): parse error FS0010: Unexpected identifier in member definition - -neg71.fsx(128,5,128,81): parse info FS3520: XML comment is not placed on a valid language element. - neg71.fsx(168,1,168,28): typecheck error FS0960: 'let' and 'do' bindings must come before member and interface definitions in type definitions neg71.fsx(104,14,104,14): typecheck error FS0887: The type ''a' is not an interface type diff --git a/tests/fsharp/typecheck/sigs/neg72.vsbsl b/tests/fsharp/typecheck/sigs/neg72.vsbsl index 29fc279ec42..e7c11aa1adf 100644 --- a/tests/fsharp/typecheck/sigs/neg72.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg72.vsbsl @@ -1,4 +1,2 @@ neg72.fsx(144,106,144,107): parse error FS0010: Unexpected symbol ')' in binding. Expected incomplete structured construct at or before this point or other token. - -neg72.fsx(144,106,144,107): parse error FS0010: Unexpected symbol ')' in binding. Expected incomplete structured construct at or before this point or other token. diff --git a/tests/fsharp/typecheck/sigs/neg73.vsbsl b/tests/fsharp/typecheck/sigs/neg73.vsbsl index b11767d5921..8ea9d755311 100644 --- a/tests/fsharp/typecheck/sigs/neg73.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg73.vsbsl @@ -1,4 +1,2 @@ neg73.fsx(153,79,153,80): parse error FS0010: Unexpected symbol ']' in binding. Expected incomplete structured construct at or before this point or other token. - -neg73.fsx(153,79,153,80): parse error FS0010: Unexpected symbol ']' in binding. Expected incomplete structured construct at or before this point or other token. diff --git a/tests/fsharp/typecheck/sigs/neg79.vsbsl b/tests/fsharp/typecheck/sigs/neg79.vsbsl index 5527cabeabb..b5599e27953 100644 --- a/tests/fsharp/typecheck/sigs/neg79.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg79.vsbsl @@ -1,4 +1,2 @@ neg79.fsx(31,32,31,33): parse error FS0010: Unexpected symbol ')' in if/then/else expression - -neg79.fsx(31,32,31,33): parse error FS0010: Unexpected symbol ')' in if/then/else expression diff --git a/tests/fsharp/typecheck/sigs/neg80.vsbsl b/tests/fsharp/typecheck/sigs/neg80.vsbsl index 63aba7d33db..86e8d40b6f4 100644 --- a/tests/fsharp/typecheck/sigs/neg80.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg80.vsbsl @@ -1,4 +1,2 @@ neg80.fsx(79,5,79,6): parse error FS0010: Unexpected symbol '|' in pattern matching - -neg80.fsx(79,5,79,6): parse error FS0010: Unexpected symbol '|' in pattern matching diff --git a/tests/fsharp/typecheck/sigs/neg84.vsbsl b/tests/fsharp/typecheck/sigs/neg84.vsbsl index 2b7a0c06bee..6d4db3adec9 100644 --- a/tests/fsharp/typecheck/sigs/neg84.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg84.vsbsl @@ -1,4 +1,2 @@ neg84.fsx(11,1,11,1): parse error FS0010: Incomplete structured construct at or before this point in expression - -neg84.fsx(11,1,11,1): parse error FS0010: Incomplete structured construct at or before this point in expression diff --git a/tests/fsharp/typecheck/sigs/neg86.vsbsl b/tests/fsharp/typecheck/sigs/neg86.vsbsl index 638377e4bf9..667ca721ae3 100644 --- a/tests/fsharp/typecheck/sigs/neg86.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg86.vsbsl @@ -1,8 +1,6 @@ neg86.fsx(18,20,18,22): parse error FS3156: Unexpected token 'in' or incomplete expression -neg86.fsx(18,20,18,22): parse error FS3156: Unexpected token 'in' or incomplete expression - neg86.fsx(4,21,4,23): typecheck error FS3156: Unexpected token 'in' or incomplete expression neg86.fsx(8,13,8,17): typecheck error FS3096: 'join' must be followed by a variable name. Usage: join var in collection on (outerKey = innerKey). Note that parentheses are required after 'on'. diff --git a/tests/fsharp/typecheck/sigs/neg89.bsl b/tests/fsharp/typecheck/sigs/neg89.bsl index 0f81ef3b09b..77ef120086e 100644 --- a/tests/fsharp/typecheck/sigs/neg89.bsl +++ b/tests/fsharp/typecheck/sigs/neg89.bsl @@ -1,44 +1,10 @@ neg89.fsx(2,10,2,11): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation -neg89.fsx(2,10,2,11): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - -neg89.fsx(3,9,3,10): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - -neg89.fsx(3,9,3,10): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - -neg89.fsx(3,9,3,10): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - neg89.fsx(3,9,3,10): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation neg89.fsx(6,10,6,11): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation -neg89.fsx(6,10,6,11): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - -neg89.fsx(6,10,6,11): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - -neg89.fsx(6,10,6,11): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - -neg89.fsx(7,9,7,10): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - -neg89.fsx(7,9,7,10): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - -neg89.fsx(7,9,7,10): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - neg89.fsx(7,9,7,10): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation neg89.fsx(8,9,8,10): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - -neg89.fsx(8,9,8,10): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - -neg89.fsx(8,9,8,10): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - -neg89.fsx(8,9,8,10): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - -neg89.fsx(8,9,8,10): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - -neg89.fsx(8,9,8,10): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - -neg89.fsx(8,9,8,10): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation - -neg89.fsx(8,9,8,10): typecheck error FS0953: This type definition involves an immediate cyclic reference through an abbreviation diff --git a/tests/fsharp/typecheck/sigs/neg90.bsl b/tests/fsharp/typecheck/sigs/neg90.bsl index 5f8f380d3ef..d04c6f2b059 100644 --- a/tests/fsharp/typecheck/sigs/neg90.bsl +++ b/tests/fsharp/typecheck/sigs/neg90.bsl @@ -3,8 +3,6 @@ neg90.fs(4,9,4,12): typecheck error FS0001: A generic construct requires that th neg90.fs(7,22,7,25): typecheck error FS0039: The type 'foo' is not defined. -neg90.fs(7,22,7,25): typecheck error FS0039: The type 'foo' is not defined. - neg90.fs(16,9,16,21): typecheck error FS0035: This construct is deprecated: The union type for union case 'Member' was defined with the RequireQualifiedAccessAttribute. Include the name of the union type ('DU') in the name you are using. neg90.fs(28,9,28,41): typecheck error FS0035: This construct is deprecated: The record type for the record field 'Field1' was defined with the RequireQualifiedAccessAttribute. Include the name of the record type ('Record1') in the name you are using. diff --git a/tests/fsharp/typecheck/sigs/neg95.bsl b/tests/fsharp/typecheck/sigs/neg95.bsl index ba9ceefb4e6..daa32cb1a99 100644 --- a/tests/fsharp/typecheck/sigs/neg95.bsl +++ b/tests/fsharp/typecheck/sigs/neg95.bsl @@ -13,4 +13,4 @@ neg95.fs(39,7,39,18): typecheck error FS3200: In a recursive declaration group, neg95.fs(45,10,45,22): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation -neg95.fs(52,10,52,21): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation \ No newline at end of file +neg95.fs(52,10,52,21): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation diff --git a/tests/fsharp/typecheck/sigs/neg96.bsl b/tests/fsharp/typecheck/sigs/neg96.bsl index cd87ec8144c..9a6e2882974 100644 --- a/tests/fsharp/typecheck/sigs/neg96.bsl +++ b/tests/fsharp/typecheck/sigs/neg96.bsl @@ -2,5 +2,3 @@ neg96.fs(11,9,11,21): typecheck error FS1133: No constructors are available for the type 'StructRecord' neg96.fs(18,10,18,11): typecheck error FS0039: The type 'X' is not defined. - -neg96.fs(18,10,18,11): typecheck error FS0039: The type 'X' is not defined. diff --git a/tests/fsharp/typecheck/sigs/neg_byref_11.bsl b/tests/fsharp/typecheck/sigs/neg_byref_11.bsl index 6c71b1f88a1..c3f35c64bf8 100644 --- a/tests/fsharp/typecheck/sigs/neg_byref_11.bsl +++ b/tests/fsharp/typecheck/sigs/neg_byref_11.bsl @@ -2,9 +2,3 @@ neg_byref_11.fs(3,13,3,14): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. neg_byref_11.fs(3,6,3,8): typecheck error FS0437: A type would store a byref typed value. This is not permitted by Common IL. - -neg_byref_11.fs(3,13,3,14): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -neg_byref_11.fs(3,13,3,14): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -neg_byref_11.fs(3,13,3,14): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. diff --git a/tests/fsharp/typecheck/sigs/neg_byref_12.bsl b/tests/fsharp/typecheck/sigs/neg_byref_12.bsl index c3ecf36b111..3bd33b8bc5e 100644 --- a/tests/fsharp/typecheck/sigs/neg_byref_12.bsl +++ b/tests/fsharp/typecheck/sigs/neg_byref_12.bsl @@ -4,7 +4,3 @@ neg_byref_12.fs(3,21,3,31): typecheck error FS0412: A type instantiation involve neg_byref_12.fs(3,6,3,8): typecheck error FS0437: A type would store a byref typed value. This is not permitted by Common IL. neg_byref_12.fs(3,11,3,17): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -neg_byref_12.fs(3,11,3,17): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -neg_byref_12.fs(3,11,3,17): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. diff --git a/tests/fsharp/typecheck/sigs/neg_byref_14.bsl b/tests/fsharp/typecheck/sigs/neg_byref_14.bsl index 71ad2babfbc..90ae023f45f 100644 --- a/tests/fsharp/typecheck/sigs/neg_byref_14.bsl +++ b/tests/fsharp/typecheck/sigs/neg_byref_14.bsl @@ -4,7 +4,3 @@ neg_byref_14.fs(3,29,3,39): typecheck error FS0412: A type instantiation involve neg_byref_14.fs(3,11,3,25): typecheck error FS0437: A type would store a byref typed value. This is not permitted by Common IL. neg_byref_14.fs(3,11,3,25): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -neg_byref_14.fs(3,11,3,25): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -neg_byref_14.fs(3,11,3,25): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. diff --git a/tests/fsharp/typecheck/sigs/neg_byref_16.bsl b/tests/fsharp/typecheck/sigs/neg_byref_16.bsl index d7964e54120..2843736a8f3 100644 --- a/tests/fsharp/typecheck/sigs/neg_byref_16.bsl +++ b/tests/fsharp/typecheck/sigs/neg_byref_16.bsl @@ -3,6 +3,4 @@ neg_byref_16.fs(3,5,3,6): typecheck error FS3301: The function or method has an neg_byref_16.fs(3,33,3,42): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. -neg_byref_16.fs(3,33,3,42): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - neg_byref_16.fs(3,40,3,41): typecheck error FS0421: The address of the variable 'a' cannot be used at this point diff --git a/tests/fsharp/typecheck/sigs/neg_byref_20.bsl b/tests/fsharp/typecheck/sigs/neg_byref_20.bsl index 408b36c3df4..eecb7fcc8f5 100644 --- a/tests/fsharp/typecheck/sigs/neg_byref_20.bsl +++ b/tests/fsharp/typecheck/sigs/neg_byref_20.bsl @@ -1,4 +1,2 @@ neg_byref_20.fs(2,2,2,21): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -neg_byref_20.fs(2,2,2,21): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. diff --git a/tests/fsharp/typecheck/sigs/neg_byref_22.bsl b/tests/fsharp/typecheck/sigs/neg_byref_22.bsl index 7c5e93d3151..a4a9bad818a 100644 --- a/tests/fsharp/typecheck/sigs/neg_byref_22.bsl +++ b/tests/fsharp/typecheck/sigs/neg_byref_22.bsl @@ -5,8 +5,3 @@ neg_byref_22.fs(3,16,3,20): typecheck error FS0001: This expression was expected 'byref' but here has type 'int' - -neg_byref_22.fs(3,16,3,20): typecheck error FS0001: This expression was expected to have type - 'byref' -but here has type - 'int' diff --git a/tests/fsharp/typecheck/sigs/neg_byref_3.bsl b/tests/fsharp/typecheck/sigs/neg_byref_3.bsl index 48fb07c7f7e..05043743640 100644 --- a/tests/fsharp/typecheck/sigs/neg_byref_3.bsl +++ b/tests/fsharp/typecheck/sigs/neg_byref_3.bsl @@ -5,10 +5,6 @@ neg_byref_3.fs(2,5,2,8): typecheck error FS0412: A type instantiation involves a neg_byref_3.fs(2,11,2,22): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. -neg_byref_3.fs(2,11,2,22): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - neg_byref_3.fs(3,5,3,6): typecheck error FS3301: The function or method has an invalid return type '(byref list -> int)'. This is not permitted by the rules of Common IL. neg_byref_3.fs(3,11,3,22): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -neg_byref_3.fs(3,11,3,22): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. diff --git a/tests/fsharp/typecheck/sigs/neg_byref_7.bsl b/tests/fsharp/typecheck/sigs/neg_byref_7.bsl index cbe7789b3a1..89a797bea13 100644 --- a/tests/fsharp/typecheck/sigs/neg_byref_7.bsl +++ b/tests/fsharp/typecheck/sigs/neg_byref_7.bsl @@ -1,10 +1,6 @@ neg_byref_7.fs(2,31,2,35): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. -neg_byref_7.fs(2,31,2,35): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -neg_byref_7.fs(2,38,2,43): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - neg_byref_7.fs(2,38,2,43): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. neg_byref_7.fs(2,39,2,40): typecheck error FS0418: The byref typed value 'v' cannot be used at this point @@ -13,12 +9,4 @@ neg_byref_7.fs(2,42,2,43): typecheck error FS0418: The byref typed value 'v' can neg_byref_7.fs(2,47,2,60): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. -neg_byref_7.fs(2,47,2,60): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -neg_byref_7.fs(2,47,2,53): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -neg_byref_7.fs(2,47,2,53): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -neg_byref_7.fs(2,47,2,53): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - neg_byref_7.fs(2,47,2,53): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. diff --git a/tests/fsharp/typecheck/sigs/neg_byref_8.bsl b/tests/fsharp/typecheck/sigs/neg_byref_8.bsl index d39ae5771d1..11830fd6b92 100644 --- a/tests/fsharp/typecheck/sigs/neg_byref_8.bsl +++ b/tests/fsharp/typecheck/sigs/neg_byref_8.bsl @@ -1,10 +1,6 @@ neg_byref_8.fs(2,31,2,35): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. -neg_byref_8.fs(2,31,2,35): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -neg_byref_8.fs(2,38,2,43): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - neg_byref_8.fs(2,38,2,43): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. neg_byref_8.fs(2,39,2,40): typecheck error FS0418: The byref typed value 'v' cannot be used at this point @@ -13,12 +9,4 @@ neg_byref_8.fs(2,42,2,43): typecheck error FS0418: The byref typed value 'v' can neg_byref_8.fs(2,47,2,60): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. -neg_byref_8.fs(2,47,2,60): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -neg_byref_8.fs(2,47,2,53): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -neg_byref_8.fs(2,47,2,53): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - -neg_byref_8.fs(2,47,2,53): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - neg_byref_8.fs(2,47,2,53): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. diff --git a/tests/fsharp/typecheck/sigs/version50/neg20.bsl b/tests/fsharp/typecheck/sigs/version50/neg20.bsl index d9f75e0f0ab..fde27808b4e 100644 --- a/tests/fsharp/typecheck/sigs/version50/neg20.bsl +++ b/tests/fsharp/typecheck/sigs/version50/neg20.bsl @@ -135,19 +135,19 @@ neg20.fs(108,12,108,16): typecheck error FS0001: Type mismatch. Expecting a 'B * B -> 'a' but given a 'A * A -> Data' -The type 'B' does not match the type 'A' +The type 'A' does not match the type 'B' neg20.fs(109,12,109,16): typecheck error FS0001: Type mismatch. Expecting a 'A * B -> 'a' but given a 'A * A -> Data' -The type 'B' does not match the type 'A' +The type 'A' does not match the type 'B' neg20.fs(110,12,110,16): typecheck error FS0001: Type mismatch. Expecting a 'B * A -> 'a' but given a 'A * A -> Data' -The type 'B' does not match the type 'A' +The type 'A' does not match the type 'B' neg20.fs(128,19,128,22): typecheck error FS0001: This expression was expected to have type 'string' @@ -197,7 +197,7 @@ neg20.fs(167,13,167,31): typecheck error FS0502: The member or object constructo neg20.fs(182,14,182,31): typecheck error FS0041: No overloads match for method 'M'. -Known types of arguments: string * obj +Known types of arguments: string * objnull Available overloads: - static member C2.M: fmt: string * [] args: int array -> string // Argument 'args' doesn't match @@ -206,22 +206,12 @@ Available overloads: neg20.fs(183,29,183,34): typecheck error FS0001: This expression was expected to have type 'int' but here has type - 'obj' - -neg20.fs(183,29,183,34): typecheck error FS0001: This expression was expected to have type - 'int' -but here has type - 'obj' + 'objnull' neg20.fs(183,35,183,40): typecheck error FS0001: This expression was expected to have type 'int' but here has type - 'obj' - -neg20.fs(183,35,183,40): typecheck error FS0001: This expression was expected to have type - 'int' -but here has type - 'obj' + 'objnull' neg20.fs(183,14,183,41): typecheck error FS0001: This expression was expected to have type 'unit' @@ -231,26 +221,16 @@ but here has type neg20.fs(184,28,184,33): typecheck error FS0001: This expression was expected to have type 'int' but here has type - 'obj' - -neg20.fs(184,28,184,33): typecheck error FS0001: This expression was expected to have type - 'int' -but here has type - 'obj' + 'objnull' neg20.fs(184,34,184,39): typecheck error FS0001: This expression was expected to have type 'int' but here has type - 'obj' - -neg20.fs(184,34,184,39): typecheck error FS0001: This expression was expected to have type - 'int' -but here has type - 'obj' + 'objnull' neg20.fs(188,14,188,31): typecheck error FS0041: No overloads match for method 'M'. -Known types of arguments: string * obj +Known types of arguments: string * objnull Available overloads: - static member C3.M: fmt: string * [] args: string array -> string // Argument 'args' doesn't match @@ -259,22 +239,12 @@ Available overloads: neg20.fs(189,29,189,34): typecheck error FS0001: This expression was expected to have type 'string' but here has type - 'obj' - -neg20.fs(189,29,189,34): typecheck error FS0001: This expression was expected to have type - 'string' -but here has type - 'obj' - -neg20.fs(189,35,189,40): typecheck error FS0001: This expression was expected to have type - 'string' -but here has type - 'obj' + 'objnull' neg20.fs(189,35,189,40): typecheck error FS0001: This expression was expected to have type 'string' but here has type - 'obj' + 'objnull' neg20.fs(189,14,189,41): typecheck error FS0001: This expression was expected to have type 'unit' @@ -284,22 +254,12 @@ but here has type neg20.fs(190,28,190,33): typecheck error FS0001: This expression was expected to have type 'string' but here has type - 'obj' - -neg20.fs(190,28,190,33): typecheck error FS0001: This expression was expected to have type - 'string' -but here has type - 'obj' + 'objnull' neg20.fs(190,34,190,39): typecheck error FS0001: This expression was expected to have type 'string' but here has type - 'obj' - -neg20.fs(190,34,190,39): typecheck error FS0001: This expression was expected to have type - 'string' -but here has type - 'obj' + 'objnull' neg20.fs(195,5,195,10): typecheck error FS0842: This attribute is not valid for use on this language element diff --git a/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40-nologo.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40-nologo.437.1033.bsl index 971ab021d50..e37ba4d1b30 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40-nologo.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40-nologo.437.1033.bsl @@ -52,6 +52,8 @@ Usage: fsiAnyCpu [script.fsx []] --nowarn: Disable specific warning messages --warnon: Enable specific warnings that may be off by default +--checknulls[+|-] Enable nullness declarations and + checks --consolecolors[+|-] Output warning and error messages in color diff --git a/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40.437.1033.bsl index 3f4de3d42fa..893bcf352af 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40.437.1033.bsl @@ -54,6 +54,8 @@ Usage: fsiAnyCpu [script.fsx []] --nowarn: Disable specific warning messages --warnon: Enable specific warnings that may be off by default +--checknulls[+|-] Enable nullness declarations and + checks --consolecolors[+|-] Output warning and error messages in color diff --git a/tests/service/data/SyntaxTree/Nullness/AbstractClassProperty.fs b/tests/service/data/SyntaxTree/Nullness/AbstractClassProperty.fs new file mode 100644 index 00000000000..a11725eb01b --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/AbstractClassProperty.fs @@ -0,0 +1,3 @@ +[] +type AbstractBase() = + abstract Property1 : string | null with get, set diff --git a/tests/service/data/SyntaxTree/Nullness/AbstractClassProperty.fs.bsl b/tests/service/data/SyntaxTree/Nullness/AbstractClassProperty.fs.bsl new file mode 100644 index 00000000000..a319c237e5d --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/AbstractClassProperty.fs.bsl @@ -0,0 +1,60 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/AbstractClassProperty.fs", false, + QualifiedNameOfFile AbstractClassProperty, [], [], + [SynModuleOrNamespace + ([AbstractClassProperty], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([{ Attributes = + [{ TypeName = + SynLongIdent ([AbstractClass], [], [None]) + ArgExpr = Const (Unit, (1,2--1,15)) + Target = None + AppliesToGetterAndSetter = false + Range = (1,2--1,15) }] + Range = (1,0--1,17) }], None, [], [AbstractBase], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (2,5--2,17)), + ObjectModel + (Unspecified, + [ImplicitCtor + (None, [], Const (Unit, (2,17--2,19)), None, + PreXmlDoc ((2,17), FSharp.Compiler.Xml.XmlDocCollector), + (2,5--2,17), { AsKeyword = None }); + AbstractSlot + (SynValSig + ([], SynIdent (Property1, None), + SynValTyparDecls (None, true), + WithNull + (LongIdent (SynLongIdent ([string], [], [None])), + false, (3,24--3,37)), + SynValInfo ([], SynArgInfo ([], false, None)), false, + false, + PreXmlDoc ((3,3), FSharp.Compiler.Xml.XmlDocCollector), + None, None, (3,3--3,51), + { LeadingKeyword = Abstract (3,3--3,11) + InlineKeyword = None + WithKeyword = Some (3,38--3,42) + EqualsRange = None }), + { IsInstance = true + IsDispatchSlot = true + IsOverrideOrExplicitImpl = false + IsFinal = false + GetterOrSetterIsCompilerGenerated = false + MemberKind = PropertyGetSet }, (3,3--3,51), + { GetSetKeywords = + Some (GetSet ((3,43--3,46), (3,48--3,51))) })], + (3,3--3,51)), [], + Some + (ImplicitCtor + (None, [], Const (Unit, (2,17--2,19)), None, + PreXmlDoc ((2,17), FSharp.Compiler.Xml.XmlDocCollector), + (2,5--2,17), { AsKeyword = None })), (1,0--3,51), + { LeadingKeyword = Type (2,0--2,4) + EqualsRange = Some (2,20--2,21) + WithKeyword = None })], (1,0--3,51))], PreXmlDocEmpty, [], + None, (1,0--4,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs b/tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs new file mode 100644 index 00000000000..6f1f90d780a --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs @@ -0,0 +1 @@ +type DU = MyCase of (string | null) diff --git a/tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs.bsl new file mode 100644 index 00000000000..fd375837c54 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs.bsl @@ -0,0 +1,38 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/DuCaseStringOrNull.fs", false, + QualifiedNameOfFile DuCaseStringOrNull, [], [], + [SynModuleOrNamespace + ([DuCaseStringOrNull], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [DU], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (1,5--1,7)), + Simple + (Union + (None, + [SynUnionCase + ([], SynIdent (MyCase, None), + Fields + [SynField + ([], false, None, + Paren + (WithNull + (LongIdent + (SynLongIdent ([string], [], [None])), + false, (1,21--1,34)), (1,20--1,35)), + false, + PreXmlDoc ((1,20), FSharp.Compiler.Xml.XmlDocCollector), + None, (1,20--1,35), { LeadingKeyword = None + MutableKeyword = None })], + PreXmlDoc ((1,10), FSharp.Compiler.Xml.XmlDocCollector), + None, (1,10--1,35), { BarRange = None })], + (1,10--1,35)), (1,10--1,35)), [], None, (1,5--1,35), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,8--1,9) + WithKeyword = None })], (1,0--1,35))], PreXmlDocEmpty, [], + None, (1,0--2,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs b/tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs new file mode 100644 index 00000000000..dda36337883 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs @@ -0,0 +1 @@ +type DU = MyCase of (string | null) * int diff --git a/tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs.bsl b/tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs.bsl new file mode 100644 index 00000000000..3af1fc28bd5 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs.bsl @@ -0,0 +1,45 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/DuCaseTuplePrecedence.fs", false, + QualifiedNameOfFile DuCaseTuplePrecedence, [], [], + [SynModuleOrNamespace + ([DuCaseTuplePrecedence], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [DU], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (1,5--1,7)), + Simple + (Union + (None, + [SynUnionCase + ([], SynIdent (MyCase, None), + Fields + [SynField + ([], false, None, + Paren + (WithNull + (LongIdent + (SynLongIdent ([string], [], [None])), + false, (1,21--1,34)), (1,20--1,35)), + false, + PreXmlDoc ((1,20), FSharp.Compiler.Xml.XmlDocCollector), + None, (1,20--1,35), { LeadingKeyword = None + MutableKeyword = None }); + SynField + ([], false, None, + LongIdent (SynLongIdent ([int], [], [None])), + false, + PreXmlDoc ((1,38), FSharp.Compiler.Xml.XmlDocCollector), + None, (1,38--1,41), { LeadingKeyword = None + MutableKeyword = None })], + PreXmlDoc ((1,10), FSharp.Compiler.Xml.XmlDocCollector), + None, (1,10--1,41), { BarRange = None })], + (1,10--1,41)), (1,10--1,41)), [], None, (1,5--1,41), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,8--1,9) + WithKeyword = None })], (1,0--1,41))], PreXmlDocEmpty, [], + None, (1,0--2,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/ExplicitField.fs b/tests/service/data/SyntaxTree/Nullness/ExplicitField.fs new file mode 100644 index 00000000000..fd93ac6b9f5 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/ExplicitField.fs @@ -0,0 +1,4 @@ +type MyStruct = + struct + val mutable myString : string | null + end diff --git a/tests/service/data/SyntaxTree/Nullness/ExplicitField.fs.bsl b/tests/service/data/SyntaxTree/Nullness/ExplicitField.fs.bsl new file mode 100644 index 00000000000..93c49b868bf --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/ExplicitField.fs.bsl @@ -0,0 +1,31 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/ExplicitField.fs", false, + QualifiedNameOfFile ExplicitField, [], [], + [SynModuleOrNamespace + ([ExplicitField], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [MyStruct], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (1,5--1,13)), + ObjectModel + (Struct, + [ValField + (SynField + ([], false, Some myString, + WithNull + (LongIdent (SynLongIdent ([string], [], [None])), + false, (3,31--3,44)), true, + PreXmlDoc ((3,8), FSharp.Compiler.Xml.XmlDocCollector), + None, (3,8--3,44), + { LeadingKeyword = Some (Val (3,8--3,11)) + MutableKeyword = Some (3,12--3,19) }), (3,8--3,44))], + (2,4--4,7)), [], None, (1,5--4,7), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,14--1,15) + WithKeyword = None })], (1,0--4,7))], PreXmlDocEmpty, [], + None, (1,0--5,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/FunctionArgAsPatternWithNullCase.fs b/tests/service/data/SyntaxTree/Nullness/FunctionArgAsPatternWithNullCase.fs new file mode 100644 index 00000000000..5cb343224f6 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/FunctionArgAsPatternWithNullCase.fs @@ -0,0 +1 @@ +let myFunc ("abc" | "" : string | null | "123") = 15 diff --git a/tests/service/data/SyntaxTree/Nullness/FunctionArgAsPatternWithNullCase.fs.bsl b/tests/service/data/SyntaxTree/Nullness/FunctionArgAsPatternWithNullCase.fs.bsl new file mode 100644 index 00000000000..016adb52e2b --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/FunctionArgAsPatternWithNullCase.fs.bsl @@ -0,0 +1,46 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/FunctionArgAsPatternWithNullCase.fs", false, + QualifiedNameOfFile FunctionArgAsPatternWithNullCase, [], [], + [SynModuleOrNamespace + ([FunctionArgAsPatternWithNullCase], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, + SynValInfo + ([[SynArgInfo ([], false, None)]], + SynArgInfo ([], false, None)), None), + LongIdent + (SynLongIdent ([myFunc], [], [None]), None, None, + Pats + [Paren + (Or + (Or + (Const + (String ("abc", Regular, (1,12--1,17)), + (1,12--1,17)), + Typed + (Const + (String ("", Regular, (1,20--1,22)), + (1,20--1,22)), + WithNull + (LongIdent + (SynLongIdent ([string], [], [None])), + false, (1,25--1,38)), (1,20--1,38)), + (1,12--1,38), { BarRange = (1,18--1,19) }), + Const + (String ("123", Regular, (1,41--1,46)), + (1,41--1,46)), (1,12--1,46), + { BarRange = (1,39--1,40) }), (1,11--1,47))], None, + (1,4--1,47)), None, Const (Int32 15, (1,50--1,52)), + (1,4--1,47), NoneAtLet, { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,48--1,49) })], + (1,0--1,52))], PreXmlDocEmpty, [], None, (1,0--2,0), + { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/GenericFunctionReturnTypeNotStructNull.fs b/tests/service/data/SyntaxTree/Nullness/GenericFunctionReturnTypeNotStructNull.fs new file mode 100644 index 00000000000..ea4694fc5e8 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericFunctionReturnTypeNotStructNull.fs @@ -0,0 +1 @@ +let myFunc() : 'T when 'T : not struct and 'T:null = null diff --git a/tests/service/data/SyntaxTree/Nullness/GenericFunctionReturnTypeNotStructNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericFunctionReturnTypeNotStructNull.fs.bsl new file mode 100644 index 00000000000..d155f74abba --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericFunctionReturnTypeNotStructNull.fs.bsl @@ -0,0 +1,42 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/GenericFunctionReturnTypeNotStructNull.fs", false, + QualifiedNameOfFile GenericFunctionReturnTypeNotStructNull, [], [], + [SynModuleOrNamespace + ([GenericFunctionReturnTypeNotStructNull], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([[]], SynArgInfo ([], false, None)), None), + LongIdent + (SynLongIdent ([myFunc], [], [None]), None, None, + Pats [Paren (Const (Unit, (1,10--1,12)), (1,10--1,12))], + None, (1,4--1,12)), + Some + (SynBindingReturnInfo + (WithGlobalConstraints + (Var (SynTypar (T, None, false), (1,15--1,17)), + [WhereTyparIsReferenceType + (SynTypar (T, None, false), (1,23--1,38)); + WhereTyparSupportsNull + (SynTypar (T, None, false), (1,43--1,50))], + (1,15--1,50)), (1,15--1,50), [], + { ColonRange = Some (1,13--1,14) })), + Typed + (Null (1,53--1,57), + WithGlobalConstraints + (Var (SynTypar (T, None, false), (1,15--1,17)), + [WhereTyparIsReferenceType + (SynTypar (T, None, false), (1,23--1,38)); + WhereTyparSupportsNull + (SynTypar (T, None, false), (1,43--1,50))], + (1,15--1,50)), (1,53--1,57)), (1,4--1,12), NoneAtLet, + { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,51--1,52) })], (1,0--1,57))], + PreXmlDocEmpty, [], None, (1,0--2,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs new file mode 100644 index 00000000000..9f80e8f8ac2 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs @@ -0,0 +1 @@ +let myFunc (x: 'T when 'T: not null) = 42 diff --git a/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs.bsl new file mode 100644 index 00000000000..2989025967c --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs.bsl @@ -0,0 +1,36 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/GenericFunctionTyparNotNull.fs", false, + QualifiedNameOfFile GenericFunctionTyparNotNull, [], [], + [SynModuleOrNamespace + ([GenericFunctionTyparNotNull], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, + SynValInfo + ([[SynArgInfo ([], false, Some x)]], + SynArgInfo ([], false, None)), None), + LongIdent + (SynLongIdent ([myFunc], [], [None]), None, None, + Pats + [Paren + (Typed + (Named + (SynIdent (x, None), false, None, (1,12--1,13)), + WithGlobalConstraints + (Var (SynTypar (T, None, false), (1,15--1,17)), + [WhereTyparNotSupportsNull + (SynTypar (T, None, false), (1,23--1,35))], + (1,15--1,35)), (1,12--1,35)), (1,11--1,36))], + None, (1,4--1,36)), None, Const (Int32 42, (1,39--1,41)), + (1,4--1,36), NoneAtLet, { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,37--1,38) })], + (1,0--1,41))], PreXmlDocEmpty, [], None, (1,0--2,0), + { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNull.fs b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNull.fs new file mode 100644 index 00000000000..712e2b94c49 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNull.fs @@ -0,0 +1 @@ +let myFunc (x: 'T when 'T: null) = 42 diff --git a/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNull.fs.bsl new file mode 100644 index 00000000000..db83d1ddcbf --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNull.fs.bsl @@ -0,0 +1,36 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/GenericFunctionTyparNull.fs", false, + QualifiedNameOfFile GenericFunctionTyparNull, [], [], + [SynModuleOrNamespace + ([GenericFunctionTyparNull], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, + SynValInfo + ([[SynArgInfo ([], false, Some x)]], + SynArgInfo ([], false, None)), None), + LongIdent + (SynLongIdent ([myFunc], [], [None]), None, None, + Pats + [Paren + (Typed + (Named + (SynIdent (x, None), false, None, (1,12--1,13)), + WithGlobalConstraints + (Var (SynTypar (T, None, false), (1,15--1,17)), + [WhereTyparSupportsNull + (SynTypar (T, None, false), (1,23--1,31))], + (1,15--1,31)), (1,12--1,31)), (1,11--1,32))], + None, (1,4--1,32)), None, Const (Int32 42, (1,35--1,37)), + (1,4--1,32), NoneAtLet, { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,33--1,34) })], + (1,0--1,37))], PreXmlDocEmpty, [], None, (1,0--2,0), + { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNull.fs b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNull.fs new file mode 100644 index 00000000000..220b9e370b9 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNull.fs @@ -0,0 +1 @@ +type C<'T when 'T: not null> = class end diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNull.fs.bsl new file mode 100644 index 00000000000..e874ec38674 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNull.fs.bsl @@ -0,0 +1,27 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/GenericTypeNotNull.fs", false, + QualifiedNameOfFile GenericTypeNotNull, [], [], + [SynModuleOrNamespace + ([GenericTypeNotNull], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], + Some + (PostfixList + ([SynTyparDecl + ([], SynTypar (T, None, false), [], + { AmpersandRanges = [] })], + [WhereTyparNotSupportsNull + (SynTypar (T, None, false), (1,15--1,27))], + (1,6--1,28))), [], [C], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + true, None, (1,5--1,6)), + ObjectModel (Class, [], (1,31--1,40)), [], None, (1,5--1,40), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,29--1,30) + WithKeyword = None })], (1,0--1,40))], PreXmlDocEmpty, [], + None, (1,0--2,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNullAndOtherConstraint.fs b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNullAndOtherConstraint.fs new file mode 100644 index 00000000000..71d3333c057 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNullAndOtherConstraint.fs @@ -0,0 +1 @@ +type C<'T when 'T: not null and 'T:equality> = class end diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNullAndOtherConstraint.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNullAndOtherConstraint.fs.bsl new file mode 100644 index 00000000000..7a53c3be066 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNullAndOtherConstraint.fs.bsl @@ -0,0 +1,29 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/GenericTypeNotNullAndOtherConstraint.fs", false, + QualifiedNameOfFile GenericTypeNotNullAndOtherConstraint, [], [], + [SynModuleOrNamespace + ([GenericTypeNotNullAndOtherConstraint], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], + Some + (PostfixList + ([SynTyparDecl + ([], SynTypar (T, None, false), [], + { AmpersandRanges = [] })], + [WhereTyparNotSupportsNull + (SynTypar (T, None, false), (1,15--1,27)); + WhereTyparIsEquatable + (SynTypar (T, None, false), (1,32--1,43))], + (1,6--1,44))), [], [C], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + true, None, (1,5--1,6)), + ObjectModel (Class, [], (1,47--1,56)), [], None, (1,5--1,56), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,45--1,46) + WithKeyword = None })], (1,0--1,56))], PreXmlDocEmpty, [], + None, (1,0--2,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs new file mode 100644 index 00000000000..8b3b5793b92 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs @@ -0,0 +1 @@ +type C<'T when 'T: not struct and 'T:equality> = class end diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs.bsl new file mode 100644 index 00000000000..6ebe197154b --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs.bsl @@ -0,0 +1,34 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs", + false, + QualifiedNameOfFile GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane, + [], [], + [SynModuleOrNamespace + ([GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane], false, + AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], + Some + (PostfixList + ([SynTyparDecl + ([], SynTypar (T, None, false), [], + { AmpersandRanges = [] })], + [WhereTyparIsReferenceType + (SynTypar (T, None, false), (1,15--1,29)); + WhereTyparIsEquatable + (SynTypar (T, None, false), (1,34--1,45))], + (1,6--1,46))), [], [C], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + true, None, (1,5--1,6)), + ObjectModel (Class, [], (1,49--1,58)), [], None, (1,5--1,58), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,47--1,48) + WithKeyword = None })], (1,0--1,58))], PreXmlDocEmpty, [], + None, (1,0--2,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(1,0)-(2,0) parse warning The declarations in this file will be placed in an implicit module 'GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane' based on the file name 'GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.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. diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs b/tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs new file mode 100644 index 00000000000..67b7b23c154 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs @@ -0,0 +1 @@ +type C<'T when 'T: null> = class end diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs.bsl new file mode 100644 index 00000000000..184b29d69d3 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs.bsl @@ -0,0 +1,27 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/GenericTypeNull.fs", false, + QualifiedNameOfFile GenericTypeNull, [], [], + [SynModuleOrNamespace + ([GenericTypeNull], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], + Some + (PostfixList + ([SynTyparDecl + ([], SynTypar (T, None, false), [], + { AmpersandRanges = [] })], + [WhereTyparSupportsNull + (SynTypar (T, None, false), (1,15--1,23))], + (1,6--1,24))), [], [C], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + true, None, (1,5--1,6)), + ObjectModel (Class, [], (1,27--1,36)), [], None, (1,5--1,36), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,25--1,26) + WithKeyword = None })], (1,0--1,36))], PreXmlDocEmpty, [], + None, (1,0--2,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs b/tests/service/data/SyntaxTree/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs new file mode 100644 index 00000000000..634161d9288 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs @@ -0,0 +1 @@ +type C<'T when 'T:equality and 'T: not null> = class end diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs.bsl new file mode 100644 index 00000000000..14ce1cec8b7 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs.bsl @@ -0,0 +1,29 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs", false, + QualifiedNameOfFile GenericTypeOtherConstraintAndThenNotNull, [], [], + [SynModuleOrNamespace + ([GenericTypeOtherConstraintAndThenNotNull], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], + Some + (PostfixList + ([SynTyparDecl + ([], SynTypar (T, None, false), [], + { AmpersandRanges = [] })], + [WhereTyparIsEquatable + (SynTypar (T, None, false), (1,15--1,26)); + WhereTyparNotSupportsNull + (SynTypar (T, None, false), (1,31--1,43))], + (1,6--1,44))), [], [C], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + true, None, (1,5--1,6)), + ObjectModel (Class, [], (1,47--1,56)), [], None, (1,5--1,56), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,45--1,46) + WithKeyword = None })], (1,0--1,56))], PreXmlDocEmpty, [], + None, (1,0--2,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs b/tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs new file mode 100644 index 00000000000..2f3dff3b4c8 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs @@ -0,0 +1 @@ +let x : int list | null = [] diff --git a/tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs.bsl new file mode 100644 index 00000000000..38442d6c68e --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs.bsl @@ -0,0 +1,37 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/IntListOrNull.fs", false, + QualifiedNameOfFile IntListOrNull, [], [], + [SynModuleOrNamespace + ([IntListOrNull], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Named (SynIdent (x, None), false, None, (1,4--1,5)), + Some + (SynBindingReturnInfo + (WithNull + (App + (LongIdent (SynLongIdent ([list], [], [None])), + None, + [LongIdent (SynLongIdent ([int], [], [None]))], [], + None, true, (1,8--1,16)), false, (1,8--1,23)), + (1,8--1,23), [], { ColonRange = Some (1,6--1,7) })), + Typed + (ArrayOrList (false, [], (1,26--1,28)), + WithNull + (App + (LongIdent (SynLongIdent ([list], [], [None])), None, + [LongIdent (SynLongIdent ([int], [], [None]))], [], + None, true, (1,8--1,16)), false, (1,8--1,23)), + (1,26--1,28)), (1,4--1,5), Yes (1,0--1,28), + { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,24--1,25) })], (1,0--1,28))], + PreXmlDocEmpty, [], None, (1,0--2,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs b/tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs new file mode 100644 index 00000000000..f162f811711 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs @@ -0,0 +1 @@ +let x : int list | null | null | null = [] diff --git a/tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs.bsl new file mode 100644 index 00000000000..e538c6dc34b --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs.bsl @@ -0,0 +1,39 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/IntListOrNullOrNullOrNull.fs", false, + QualifiedNameOfFile IntListOrNullOrNullOrNull, [], [], + [SynModuleOrNamespace + ([IntListOrNullOrNullOrNull], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Named (SynIdent (x, None), false, None, (1,4--1,5)), + Some + (SynBindingReturnInfo + (WithNull + (App + (LongIdent (SynLongIdent ([list], [], [None])), + None, + [LongIdent (SynLongIdent ([int], [], [None]))], [], + None, true, (1,8--1,16)), false, (1,8--1,23)), + (1,8--1,23), [], { ColonRange = Some (1,6--1,7) })), + Typed + (ArbitraryAfterError ("localBinding2", (1,23--1,23)), + WithNull + (App + (LongIdent (SynLongIdent ([list], [], [None])), None, + [LongIdent (SynLongIdent ([int], [], [None]))], [], + None, true, (1,8--1,16)), false, (1,8--1,23)), + (1,23--1,23)), (1,4--1,5), Yes (1,0--1,23), + { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = None })], (1,0--1,23))], PreXmlDocEmpty, [], + None, (1,0--2,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(1,24)-(1,25) parse error Unexpected symbol '|' (directly before 'null') in binding. Expected '=' or other token. diff --git a/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCast.fs b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCast.fs new file mode 100644 index 00000000000..9986cca84a6 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCast.fs @@ -0,0 +1,2 @@ +match x with +| :? string | null -> () diff --git a/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCast.fs.bsl b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCast.fs.bsl new file mode 100644 index 00000000000..86094715714 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCast.fs.bsl @@ -0,0 +1,23 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/MatchWithTypeCast.fs", false, + QualifiedNameOfFile MatchWithTypeCast, [], [], + [SynModuleOrNamespace + ([MatchWithTypeCast], false, AnonModule, + [Expr + (Match + (Yes (1,0--1,12), Ident x, + [SynMatchClause + (Or + (IsInst + (LongIdent (SynLongIdent ([string], [], [None])), + (2,2--2,11)), Null (2,14--2,18), (2,2--2,18), + { BarRange = (2,12--2,13) }), None, + Const (Unit, (2,22--2,24)), (2,2--2,24), Yes, + { ArrowRange = Some (2,19--2,21) + BarRange = Some (2,0--2,1) })], (1,0--2,24), + { MatchKeyword = (1,0--1,5) + WithKeyword = (1,8--1,12) }), (1,0--2,24))], PreXmlDocEmpty, + [], None, (1,0--3,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParens.fs b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParens.fs new file mode 100644 index 00000000000..180b3db96df --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParens.fs @@ -0,0 +1,2 @@ +match x with +| :? (string | null) -> () diff --git a/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParens.fs.bsl b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParens.fs.bsl new file mode 100644 index 00000000000..e3a174fcf11 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParens.fs.bsl @@ -0,0 +1,23 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/MatchWithTypeCastParens.fs", false, + QualifiedNameOfFile MatchWithTypeCastParens, [], [], + [SynModuleOrNamespace + ([MatchWithTypeCastParens], false, AnonModule, + [Expr + (Match + (Yes (1,0--1,12), Ident x, + [SynMatchClause + (IsInst + (Paren + (WithNull + (LongIdent (SynLongIdent ([string], [], [None])), + false, (2,6--2,19)), (2,5--2,20)), (2,2--2,20)), + None, Const (Unit, (2,24--2,26)), (2,2--2,26), Yes, + { ArrowRange = Some (2,21--2,23) + BarRange = Some (2,0--2,1) })], (1,0--2,26), + { MatchKeyword = (1,0--1,5) + WithKeyword = (1,8--1,12) }), (1,0--2,26))], PreXmlDocEmpty, + [], None, (1,0--3,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParensAndSeparateNullCase.fs b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParensAndSeparateNullCase.fs new file mode 100644 index 00000000000..c738f9f8fed --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParensAndSeparateNullCase.fs @@ -0,0 +1,2 @@ +match x with +| :? (string | null) | null -> () diff --git a/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParensAndSeparateNullCase.fs.bsl b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParensAndSeparateNullCase.fs.bsl new file mode 100644 index 00000000000..2c62cd5cd41 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParensAndSeparateNullCase.fs.bsl @@ -0,0 +1,26 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/MatchWithTypeCastParensAndSeparateNullCase.fs", false, + QualifiedNameOfFile MatchWithTypeCastParensAndSeparateNullCase, [], [], + [SynModuleOrNamespace + ([MatchWithTypeCastParensAndSeparateNullCase], false, AnonModule, + [Expr + (Match + (Yes (1,0--1,12), Ident x, + [SynMatchClause + (Or + (IsInst + (Paren + (WithNull + (LongIdent (SynLongIdent ([string], [], [None])), + false, (2,6--2,19)), (2,5--2,20)), (2,2--2,20)), + Null (2,23--2,27), (2,2--2,27), + { BarRange = (2,21--2,22) }), None, + Const (Unit, (2,31--2,33)), (2,2--2,33), Yes, + { ArrowRange = Some (2,28--2,30) + BarRange = Some (2,0--2,1) })], (1,0--2,33), + { MatchKeyword = (1,0--1,5) + WithKeyword = (1,8--1,12) }), (1,0--2,33))], PreXmlDocEmpty, + [], None, (1,0--3,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/NullAnnotatedExpression.fs b/tests/service/data/SyntaxTree/Nullness/NullAnnotatedExpression.fs new file mode 100644 index 00000000000..b824f784a61 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/NullAnnotatedExpression.fs @@ -0,0 +1 @@ +let x : Expression | null> | null = null diff --git a/tests/service/data/SyntaxTree/Nullness/NullAnnotatedExpression.fs.bsl b/tests/service/data/SyntaxTree/Nullness/NullAnnotatedExpression.fs.bsl new file mode 100644 index 00000000000..0b9c6e0da1f --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/NullAnnotatedExpression.fs.bsl @@ -0,0 +1,65 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/NullAnnotatedExpression.fs", false, + QualifiedNameOfFile NullAnnotatedExpression, [], [], + [SynModuleOrNamespace + ([NullAnnotatedExpression], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Named (SynIdent (x, None), false, None, (1,4--1,5)), + Some + (SynBindingReturnInfo + (WithNull + (App + (LongIdent + (SynLongIdent ([Expression], [], [None])), + Some (1,18--1,19), + [WithNull + (App + (LongIdent + (SynLongIdent ([Func], [], [None])), + Some (1,23--1,24), + [WithNull + (LongIdent + (SynLongIdent ([string], [], [None])), + false, (1,24--1,37)); + WithNull + (LongIdent + (SynLongIdent ([T], [], [None])), + false, (1,39--1,47))], [(1,37--1,38)], + Some (1,47--1,48), false, (1,19--1,48)), + false, (1,19--1,55))], [], Some (1,55--1,56), + false, (1,8--1,56)), false, (1,8--1,63)), + (1,8--1,63), [], { ColonRange = Some (1,6--1,7) })), + Typed + (Null (1,66--1,70), + WithNull + (App + (LongIdent (SynLongIdent ([Expression], [], [None])), + Some (1,18--1,19), + [WithNull + (App + (LongIdent (SynLongIdent ([Func], [], [None])), + Some (1,23--1,24), + [WithNull + (LongIdent + (SynLongIdent ([string], [], [None])), + false, (1,24--1,37)); + WithNull + (LongIdent (SynLongIdent ([T], [], [None])), + false, (1,39--1,47))], [(1,37--1,38)], + Some (1,47--1,48), false, (1,19--1,48)), false, + (1,19--1,55))], [], Some (1,55--1,56), false, + (1,8--1,56)), false, (1,8--1,63)), (1,66--1,70)), + (1,4--1,5), Yes (1,0--1,70), + { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,64--1,65) })], (1,0--1,70))], + PreXmlDocEmpty, [], None, (1,0--2,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs b/tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs new file mode 100644 index 00000000000..e608c5198c9 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs @@ -0,0 +1,2 @@ +match x with +| "123" -> "": string | null -> "456" \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs.bsl b/tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs.bsl new file mode 100644 index 00000000000..54e114c95ab --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs.bsl @@ -0,0 +1,29 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/RegressionAnnotatedInlinePatternMatch.fs", false, + QualifiedNameOfFile RegressionAnnotatedInlinePatternMatch, [], [], + [SynModuleOrNamespace + ([RegressionAnnotatedInlinePatternMatch], false, AnonModule, + [Expr + (Match + (Yes (1,0--1,12), Ident x, + [SynMatchClause + (Const (String ("123", Regular, (2,2--2,7)), (2,2--2,7)), + None, + Typed + (Const (String ("", Regular, (2,11--2,13)), (2,11--2,13)), + Fun + (WithNull + (LongIdent (SynLongIdent ([string], [], [None])), + false, (2,15--2,28)), + StaticConstant + (String ("456", Regular, (2,32--2,37)), + (2,32--2,37)), (2,15--2,37), + { ArrowRange = (2,29--2,31) }), (2,11--2,37)), + (2,2--2,37), Yes, { ArrowRange = Some (2,8--2,10) + BarRange = Some (2,0--2,1) })], + (1,0--2,37), { MatchKeyword = (1,0--1,5) + WithKeyword = (1,8--1,12) }), (1,0--2,37))], + PreXmlDocEmpty, [], None, (1,0--2,37), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs b/tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs new file mode 100644 index 00000000000..dde76747ac4 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs @@ -0,0 +1,7 @@ +type MyChoice<'T1,'T2> = + + /// Choice 1 of 2 choices + | MyChoice of 'T1 + + /// Choice 2 of 2 choices + | MyChoice of 'T2 diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs.bsl b/tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs.bsl new file mode 100644 index 00000000000..aa2b6752d76 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs.bsl @@ -0,0 +1,55 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/RegressionChoiceType.fs", false, + QualifiedNameOfFile RegressionChoiceType, [], [], + [SynModuleOrNamespace + ([RegressionChoiceType], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], + Some + (PostfixList + ([SynTyparDecl + ([], SynTypar (T1, None, false), [], + { AmpersandRanges = [] }); + SynTyparDecl + ([], SynTypar (T2, None, false), [], + { AmpersandRanges = [] })], [], (1,13--1,22))), + [], [MyChoice], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + true, None, (1,5--1,13)), + Simple + (Union + (None, + [SynUnionCase + ([], SynIdent (MyChoice, None), + Fields + [SynField + ([], false, None, + Var (SynTypar (T1, None, false), (4,16--4,19)), + false, + PreXmlDoc ((4,16), FSharp.Compiler.Xml.XmlDocCollector), + None, (4,16--4,19), { LeadingKeyword = None + MutableKeyword = None })], + PreXmlDoc ((4,2), FSharp.Compiler.Xml.XmlDocCollector), + None, (3,2--4,19), { BarRange = Some (4,2--4,3) }); + SynUnionCase + ([], SynIdent (MyChoice, None), + Fields + [SynField + ([], false, None, + Var (SynTypar (T2, None, false), (7,16--7,19)), + false, + PreXmlDoc ((7,16), FSharp.Compiler.Xml.XmlDocCollector), + None, (7,16--7,19), { LeadingKeyword = None + MutableKeyword = None })], + PreXmlDoc ((7,2), FSharp.Compiler.Xml.XmlDocCollector), + None, (6,2--7,19), { BarRange = Some (7,2--7,3) })], + (3,2--7,19)), (3,2--7,19)), [], None, (1,5--7,19), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,23--1,24) + WithKeyword = None })], (1,0--7,19))], PreXmlDocEmpty, [], + None, (1,0--8,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionListType.fs b/tests/service/data/SyntaxTree/Nullness/RegressionListType.fs new file mode 100644 index 00000000000..fca67d8f23e --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionListType.fs @@ -0,0 +1,3 @@ +type List<'T> = + | ([]) + | ( :: ) of Head: 'T * Tail: 'T list \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionListType.fs.bsl b/tests/service/data/SyntaxTree/Nullness/RegressionListType.fs.bsl new file mode 100644 index 00000000000..5b1a914a438 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionListType.fs.bsl @@ -0,0 +1,65 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/RegressionListType.fs", false, + QualifiedNameOfFile RegressionListType, [], [], + [SynModuleOrNamespace + ([RegressionListType], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], + Some + (PostfixList + ([SynTyparDecl + ([], SynTypar (T, None, false), [], + { AmpersandRanges = [] })], [], (1,9--1,13))), [], + [List], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + true, None, (1,5--1,9)), + Simple + (Union + (None, + [SynUnionCase + ([], + SynIdent + (op_Nil, + Some + (OriginalNotationWithParen + ((2,6--2,7), "[]", (2,8--2,9)))), Fields [], + PreXmlDoc ((2,4), FSharp.Compiler.Xml.XmlDocCollector), + None, (2,6--2,10), { BarRange = Some (2,4--2,5) }); + SynUnionCase + ([], + SynIdent + (op_ColonColon, + Some + (OriginalNotationWithParen + ((3,6--3,7), "::", (3,11--3,12)))), + Fields + [SynField + ([], false, Some Head, + Var (SynTypar (T, None, false), (3,23--3,25)), + false, + PreXmlDoc ((3,17), FSharp.Compiler.Xml.XmlDocCollector), + None, (3,17--3,25), { LeadingKeyword = None + MutableKeyword = None }); + SynField + ([], false, Some Tail, + App + (LongIdent + (SynLongIdent ([list], [], [None])), None, + [Var + (SynTypar (T, None, false), (3,34--3,36))], + [], None, true, (3,34--3,41)), false, + PreXmlDoc ((3,28), FSharp.Compiler.Xml.XmlDocCollector), + None, (3,28--3,41), { LeadingKeyword = None + MutableKeyword = None })], + PreXmlDoc ((3,4), FSharp.Compiler.Xml.XmlDocCollector), + None, (3,6--3,41), { BarRange = Some (3,4--3,5) })], + (2,4--3,41)), (2,4--3,41)), [], None, (1,5--3,41), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,14--1,15) + WithKeyword = None })], (1,0--3,41))], PreXmlDocEmpty, [], + None, (1,0--3,41), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionOneLinerOptionType.fs b/tests/service/data/SyntaxTree/Nullness/RegressionOneLinerOptionType.fs new file mode 100644 index 00000000000..4b54405dff0 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionOneLinerOptionType.fs @@ -0,0 +1 @@ +type MyFlatOption = None | Some of string \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionOneLinerOptionType.fs.bsl b/tests/service/data/SyntaxTree/Nullness/RegressionOneLinerOptionType.fs.bsl new file mode 100644 index 00000000000..7a062070cb7 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionOneLinerOptionType.fs.bsl @@ -0,0 +1,38 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/RegressionOneLinerOptionType.fs", false, + QualifiedNameOfFile RegressionOneLinerOptionType, [], [], + [SynModuleOrNamespace + ([RegressionOneLinerOptionType], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [MyFlatOption], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (1,5--1,17)), + Simple + (Union + (None, + [SynUnionCase + ([], SynIdent (None, None), Fields [], + PreXmlDoc ((1,20), FSharp.Compiler.Xml.XmlDocCollector), + None, (1,20--1,24), { BarRange = None }); + SynUnionCase + ([], SynIdent (Some, None), + Fields + [SynField + ([], false, None, + LongIdent + (SynLongIdent ([string], [], [None])), false, + PreXmlDoc ((1,35), FSharp.Compiler.Xml.XmlDocCollector), + None, (1,35--1,41), { LeadingKeyword = None + MutableKeyword = None })], + PreXmlDoc ((1,25), FSharp.Compiler.Xml.XmlDocCollector), + None, (1,27--1,41), { BarRange = Some (1,25--1,26) })], + (1,20--1,41)), (1,20--1,41)), [], None, (1,5--1,41), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,18--1,19) + WithKeyword = None })], (1,0--1,41))], PreXmlDocEmpty, [], + None, (1,0--1,41), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs b/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs new file mode 100644 index 00000000000..8b1018d513f --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs @@ -0,0 +1,3 @@ +type Option<'T> = + | None: 'T option + | Some: Value:'T -> 'T option \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs.bsl b/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs.bsl new file mode 100644 index 00000000000..5491684ccaa --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs.bsl @@ -0,0 +1,64 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/RegressionOptionType.fs", false, + QualifiedNameOfFile RegressionOptionType, [], [], + [SynModuleOrNamespace + ([RegressionOptionType], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], + Some + (PostfixList + ([SynTyparDecl + ([], SynTypar (T, None, false), [], + { AmpersandRanges = [] })], [], (1,11--1,15))), + [], [Option], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + true, None, (1,5--1,11)), + Simple + (Union + (None, + [SynUnionCase + ([], SynIdent (None, None), + FullType + (App + (LongIdent + (SynLongIdent ([option], [], [None])), None, + [Var (SynTypar (T, None, false), (2,18--2,20))], + [], None, true, (2,18--2,27)), + SynValInfo ([], SynArgInfo ([], false, None))), + PreXmlDoc ((2,4), FSharp.Compiler.Xml.XmlDocCollector), + None, (2,6--2,27), { BarRange = Some (2,4--2,5) }); + SynUnionCase + ([], SynIdent (Some, None), + FullType + (Fun + (SignatureParameter + ([], false, Some Value, + Var + (SynTypar (T, None, false), (3,18--3,20)), + (3,12--3,20)), + App + (LongIdent + (SynLongIdent ([option], [], [None])), + None, + [Var + (SynTypar (T, None, false), (3,24--3,26))], + [], None, true, (3,24--3,33)), (3,12--3,33), + { ArrowRange = (3,21--3,23) }), + SynValInfo + ([[SynArgInfo ([], false, Some Value)]], + SynArgInfo ([], false, None))), + PreXmlDoc ((3,4), FSharp.Compiler.Xml.XmlDocCollector), + None, (3,6--3,33), { BarRange = Some (3,4--3,5) })], + (2,4--3,33)), (2,4--3,33)), [], None, (1,5--3,33), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,16--1,17) + WithKeyword = None })], (1,0--3,33))], PreXmlDocEmpty, [], + None, (1,0--3,34), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(2,6)-(2,27) parse warning This construct is deprecated: it is only for use in the F# library +(3,6)-(3,33) parse warning This construct is deprecated: it is only for use in the F# library diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionOrPattern.fs b/tests/service/data/SyntaxTree/Nullness/RegressionOrPattern.fs new file mode 100644 index 00000000000..d8374a93f90 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionOrPattern.fs @@ -0,0 +1,3 @@ +match exn with +| InternalError (s, _) +| Failure s as exn -> () \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionOrPattern.fs.bsl b/tests/service/data/SyntaxTree/Nullness/RegressionOrPattern.fs.bsl new file mode 100644 index 00000000000..82fe5cb33d5 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionOrPattern.fs.bsl @@ -0,0 +1,40 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/RegressionOrPattern.fs", false, + QualifiedNameOfFile RegressionOrPattern, [], [], + [SynModuleOrNamespace + ([RegressionOrPattern], false, AnonModule, + [Expr + (Match + (Yes (1,0--1,14), Ident exn, + [SynMatchClause + (As + (Or + (LongIdent + (SynLongIdent ([InternalError], [], [None]), None, + None, + Pats + [Paren + (Tuple + (false, + [Named + (SynIdent (s, None), false, None, + (2,17--2,18)); Wild (2,20--2,21)], + [(2,18--2,19)], (2,17--2,21)), + (2,16--2,22))], None, (2,2--2,22)), + LongIdent + (SynLongIdent ([Failure], [], [None]), None, None, + Pats + [Named + (SynIdent (s, None), false, None, + (3,10--3,11))], None, (3,2--3,11)), + (2,2--3,11), { BarRange = (3,0--3,1) }), + Named (SynIdent (exn, None), false, None, (3,15--3,18)), + (2,2--3,18)), None, Const (Unit, (3,22--3,24)), + (2,2--3,24), Yes, { ArrowRange = Some (3,19--3,21) + BarRange = Some (2,0--2,1) })], + (1,0--3,24), { MatchKeyword = (1,0--1,5) + WithKeyword = (1,10--1,14) }), (1,0--3,24))], + PreXmlDocEmpty, [], None, (1,0--3,24), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionResultType.fs b/tests/service/data/SyntaxTree/Nullness/RegressionResultType.fs new file mode 100644 index 00000000000..b2974154002 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionResultType.fs @@ -0,0 +1,7 @@ + type MyResult<'T,'TError> = + + /// Represents an OK or a Successful result. The code succeeded with a value of 'T. + | Ok of ResultValue:'T + + /// Represents an Error or a Failure. The code failed with a value of 'TError representing what went wrong. + | Error of ErrorValue:'TError \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionResultType.fs.bsl b/tests/service/data/SyntaxTree/Nullness/RegressionResultType.fs.bsl new file mode 100644 index 00000000000..c36213899e7 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionResultType.fs.bsl @@ -0,0 +1,56 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/RegressionResultType.fs", false, + QualifiedNameOfFile RegressionResultType, [], [], + [SynModuleOrNamespace + ([RegressionResultType], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], + Some + (PostfixList + ([SynTyparDecl + ([], SynTypar (T, None, false), [], + { AmpersandRanges = [] }); + SynTyparDecl + ([], SynTypar (TError, None, false), [], + { AmpersandRanges = [] })], [], (1,17--1,29))), + [], [MyResult], + PreXmlDoc ((1,4), FSharp.Compiler.Xml.XmlDocCollector), + true, None, (1,9--1,17)), + Simple + (Union + (None, + [SynUnionCase + ([], SynIdent (Ok, None), + Fields + [SynField + ([], false, Some ResultValue, + Var (SynTypar (T, None, false), (4,26--4,28)), + false, + PreXmlDoc ((4,14), FSharp.Compiler.Xml.XmlDocCollector), + None, (4,14--4,28), { LeadingKeyword = None + MutableKeyword = None })], + PreXmlDoc ((4,6), FSharp.Compiler.Xml.XmlDocCollector), + None, (3,6--4,28), { BarRange = Some (4,6--4,7) }); + SynUnionCase + ([], SynIdent (Error, None), + Fields + [SynField + ([], false, Some ErrorValue, + Var + (SynTypar (TError, None, false), + (7,28--7,35)), false, + PreXmlDoc ((7,17), FSharp.Compiler.Xml.XmlDocCollector), + None, (7,17--7,35), { LeadingKeyword = None + MutableKeyword = None })], + PreXmlDoc ((7,6), FSharp.Compiler.Xml.XmlDocCollector), + None, (6,6--7,35), { BarRange = Some (7,6--7,7) })], + (3,6--7,35)), (3,6--7,35)), [], None, (1,9--7,35), + { LeadingKeyword = Type (1,4--1,8) + EqualsRange = Some (1,30--1,31) + WithKeyword = None })], (1,4--7,35))], PreXmlDocEmpty, [], + None, (1,4--7,35), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/SignatureInAbstractMember.fs b/tests/service/data/SyntaxTree/Nullness/SignatureInAbstractMember.fs new file mode 100644 index 00000000000..9839c9cd370 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/SignatureInAbstractMember.fs @@ -0,0 +1,2 @@ +type MyClassBase1() = + abstract member function1 : string | null -> string | null diff --git a/tests/service/data/SyntaxTree/Nullness/SignatureInAbstractMember.fs.bsl b/tests/service/data/SyntaxTree/Nullness/SignatureInAbstractMember.fs.bsl new file mode 100644 index 00000000000..f6aca925483 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/SignatureInAbstractMember.fs.bsl @@ -0,0 +1,60 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/SignatureInAbstractMember.fs", false, + QualifiedNameOfFile SignatureInAbstractMember, [], [], + [SynModuleOrNamespace + ([SignatureInAbstractMember], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [MyClassBase1], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (1,5--1,17)), + ObjectModel + (Unspecified, + [ImplicitCtor + (None, [], Const (Unit, (1,17--1,19)), None, + PreXmlDoc ((1,17), FSharp.Compiler.Xml.XmlDocCollector), + (1,5--1,17), { AsKeyword = None }); + AbstractSlot + (SynValSig + ([], SynIdent (function1, None), + SynValTyparDecls (None, true), + Fun + (WithNull + (LongIdent + (SynLongIdent ([string], [], [None])), false, + (2,31--2,44)), + WithNull + (LongIdent + (SynLongIdent ([string], [], [None])), false, + (2,48--2,61)), (2,31--2,61), + { ArrowRange = (2,45--2,47) }), + SynValInfo + ([[SynArgInfo ([], false, None)]], + SynArgInfo ([], false, None)), false, false, + PreXmlDoc ((2,3), FSharp.Compiler.Xml.XmlDocCollector), + None, None, (2,3--2,61), + { LeadingKeyword = + AbstractMember ((2,3--2,11), (2,12--2,18)) + InlineKeyword = None + WithKeyword = None + EqualsRange = None }), + { IsInstance = true + IsDispatchSlot = true + IsOverrideOrExplicitImpl = false + IsFinal = false + GetterOrSetterIsCompilerGenerated = false + MemberKind = Member }, (2,3--2,61), + { GetSetKeywords = None })], (2,3--2,61)), [], + Some + (ImplicitCtor + (None, [], Const (Unit, (1,17--1,19)), None, + PreXmlDoc ((1,17), FSharp.Compiler.Xml.XmlDocCollector), + (1,5--1,17), { AsKeyword = None })), (1,5--2,61), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,20--1,21) + WithKeyword = None })], (1,0--2,61))], PreXmlDocEmpty, [], + None, (1,0--3,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/StringOrNull.fs b/tests/service/data/SyntaxTree/Nullness/StringOrNull.fs new file mode 100644 index 00000000000..f27f3c86f09 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/StringOrNull.fs @@ -0,0 +1 @@ +let x : string | null = null diff --git a/tests/service/data/SyntaxTree/Nullness/StringOrNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/StringOrNull.fs.bsl new file mode 100644 index 00000000000..e803aeedb1f --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/StringOrNull.fs.bsl @@ -0,0 +1,31 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/StringOrNull.fs", false, QualifiedNameOfFile StringOrNull, + [], [], + [SynModuleOrNamespace + ([StringOrNull], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Named (SynIdent (x, None), false, None, (1,4--1,5)), + Some + (SynBindingReturnInfo + (WithNull + (LongIdent (SynLongIdent ([string], [], [None])), + false, (1,8--1,21)), (1,8--1,21), [], + { ColonRange = Some (1,6--1,7) })), + Typed + (Null (1,24--1,28), + WithNull + (LongIdent (SynLongIdent ([string], [], [None])), false, + (1,8--1,21)), (1,24--1,28)), (1,4--1,5), Yes (1,0--1,28), + { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,22--1,23) })], (1,0--1,28))], + PreXmlDocEmpty, [], None, (1,0--2,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs b/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs new file mode 100644 index 00000000000..37569d4900a --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs @@ -0,0 +1 @@ +let myFunc (x: (string | null)) = 42 diff --git a/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs.bsl b/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs.bsl new file mode 100644 index 00000000000..f369e771916 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs.bsl @@ -0,0 +1,36 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/StringOrNullInFunctionArg.fs", false, + QualifiedNameOfFile StringOrNullInFunctionArg, [], [], + [SynModuleOrNamespace + ([StringOrNullInFunctionArg], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, + SynValInfo + ([[SynArgInfo ([], false, Some x)]], + SynArgInfo ([], false, None)), None), + LongIdent + (SynLongIdent ([myFunc], [], [None]), None, None, + Pats + [Paren + (Typed + (Named + (SynIdent (x, None), false, None, (1,12--1,13)), + Paren + (WithNull + (LongIdent + (SynLongIdent ([string], [], [None])), + false, (1,16--1,29)), (1,15--1,30)), + (1,12--1,30)), (1,11--1,31))], None, (1,4--1,31)), + None, Const (Int32 42, (1,34--1,36)), (1,4--1,31), NoneAtLet, + { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,32--1,33) })], (1,0--1,36))], + PreXmlDocEmpty, [], None, (1,0--2,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/TypeAbbreviationAddingWithNull.fs b/tests/service/data/SyntaxTree/Nullness/TypeAbbreviationAddingWithNull.fs new file mode 100644 index 00000000000..194814afffa --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/TypeAbbreviationAddingWithNull.fs @@ -0,0 +1 @@ +type MyFlatOption = string | null \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/Nullness/TypeAbbreviationAddingWithNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/TypeAbbreviationAddingWithNull.fs.bsl new file mode 100644 index 00000000000..1a874cb67b7 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/TypeAbbreviationAddingWithNull.fs.bsl @@ -0,0 +1,24 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/TypeAbbreviationAddingWithNull.fs", false, + QualifiedNameOfFile TypeAbbreviationAddingWithNull, [], [], + [SynModuleOrNamespace + ([TypeAbbreviationAddingWithNull], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [MyFlatOption], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (1,5--1,17)), + Simple + (TypeAbbrev + (Ok, + WithNull + (LongIdent (SynLongIdent ([string], [], [None])), + false, (1,20--1,33)), (1,20--1,33)), (1,20--1,33)), + [], None, (1,5--1,33), { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,18--1,19) + WithKeyword = None })], (1,0--1,33))], + PreXmlDocEmpty, [], None, (1,0--1,33), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/TestTP/ProvidedTypes.fs b/tests/service/data/TestTP/ProvidedTypes.fs index 9cd4c0dc0a2..606ba52b3e2 100644 --- a/tests/service/data/TestTP/ProvidedTypes.fs +++ b/tests/service/data/TestTP/ProvidedTypes.fs @@ -3220,7 +3220,6 @@ module internal AssemblyReader = systemRuntimeScopeRef: ILScopeRef } override __.ToString() = "" - [] [] type ILTableName(idx: int) = member __.Index = idx diff --git a/vsintegration/src/FSharp.VS.FSI/fsiBasis.fs b/vsintegration/src/FSharp.VS.FSI/fsiBasis.fs index 8e4d3974761..771b9c0c979 100644 --- a/vsintegration/src/FSharp.VS.FSI/fsiBasis.fs +++ b/vsintegration/src/FSharp.VS.FSI/fsiBasis.fs @@ -38,11 +38,12 @@ module internal Guids = let guidFSharpProjectPkgString = "91A04A73-4F2C-4E7C-AD38-C1A68E7DA05C" // FSI-LINKAGE-POINT: when packaged in project system [] - /// "35A5E6B8-4012-41fc-A652-2CDC56D74E9F" + + // "35A5E6B8-4012-41fc-A652-2CDC56D74E9F" let guidFsiLanguageService = "35A5E6B8-4012-41fc-A652-2CDC56D74E9F" // The FSI lang service [] - /// "dee22b65-9761-4a26-8fb2-759b971d6dfc" + // "dee22b65-9761-4a26-8fb2-759b971d6dfc" let guidFsiSessionToolWindow = "dee22b65-9761-4a26-8fb2-759b971d6dfc" // FSI Package command set diff --git a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.QuickInfo.fs b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.QuickInfo.fs index 931b9b3e5e0..9ffb01650be 100644 --- a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.QuickInfo.fs +++ b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.QuickInfo.fs @@ -262,7 +262,7 @@ type UsingMSBuild() = """ let expectedTooltip = """ type Async = - static member AsBeginEnd: computation: ('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit) + static member AsBeginEnd: computation: ('Arg -> Async<'T>) -> ('Arg * AsyncCallback * objnull -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit) static member AwaitEvent: event: IEvent<'Del,'T> * ?cancelAction: (unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate) static member AwaitIAsyncResult: iar: IAsyncResult * ?millisecondsTimeout: int -> Async static member AwaitTask: task: Task<'T> -> Async<'T> + 1 overload @@ -270,7 +270,7 @@ type Async = static member CancelDefaultToken: unit -> unit static member Catch: computation: Async<'T> -> Async> static member Choice: computations: Async<'T option> seq -> Async<'T option> - static member FromBeginEnd: beginAction: (AsyncCallback * obj -> IAsyncResult) * endAction: (IAsyncResult -> 'T) * ?cancelAction: (unit -> unit) -> Async<'T> + 3 overloads + static member FromBeginEnd: beginAction: (AsyncCallback * objnull -> IAsyncResult) * endAction: (IAsyncResult -> 'T) * ?cancelAction: (unit -> unit) -> Async<'T> + 3 overloads static member FromContinuations: callback: (('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T> ... Full name: Microsoft.FSharp.Control.Async""".TrimStart().Replace("\r\n", "\n")