From d4b4e3b2bb478428a8b0a155d67788d03807e818 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Mon, 20 Feb 2023 22:31:42 +0100 Subject: [PATCH 1/3] Name resolution: report interface, record, and union types --- src/Compiler/Checking/CheckExpressions.fs | 36 +++++++++++++++-------- src/Compiler/Checking/NameResolution.fs | 11 +++++-- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 806b516dccd..1b43a25e602 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -4877,6 +4877,16 @@ and TcTypeApp (cenv: cenv) newOk checkConstraints occ env tpenv m tcref pathType // Try to decode System.Tuple --> F# tuple types etc. let ty = g.decompileType tcref actualArgTys + let getInst (ty: TType) = + match stripTyparEqns ty with + | TType_app (tcref, typeArgs, _) -> + List.zip tcref.Deref.TyparsNoRange typeArgs + | _ -> [] + + let item = Item.Types(tcref.DisplayNameCore, [ty]) + let inst = getInst ty + CallNameResolutionSink cenv.tcSink (m, env.NameEnv, item, inst, occ, env.eAccessRights) + ty, tpenv and TcTypeOrMeasureAndRecover kindOpt (cenv: cenv) newOk checkConstraints occ iwsam env tpenv ty = @@ -8186,8 +8196,9 @@ and TcItemThen (cenv: cenv) (overallTy: OverallTy) env tpenv (tinstEnclosing, it | Item.CtorGroup(nm, minfos) -> TcCtorItemThen cenv overallTy env item nm minfos tinstEnclosing tpenv mItem afterResolution delayed - | Item.FakeInterfaceCtor _ -> - error(Error(FSComp.SR.tcInvalidUseOfInterfaceType(), mItem)) + | Item.FakeInterfaceCtor ty -> + let nm = NicePrint.minimalStringOfType env.DisplayEnv ty + TcTypeItemThen cenv overallTy env nm ty tpenv mItem tinstEnclosing delayed | Item.ImplicitOp(id, sln) -> TcImplicitOpItemThen cenv overallTy env id sln tpenv mItem delayed @@ -8387,16 +8398,19 @@ and TcUnionCaseOrExnCaseOrActivePatternResultItemThen (cenv: cenv) overallTy env and TcTypeItemThen (cenv: cenv) overallTy env nm ty tpenv mItem tinstEnclosing delayed = let g = cenv.g let ad = env.eAccessRights + + let reportWrongType ty m _mWithArgs = + if isInterfaceTy g ty then + error(Error(FSComp.SR.tcInvalidUseOfInterfaceType(), m)) + else + error(Error(FSComp.SR.tcInvalidUseOfTypeName(), m)) + match delayed with | DelayedTypeApp(tyargs, _mTypeArgs, mExprAndTypeArgs) :: DelayedDotLookup (longId, mLongId) :: otherDelayed -> // If Item.Types is returned then the ty will be of the form TType_app(tcref, genericTyargs) where tyargs // is a fresh instantiation for tcref. TcNestedTypeApplication will chop off precisely #genericTyargs args // and replace them by 'tyargs' let ty, tpenv = TcNestedTypeApplication cenv NewTyparsOK CheckCxs ItemOccurence.UseInType WarnOnIWSAM.Yes env tpenv mExprAndTypeArgs ty tinstEnclosing tyargs - - // Report information about the whole expression including type arguments to VS - let item = Item.Types(nm, [ty]) - CallNameResolutionSink cenv.tcSink (mExprAndTypeArgs, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) let typeNameResInfo = GetLongIdentTypeNameInfo otherDelayed let item, mItem, rest, afterResolution = ResolveExprDotLongIdentAndComputeRange cenv.tcSink cenv.nameResolver (unionRanges mExprAndTypeArgs mLongId) ad env.eNameResEnv ty longId typeNameResInfo IgnoreOverrides true TcItemThen cenv overallTy env tpenv ((argsOfAppTy g ty), item, mItem, rest, afterResolution) None otherDelayed @@ -8404,17 +8418,15 @@ and TcTypeItemThen (cenv: cenv) overallTy env nm ty tpenv mItem tinstEnclosing d | DelayedTypeApp(tyargs, _mTypeArgs, mExprAndTypeArgs) :: _delayed' -> // A case where we have an incomplete name e.g. 'Foo.' - we still want to report it to VS! let ty, _ = TcNestedTypeApplication cenv NewTyparsOK CheckCxs ItemOccurence.UseInType WarnOnIWSAM.Yes env tpenv mExprAndTypeArgs ty tinstEnclosing tyargs - let item = Item.Types(nm, [ty]) - CallNameResolutionSink cenv.tcSink (mExprAndTypeArgs, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) - - // Same error as in the following case - error(Error(FSComp.SR.tcInvalidUseOfTypeName(), mItem)) + reportWrongType ty mItem mExprAndTypeArgs | _ -> // In this case the type is not generic, and indeed we should never have returned Item.Types. // That's because ResolveTypeNamesToCtors should have been set at the original // call to ResolveLongIdentAsExprAndComputeRange - error(Error(FSComp.SR.tcInvalidUseOfTypeName(), mItem)) + let item = Item.Types(nm, [ty]) + CallNameResolutionSink cenv.tcSink (mItem, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) + reportWrongType ty mItem mItem and TcMethodItemThen (cenv: cenv) overallTy env item methodName minfos tpenv mItem afterResolution staticTyOpt delayed = let ad = env.eAccessRights diff --git a/src/Compiler/Checking/NameResolution.fs b/src/Compiler/Checking/NameResolution.fs index 414d102b691..950bb96c819 100644 --- a/src/Compiler/Checking/NameResolution.fs +++ b/src/Compiler/Checking/NameResolution.fs @@ -2483,7 +2483,11 @@ let private ResolveObjectConstructorPrim (ncenv: NameResolver) edenv resInfo m a [DefaultStructCtor(g, ty)] else [] if (isNil defaultStructCtorInfo && isNil ctorInfos) || (not (isAppTy g ty) && not (isAnyTupleTy g ty)) then - raze (Error(FSComp.SR.nrNoConstructorsAvailableForType(NicePrint.minimalStringOfType edenv ty), m)) + let nm = NicePrint.minimalStringOfType edenv ty + if not (isRecdTy g ty || isUnionTy g ty) then + errorR (Error(FSComp.SR.nrNoConstructorsAvailableForType(nm), m)) + + success (resInfo, Item.Types(nm, [ty])) else let ctorInfos = ctorInfos |> List.filter (IsMethInfoAccessible amap m ad) let metadataTy = convertToTypeWithMetadataIfPossible g ty @@ -3496,8 +3500,9 @@ let ResolveTypeLongIdentAux sink (ncenv: NameResolver) occurence fullyQualified match res with | Result (resInfo, tcref) -> ResolutionInfo.SendEntityPathToSink(sink, ncenv, nenv, ItemOccurence.UseInType, ad, resInfo, ResultTyparChecker(fun () -> true)) - let item = Item.Types(tcref.DisplayName, [FreshenTycon ncenv m tcref]) - CallNameResolutionSink sink (m, nenv, item, emptyTyparInst, occurence, ad) + if occurence = ItemOccurence.Binding then + let item = Item.Types(tcref.DisplayName, [FreshenTycon ncenv m tcref]) + CallNameResolutionSink sink (m, nenv, item, emptyTyparInst, occurence, ad) | _ -> () res From 029723f950ec7e911e73dd00067cdbf6029e8e56 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Mon, 20 Feb 2023 22:59:37 +0100 Subject: [PATCH 2/3] Don't raise no constructor exception --- src/Compiler/Checking/NameResolution.fs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Compiler/Checking/NameResolution.fs b/src/Compiler/Checking/NameResolution.fs index 950bb96c819..75dcfc57602 100644 --- a/src/Compiler/Checking/NameResolution.fs +++ b/src/Compiler/Checking/NameResolution.fs @@ -2484,10 +2484,10 @@ let private ResolveObjectConstructorPrim (ncenv: NameResolver) edenv resInfo m a else [] if (isNil defaultStructCtorInfo && isNil ctorInfos) || (not (isAppTy g ty) && not (isAnyTupleTy g ty)) then let nm = NicePrint.minimalStringOfType edenv ty - if not (isRecdTy g ty || isUnionTy g ty) then - errorR (Error(FSComp.SR.nrNoConstructorsAvailableForType(nm), m)) - - success (resInfo, Item.Types(nm, [ty])) + if isRecdTy g ty || isUnionTy g ty then + success (resInfo, Item.Types(nm, [ty])) + else + raze (Error(FSComp.SR.nrNoConstructorsAvailableForType(nm), m)) else let ctorInfos = ctorInfos |> List.filter (IsMethInfoAccessible amap m ad) let metadataTy = convertToTypeWithMetadataIfPossible g ty From 819f33dd988f0f1fdeab805b449df43dd8f0535b Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Tue, 21 Feb 2023 09:05:09 +0100 Subject: [PATCH 3/3] Remove error/union recovery --- src/Compiler/Checking/NameResolution.fs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Compiler/Checking/NameResolution.fs b/src/Compiler/Checking/NameResolution.fs index 75dcfc57602..1536dd9d9e9 100644 --- a/src/Compiler/Checking/NameResolution.fs +++ b/src/Compiler/Checking/NameResolution.fs @@ -2483,11 +2483,7 @@ let private ResolveObjectConstructorPrim (ncenv: NameResolver) edenv resInfo m a [DefaultStructCtor(g, ty)] else [] if (isNil defaultStructCtorInfo && isNil ctorInfos) || (not (isAppTy g ty) && not (isAnyTupleTy g ty)) then - let nm = NicePrint.minimalStringOfType edenv ty - if isRecdTy g ty || isUnionTy g ty then - success (resInfo, Item.Types(nm, [ty])) - else - raze (Error(FSComp.SR.nrNoConstructorsAvailableForType(nm), m)) + raze (Error(FSComp.SR.nrNoConstructorsAvailableForType(NicePrint.minimalStringOfType edenv ty), m)) else let ctorInfos = ctorInfos |> List.filter (IsMethInfoAccessible amap m ad) let metadataTy = convertToTypeWithMetadataIfPossible g ty