diff --git a/src/Compiler/Checking/CheckComputationExpressions.fs b/src/Compiler/Checking/CheckComputationExpressions.fs index f9887d625f3..26b10550394 100644 --- a/src/Compiler/Checking/CheckComputationExpressions.fs +++ b/src/Compiler/Checking/CheckComputationExpressions.fs @@ -58,7 +58,7 @@ let (|JoinRelation|_|) cenv env (expr: SynExpr) = let isOpName opName vref s = (s = opName) && - match ResolveExprLongIdent cenv.tcSink cenv.nameResolver m ad env.eNameResEnv TypeNameResolutionInfo.Default [ident(opName, m)] with + match ResolveExprLongIdent cenv.tcSink cenv.nameResolver m ad env.eNameResEnv TypeNameResolutionInfo.Default [ident(opName, m)] None with | Result (_, Item.Value vref2, []) -> valRefEq cenv.g vref vref2 | _ -> false diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 54fd5a756a4..e621eb98f4e 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -2387,7 +2387,7 @@ module TcExceptionDeclarations = match reprIdOpt with | Some longId -> let resolution = - ResolveExprLongIdent cenv.tcSink cenv.nameResolver m ad env.NameEnv TypeNameResolutionInfo.Default longId + ResolveExprLongIdent cenv.tcSink cenv.nameResolver m ad env.NameEnv TypeNameResolutionInfo.Default longId None |> ForceRaise match resolution with | _, Item.ExnCase exnc, [] -> diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index b268e80bf0b..3beb48b00f5 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -3811,6 +3811,13 @@ type DelayedItem = /// Represents the valueExpr in "item <- valueExpr", also "item.[indexerArgs] <- valueExpr" etc. | DelayedSet of SynExpr * range +module DelayedItem = + let maybeAppliedArgForPreferExtensionOverProperty delayed = + match delayed with + | [] -> None + | DelayedItem.DelayedApp(argExpr=argExpr) :: _ -> Some argExpr + | _ -> None + let MakeDelayedSet(e: SynExpr, m) = // We have longId <- e. Wrap 'e' in another pair of parentheses to ensure it's never interpreted as // a named argument, e.g. for "el.Checked <- (el = el2)" @@ -8119,7 +8126,7 @@ and TcNameOfExpr (cenv: cenv) env tpenv (synArg: SynExpr) = // However we don't commit for a type names - nameof allows 'naked' type names and thus all type name // resolutions are checked separately in the next step. let typeNameResInfo = GetLongIdentTypeNameInfo delayed - let nameResolutionResult = ResolveLongIdentAsExprAndComputeRange cenv.tcSink cenv.nameResolver (rangeOfLid longId) ad env.eNameResEnv typeNameResInfo longId + let nameResolutionResult = ResolveLongIdentAsExprAndComputeRange cenv.tcSink cenv.nameResolver (rangeOfLid longId) ad env.eNameResEnv typeNameResInfo longId None let resolvesAsExpr = match nameResolutionResult with | Result (_, item, _, _, _ as res) @@ -8330,7 +8337,8 @@ and TcLongIdentThen (cenv: cenv) (overallTy: OverallTy) env tpenv (SynLongIdent( let ad = env.eAccessRights let typeNameResInfo = GetLongIdentTypeNameInfo delayed let nameResolutionResult = - ResolveLongIdentAsExprAndComputeRange cenv.tcSink cenv.nameResolver (rangeOfLid longId) ad env.eNameResEnv typeNameResInfo longId + let maybeAppliedArgExpr = DelayedItem.maybeAppliedArgForPreferExtensionOverProperty delayed + ResolveLongIdentAsExprAndComputeRange cenv.tcSink cenv.nameResolver (rangeOfLid longId) ad env.eNameResEnv typeNameResInfo longId maybeAppliedArgExpr |> ForceRaise TcItemThen cenv overallTy env tpenv nameResolutionResult None delayed @@ -8582,7 +8590,7 @@ and TcTypeItemThen (cenv: cenv) overallTy env nm ty tpenv mItem tinstEnclosing d 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 + let item, mItem, rest, afterResolution = ResolveExprDotLongIdentAndComputeRange cenv.tcSink cenv.nameResolver (unionRanges mExprAndTypeArgs mLongId) ad env.eNameResEnv ty longId typeNameResInfo IgnoreOverrides true None TcItemThen cenv overallTy env tpenv ((argsOfAppTy g ty), item, mItem, rest, afterResolution) None otherDelayed | DelayedTypeApp(tyargs, _mTypeArgs, mExprAndTypeArgs) :: _delayed' -> @@ -9146,8 +9154,9 @@ and TcLookupThen cenv overallTy env tpenv mObjExpr objExpr objExprTy longId dela // Canonicalize inference problem prior to '.' lookup on variable types if isTyparTy g objExprTy then CanonicalizePartialInferenceProblem cenv.css env.DisplayEnv mExprAndLongId (freeInTypeLeftToRight g false objExprTy) - - let item, mItem, rest, afterResolution = ResolveExprDotLongIdentAndComputeRange cenv.tcSink cenv.nameResolver mExprAndLongId ad env.NameEnv objExprTy longId TypeNameResolutionInfo.Default findFlag false + + let maybeAppliedArgExpr = DelayedItem.maybeAppliedArgForPreferExtensionOverProperty delayed + let item, mItem, rest, afterResolution = ResolveExprDotLongIdentAndComputeRange cenv.tcSink cenv.nameResolver mExprAndLongId ad env.NameEnv objExprTy longId TypeNameResolutionInfo.Default findFlag false maybeAppliedArgExpr TcLookupItemThen cenv overallTy env tpenv mObjExpr objExpr objExprTy delayed item mItem rest afterResolution and TcLookupItemThen cenv overallTy env tpenv mObjExpr objExpr objExprTy delayed item mItem rest afterResolution = diff --git a/src/Compiler/Checking/CheckPatterns.fs b/src/Compiler/Checking/CheckPatterns.fs index 5aba16020fa..b009ef02825 100644 --- a/src/Compiler/Checking/CheckPatterns.fs +++ b/src/Compiler/Checking/CheckPatterns.fs @@ -486,7 +486,7 @@ and IsNameOf (cenv: cenv) (env: TcEnv) ad m (id: Ident) = let g = cenv.g id.idText = "nameof" && try - match ResolveExprLongIdent cenv.tcSink cenv.nameResolver m ad env.NameEnv TypeNameResolutionInfo.Default [id] with + match ResolveExprLongIdent cenv.tcSink cenv.nameResolver m ad env.NameEnv TypeNameResolutionInfo.Default [id] None with | Result (_, Item.Value vref, _) -> valRefEq g vref g.nameof_vref | _ -> false with _ -> false diff --git a/src/Compiler/Checking/NameResolution.fs b/src/Compiler/Checking/NameResolution.fs index eb753da44f8..c5e50a97a30 100644 --- a/src/Compiler/Checking/NameResolution.fs +++ b/src/Compiler/Checking/NameResolution.fs @@ -2581,7 +2581,10 @@ let CheckNestedTypesOfType (ncenv: NameResolver) (resInfo: ResolutionInfo) ad nm // REVIEW: this shows up on performance logs. Consider for example endless resolutions of "List.map" to // the empty set of results, or "x.Length" for a list or array type. This indicates it could be worth adding a cache here. -let rec ResolveLongIdentInTypePrim (ncenv: NameResolver) nenv lookupKind (resInfo: ResolutionInfo) depth m ad (id: Ident) (rest: Ident list) findFlag (typeNameResInfo: TypeNameResolutionInfo) ty = + +// maybeAppliedArgExpr is used in context of resolving extension method that would override property name, it may contain argExpr coming from the DelayedApp(argExpr: SynExpr) +// see RFC-1137 +let rec ResolveLongIdentInTypePrim (ncenv: NameResolver) nenv lookupKind (resInfo: ResolutionInfo) depth m ad (id: Ident) (rest: Ident list) findFlag (typeNameResInfo: TypeNameResolutionInfo) ty (maybeAppliedArgExpr: SynExpr option) = let g = ncenv.g let m = unionRanges m id.idRange let nm = id.idText // used to filter the searches of the tables @@ -2625,8 +2628,56 @@ let rec ResolveLongIdentInTypePrim (ncenv: NameResolver) nenv lookupKind (resInf // make sure to keep the intrinsic pinfos before the extension pinfos in the list, // since later on this logic is used when giving preference to intrinsic definitions match DecodeFSharpEvent (pinfos@extensionPropInfos) ad g ncenv m with - | Some x -> success [resInfo, x, rest] - | None -> raze (UndefinedName (depth, FSComp.SR.undefinedNameFieldConstructorOrMember, id, NoSuggestions)) + | Some x -> + if + not (g.langVersion.SupportsFeature LanguageFeature.PreferExtensionMethodOverPlainProperty) + || not (List.isEmpty rest) // if not empty, it is .X.Y... + then + success [resInfo, x, rest] + else + match maybeAppliedArgExpr with + | None -> success [resInfo, x, rest] + | Some _argExpr -> + // RFC-1137 prefer extension method when ... + + let ignoreProperty (p: PropInfo) = + // do not hide properties if: + // * is indexed property e.g.: + // ```fsharp + // member x.Prop with + // get (indexPiece1:int,indexPiece2: string) = ... + // and set (indexPiece1:int,indexPiece2: string) value = ... + // ``` + // which is called like this: obj.Prop(1,"a") or obj.Prop(1,"a") <- someValue + // * is function type e.g.: + // ```fsharp + // member x.Prop with + // get () = fun a -> printfn $"{a}" + // ``` + // which is called like this: obj.Prop 123 + if p.IsIndexer then + true + else + match p.GetPropertyType(ncenv.amap, m) with + | TType_var(typar={typar_solution = Some (TType_fun _) }) -> + true + | _ -> false + + match x with + | Item.Property(info=ps) when ps |> List.exists ignoreProperty -> + success [resInfo, x, rest] + | _ -> + // lookup in-scope extension methods + // to keep in sync with the same expression in `| Some(MethodItem msets) when isLookupExpr` below + match ExtensionMethInfosOfTypeInScope ResultCollectionSettings.AllResults ncenv.InfoReader nenv optFilter isInstanceFilter m ty with + | [] -> success [resInfo, x, rest] + | methods -> + let extensionMethods = Item.MakeMethGroup(nm, methods) + success ((resInfo,extensionMethods,rest)::[resInfo,x,rest]) + | None -> + // todo: consider if we should check extension method, but we'd probably won't have matched + // `Some(PropertyItem psets) when isLookUpExpr` in the first place. + raze (UndefinedName (depth, FSComp.SR.undefinedNameFieldConstructorOrMember, id, NoSuggestions)) | Some(MethodItem msets) when isLookUpExpr -> let minfos = msets |> ExcludeHiddenOfMethInfos g ncenv.amap m @@ -2759,20 +2810,20 @@ and ResolveLongIdentInNestedTypes (ncenv: NameResolver) nenv lookupKind resInfo resInfo.AddEntity(id.idRange, tcref) | _ -> resInfo - ResolveLongIdentInTypePrim ncenv nenv lookupKind resInfo depth m ad id2 rest findFlag typeNameResInfo ty + ResolveLongIdentInTypePrim ncenv nenv lookupKind resInfo depth m ad id2 rest findFlag typeNameResInfo ty None |> AtMostOneResult m) /// Resolve a long identifier using type-qualified name resolution. let ResolveLongIdentInType sink (ncenv: NameResolver) nenv lookupKind m ad id findFlag typeNameResInfo ty = let resInfo, item, rest = - ResolveLongIdentInTypePrim ncenv nenv lookupKind ResolutionInfo.Empty 0 m ad id [] findFlag typeNameResInfo ty + ResolveLongIdentInTypePrim ncenv nenv lookupKind ResolutionInfo.Empty 0 m ad id [] findFlag typeNameResInfo ty None |> AtMostOneResult m |> ForceRaise ResolutionInfo.SendEntityPathToSink (sink, ncenv, nenv, ItemOccurence.UseInType, ad, resInfo, ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap m item)) item, rest -let private ResolveLongIdentInTyconRef (ncenv: NameResolver) nenv lookupKind (resInfo: ResolutionInfo) depth m ad id rest typeNameResInfo tcref = +let private ResolveLongIdentInTyconRef (ncenv: NameResolver) nenv lookupKind (resInfo: ResolutionInfo) depth m ad id rest typeNameResInfo tcref maybeAppliedArgExpr = #if !NO_TYPEPROVIDERS // No dotting through type generators to get to a member! CheckForDirectReferenceToGeneratedType (tcref, PermitDirectReferenceToGeneratedType.No, m) @@ -2781,12 +2832,12 @@ let private ResolveLongIdentInTyconRef (ncenv: NameResolver) nenv lookupKind (re match resInfo.EnclosingTypeInst with | [] -> FreshenTycon ncenv m tcref | tinstEnclosing -> FreshenTyconWithEnclosingTypeInst ncenv m tinstEnclosing tcref - ty |> ResolveLongIdentInTypePrim ncenv nenv lookupKind resInfo depth m ad id rest IgnoreOverrides typeNameResInfo + ResolveLongIdentInTypePrim ncenv nenv lookupKind resInfo depth m ad id rest IgnoreOverrides typeNameResInfo ty maybeAppliedArgExpr -let private ResolveLongIdentInTyconRefs atMostOne (ncenv: NameResolver) nenv lookupKind depth m ad id rest typeNameResInfo idRange tcrefs = +let private ResolveLongIdentInTyconRefs atMostOne (ncenv: NameResolver) nenv lookupKind depth m ad id rest typeNameResInfo idRange tcrefs maybeAppliedArgExpr = tcrefs |> CollectResults2 atMostOne (fun (resInfo: ResolutionInfo, tcref) -> let resInfo = resInfo.AddEntity(idRange, tcref) - tcref |> ResolveLongIdentInTyconRef ncenv nenv lookupKind resInfo depth m ad id rest typeNameResInfo |> AtMostOneResult m) + ResolveLongIdentInTyconRef ncenv nenv lookupKind resInfo depth m ad id rest typeNameResInfo tcref maybeAppliedArgExpr |> AtMostOneResult m) //------------------------------------------------------------------------- // ResolveExprLongIdentInModuleOrNamespace @@ -2835,7 +2886,7 @@ let rec ResolveExprLongIdentInModuleOrNamespace (ncenv: NameResolver) nenv (type let typeNameResInfo = TypeNameResolutionInfo.ResolveToTypeRefs typeNameResInfo.StaticArgsInfo CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities (tcrefs, typeNameResInfo, PermitDirectReferenceToGeneratedType.No, unionRanges m id.idRange) - ResolveLongIdentInTyconRefs ResultCollectionSettings.AtMostOneResult ncenv nenv lookupKind (depth+1) m ad id2 rest2 typeNameResInfo id.idRange tcrefs + ResolveLongIdentInTyconRefs ResultCollectionSettings.AtMostOneResult ncenv nenv lookupKind (depth+1) m ad id2 rest2 typeNameResInfo id.idRange tcrefs None // Check if we've got some explicit type arguments | _ -> @@ -2933,7 +2984,7 @@ let ResolveUnqualifiedTyconRefs nenv tcrefs = /// Resolve F# "A.B.C" syntax in expressions /// Not all of the sequence will necessarily be swallowed, i.e. we return some identifiers /// that may represent further actions, e.g. further lookups. -let rec ResolveExprLongIdentPrim sink (ncenv: NameResolver) first fullyQualified m ad nenv (typeNameResInfo: TypeNameResolutionInfo) (id: Ident) (rest: Ident list) isOpenDecl = +let rec ResolveExprLongIdentPrim sink (ncenv: NameResolver) first fullyQualified m ad nenv (typeNameResInfo: TypeNameResolutionInfo) (id: Ident) (rest: Ident list) isOpenDecl maybeAppliedArgExpr = let lookupKind = LookupKind.Expr LookupIsInstance.No @@ -2951,9 +3002,9 @@ let rec ResolveExprLongIdentPrim sink (ncenv: NameResolver) first fullyQualified | [] -> raze (Error(FSComp.SR.nrGlobalUsedOnlyAsFirstName(), id.idRange)) | [next] -> - ResolveExprLongIdentPrim sink ncenv false fullyQualified m ad nenv typeNameResInfo next [] isOpenDecl + ResolveExprLongIdentPrim sink ncenv false fullyQualified m ad nenv typeNameResInfo next [] isOpenDecl maybeAppliedArgExpr | id2 :: rest2 -> - ResolveExprLongIdentPrim sink ncenv false FullyQualified m ad nenv typeNameResInfo id2 rest2 isOpenDecl + ResolveExprLongIdentPrim sink ncenv false FullyQualified m ad nenv typeNameResInfo id2 rest2 isOpenDecl maybeAppliedArgExpr else if isNil rest && fullyQualified <> FullyQualified then let mutable typeError = None @@ -3088,7 +3139,7 @@ let rec ResolveExprLongIdentPrim sink (ncenv: NameResolver) first fullyQualified let tcrefs = let typeNameResInfo = TypeNameResolutionInfo.ResolveToTypeRefs typeNameResInfo.StaticArgsInfo CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities (tcrefs, typeNameResInfo, PermitDirectReferenceToGeneratedType.No, unionRanges m id.idRange) - ResolveLongIdentInTyconRefs ResultCollectionSettings.AtMostOneResult ncenv nenv lookupKind 1 m ad id2 rest2 typeNameResInfo id.idRange tcrefs + ResolveLongIdentInTyconRefs ResultCollectionSettings.AtMostOneResult ncenv nenv lookupKind 1 m ad id2 rest2 typeNameResInfo id.idRange tcrefs maybeAppliedArgExpr | _ -> NoResultsOrUsefulErrors @@ -3142,10 +3193,10 @@ let rec ResolveExprLongIdentPrim sink (ncenv: NameResolver) first fullyQualified ResolutionInfo.SendEntityPathToSink(sink, ncenv, nenv, ItemOccurence.Use, ad, resInfo, ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap m item)) success (resInfo.EnclosingTypeInst, item, rest) -let ResolveExprLongIdent sink (ncenv: NameResolver) m ad nenv typeNameResInfo lid = +let ResolveExprLongIdent sink (ncenv: NameResolver) m ad nenv typeNameResInfo lid maybeAppliedArgExpr = match lid with | [] -> raze (Error(FSComp.SR.nrInvalidExpression(textOfLid lid), m)) - | id :: rest -> ResolveExprLongIdentPrim sink ncenv true OpenQualified m ad nenv typeNameResInfo id rest false + | id :: rest -> ResolveExprLongIdentPrim sink ncenv true OpenQualified m ad nenv typeNameResInfo id rest false maybeAppliedArgExpr //------------------------------------------------------------------------- // Resolve F#/IL "." syntax in patterns @@ -3183,7 +3234,7 @@ let rec ResolvePatternLongIdentInModuleOrNamespace (ncenv: NameResolver) nenv nu match rest with | id2 :: rest2 -> let tcrefs = tcrefs.Force() - ResolveLongIdentInTyconRefs ResultCollectionSettings.AtMostOneResult (ncenv: NameResolver) nenv LookupKind.Pattern (depth+1) m ad id2 rest2 numTyArgsOpt id.idRange tcrefs + ResolveLongIdentInTyconRefs ResultCollectionSettings.AtMostOneResult (ncenv: NameResolver) nenv LookupKind.Pattern (depth+1) m ad id2 rest2 numTyArgsOpt id.idRange tcrefs None | _ -> NoResultsOrUsefulErrors @@ -3286,7 +3337,7 @@ let rec ResolvePatternLongIdentPrim sink (ncenv: NameResolver) fullyQualified wa let tcrefs = LookupTypeNameInEnvNoArity fullyQualified id.idText nenv if isNil tcrefs then NoResultsOrUsefulErrors else let tcrefs = tcrefs |> List.map (fun tcref -> (ResolutionInfo.Empty, tcref)) - ResolveLongIdentInTyconRefs ResultCollectionSettings.AtMostOneResult ncenv nenv LookupKind.Pattern 1 id.idRange ad id2 rest2 numTyArgsOpt id.idRange tcrefs + ResolveLongIdentInTyconRefs ResultCollectionSettings.AtMostOneResult ncenv nenv LookupKind.Pattern 1 id.idRange ad id2 rest2 numTyArgsOpt id.idRange tcrefs None | _ -> NoResultsOrUsefulErrors @@ -3577,7 +3628,7 @@ let rec ResolveFieldInModuleOrNamespace (ncenv: NameResolver) nenv ad (resInfo: let tcrefs = LookupTypeNameInEntityMaybeHaveArity (ncenv.amap, id.idRange, ad, id.idText, TypeNameResolutionStaticArgsInfo.Indefinite, modref) if isNil tcrefs then NoResultsOrUsefulErrors else let tcrefs = tcrefs |> List.map (fun tcref -> (ResolutionInfo.Empty, tcref)) - let tyconSearch = ResolveLongIdentInTyconRefs ResultCollectionSettings.AllResults ncenv nenv LookupKind.RecdField (depth+1) m ad id2 rest2 typeNameResInfo id.idRange tcrefs + let tyconSearch = ResolveLongIdentInTyconRefs ResultCollectionSettings.AllResults ncenv nenv LookupKind.RecdField (depth+1) m ad id2 rest2 typeNameResInfo id.idRange tcrefs None // choose only fields let tyconSearch = tyconSearch |?> List.choose (function resInfo, Item.RecdField(RecdFieldInfo(_, rfref)), rest -> Some(resInfo, FieldResolution(FreshenRecdFieldRef ncenv m rfref, false), rest) | _ -> None) tyconSearch @@ -3706,7 +3757,7 @@ let ResolveFieldPrim sink (ncenv: NameResolver) nenv ad ty (mp, id: Ident) allFi let tcrefs = LookupTypeNameInEnvNoArity OpenQualified tn.idText nenv if isNil tcrefs then NoResultsOrUsefulErrors else let tcrefs = tcrefs |> List.map (fun tcref -> (ResolutionInfo.Empty, tcref)) - let tyconSearch = ResolveLongIdentInTyconRefs ResultCollectionSettings.AllResults ncenv nenv LookupKind.RecdField 1 m ad id2 rest2 typeNameResInfo tn.idRange tcrefs + let tyconSearch = ResolveLongIdentInTyconRefs ResultCollectionSettings.AllResults ncenv nenv LookupKind.RecdField 1 m ad id2 rest2 typeNameResInfo tn.idRange tcrefs None // choose only fields let tyconSearch = tyconSearch |?> List.choose (function resInfo, Item.RecdField(RecdFieldInfo(_, rfref)), rest -> Some(resInfo, FieldResolution(FreshenRecdFieldRef ncenv m rfref, false), rest) | _ -> None) tyconSearch @@ -3818,7 +3869,7 @@ let ResolveNestedField sink (ncenv: NameResolver) nenv ad recdTy lid = if isNil tcrefs then NoResultsOrUsefulErrors else - ResolveLongIdentInTyconRefs ResultCollectionSettings.AllResults ncenv nenv LookupKind.RecdField 1 tyconId.idRange ad fieldId rest typeNameResInfo fieldId.idRange tcrefs + ResolveLongIdentInTyconRefs ResultCollectionSettings.AllResults ncenv nenv LookupKind.RecdField 1 tyconId.idRange ad fieldId rest typeNameResInfo fieldId.idRange tcrefs None |?> List.choose (fun x -> match x with | _, (Item.RecdField _ as item), rest -> Some (fieldId, item, rest) @@ -3885,9 +3936,9 @@ let ResolveNestedField sink (ncenv: NameResolver) nenv ad recdTy lid = /// determine any valid members // // QUERY (instantiationGenerator cleanup): it would be really nice not to flow instantiationGenerator to here. -let private ResolveExprDotLongIdent (ncenv: NameResolver) m ad nenv ty (id: Ident) rest (typeNameResInfo: TypeNameResolutionInfo) findFlag = +let private ResolveExprDotLongIdent (ncenv: NameResolver) m ad nenv ty (id: Ident) rest (typeNameResInfo: TypeNameResolutionInfo) findFlag maybeArgExpr = let lookupKind = LookupKind.Expr LookupIsInstance.Yes - let adhocDotSearchAccessible = AtMostOneResult m (ResolveLongIdentInTypePrim ncenv nenv lookupKind ResolutionInfo.Empty 1 m ad id rest findFlag typeNameResInfo ty) + let adhocDotSearchAccessible = AtMostOneResult m (ResolveLongIdentInTypePrim ncenv nenv lookupKind ResolutionInfo.Empty 1 m ad id rest findFlag typeNameResInfo ty maybeArgExpr) match adhocDotSearchAccessible with | Exception _ -> // If the dot is not resolved by adhoc overloading then look for a record field @@ -3907,7 +3958,7 @@ let private ResolveExprDotLongIdent (ncenv: NameResolver) m ad nenv ty (id: Iden let adhocDotSearchAll () = let lookupKind = LookupKind.Expr LookupIsInstance.Ambivalent - ResolveLongIdentInTypePrim ncenv nenv lookupKind ResolutionInfo.Empty 1 m AccessibleFromSomeFSharpCode id rest findFlag typeNameResInfo ty + ResolveLongIdentInTypePrim ncenv nenv lookupKind ResolutionInfo.Empty 1 m AccessibleFromSomeFSharpCode id rest findFlag typeNameResInfo ty None dotFieldIdSearch +++ adhocDotSearchAll |> AtMostOneResult m @@ -3959,8 +4010,10 @@ type AfterResolution = /// Resolve a long identifier occurring in an expression position. /// /// Called for 'TypeName.Bar' - for VS IntelliSense, we can filter out instance members from method groups -let ResolveLongIdentAsExprAndComputeRange (sink: TcResultsSink) (ncenv: NameResolver) wholem ad nenv typeNameResInfo lid = - match ResolveExprLongIdent sink ncenv wholem ad nenv typeNameResInfo lid with +// maybeAppliedArgExpr is used in context of resolving extension method that would override property name, it may contain argExpr coming from the DelayedApp(argExpr: SynExpr) +// see RFC-1137 +let ResolveLongIdentAsExprAndComputeRange (sink: TcResultsSink) (ncenv: NameResolver) wholem ad nenv typeNameResInfo lid (maybeAppliedArgExpr: SynExpr option) = + match ResolveExprLongIdent sink ncenv wholem ad nenv typeNameResInfo lid maybeAppliedArgExpr with | Exception e -> Exception e | Result (tinstEnclosing, item1, rest) -> let itemRange = ComputeItemRange wholem lid rest @@ -4020,12 +4073,12 @@ let (|NonOverridable|_|) namedItem = /// Called for 'expression.Bar' - for VS IntelliSense, we can filter out static members from method groups /// Also called for 'GenericType.Bar' - for VS IntelliSense, we can filter out non-static members from method groups -let ResolveExprDotLongIdentAndComputeRange (sink: TcResultsSink) (ncenv: NameResolver) wholem ad nenv ty lid (typeNameResInfo: TypeNameResolutionInfo) findFlag staticOnly = +let ResolveExprDotLongIdentAndComputeRange (sink: TcResultsSink) (ncenv: NameResolver) wholem ad nenv ty lid (typeNameResInfo: TypeNameResolutionInfo) findFlag staticOnly maybeAppliedArgExpr = let resolveExpr findFlag = let resInfo, item, rest = match lid with | id :: rest -> - ResolveExprDotLongIdent ncenv wholem ad nenv ty id rest typeNameResInfo findFlag + ResolveExprDotLongIdent ncenv wholem ad nenv ty id rest typeNameResInfo findFlag maybeAppliedArgExpr | _ -> error(InternalError("ResolveExprDotLongIdentAndComputeRange", wholem)) let itemRange = ComputeItemRange wholem lid rest resInfo, item, rest, itemRange diff --git a/src/Compiler/Checking/NameResolution.fsi b/src/Compiler/Checking/NameResolution.fsi index e7c970c14cb..3ba5113b004 100755 --- a/src/Compiler/Checking/NameResolution.fsi +++ b/src/Compiler/Checking/NameResolution.fsi @@ -781,6 +781,7 @@ val internal ResolveExprLongIdent: nenv: NameResolutionEnv -> typeNameResInfo: TypeNameResolutionInfo -> lid: Ident list -> + maybeAppliedArgExpr: SynExpr option -> ResultOrException val internal getRecordFieldsInScope: NameResolutionEnv -> Item list @@ -801,6 +802,7 @@ val internal ResolveLongIdentAsExprAndComputeRange: nenv: NameResolutionEnv -> typeNameResInfo: TypeNameResolutionInfo -> lid: Ident list -> + maybeAppliedArgExpr: SynExpr option -> ResultOrException /// Resolve a long identifier occurring in an expression position, qualified by a type. @@ -815,6 +817,7 @@ val internal ResolveExprDotLongIdentAndComputeRange: typeNameResInfo: TypeNameResolutionInfo -> findFlag: FindMemberFlag -> staticOnly: bool -> + maybeAppliedArgExpr: SynExpr option -> Item * range * Ident list * AfterResolution /// A generator of type instantiations used when no more specific type instantiation is known. diff --git a/src/Compiler/Checking/infos.fs b/src/Compiler/Checking/infos.fs index af33e162200..05f361c1f81 100644 --- a/src/Compiler/Checking/infos.fs +++ b/src/Compiler/Checking/infos.fs @@ -1851,6 +1851,11 @@ type PropInfo = | None -> false /// Indicates if this property is an indexer property, i.e. a property with arguments. + /// + /// member x.Prop with + /// get (indexPiece1:int,indexPiece2: string) = ... + /// and set (indexPiece1:int,indexPiece2: string) value = ... + /// member x.IsIndexer = match x with | ILProp(ILPropInfo(_, pdef)) -> pdef.Args.Length <> 0 diff --git a/src/Compiler/Checking/infos.fsi b/src/Compiler/Checking/infos.fsi index 5f6aab66a91..041c652650a 100644 --- a/src/Compiler/Checking/infos.fsi +++ b/src/Compiler/Checking/infos.fsi @@ -836,6 +836,11 @@ type PropInfo = member IsFSharpExplicitInterfaceImplementation: bool /// Indicates if this property is an indexer property, i.e. a property with arguments. + /// + /// member x.Prop with + /// get (indexPiece1:int,indexPiece2: string) = ... + /// and set (indexPiece1:int,indexPiece2: string) value = ... + /// member IsIndexer: bool /// Indicates if the property is logically a 'newslot', i.e. hides any previous slots of the same name. diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 81068d1c7ab..13aa99fd609 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1588,6 +1588,7 @@ featureChkNotTailRecursive,"Raises warnings if a member or function has the 'Tai featureWhileBang,"'while!' expression" featureExtendedFixedBindings,"extended fixed bindings for byref and GetPinnableReference" featurePreferStringGetPinnableReference,"prefer String.GetPinnableReference in fixed bindings" +featurePreferExtensionMethodOverPlainProperty,"prefer extension method over plain property" featureWarningIndexedPropertiesGetSetSameType,"Indexed properties getter and setter must have the same type" 3354,tcNotAFunctionButIndexerNamedIndexingNotYetEnabled,"This value supports indexing, e.g. '%s.[index]'. The syntax '%s[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." 3354,tcNotAFunctionButIndexerIndexingNotYetEnabled,"This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs index b17f1671200..7f9fb1f4b58 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fs +++ b/src/Compiler/Facilities/LanguageFeatures.fs @@ -79,6 +79,7 @@ type LanguageFeature = | WhileBang | ExtendedFixedBindings | PreferStringGetPinnableReference + | PreferExtensionMethodOverPlainProperty | WarningIndexedPropertiesGetSetSameType /// LanguageVersion management @@ -186,6 +187,7 @@ type LanguageVersion(versionText) = // F# preview LanguageFeature.FromEndSlicing, previewVersion LanguageFeature.UnmanagedConstraintCsharpInterop, previewVersion + LanguageFeature.PreferExtensionMethodOverPlainProperty, previewVersion LanguageFeature.WarningIndexedPropertiesGetSetSameType, previewVersion ] @@ -323,6 +325,7 @@ type LanguageVersion(versionText) = | LanguageFeature.WhileBang -> FSComp.SR.featureWhileBang () | LanguageFeature.ExtendedFixedBindings -> FSComp.SR.featureExtendedFixedBindings () | LanguageFeature.PreferStringGetPinnableReference -> FSComp.SR.featurePreferStringGetPinnableReference () + | LanguageFeature.PreferExtensionMethodOverPlainProperty -> FSComp.SR.featurePreferExtensionMethodOverPlainProperty () | LanguageFeature.WarningIndexedPropertiesGetSetSameType -> FSComp.SR.featureWarningIndexedPropertiesGetSetSameType () /// Get a version string associated with the given feature. diff --git a/src/Compiler/Facilities/LanguageFeatures.fsi b/src/Compiler/Facilities/LanguageFeatures.fsi index e3d7e7232bc..93b8b231534 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fsi +++ b/src/Compiler/Facilities/LanguageFeatures.fsi @@ -69,6 +69,8 @@ type LanguageFeature = | WhileBang | ExtendedFixedBindings | PreferStringGetPinnableReference + /// RFC-1137 + | PreferExtensionMethodOverPlainProperty | WarningIndexedPropertiesGetSetSameType /// LanguageVersion management diff --git a/src/Compiler/Service/ServiceDeclarationLists.fs b/src/Compiler/Service/ServiceDeclarationLists.fs index 104ae1da0ff..1251432d51c 100644 --- a/src/Compiler/Service/ServiceDeclarationLists.fs +++ b/src/Compiler/Service/ServiceDeclarationLists.fs @@ -1128,6 +1128,7 @@ type DeclarationListInfo(declarations: DeclarationListItem[], isForType: bool, i ) (0, 0, []) if verbose then dprintf "service.ml: mkDecls: %d found groups after filtering\n" (List.length items); + let supportsPreferExtsMethodsOverProperty = denv.g.langVersion.SupportsFeature Features.LanguageFeature.PreferExtensionMethodOverPlainProperty // Group by full name for unresolved items and by display name for resolved ones. let decls = @@ -1144,22 +1145,79 @@ type DeclarationListInfo(declarations: DeclarationListItem[], isForType: bool, i | [||] -> u.DisplayName | ns -> (ns |> String.concat ".") + "." + u.DisplayName | None -> x.Item.DisplayName) - - |> List.map (fun (_, items) -> - let item = items.Head - let textInDeclList = + |> List.map ( + let textInDeclList item = match item.Unresolved with | Some u -> u.DisplayName | None -> item.Item.DisplayNameCore - let textInCode = + let textInCode (item: CompletionItem) = match item.Item with | Item.TypeVar (name, typar) -> (if typar.StaticReq = Syntax.TyparStaticReq.None then "'" else " ^") + name | _ -> match item.Unresolved with | Some u -> u.DisplayName | None -> item.Item.DisplayName - textInDeclList, textInCode, items) - + if not supportsPreferExtsMethodsOverProperty then + // we don't pay the cost of filtering specific to RFC-1137 + // nor risk a change in behaviour for the intellisense item list + // if the feature is disabled + fun (_, items) -> + let item = items.Head + [textInDeclList item, textInCode item, items] + else + // RFC-1137 shenanigans: + // due to not desiring to merge Property and extension Method bearing same name, + // but still merging extension method if it tries to shadow other stuff than a Property + // we proceed with a pre-scan to see if we hit the particular case, in which case we partition + // items to be split and those that were initially remaining grouped. + // If we don't hit the specific case, or have a single entry, we keep the same logic as originally + // N.B: due to the logic returning 1 to N instead of 1, the next stage of the pipeline is List.concat + // introduced for this RFC + let hasBothPropertiesAndExtensionMethods items = + let rec inner hasProperty hasExtensionMethod items = + if hasProperty && hasExtensionMethod then + true + else + match items with + | [] -> hasProperty && hasExtensionMethod + | item :: tail when item.Kind = CompletionItemKind.Property -> inner true hasExtensionMethod tail + | item :: tail when item.Kind = CompletionItemKind.Method(isExtension=true) -> inner hasProperty true tail + | _ :: tail -> inner hasProperty hasExtensionMethod tail + inner false false items + function + | _, ([_] as items) + | _,items when not (hasBothPropertiesAndExtensionMethods items) -> + let item = items.Head + [textInDeclList item, textInCode item, items] + | _, items (* RFC-1137 we have both property and extension method ...*) -> + let toSplit, together = + items + |> List.partition + (fun item -> + match item.Kind with + | CompletionItemKind.Property | CompletionItemKind.Method(isExtension=true) -> true + | _ -> false + ) + [ + let rec createSublists list = + match list with + | [] -> [] + | _ :: tail -> list :: createSublists tail + + // we use createSublists here so the `items` sent down the + // pipeline have their first element being the actual + // item, in order for the glyph to be the correct one + // notice how the later stage uses `GlyphOfItem(denv,items.Head)` + for items in createSublists toSplit do + let item = items.Head + textInDeclList item, textInCode item, items + if not together.IsEmpty then + let item = together.Head + textInDeclList item, textInCode item, items + ] + ) + // RFC-1137: concat previous result + |> List.concat // Filter out operators, active patterns (as values) |> List.filter (fun (_textInDeclList, textInCode, items) -> not (isOperatorItem textInCode items) && diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 96848c254ba..e00ae35e455 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -407,6 +407,11 @@ správa balíčků + + prefer extension method over plain property + prefer extension method over plain property + + prefer String.GetPinnableReference in fixed bindings preferovat String.GetPinnableReference v pevných vazbách diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 14a98b6d7d0..2ba20dfee57 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -407,6 +407,11 @@ Paketverwaltung + + prefer extension method over plain property + prefer extension method over plain property + + prefer String.GetPinnableReference in fixed bindings String.GetPinnableReference in festen Bindungen bevorzugen diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 370b6c2ae26..a240ae2b02a 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -407,6 +407,11 @@ administración de paquetes + + prefer extension method over plain property + prefer extension method over plain property + + prefer String.GetPinnableReference in fixed bindings preferir String.GetPinnableReference en enlaces fijos diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 798bde70d98..6d18837734d 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -407,6 +407,11 @@ Package Management + + prefer extension method over plain property + prefer extension method over plain property + + prefer String.GetPinnableReference in fixed bindings préférez String.GetPinnableReference dans les liaisons fixes diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 43fcac7a1e7..d001d237f7b 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -407,6 +407,11 @@ gestione pacchetti + + prefer extension method over plain property + prefer extension method over plain property + + prefer String.GetPinnableReference in fixed bindings preferisci String.GetPinnableReference nei binding fissi diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index d46ad590b45..95c48ab8f3e 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -407,6 +407,11 @@ パッケージの管理 + + prefer extension method over plain property + prefer extension method over plain property + + prefer String.GetPinnableReference in fixed bindings 固定バインドで String.GetPinnableReference を優先する diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index ccb5c18ba7a..6eebf9bf1ff 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -407,6 +407,11 @@ 패키지 관리 + + prefer extension method over plain property + prefer extension method over plain property + + prefer String.GetPinnableReference in fixed bindings 고정 바인딩에서 String.GetPinnableReference 선호 diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index ad6d76cea74..e7b4c6348d1 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -407,6 +407,11 @@ zarządzanie pakietami + + prefer extension method over plain property + prefer extension method over plain property + + prefer String.GetPinnableReference in fixed bindings preferuj element String.GetPinnableReference w stałych powiązaniach diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 38ed59a25b6..18e45a3e3cb 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -407,6 +407,11 @@ gerenciamento de pacotes + + prefer extension method over plain property + prefer extension method over plain property + + prefer String.GetPinnableReference in fixed bindings preferir String.GetPinnableReference em associações fixas diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index adc039b247a..39bcb4d4881 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -407,6 +407,11 @@ управление пакетами + + prefer extension method over plain property + prefer extension method over plain property + + prefer String.GetPinnableReference in fixed bindings рекомендуется использовать String.GetPinnableReference в фиксированных привязках diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index e6dd270b4ba..2b41bf7ad5d 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -407,6 +407,11 @@ paket yönetimi + + prefer extension method over plain property + prefer extension method over plain property + + prefer String.GetPinnableReference in fixed bindings sabit bağlamalarda String.GetPinnableReference tercih edin diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 17f0e605027..ed319784660 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -407,6 +407,11 @@ 包管理 + + prefer extension method over plain property + prefer extension method over plain property + + prefer String.GetPinnableReference in fixed bindings 在固定绑定中首选 String.GetPinnableReference diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 059ec9c0698..6b693de3830 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -407,6 +407,11 @@ 套件管理 + + prefer extension method over plain property + prefer extension method over plain property + + prefer String.GetPinnableReference in fixed bindings 在固定繫結中優先使用 String.GetPinnableReference diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 1c835b603da..b04d4a9a5ec 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -244,6 +244,7 @@ + diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowFunctionPropertyWithExtensionMethod.fsx b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowFunctionPropertyWithExtensionMethod.fsx new file mode 100644 index 00000000000..31fdc72d693 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowFunctionPropertyWithExtensionMethod.fsx @@ -0,0 +1,20 @@ +open System.Runtime.CompilerServices + +type Foo() = + member val X : int -> int = (+) 1 with get,set + +[] +type FooExt = + [] + static member X (f: Foo, i: int -> int) = f.X <- i; f + +let f = Foo() +f.X 1 +if f.X 0 <> 1 then + System.Environment.Exit 1 +f.X <- (-) 1 + +if f.X 2 <> -1 then + System.Environment.Exit 2 + +f.X((-) 1) // This expression was expected to have type 'int' but here has type ''a -> 'c' \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowFunctionPropertyWithExtensionMethod.fsx.err.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowFunctionPropertyWithExtensionMethod.fsx.err.bsl new file mode 100644 index 00000000000..85e445736c6 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowFunctionPropertyWithExtensionMethod.fsx.err.bsl @@ -0,0 +1,8 @@ +E_CannotShadowFunctionPropertyWithExtensionMethod.fsx (20,5)-(20,10) typecheck error This expression was expected to have type + 'int' +but here has type + ''a -> 'c' +E_CannotShadowFunctionPropertyWithExtensionMethod.fsx (20,5)-(20,10) typecheck error This expression was expected to have type + 'int' +but here has type + ''a -> 'b' \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowFunctionPropertyWithExtensionMethod.fsx.il.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowFunctionPropertyWithExtensionMethod.fsx.il.bsl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowFunctionPropertyWithTypeExtension.fsx b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowFunctionPropertyWithTypeExtension.fsx new file mode 100644 index 00000000000..3bf9617edc7 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowFunctionPropertyWithTypeExtension.fsx @@ -0,0 +1,19 @@ +open System.Runtime.CompilerServices + +type Foo() = + member val X : int -> int = (+) 1 with get,set + +module Exts = + type Foo with + member f.X (i: int -> int, j) = f.X i <- j // note: the RFC excludes hiding function typed properties +open Exts +let f = Foo() +f.X 1 +if f.X 0 <> 1 then + System.Environment.Exit 1 +f.X <- (-) 1 + +if f.X 2 <> -1 then + System.Environment.Exit 2 + +f.X((-) 1) // This expression was expected to have type 'int' but here has type ''a -> 'c' \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowFunctionPropertyWithTypeExtension.fsx.err.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowFunctionPropertyWithTypeExtension.fsx.err.bsl new file mode 100644 index 00000000000..7523058fb49 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowFunctionPropertyWithTypeExtension.fsx.err.bsl @@ -0,0 +1,13 @@ +E_CannotShadowFunctionPropertyWithTypeExtension.fsx (8,45)-(8,46) typecheck error This expression was expected to have type + 'int' +but here has type + 'int -> int' +E_CannotShadowFunctionPropertyWithTypeExtension.fsx (8,41)-(8,51) typecheck error Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'. +E_CannotShadowFunctionPropertyWithTypeExtension.fsx (19,5)-(19,10) typecheck error This expression was expected to have type + 'int' +but here has type + ''a -> 'c' +E_CannotShadowFunctionPropertyWithTypeExtension.fsx (19,5)-(19,10) typecheck error This expression was expected to have type + 'int' +but here has type + ''a -> 'b' \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowFunctionPropertyWithTypeExtension.fsx.il.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowFunctionPropertyWithTypeExtension.fsx.il.bsl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowIndexedPropertyWithExtensionMethod.fsx b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowIndexedPropertyWithExtensionMethod.fsx new file mode 100644 index 00000000000..5c0ace71525 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowIndexedPropertyWithExtensionMethod.fsx @@ -0,0 +1,23 @@ +open System.Runtime.CompilerServices + +type Foo() = + let mutable x = 0 + member _.X + with get (i: int) = i + x + and set(i: int) value = x <- i + value + +[] +type FooExt = + [] + static member X (f: Foo, i: int, j) = f.X(i) <- j // note: the RFC excludes hiding indexed properties + +let f = Foo() + +if f.X 0 <> 0 then + System.Environment.Exit 1 +f.X 1 <- 1 +if f.X 0 <> 2 then + System.Environment.Exit 2 +;; +// This expression was expected to have type ... +f.X(1,2) \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowIndexedPropertyWithExtensionMethod.fsx.err.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowIndexedPropertyWithExtensionMethod.fsx.err.bsl new file mode 100644 index 00000000000..a7537411869 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowIndexedPropertyWithExtensionMethod.fsx.err.bsl @@ -0,0 +1,4 @@ +E_CannotShadowIndexedPropertyWithExtensionMethod.fsx (23,5)-(23,8) typecheck error This expression was expected to have type + 'int' +but here has type + 'int * int' \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowIndexedPropertyWithExtensionMethod.fsx.il.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowIndexedPropertyWithExtensionMethod.fsx.il.bsl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowIndexedPropertyWithTypeExtension.fsx b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowIndexedPropertyWithTypeExtension.fsx new file mode 100644 index 00000000000..cdf288110d3 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowIndexedPropertyWithTypeExtension.fsx @@ -0,0 +1,20 @@ +type Foo() = + let mutable x = 0 + member _.X + with get (i: int) = i + x + and set(i: int) value = x <- i + value + +module Exts = + type Foo with + member f.X (i: int, j) = f.X i <- j // note: the RFC excludes hiding indexed properties +open Exts +let f = Foo() + +if f.X 0 <> 0 then + System.Environment.Exit 1 +f.X 1 <- 1 +if f.X 0 <> 2 then + System.Environment.Exit 2 +;; +// This expression was expected to have type ... +f.X(1,2) \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowIndexedPropertyWithTypeExtension.fsx.err.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowIndexedPropertyWithTypeExtension.fsx.err.bsl new file mode 100644 index 00000000000..ec65c7a754b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowIndexedPropertyWithTypeExtension.fsx.err.bsl @@ -0,0 +1,4 @@ +E_CannotShadowIndexedPropertyWithTypeExtension.fsx (20,5)-(20,8) typecheck error This expression was expected to have type + 'int' +but here has type + 'int * int' \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowIndexedPropertyWithTypeExtension.fsx.il.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_CannotShadowIndexedPropertyWithTypeExtension.fsx.il.bsl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_NoChangeForEvent.fsx b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_NoChangeForEvent.fsx new file mode 100644 index 00000000000..5fc471bf2bd --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_NoChangeForEvent.fsx @@ -0,0 +1,18 @@ +#nowarn "52" +open System.Runtime.CompilerServices +open System.Data +[] +type DataSetExts = + [] + static member Disposed(self: DataSet) = self + +let d = System.Data.DataSet() +d.Disposed().Disposed().add_Disposed(fun a b -> ()) + +module Exts = + type DataSet with + member x.Disposed() = x + +open Exts + +d.Disposed().Disposed().add_Disposed(fun a b -> ()) \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_NoChangeForEvent.fsx.err.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_NoChangeForEvent.fsx.err.bsl new file mode 100644 index 00000000000..e022666431a --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_NoChangeForEvent.fsx.err.bsl @@ -0,0 +1,3 @@ +E_NoChangeForEvent.fsx (9,9)-(9,30) typecheck warning It is recommended that objects supporting the IDisposable interface are created using the syntax 'new Type(args)', rather than 'Type(args)' or 'Type' as a function value representing the constructor, to indicate that resources may be owned by the generated value +E_NoChangeForEvent.fsx (10,1)-(10,11) typecheck error This value is not a function and cannot be applied. +E_NoChangeForEvent.fsx (18,1)-(18,11) typecheck error This value is not a function and cannot be applied. \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_NoChangeForEvent.fsx.il.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/E_NoChangeForEvent.fsx.il.bsl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/LinqCount.fsx b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/LinqCount.fsx new file mode 100644 index 00000000000..0e7661abe7b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/LinqCount.fsx @@ -0,0 +1,4 @@ +open System.Linq +let r = ResizeArray() +r.Count +r.Count(fun _ -> true) diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/LinqCount.fsx.il.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/LinqCount.fsx.il.bsl new file mode 100644 index 00000000000..684fa3ce5e7 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/LinqCount.fsx.il.bsl @@ -0,0 +1,118 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly extern System.Collections +{ + .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) + .ver 8:0:0:0 +} +.assembly extern System.Linq +{ + .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) + .ver 8:0:0:0 +} +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.mresource public FSharpSignatureData.assembly +{ + + +} +.mresource public FSharpOptimizationData.assembly +{ + + +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + 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 abstract auto autochar serializable sealed nested assembly beforefieldinit specialname clo@4 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static bool Invoke(int32 _arg1) cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: ret + } + + } + + .method public specialname static class [System.Collections]System.Collections.Generic.List`1 + get_r() cil managed + { + + .maxstack 8 + IL_0000: ldsfld class [System.Collections]System.Collections.Generic.List`1 ''.$assembly$fsx::r@2 + IL_0005: ret + } + + .property class [System.Collections]System.Collections.Generic.List`1 + r() + { + .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 [System.Collections]System.Collections.Generic.List`1 assembly::get_r() + } +} + +.class private abstract auto ansi sealed ''.$assembly$fsx + extends [runtime]System.Object +{ + .field static assembly initonly class [System.Collections]System.Collections.Generic.List`1 r@2 + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 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: newobj instance void class [System.Collections]System.Collections.Generic.List`1::.ctor() + IL_0005: stsfld class [System.Collections]System.Collections.Generic.List`1 ''.$assembly$fsx::r@2 + IL_000a: call class [System.Collections]System.Collections.Generic.List`1 assembly::get_r() + IL_000f: callvirt instance int32 class [System.Collections]System.Collections.Generic.List`1::get_Count() + IL_0014: pop + IL_0015: call class [System.Collections]System.Collections.Generic.List`1 assembly::get_r() + IL_001a: ldnull + IL_001b: ldftn bool assembly/clo@4::Invoke(int32) + IL_0021: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_0026: call int32 [System.Linq]System.Linq.Enumerable::Count(class [runtime]System.Collections.Generic.IEnumerable`1, + class [runtime]System.Func`2) + IL_002b: pop + IL_002c: ret + } + +} + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/LinqCount.fsx.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/LinqCount.fsx.il.net472.bsl new file mode 100644 index 00000000000..3b62d843887 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/LinqCount.fsx.il.net472.bsl @@ -0,0 +1,114 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly extern System.Core +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) + .ver 4:0:0:0 +} +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.mresource public FSharpSignatureData.assembly +{ + + +} +.mresource public FSharpOptimizationData.assembly +{ + + +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + 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 abstract auto autochar serializable sealed nested assembly beforefieldinit specialname clo@4 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static bool Invoke(int32 _arg1) cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: ret + } + + } + + .method public specialname static class [runtime]System.Collections.Generic.List`1 + get_r() cil managed + { + + .maxstack 8 + IL_0000: ldsfld class [runtime]System.Collections.Generic.List`1 ''.$assembly$fsx::r@2 + IL_0005: ret + } + + .property class [runtime]System.Collections.Generic.List`1 + r() + { + .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 [runtime]System.Collections.Generic.List`1 assembly::get_r() + } +} + +.class private abstract auto ansi sealed ''.$assembly$fsx + extends [runtime]System.Object +{ + .field static assembly initonly class [runtime]System.Collections.Generic.List`1 r@2 + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 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: newobj instance void class [runtime]System.Collections.Generic.List`1::.ctor() + IL_0005: stsfld class [runtime]System.Collections.Generic.List`1 ''.$assembly$fsx::r@2 + IL_000a: call class [runtime]System.Collections.Generic.List`1 assembly::get_r() + IL_000f: callvirt instance int32 class [runtime]System.Collections.Generic.List`1::get_Count() + IL_0014: pop + IL_0015: call class [runtime]System.Collections.Generic.List`1 assembly::get_r() + IL_001a: ldnull + IL_001b: ldftn bool assembly/clo@4::Invoke(int32) + IL_0021: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_0026: call int32 [System.Core]System.Linq.Enumerable::Count(class [runtime]System.Collections.Generic.IEnumerable`1, + class [runtime]System.Func`2) + IL_002b: pop + IL_002c: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/LinqCount.fsx.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/LinqCount.fsx.il.netcore.bsl new file mode 100644 index 00000000000..684fa3ce5e7 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/LinqCount.fsx.il.netcore.bsl @@ -0,0 +1,118 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly extern System.Collections +{ + .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) + .ver 8:0:0:0 +} +.assembly extern System.Linq +{ + .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) + .ver 8:0:0:0 +} +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.mresource public FSharpSignatureData.assembly +{ + + +} +.mresource public FSharpOptimizationData.assembly +{ + + +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + 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 abstract auto autochar serializable sealed nested assembly beforefieldinit specialname clo@4 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static bool Invoke(int32 _arg1) cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: ret + } + + } + + .method public specialname static class [System.Collections]System.Collections.Generic.List`1 + get_r() cil managed + { + + .maxstack 8 + IL_0000: ldsfld class [System.Collections]System.Collections.Generic.List`1 ''.$assembly$fsx::r@2 + IL_0005: ret + } + + .property class [System.Collections]System.Collections.Generic.List`1 + r() + { + .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 [System.Collections]System.Collections.Generic.List`1 assembly::get_r() + } +} + +.class private abstract auto ansi sealed ''.$assembly$fsx + extends [runtime]System.Object +{ + .field static assembly initonly class [System.Collections]System.Collections.Generic.List`1 r@2 + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 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: newobj instance void class [System.Collections]System.Collections.Generic.List`1::.ctor() + IL_0005: stsfld class [System.Collections]System.Collections.Generic.List`1 ''.$assembly$fsx::r@2 + IL_000a: call class [System.Collections]System.Collections.Generic.List`1 assembly::get_r() + IL_000f: callvirt instance int32 class [System.Collections]System.Collections.Generic.List`1::get_Count() + IL_0014: pop + IL_0015: call class [System.Collections]System.Collections.Generic.List`1 assembly::get_r() + IL_001a: ldnull + IL_001b: ldftn bool assembly/clo@4::Invoke(int32) + IL_0021: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_0026: call int32 [System.Linq]System.Linq.Enumerable::Count(class [runtime]System.Collections.Generic.IEnumerable`1, + class [runtime]System.Func`2) + IL_002b: pop + IL_002c: ret + } + +} + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/LinqCount.fsx.support.added.later.err.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/LinqCount.fsx.support.added.later.err.bsl new file mode 100644 index 00000000000..829ea13ac59 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/LinqCount.fsx.support.added.later.err.bsl @@ -0,0 +1 @@ +LinqCount.fsx (4,1)-(4,8) typecheck error This value is not a function and cannot be applied. \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/LinqCount.fsx.support.added.later.il.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/LinqCount.fsx.support.added.later.il.bsl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowStaticProperty.fsx b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowStaticProperty.fsx new file mode 100644 index 00000000000..3d891da058a --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowStaticProperty.fsx @@ -0,0 +1,26 @@ +type Foo private () = + static let mutable x = 0 + static member X + with get () = x + and set v = x <- v + +module Exts = + type Foo with + static member X v = Foo.X <- v + +open Exts +Foo.X(1) + +if Foo.X <> 1 then + System.Environment.Exit 1 + +module Exts2 = + type Foo with + static member X v = Foo.X <- v * 2 + +open Exts2 + +Foo.X 2 + +if Foo.X <> 4 then + System.Environment.Exit 2 diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowStaticProperty.fsx.il.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowStaticProperty.fsx.il.bsl new file mode 100644 index 00000000000..ee9e1d3b8a2 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowStaticProperty.fsx.il.bsl @@ -0,0 +1,193 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.mresource public FSharpSignatureData.assembly +{ + + +} +.mresource public FSharpOptimizationData.assembly +{ + + +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + 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 Foo + extends [runtime]System.Object + { + .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 ) + .field static assembly int32 x + .field static assembly int32 init@1 + .method assembly 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 public specialname static int32 + get_X() cil managed + { + + .maxstack 8 + IL_0000: volatile. + IL_0002: ldsfld int32 assembly/Foo::init@1 + IL_0007: ldc.i4.1 + 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 int32 assembly/Foo::x + IL_0016: ret + } + + .method public specialname static void + set_X(int32 v) cil managed + { + + .maxstack 8 + IL_0000: volatile. + IL_0002: ldsfld int32 assembly/Foo::init@1 + IL_0007: ldc.i4.1 + 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: ldarg.0 + IL_0012: stsfld int32 assembly/Foo::x + IL_0017: ret + } + + .method private specialname rtspecialname static + void .cctor() cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: stsfld int32 ''.$assembly$fsx::init@ + IL_0006: ldsfld int32 ''.$assembly$fsx::init@ + IL_000b: pop + IL_000c: ret + } + + .property int32 X() + { + .set void assembly/Foo::set_X(int32) + .get int32 assembly/Foo::get_X() + } + } + + .class abstract auto ansi sealed nested public Exts2 + 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 ) + .method public static void Foo.X.Static(int32 v) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldc.i4.2 + IL_0002: mul + IL_0003: call void assembly/Foo::set_X(int32) + IL_0008: ret + } + + } + + .class abstract auto ansi sealed nested public Exts + 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 ) + .method public static void Foo.X.Static(int32 v) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call void assembly/Foo::set_X(int32) + IL_0006: ret + } + + } + +} + +.class private abstract auto ansi sealed ''.$assembly$fsx + extends [runtime]System.Object +{ + .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: ldc.i4.0 + IL_0001: stsfld int32 assembly/Foo::x + IL_0006: ldc.i4.1 + IL_0007: volatile. + IL_0009: stsfld int32 assembly/Foo::init@1 + IL_000e: ldc.i4.1 + IL_000f: call void assembly/Foo::set_X(int32) + IL_0014: call int32 assembly/Foo::get_X() + IL_0019: ldc.i4.1 + IL_001a: beq.s IL_0024 + + IL_001c: ldc.i4.1 + IL_001d: call void [runtime]System.Environment::Exit(int32) + IL_0022: br.s IL_0024 + + IL_0024: ldc.i4.4 + IL_0025: call void assembly/Foo::set_X(int32) + IL_002a: call int32 assembly/Foo::get_X() + IL_002f: ldc.i4.4 + IL_0030: beq.s IL_003a + + IL_0032: ldc.i4.2 + IL_0033: call void [runtime]System.Environment::Exit(int32) + IL_0038: br.s IL_003a + + IL_003a: ret + } + +} + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowStaticProperty.fsx.support.added.later.err.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowStaticProperty.fsx.support.added.later.err.bsl new file mode 100644 index 00000000000..5721a44c50f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowStaticProperty.fsx.support.added.later.err.bsl @@ -0,0 +1,2 @@ +ShadowStaticProperty.fsx (12,1)-(12,6) typecheck error This value is not a function and cannot be applied. +ShadowStaticProperty.fsx (23,1)-(23,6) typecheck error This value is not a function and cannot be applied. \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowStaticProperty.fsx.support.added.later.il.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowStaticProperty.fsx.support.added.later.il.bsl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithExtensionMethod.fsx b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithExtensionMethod.fsx new file mode 100644 index 00000000000..d12f6aa9007 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithExtensionMethod.fsx @@ -0,0 +1,20 @@ +open System.Runtime.CompilerServices + +type Foo() = + member val X : int = 0 with get,set + +[] +type FooExt = + [] + static member X (f: Foo, i: int) = f.X <- i; f + + +let f = Foo() +f.X(1) +if f.X <> 1 then + System.Environment.Exit 1 + +f.X(1).X(2).X(3) + +if f.X <> 3 then + System.Environment.Exit 2 diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithExtensionMethod.fsx.err.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithExtensionMethod.fsx.err.bsl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithExtensionMethod.fsx.il.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithExtensionMethod.fsx.il.bsl new file mode 100644 index 00000000000..66c098c1490 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithExtensionMethod.fsx.il.bsl @@ -0,0 +1,228 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.mresource public FSharpSignatureData.assembly +{ + + +} +.mresource public FSharpOptimizationData.assembly +{ + + +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + 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 Foo + extends [runtime]System.Object + { + .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 ) + .field assembly int32 X@ + .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: ldarg.0 + IL_0009: ldc.i4.0 + IL_000a: stfld int32 assembly/Foo::X@ + IL_000f: ret + } + + .method public hidebysig specialname + instance int32 get_X() 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 assembly/Foo::X@ + IL_0006: ret + } + + .method public hidebysig specialname + instance void set_X(int32 v) 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: ldarg.1 + IL_0002: stfld int32 assembly/Foo::X@ + IL_0007: ret + } + + .property instance int32 X() + { + .set instance void assembly/Foo::set_X(int32) + .get instance int32 assembly/Foo::get_X() + } + } + + .class auto ansi serializable nested public FooExt + extends [runtime]System.Object + { + .custom instance void [runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 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 ) + .method public static class assembly/Foo + X(class assembly/Foo f, + int32 i) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 assembly/Foo::X@ + IL_0007: ldarg.0 + IL_0008: ret + } + + } + + .method public specialname static class assembly/Foo + get_f() cil managed + { + + .maxstack 8 + IL_0000: ldsfld class assembly/Foo ''.$assembly$fsx::f@12 + IL_0005: ret + } + + .method assembly specialname static class assembly/Foo + get_f@9() cil managed + { + + .maxstack 8 + IL_0000: ldsfld class assembly/Foo ''.$assembly$fsx::'f@9-1' + IL_0005: ret + } + + .method assembly specialname static class assembly/Foo + 'get_f@9-1'() cil managed + { + + .maxstack 8 + IL_0000: ldsfld class assembly/Foo ''.$assembly$fsx::'f@9-2' + IL_0005: ret + } + + .property class assembly/Foo + f() + { + .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 assembly/Foo assembly::get_f() + } + .property class assembly/Foo + f@9() + { + .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 assembly/Foo assembly::get_f@9() + } + .property class assembly/Foo + 'f@9-1'() + { + .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 assembly/Foo assembly::'get_f@9-1'() + } +} + +.class private abstract auto ansi sealed ''.$assembly$fsx + extends [runtime]System.Object +{ + .field static assembly initonly class assembly/Foo f@12 + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field static assembly initonly class assembly/Foo 'f@9-1' + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field static assembly initonly class assembly/Foo 'f@9-2' + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 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 4 + IL_0000: newobj instance void assembly/Foo::.ctor() + IL_0005: stsfld class assembly/Foo ''.$assembly$fsx::f@12 + IL_000a: call class assembly/Foo assembly::get_f() + IL_000f: ldc.i4.1 + IL_0010: stfld int32 assembly/Foo::X@ + IL_0015: call class assembly/Foo assembly::get_f() + IL_001a: pop + IL_001b: call class assembly/Foo assembly::get_f() + IL_0020: ldfld int32 assembly/Foo::X@ + IL_0025: ldc.i4.1 + IL_0026: beq.s IL_0030 + + IL_0028: ldc.i4.1 + IL_0029: call void [runtime]System.Environment::Exit(int32) + IL_002e: br.s IL_0030 + + IL_0030: call class assembly/Foo assembly::get_f() + IL_0035: ldc.i4.1 + IL_0036: stfld int32 assembly/Foo::X@ + IL_003b: call class assembly/Foo assembly::get_f() + IL_0040: stsfld class assembly/Foo ''.$assembly$fsx::'f@9-2' + IL_0045: call class assembly/Foo assembly::'get_f@9-1'() + IL_004a: ldc.i4.2 + IL_004b: stfld int32 assembly/Foo::X@ + IL_0050: call class assembly/Foo assembly::'get_f@9-1'() + IL_0055: stsfld class assembly/Foo ''.$assembly$fsx::'f@9-1' + IL_005a: call class assembly/Foo assembly::get_f@9() + IL_005f: ldc.i4.3 + IL_0060: stfld int32 assembly/Foo::X@ + IL_0065: call class assembly/Foo assembly::get_f@9() + IL_006a: pop + IL_006b: call class assembly/Foo assembly::get_f() + IL_0070: ldfld int32 assembly/Foo::X@ + IL_0075: ldc.i4.3 + IL_0076: beq.s IL_0080 + + IL_0078: ldc.i4.2 + IL_0079: call void [runtime]System.Environment::Exit(int32) + IL_007e: br.s IL_0080 + + IL_0080: ret + } + +} + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithExtensionMethod.fsx.support.added.later.err.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithExtensionMethod.fsx.support.added.later.err.bsl new file mode 100644 index 00000000000..43881e3a026 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithExtensionMethod.fsx.support.added.later.err.bsl @@ -0,0 +1,2 @@ +ShadowWithExtensionMethod.fsx (13,1)-(13,4) typecheck error This value is not a function and cannot be applied. +ShadowWithExtensionMethod.fsx (17,1)-(17,4) typecheck error This value is not a function and cannot be applied. \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithExtensionMethod.fsx.support.added.later.il.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithExtensionMethod.fsx.support.added.later.il.bsl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithLastOpenedTypeExtensions.fsx b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithLastOpenedTypeExtensions.fsx new file mode 100644 index 00000000000..980fca2a2fd --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithLastOpenedTypeExtensions.fsx @@ -0,0 +1,46 @@ +#nowarn "52" +open System + +type Foo private () = + static let mutable x = 0 + static member X + with get () = x + and set v = x <- v + +module Exts = + type Foo with + static member X v = Foo.X <- v + +open Exts + +let todo1 = + async { + Foo.X(1) + if Foo.X <> 1 then + return Error 1 + else + return Ok () + } + +match todo1 |> Async.RunSynchronously with +| Ok _ -> () +| Error e -> System.Environment.Exit e + +module Exts2 = + type Foo with + static member X v = Foo.X <- v * 2 + +open Exts2 + +let todo2 = + async { + Foo.X(1) + if Foo.X <> 2 then + return Error 2 + else + return Ok () + } + +match todo2 |> Async.RunSynchronously with +| Ok _ -> () +| Error e -> System.Environment.Exit e diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithLastOpenedTypeExtensions.fsx.err.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithLastOpenedTypeExtensions.fsx.err.bsl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithLastOpenedTypeExtensions.fsx.il.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithLastOpenedTypeExtensions.fsx.il.bsl new file mode 100644 index 00000000000..2244a998dae --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithLastOpenedTypeExtensions.fsx.il.bsl @@ -0,0 +1,557 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.mresource public FSharpSignatureData.assembly +{ + + +} +.mresource public FSharpOptimizationData.assembly +{ + + +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + 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 Foo + extends [runtime]System.Object + { + .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 ) + .field static assembly int32 x + .field static assembly int32 init@4 + .method assembly 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 public specialname static int32 + get_X() cil managed + { + + .maxstack 8 + IL_0000: volatile. + IL_0002: ldsfld int32 assembly/Foo::init@4 + IL_0007: ldc.i4.1 + 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 int32 assembly/Foo::x + IL_0016: ret + } + + .method public specialname static void + set_X(int32 v) cil managed + { + + .maxstack 8 + IL_0000: volatile. + IL_0002: ldsfld int32 assembly/Foo::init@4 + IL_0007: ldc.i4.1 + 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: ldarg.0 + IL_0012: stsfld int32 assembly/Foo::x + IL_0017: ret + } + + .method private specialname rtspecialname static + void .cctor() cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: stsfld int32 ''.$assembly$fsx::init@ + IL_0006: ldsfld int32 ''.$assembly$fsx::init@ + IL_000b: pop + IL_000c: ret + } + + .property int32 X() + { + .set void assembly/Foo::set_X(int32) + .get int32 assembly/Foo::get_X() + } + } + + .class auto ansi serializable sealed nested assembly beforefieldinit 'todo1@20-1' + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> + { + .field public valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 '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(valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 '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: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 assembly/'todo1@20-1'::'value' + IL_000d: ret + } + + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn + Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1> ctxt) cil managed + { + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.0 + IL_0002: ldfld valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 assembly/'todo1@20-1'::'value' + IL_0007: tail. + IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1>::Success(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, + !0) + IL_000e: ret + } + + } + + .class auto ansi serializable sealed nested assembly beforefieldinit 'todo1@22-2' + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> + { + .field public valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 '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(valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 '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: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 assembly/'todo1@22-2'::'value' + IL_000d: ret + } + + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn + Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1> ctxt) cil managed + { + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.0 + IL_0002: ldfld valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 assembly/'todo1@22-2'::'value' + IL_0007: tail. + IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1>::Success(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, + !0) + IL_000e: ret + } + + } + + .class auto ansi serializable sealed nested assembly beforefieldinit todo1@18 + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>> + { + .field static assembly initonly class assembly/todo1@18 @_instance + .method assembly specialname rtspecialname + instance void .ctor() 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.FSharpFunc`2>>::.ctor() + IL_0006: ret + } + + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1> + Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed + { + + .maxstack 6 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 V_0) + IL_0000: ldc.i4.1 + IL_0001: call void assembly/Foo::set_X(int32) + IL_0006: call int32 assembly/Foo::get_X() + IL_000b: ldc.i4.1 + IL_000c: beq.s IL_0023 + + IL_000e: ldc.i4.1 + IL_000f: call valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2::NewError(!1) + IL_0014: stloc.0 + IL_0015: ldloc.0 + IL_0016: newobj instance void assembly/'todo1@20-1'::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2) + IL_001b: tail. + IL_001d: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) + IL_0022: ret + + IL_0023: ldnull + IL_0024: call valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2::NewOk(!0) + IL_0029: stloc.0 + IL_002a: ldloc.0 + IL_002b: newobj instance void assembly/'todo1@22-2'::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2) + IL_0030: tail. + IL_0032: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) + IL_0037: ret + } + + .method private specialname rtspecialname static + void .cctor() cil managed + { + + .maxstack 10 + IL_0000: newobj instance void assembly/todo1@18::.ctor() + IL_0005: stsfld class assembly/todo1@18 assembly/todo1@18::@_instance + IL_000a: ret + } + + } + + .class auto ansi serializable sealed nested assembly beforefieldinit 'todo2@39-1' + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> + { + .field public valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 '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(valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 '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: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 assembly/'todo2@39-1'::'value' + IL_000d: ret + } + + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn + Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1> ctxt) cil managed + { + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.0 + IL_0002: ldfld valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 assembly/'todo2@39-1'::'value' + IL_0007: tail. + IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1>::Success(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, + !0) + IL_000e: ret + } + + } + + .class auto ansi serializable sealed nested assembly beforefieldinit 'todo2@41-2' + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> + { + .field public valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 '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(valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 '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: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 assembly/'todo2@41-2'::'value' + IL_000d: ret + } + + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn + Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1> ctxt) cil managed + { + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.0 + IL_0002: ldfld valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 assembly/'todo2@41-2'::'value' + IL_0007: tail. + IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1>::Success(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, + !0) + IL_000e: ret + } + + } + + .class auto ansi serializable sealed nested assembly beforefieldinit todo2@37 + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>> + { + .field static assembly initonly class assembly/todo2@37 @_instance + .method assembly specialname rtspecialname + instance void .ctor() 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.FSharpFunc`2>>::.ctor() + IL_0006: ret + } + + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1> + Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed + { + + .maxstack 6 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 V_0) + IL_0000: ldc.i4.2 + IL_0001: call void assembly/Foo::set_X(int32) + IL_0006: call int32 assembly/Foo::get_X() + IL_000b: ldc.i4.2 + IL_000c: beq.s IL_0023 + + IL_000e: ldc.i4.2 + IL_000f: call valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2::NewError(!1) + IL_0014: stloc.0 + IL_0015: ldloc.0 + IL_0016: newobj instance void assembly/'todo2@39-1'::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2) + IL_001b: tail. + IL_001d: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) + IL_0022: ret + + IL_0023: ldnull + IL_0024: call valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2::NewOk(!0) + IL_0029: stloc.0 + IL_002a: ldloc.0 + IL_002b: newobj instance void assembly/'todo2@41-2'::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2) + IL_0030: tail. + IL_0032: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) + IL_0037: ret + } + + .method private specialname rtspecialname static + void .cctor() cil managed + { + + .maxstack 10 + IL_0000: newobj instance void assembly/todo2@37::.ctor() + IL_0005: stsfld class assembly/todo2@37 assembly/todo2@37::@_instance + IL_000a: ret + } + + } + + .class abstract auto ansi sealed nested public Exts2 + 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 ) + .method public static void Foo.X.Static(int32 v) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldc.i4.2 + IL_0002: mul + IL_0003: call void assembly/Foo::set_X(int32) + IL_0008: ret + } + + } + + .class abstract auto ansi sealed nested public Exts + 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 ) + .method public static void Foo.X.Static(int32 v) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call void assembly/Foo::set_X(int32) + IL_0006: ret + } + + } + + .method public specialname static class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1> + get_todo1() cil managed + { + + .maxstack 8 + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1> ''.$assembly$fsx::todo1@16 + IL_0005: ret + } + + .method assembly specialname static valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 + get_matchValue@25() cil managed + { + + .maxstack 8 + IL_0000: ldsfld valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 ''.$assembly$fsx::matchValue@25 + IL_0005: ret + } + + .method public specialname static class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1> + get_todo2() cil managed + { + + .maxstack 8 + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1> ''.$assembly$fsx::todo2@35 + IL_0005: ret + } + + .method assembly specialname static valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 + 'get_matchValue@44-1'() cil managed + { + + .maxstack 8 + IL_0000: ldsfld valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 ''.$assembly$fsx::'matchValue@44-1' + IL_0005: ret + } + + .property class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1> + todo1() + { + .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.Control.FSharpAsync`1> assembly::get_todo1() + } + .property valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 + matchValue@25() + { + .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 valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 assembly::get_matchValue@25() + } + .property class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1> + todo2() + { + .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.Control.FSharpAsync`1> assembly::get_todo2() + } + .property valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 + 'matchValue@44-1'() + { + .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 valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 assembly::'get_matchValue@44-1'() + } +} + +.class private abstract auto ansi sealed ''.$assembly$fsx + extends [runtime]System.Object +{ + .field static assembly initonly class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1> todo1@16 + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field static assembly initonly valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 matchValue@25 + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field static assembly initonly class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1> todo2@35 + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field static assembly initonly valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 'matchValue@44-1' + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 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 5 + IL_0000: ldc.i4.0 + IL_0001: stsfld int32 assembly/Foo::x + IL_0006: ldc.i4.1 + IL_0007: volatile. + IL_0009: stsfld int32 assembly/Foo::init@4 + IL_000e: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_DefaultAsyncBuilder() + IL_0013: ldsfld class assembly/todo1@18 assembly/todo1@18::@_instance + IL_0018: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Delay>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_001d: stsfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1> ''.$assembly$fsx::todo1@16 + IL_0022: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1> assembly::get_todo1() + IL_0027: ldnull + IL_0028: ldnull + IL_0029: call !!0 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync::RunSynchronously>(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1) + IL_002e: stsfld valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 ''.$assembly$fsx::matchValue@25 + IL_0033: ldsflda valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 ''.$assembly$fsx::matchValue@25 + IL_0038: call instance int32 valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2::get_Tag() + IL_003d: ldc.i4.1 + IL_003e: bne.un.s IL_0042 + + IL_0040: br.s IL_0044 + + IL_0042: br.s IL_0053 + + IL_0044: ldsflda valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 ''.$assembly$fsx::matchValue@25 + IL_0049: call instance !1 valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2::get_ErrorValue() + IL_004e: call void [runtime]System.Environment::Exit(int32) + IL_0053: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_DefaultAsyncBuilder() + IL_0058: ldsfld class assembly/todo2@37 assembly/todo2@37::@_instance + IL_005d: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Delay>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0062: stsfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1> ''.$assembly$fsx::todo2@35 + IL_0067: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1> assembly::get_todo2() + IL_006c: ldnull + IL_006d: ldnull + IL_006e: call !!0 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync::RunSynchronously>(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1) + IL_0073: stsfld valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 ''.$assembly$fsx::'matchValue@44-1' + IL_0078: ldsflda valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 ''.$assembly$fsx::'matchValue@44-1' + IL_007d: call instance int32 valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2::get_Tag() + IL_0082: ldc.i4.1 + IL_0083: bne.un.s IL_0087 + + IL_0085: br.s IL_0089 + + IL_0087: br.s IL_0098 + + IL_0089: ldsflda valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2 ''.$assembly$fsx::'matchValue@44-1' + IL_008e: call instance !1 valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpResult`2::get_ErrorValue() + IL_0093: call void [runtime]System.Environment::Exit(int32) + IL_0098: ret + } + +} + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithLastOpenedTypeExtensions.fsx.support.added.later.err.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithLastOpenedTypeExtensions.fsx.support.added.later.err.bsl new file mode 100644 index 00000000000..8ba0a6f2ffb --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithLastOpenedTypeExtensions.fsx.support.added.later.err.bsl @@ -0,0 +1,2 @@ +ShadowWithLastOpenedTypeExtensions.fsx (18,9)-(18,14) typecheck error This value is not a function and cannot be applied. +ShadowWithLastOpenedTypeExtensions.fsx (37,9)-(37,14) typecheck error This value is not a function and cannot be applied. \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithLastOpenedTypeExtensions.fsx.support.added.later.il.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithLastOpenedTypeExtensions.fsx.support.added.later.il.bsl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithTypeExtension.fsx b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithTypeExtension.fsx new file mode 100644 index 00000000000..41c5d727327 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithTypeExtension.fsx @@ -0,0 +1,19 @@ +open System.Runtime.CompilerServices + +type Foo() = + member val X : int = 0 with get,set + +module Exts = + type Foo with + member f.X (i: int) = f.X <- i; f + +open Exts +let f = Foo() +f.X(1) +if f.X <> 1 then + System.Environment.Exit 1 + +f.X(1).X(2).X(3) + +if f.X <> 3 then + System.Environment.Exit 2 diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithTypeExtension.fsx.err.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithTypeExtension.fsx.err.bsl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithTypeExtension.fsx.il.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithTypeExtension.fsx.il.bsl new file mode 100644 index 00000000000..b9883181ec6 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithTypeExtension.fsx.il.bsl @@ -0,0 +1,227 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.mresource public FSharpSignatureData.assembly +{ + + +} +.mresource public FSharpOptimizationData.assembly +{ + + +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + 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 Foo + extends [runtime]System.Object + { + .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 ) + .field assembly int32 X@ + .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: ldarg.0 + IL_0009: ldc.i4.0 + IL_000a: stfld int32 assembly/Foo::X@ + IL_000f: ret + } + + .method public hidebysig specialname + instance int32 get_X() 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 assembly/Foo::X@ + IL_0006: ret + } + + .method public hidebysig specialname + instance void set_X(int32 v) 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: ldarg.1 + IL_0002: stfld int32 assembly/Foo::X@ + IL_0007: ret + } + + .property instance int32 X() + { + .set instance void assembly/Foo::set_X(int32) + .get instance int32 assembly/Foo::get_X() + } + } + + .class abstract auto ansi sealed nested public Exts + 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 ) + .method public static class assembly/Foo + Foo.X(class assembly/Foo f, + int32 i) 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 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 assembly/Foo::X@ + IL_0007: ldarg.0 + IL_0008: ret + } + + } + + .method public specialname static class assembly/Foo + get_f() cil managed + { + + .maxstack 8 + IL_0000: ldsfld class assembly/Foo ''.$assembly$fsx::f@11 + IL_0005: ret + } + + .method assembly specialname static class assembly/Foo + get_f@8() cil managed + { + + .maxstack 8 + IL_0000: ldsfld class assembly/Foo ''.$assembly$fsx::'f@8-1' + IL_0005: ret + } + + .method assembly specialname static class assembly/Foo + 'get_f@8-1'() cil managed + { + + .maxstack 8 + IL_0000: ldsfld class assembly/Foo ''.$assembly$fsx::'f@8-2' + IL_0005: ret + } + + .property class assembly/Foo + f() + { + .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 assembly/Foo assembly::get_f() + } + .property class assembly/Foo + f@8() + { + .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 assembly/Foo assembly::get_f@8() + } + .property class assembly/Foo + 'f@8-1'() + { + .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 assembly/Foo assembly::'get_f@8-1'() + } +} + +.class private abstract auto ansi sealed ''.$assembly$fsx + extends [runtime]System.Object +{ + .field static assembly initonly class assembly/Foo f@11 + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field static assembly initonly class assembly/Foo 'f@8-1' + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field static assembly initonly class assembly/Foo 'f@8-2' + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 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 4 + IL_0000: newobj instance void assembly/Foo::.ctor() + IL_0005: stsfld class assembly/Foo ''.$assembly$fsx::f@11 + IL_000a: call class assembly/Foo assembly::get_f() + IL_000f: ldc.i4.1 + IL_0010: stfld int32 assembly/Foo::X@ + IL_0015: call class assembly/Foo assembly::get_f() + IL_001a: pop + IL_001b: call class assembly/Foo assembly::get_f() + IL_0020: ldfld int32 assembly/Foo::X@ + IL_0025: ldc.i4.1 + IL_0026: beq.s IL_0030 + + IL_0028: ldc.i4.1 + IL_0029: call void [runtime]System.Environment::Exit(int32) + IL_002e: br.s IL_0030 + + IL_0030: call class assembly/Foo assembly::get_f() + IL_0035: ldc.i4.1 + IL_0036: stfld int32 assembly/Foo::X@ + IL_003b: call class assembly/Foo assembly::get_f() + IL_0040: stsfld class assembly/Foo ''.$assembly$fsx::'f@8-2' + IL_0045: call class assembly/Foo assembly::'get_f@8-1'() + IL_004a: ldc.i4.2 + IL_004b: stfld int32 assembly/Foo::X@ + IL_0050: call class assembly/Foo assembly::'get_f@8-1'() + IL_0055: stsfld class assembly/Foo ''.$assembly$fsx::'f@8-1' + IL_005a: call class assembly/Foo assembly::get_f@8() + IL_005f: ldc.i4.3 + IL_0060: stfld int32 assembly/Foo::X@ + IL_0065: call class assembly/Foo assembly::get_f@8() + IL_006a: pop + IL_006b: call class assembly/Foo assembly::get_f() + IL_0070: ldfld int32 assembly/Foo::X@ + IL_0075: ldc.i4.3 + IL_0076: beq.s IL_0080 + + IL_0078: ldc.i4.2 + IL_0079: call void [runtime]System.Environment::Exit(int32) + IL_007e: br.s IL_0080 + + IL_0080: ret + } + +} + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithTypeExtension.fsx.support.added.later.err.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithTypeExtension.fsx.support.added.later.err.bsl new file mode 100644 index 00000000000..ea6a175c648 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithTypeExtension.fsx.support.added.later.err.bsl @@ -0,0 +1,2 @@ +ShadowWithTypeExtension.fsx (12,1)-(12,4) typecheck error This value is not a function and cannot be applied. +ShadowWithTypeExtension.fsx (16,1)-(16,4) typecheck error This value is not a function and cannot be applied. \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithTypeExtension.fsx.support.added.later.il.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowWithTypeExtension.fsx.support.added.later.il.bsl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowingAndStillOkWithChainedCalls.fsx b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowingAndStillOkWithChainedCalls.fsx new file mode 100644 index 00000000000..d48bd949440 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowingAndStillOkWithChainedCalls.fsx @@ -0,0 +1,25 @@ +#nowarn "52" +open System.Runtime.CompilerServices + +type Foo() = + member val X : int = 0 with get,set + +[] +type FooExt = + [] + static member X (f: Foo, i: int) = f.X <- i; f + [] + static member X (f: Foo, i: string) = + // chained call on the property are still ok + f.X <- f.X.ToString().Length + i.Length; f + + +let f = Foo() +f.X(1) +if f.X <> 1 then + System.Environment.Exit 1 + +f.X(1).X(2).X(3) + +if f.X <> 3 then + System.Environment.Exit 2 diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowingAndStillOkWithChainedCalls.fsx.err.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowingAndStillOkWithChainedCalls.fsx.err.bsl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowingAndStillOkWithChainedCalls.fsx.il.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowingAndStillOkWithChainedCalls.fsx.il.bsl new file mode 100644 index 00000000000..b7969f50320 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowingAndStillOkWithChainedCalls.fsx.il.bsl @@ -0,0 +1,247 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.mresource public FSharpSignatureData.assembly +{ + + +} +.mresource public FSharpOptimizationData.assembly +{ + + +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + 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 Foo + extends [runtime]System.Object + { + .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 ) + .field assembly int32 X@ + .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: ldarg.0 + IL_0009: ldc.i4.0 + IL_000a: stfld int32 assembly/Foo::X@ + IL_000f: ret + } + + .method public hidebysig specialname + instance int32 get_X() 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 assembly/Foo::X@ + IL_0006: ret + } + + .method public hidebysig specialname + instance void set_X(int32 v) 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: ldarg.1 + IL_0002: stfld int32 assembly/Foo::X@ + IL_0007: ret + } + + .property instance int32 X() + { + .set instance void assembly/Foo::set_X(int32) + .get instance int32 assembly/Foo::get_X() + } + } + + .class auto ansi serializable nested public FooExt + extends [runtime]System.Object + { + .custom instance void [runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 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 ) + .method public static class assembly/Foo + X(class assembly/Foo f, + int32 i) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 assembly/Foo::X@ + IL_0007: ldarg.0 + IL_0008: ret + } + + .method public static class assembly/Foo + X(class assembly/Foo f, + string i) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 5 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldarg.0 + IL_0002: ldfld int32 assembly/Foo::X@ + IL_0007: stloc.0 + IL_0008: ldloca.s V_0 + IL_000a: constrained. [runtime]System.Int32 + IL_0010: callvirt instance string [runtime]System.Object::ToString() + IL_0015: callvirt instance int32 [runtime]System.String::get_Length() + IL_001a: ldarg.1 + IL_001b: callvirt instance int32 [runtime]System.String::get_Length() + IL_0020: add + IL_0021: stfld int32 assembly/Foo::X@ + IL_0026: ldarg.0 + IL_0027: ret + } + + } + + .method public specialname static class assembly/Foo + get_f() cil managed + { + + .maxstack 8 + IL_0000: ldsfld class assembly/Foo ''.$assembly$fsx::f@17 + IL_0005: ret + } + + .method assembly specialname static class assembly/Foo + get_f@10() cil managed + { + + .maxstack 8 + IL_0000: ldsfld class assembly/Foo ''.$assembly$fsx::'f@10-1' + IL_0005: ret + } + + .method assembly specialname static class assembly/Foo + 'get_f@10-1'() cil managed + { + + .maxstack 8 + IL_0000: ldsfld class assembly/Foo ''.$assembly$fsx::'f@10-2' + IL_0005: ret + } + + .property class assembly/Foo + f() + { + .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 assembly/Foo assembly::get_f() + } + .property class assembly/Foo + f@10() + { + .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 assembly/Foo assembly::get_f@10() + } + .property class assembly/Foo + 'f@10-1'() + { + .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 assembly/Foo assembly::'get_f@10-1'() + } +} + +.class private abstract auto ansi sealed ''.$assembly$fsx + extends [runtime]System.Object +{ + .field static assembly initonly class assembly/Foo f@17 + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field static assembly initonly class assembly/Foo 'f@10-1' + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field static assembly initonly class assembly/Foo 'f@10-2' + .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 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 4 + IL_0000: newobj instance void assembly/Foo::.ctor() + IL_0005: stsfld class assembly/Foo ''.$assembly$fsx::f@17 + IL_000a: call class assembly/Foo assembly::get_f() + IL_000f: ldc.i4.1 + IL_0010: stfld int32 assembly/Foo::X@ + IL_0015: call class assembly/Foo assembly::get_f() + IL_001a: pop + IL_001b: call class assembly/Foo assembly::get_f() + IL_0020: ldfld int32 assembly/Foo::X@ + IL_0025: ldc.i4.1 + IL_0026: beq.s IL_0030 + + IL_0028: ldc.i4.1 + IL_0029: call void [runtime]System.Environment::Exit(int32) + IL_002e: br.s IL_0030 + + IL_0030: call class assembly/Foo assembly::get_f() + IL_0035: ldc.i4.1 + IL_0036: stfld int32 assembly/Foo::X@ + IL_003b: call class assembly/Foo assembly::get_f() + IL_0040: stsfld class assembly/Foo ''.$assembly$fsx::'f@10-2' + IL_0045: call class assembly/Foo assembly::'get_f@10-1'() + IL_004a: ldc.i4.2 + IL_004b: stfld int32 assembly/Foo::X@ + IL_0050: call class assembly/Foo assembly::'get_f@10-1'() + IL_0055: stsfld class assembly/Foo ''.$assembly$fsx::'f@10-1' + IL_005a: call class assembly/Foo assembly::get_f@10() + IL_005f: ldc.i4.3 + IL_0060: stfld int32 assembly/Foo::X@ + IL_0065: call class assembly/Foo assembly::get_f@10() + IL_006a: pop + IL_006b: call class assembly/Foo assembly::get_f() + IL_0070: ldfld int32 assembly/Foo::X@ + IL_0075: ldc.i4.3 + IL_0076: beq.s IL_0080 + + IL_0078: ldc.i4.2 + IL_0079: call void [runtime]System.Environment::Exit(int32) + IL_007e: br.s IL_0080 + + IL_0080: ret + } + +} diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowingAndStillOkWithChainedCalls.fsx.support.added.later.err.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowingAndStillOkWithChainedCalls.fsx.support.added.later.err.bsl new file mode 100644 index 00000000000..9885a2f82bb --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowingAndStillOkWithChainedCalls.fsx.support.added.later.err.bsl @@ -0,0 +1,2 @@ +ShadowingAndStillOkWithChainedCalls.fsx (18,1)-(18,4) typecheck error This value is not a function and cannot be applied. +ShadowingAndStillOkWithChainedCalls.fsx (22,1)-(22,4) typecheck error This value is not a function and cannot be applied. \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowingAndStillOkWithChainedCalls.fsx.support.added.later.il.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowing/ShadowingAndStillOkWithChainedCalls.fsx.support.added.later.il.bsl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowingTests.fs b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowingTests.fs new file mode 100644 index 00000000000..fe178ad1975 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/TypeExtensions/PropertyShadowingTests.fs @@ -0,0 +1,86 @@ +module FSharp.Compiler.ComponentTests.TypeChecks.TypeExtensions.PropertyShadowingTests +open Xunit +open FSharp.Test +open FSharp.Test.Compiler + +let [] folder = __SOURCE_DIRECTORY__ + "/PropertyShadowing" + +[] +let ``can hide property`` compilation = + compilation + |> asFsx + |> withOptions ["--langversion:preview"] + |> verifyBaselines + |> compileAndRun + |> shouldSucceed + +[] +let ``cannot hide property v7.0 support added later`` compilation = + compilation + |> asFsx + |> withOptions ["--langversion:7.0"] + |> verifyBaselines + |> compile + |> shouldFail + +[] +let ``cannot hide property`` compilation = + compilation + |> asFsx + |> withOptions ["--langversion:preview"] + |> verifyBaselines + |> compile + |> shouldFail + + +[] +let ``cannot hide property v7.0`` compilation = + compilation + |> asFsx + |> withOptions ["--langversion:7.0"] + |> verifyBaselines + |> compile + |> shouldFail diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs index aabefaf4b35..52c9b033119 100644 --- a/tests/FSharp.Test.Utilities/Compiler.fs +++ b/tests/FSharp.Test.Utilities/Compiler.fs @@ -945,7 +945,14 @@ module rec Compiler = match s.OutputPath with | None -> failwith "Compilation didn't produce any output. Unable to run. (Did you forget to set output type to Exe?)" | Some p -> - let (exitCode, output, errors) = CompilerAssert.ExecuteAndReturnResult (p, s.Dependencies, false) + let isFsx = + match s.Compilation with + | FS fs -> + match fs.Source with + | SourceCodeFileKind.Fsx _ -> true + | _ -> false + | _ -> false + let exitCode, output, errors = CompilerAssert.ExecuteAndReturnResult (p, isFsx, s.Dependencies, false) printfn "---------output-------\n%s\n-------" output printfn "---------errors-------\n%s\n-------" errors let executionResult = { s with Output = Some (ExecutionOutput { ExitCode = exitCode; StdOut = output; StdErr = errors }) } @@ -1075,10 +1082,37 @@ module rec Compiler = | _ -> failwith "FSI running only supports F#." + let convenienceBaselineInstructions baseline expected actual = + $"""to update baseline: +$ cp {baseline.FilePath} {baseline.BslSource} +to compare baseline: +$ code --diff {baseline.FilePath} {baseline.BslSource} +Expected: +{expected} +Actual: +{actual}""" + let updateBaseline () = + snd (Int32.TryParse(Environment.GetEnvironmentVariable("TEST_UPDATE_BSL"))) <> 0 + let updateBaseLineIfEnvironmentSaysSo baseline = + if updateBaseline () then + if FileSystem.FileExistsShim baseline.FilePath then + FileSystem.CopyShim(baseline.FilePath, baseline.BslSource, true) + + let assertBaseline expected actual baseline fOnFail = + if expected <> actual then + fOnFail() + updateBaseLineIfEnvironmentSaysSo baseline + createBaselineErrors baseline actual + Assert.AreEqual(expected, actual, convenienceBaselineInstructions baseline expected actual) + elif FileSystem.FileExistsShim baseline.FilePath then + FileSystem.FileDeleteShim baseline.FilePath + + let private createBaselineErrors (baselineFile: BaselineFile) (actualErrors: string) : unit = - FileSystem.OpenFileForWriteShim(baselineFile.FilePath + ".err").Write(actualErrors) + printfn $"creating baseline error file for convenience: {baselineFile.FilePath}, expected: {baselineFile.BslSource}" + FileSystem.OpenFileForWriteShim(baselineFile.FilePath).Write(actualErrors) - let private verifyFSBaseline (fs) : unit = + let private verifyFSBaseline fs : unit = match fs.Baseline with | None -> failwith "Baseline was not provided." | Some bsl -> @@ -1089,16 +1123,21 @@ module rec Compiler = let typecheckDiagnostics = fs |> typecheckFSharpSourceAndReturnErrors - let errorsActual = (typecheckDiagnostics |> Array.map (sprintf "%A") |> String.concat "\n").Replace("\r\n","\n") + let errorsActual = + (typecheckDiagnostics + |> Array.map (sprintf "%A") + |> String.concat "\n" + ).Replace("\r\n","\n") if errorsExpectedBaseLine <> errorsActual then fs.CreateOutputDirectory() createBaselineErrors bsl.FSBaseline errorsActual + updateBaseLineIfEnvironmentSaysSo bsl.FSBaseline + let errorMsg = (convenienceBaselineInstructions bsl.FSBaseline errorsExpectedBaseLine errorsActual) + Assert.AreEqual(errorsExpectedBaseLine, errorsActual, errorMsg) elif FileSystem.FileExistsShim(bsl.FSBaseline.FilePath) then FileSystem.FileDeleteShim(bsl.FSBaseline.FilePath) - Assert.AreEqual(errorsExpectedBaseLine, errorsActual, $"\nExpected:\n{errorsExpectedBaseLine}\nActual:\n{errorsActual}") - /// Check the typechecker output against the baseline, if invoked with empty baseline, will expect no error/warnings output. let verifyBaseline (cUnit: CompilationUnit) : CompilationUnit = match cUnit with @@ -1121,37 +1160,42 @@ module rec Compiler = let verifyILBinary (il: string list) (dll: string)= ILChecker.checkIL dll il - let private verifyFSILBaseline (baseline: Baseline option) (result: CompilationOutput) : unit = - match baseline with - | None -> failwith "Baseline was not provided." - | Some bsl -> - match result.OutputPath with - | None -> failwith "Operation didn't produce any output!" - | Some p -> - let expectedIL = - match bsl.ILBaseline.Content with - | Some b -> b - | None -> String.Empty - let (success, errorMsg, actualIL) = ILChecker.verifyILAndReturnActual p expectedIL - - if not success then - // Failed try update baselines if required - // If we are here then the il file has been produced we can write it back to the baseline location - // if the environment variable TEST_UPDATE_BSL has been set - if snd (Int32.TryParse(Environment.GetEnvironmentVariable("TEST_UPDATE_BSL"))) <> 0 then - match baseline with - | Some baseline -> System.IO.File.Copy(baseline.ILBaseline.FilePath, baseline.ILBaseline.BslSource, true) - | None -> () - - createBaselineErrors bsl.ILBaseline actualIL - Assert.Fail(errorMsg) + let private verifyFSILBaseline (baseline: Baseline) (result: CompilationOutput) : unit = + match result.OutputPath with + | None -> failwith "Operation didn't produce any output!" + | Some p -> + let expectedIL = + match baseline.ILBaseline.Content with + | Some b -> b + | None -> String.Empty + let success, errorMsg, actualIL = ILChecker.verifyILAndReturnActual p expectedIL + + if not success then + // Failed try update baselines if required + // If we are here then the il file has been produced we can write it back to the baseline location + // if the environment variable TEST_UPDATE_BSL has been set + updateBaseLineIfEnvironmentSaysSo baseline.ILBaseline + createBaselineErrors baseline.ILBaseline actualIL + let errorMsg = (convenienceBaselineInstructions baseline.ILBaseline expectedIL actualIL) + errorMsg + Assert.Fail(errorMsg) let verifyILBaseline (cUnit: CompilationUnit) : CompilationUnit = match cUnit with | FS fs -> - match fs |> compileFSharp with - | CompilationResult.Failure a -> failwith $"Build failure: {a}" - | CompilationResult.Success s -> verifyFSILBaseline fs.Baseline s + match fs |> compileFSharp, fs.Baseline with + | CompilationResult.Failure a, Some baseline -> + match baseline.ILBaseline.Content with + | Some "" -> () + | Some il -> + failwith $"Build failure: {a} while expected il\n{il}" + | None -> + if not (FileSystem.FileExistsShim baseline.ILBaseline.BslSource) && updateBaseline () then + File.WriteAllText(baseline.ILBaseline.BslSource, "") + else + failwith $"Build failure empty baseline at {baseline.ILBaseline.BslSource}: {a}" + | CompilationResult.Success s, Some baseline -> verifyFSILBaseline baseline s + | _, None -> + failwithf $"Baseline was not provided." | _ -> failwith "Baseline tests are only supported for F#." cUnit diff --git a/tests/FSharp.Test.Utilities/CompilerAssert.fs b/tests/FSharp.Test.Utilities/CompilerAssert.fs index 4d13168c4ef..1dcbcb846ff 100644 --- a/tests/FSharp.Test.Utilities/CompilerAssert.fs +++ b/tests/FSharp.Test.Utilities/CompilerAssert.fs @@ -261,18 +261,27 @@ module rec CompilerAssertHelpers = let checker = FSharpChecker.Create(suggestNamesForErrors=true) // Unlike C# whose entrypoint is always string[] F# can make an entrypoint with 0 args, or with an array of string[] - let mkDefaultArgs (entryPoint:MethodInfo) : obj[] = [| + let mkDefaultArgs (entryPoint:MethodBase) : obj[] = [| if entryPoint.GetParameters().Length = 1 then yield Array.empty |] - let executeAssemblyEntryPoint (asm: Assembly) = - let entryPoint = asm.EntryPoint + let executeAssemblyEntryPoint (asm: Assembly) isFsx = + let entryPoint : MethodBase = asm.EntryPoint + let entryPoint = + if isNull entryPoint && isFsx then + // lookup the last static constructor + // of the assembly types, which should match + // the equivalent of a .fsx entry point + let moduleInitType = asm.GetTypes() |> Array.last + moduleInitType.GetConstructors(BindingFlags.Static ||| BindingFlags.NonPublic).[0] :> MethodBase + else + entryPoint let args = mkDefaultArgs entryPoint captureConsoleOutputs (fun () -> entryPoint.Invoke(Unchecked.defaultof, args) |> ignore) #if NETCOREAPP - let executeBuiltApp assembly deps = + let executeBuiltApp assembly deps isFsx = let ctxt = AssemblyLoadContext("ContextName", true) try ctxt.add_Resolving(fun ctxt name -> @@ -281,14 +290,14 @@ module rec CompilerAssertHelpers = |> Option.map ctxt.LoadFromAssemblyPath |> Option.defaultValue null) - ctxt.LoadFromAssemblyPath assembly |> executeAssemblyEntryPoint + executeAssemblyEntryPoint (ctxt.LoadFromAssemblyPath assembly) isFsx finally ctxt.Unload() #else type Worker () = inherit MarshalByRefObject() - member x.ExecuteTestCase assemblyPath (deps: string[]) = + member x.ExecuteTestCase assemblyPath (deps: string[]) isFsx = AppDomain.CurrentDomain.add_AssemblyResolve(ResolveEventHandler(fun _ args -> deps |> Array.tryFind (fun (x: string) -> Path.GetFileNameWithoutExtension x = AssemblyName(args.Name).Name) @@ -296,7 +305,8 @@ module rec CompilerAssertHelpers = |> Option.map Assembly.LoadFile |> Option.defaultValue null)) - Assembly.LoadFrom assemblyPath |> executeAssemblyEntryPoint + let assembly = Assembly.LoadFrom assemblyPath + executeAssemblyEntryPoint assembly isFsx let adSetup = let setup = new System.AppDomainSetup () @@ -577,8 +587,8 @@ module rec CompilerAssertHelpers = succeeded, stdout.ToString(), stderr.ToString(), exn - let executeBuiltAppAndReturnResult (outputFilePath: string) (deps: string list) : (int * string * string) = - let succeeded, stdout, stderr, _ = executeBuiltApp outputFilePath deps + let executeBuiltAppAndReturnResult (outputFilePath: string) (deps: string list) isFsx : (int * string * string) = + let succeeded, stdout, stderr, _ = executeBuiltApp outputFilePath deps isFsx let exitCode = if succeeded then 0 else -1 exitCode, stdout, stderr @@ -620,7 +630,7 @@ type CompilerAssert private () = if errors.Length > 0 then Assert.Fail (sprintf "Compile had warnings and/or errors: %A" errors) - executeBuiltApp outputExe [] |> ignore + executeBuiltApp outputExe [] false |> ignore ) static let compileLibraryAndVerifyILWithOptions options (source: SourceCodeFileKind) (f: ILVerifier -> unit) = @@ -681,10 +691,10 @@ Updated automatically, please check diffs in your pull request, changes must be static member CompileRaw(cmpl: Compilation, ?ignoreWarnings) = returnCompilation cmpl (defaultArg ignoreWarnings false) - static member ExecuteAndReturnResult (outputFilePath: string, deps: string list, newProcess: bool) = + static member ExecuteAndReturnResult (outputFilePath: string, isFsx: bool, deps: string list, newProcess: bool) = // If we execute in-process (true by default), then the only way of getting STDOUT is to redirect it to SB, and STDERR is from catching an exception. if not newProcess then - executeBuiltAppAndReturnResult outputFilePath deps + executeBuiltAppAndReturnResult outputFilePath deps isFsx else executeBuiltAppNewProcessAndReturnResult outputFilePath @@ -710,7 +720,7 @@ Updated automatically, please check diffs in your pull request, changes must be Assert.Fail errors onOutput output else - let _succeeded, _stdout, _stderr, exn = executeBuiltApp outputFilePath deps + let _succeeded, _stdout, _stderr, exn = executeBuiltApp outputFilePath deps false exn |> Option.iter raise) static member ExecutionHasOutput(cmpl: Compilation, expectedOutput: string) = diff --git a/tests/FSharp.Test.Utilities/DirectoryAttribute.fs b/tests/FSharp.Test.Utilities/DirectoryAttribute.fs index fbb40b70b17..5365abdbdb5 100644 --- a/tests/FSharp.Test.Utilities/DirectoryAttribute.fs +++ b/tests/FSharp.Test.Utilities/DirectoryAttribute.fs @@ -35,7 +35,8 @@ type DirectoryAttribute(dir: string) = // if there are multiple files being processed, add extra directory for each test to avoid reference file conflicts let extraDirectory = if multipleFiles then - filename.Substring(0, filename.Length - 3) // remove .fs + let extension = Path.GetExtension(filename) + filename.Substring(0, filename.Length - extension.Length) // remove .fs/the extension |> normalizeName else "" let outputDirectory = outputDirectory methodName extraDirectory @@ -44,7 +45,7 @@ type DirectoryAttribute(dir: string) = | Some path -> path.FullName | None -> failwith "Can't set the output directory" let sourceFilePath = normalizePathSeparator (path ++ filename) - let fsBslFilePath = sourceFilePath + ".err.bsl" + let fsBslFilePath = sourceFilePath + baselineSuffix + ".err.bsl" let ilBslFilePath = let ilBslPaths = [| #if DEBUG @@ -78,7 +79,7 @@ type DirectoryAttribute(dir: string) = | None -> sourceFilePath + baselineSuffix + ".il.bsl" let fsOutFilePath = normalizePathSeparator (Path.ChangeExtension(outputDirectoryPath ++ filename, ".err")) - let ilOutFilePath = normalizePathSeparator ( Path.ChangeExtension(outputDirectoryPath ++ filename, ".il")) + let ilOutFilePath = normalizePathSeparator (Path.ChangeExtension(outputDirectoryPath ++ filename, ".il.err")) let fsBslSource = readFileOrDefault fsBslFilePath let ilBslSource = readFileOrDefault ilBslFilePath @@ -88,8 +89,8 @@ type DirectoryAttribute(dir: string) = Some { SourceFilename = Some sourceFilePath - FSBaseline = { FilePath = fsOutFilePath; BslSource=fsBslFilePath; Content = fsBslSource } - ILBaseline = { FilePath = ilOutFilePath; BslSource=ilBslFilePath ; Content = ilBslSource } + FSBaseline = { FilePath = fsOutFilePath; BslSource = fsBslFilePath; Content = fsBslSource } + ILBaseline = { FilePath = ilOutFilePath; BslSource = ilBslFilePath; Content = ilBslSource } } Options = [] OutputType = Library @@ -98,7 +99,7 @@ type DirectoryAttribute(dir: string) = References = [] OutputDirectory = outputDirectory TargetFramework = TargetFramework.Current - StaticLink = false + StaticLink = false } |> FS new([] dirs: string[]) = DirectoryAttribute(Path.Combine(dirs) : string) diff --git a/tests/FSharp.Test.Utilities/ILChecker.fs b/tests/FSharp.Test.Utilities/ILChecker.fs index 58ba5e1b7fe..8164f876a52 100644 --- a/tests/FSharp.Test.Utilities/ILChecker.fs +++ b/tests/FSharp.Test.Utilities/ILChecker.fs @@ -104,48 +104,46 @@ module ILChecker = |> Array.skipWhile(String.IsNullOrWhiteSpace) |> Array.rev - expectedIL - |> List.map (fun (ilCode: string) -> ilCode.Trim()) - |> List.iter (fun (ilCode: string) -> - let expectedLines = ilCode |> normalizeILText (Some assemblyName) |> prepareLines - - if expectedLines.Length = 0 then - errorMsgOpt <- Some("ExpectedLines length invalid: 0") - else - let startIndex = - let index = actualIL.IndexOf(expectedLines[0].Trim()) - if index > 0 then - index - else - 0 - let actualLines = actualIL.Substring(startIndex) |> prepareLines - - let errors = ResizeArray() - if actualLines.Length < expectedLines.Length then - let msg = $"\nExpected at least %d{expectedLines.Length} lines but found only %d{actualLines.Length}\n" - errorMsgOpt <- Some(msg + "\nExpected:\n" + ilCode + "\n") + match expectedIL with + | [] -> errorMsgOpt <- Some "No Expected IL" + | expectedIL -> + expectedIL + |> List.map (fun (ilCode: string) -> ilCode.Trim()) + |> List.iter (fun (ilCode: string) -> + let expectedLines = ilCode |> normalizeILText (Some assemblyName) |> prepareLines + + if expectedLines.Length = 0 then + errorMsgOpt <- Some("ExpectedLines length invalid: 0") else - for i = 0 to expectedLines.Length - 1 do - let expected = expectedLines[i].Trim() - let actual = actualLines[i].Trim() - if expected <> actual then - errors.Add $"\n==\nName: '%s{actualLines[0]}'\n\nExpected:\t %s{expected}\nActual:\t\t %s{actual}\n==" - - if errors.Count > 0 then - let msg = String.concat "\n" errors + "\n\n\Expected:\n" + ilCode + "\n" - errorMsgOpt <- Some(msg + "\n\n\nActual:\n" + String.Join("\n", actualLines, 0, expectedLines.Length)) - ) - - if expectedIL.Length = 0 then - errorMsgOpt <- Some ("No Expected IL") + let startIndex = + let index = actualIL.IndexOf(expectedLines[0].Trim()) + if index > 0 then + index + else + 0 + let actualLines = actualIL.Substring(startIndex) |> prepareLines + + let errors = ResizeArray() + if actualLines.Length < expectedLines.Length then + let msg = $"\nExpected at least %d{expectedLines.Length} lines but found only %d{actualLines.Length}\n" + errorMsgOpt <- Some(msg + "\nExpected:\n" + ilCode + "\n") + else + for i = 0 to expectedLines.Length - 1 do + let expected = expectedLines[i].Trim() + let actual = actualLines[i].Trim() + if expected <> actual then + errors.Add $"\n==\nName: '%s{actualLines[0]}'\n\nExpected:\t %s{expected}\nActual:\t\t %s{actual}\n==" - match errorMsgOpt with - | Some(msg) -> errorMsgOpt <- Some(msg + "\n\n\nEntire actual:\n" + actualIL) - | _ -> () + if errors.Count > 0 then + let msg = String.concat "\n" errors + "\n\n\Expected:\n" + ilCode + "\n" + errorMsgOpt <- Some(msg + "\n\n\nActual:\n" + String.Join("\n", actualLines, 0, expectedLines.Length)) + ) match errorMsgOpt with - | Some(errorMsg) -> (false, errorMsg, actualIL) - | _ -> (true, String.Empty, String.Empty) + | Some msg -> + let msg = msg + "\n\n\nEntire actual:\n" + actualIL + (false, msg, actualIL) + | _ -> (true, String.Empty, actualIL) let private checkILPrim ildasmArgs dllFilePath = let actualIL = generateIL dllFilePath ildasmArgs