提交 a71bbdc1 编写于 作者: D Don Syme 提交者: latkin

Let provided types be non-nullable

commit edc4d9bf4a3a6ac017ccf85c1e765374cc63b529
Author: latkin <latkin@microsoft.com>
Date:   Mon Dec 1 13:32:55 2014 -0800

    Updating surface area tests

commit 9380ad5e64cfead4af96558a3bbd9fa121d10860
Author: latkin <latkin@microsoft.com>
Date:   Mon Dec 1 11:27:14 2014 -0800

    Fixups to correct build issues

commit b280e160d717966e0b3128e0e608988ec31e0af3
Merge: 48f3fd6c 7deeeca
Author: latkin <latkin@microsoft.com>
Date:   Mon Dec 1 10:29:45 2014 -0800

    Merge branch 'feature1' of https://git01.codeplex.com/forks/dsyme/cleanup into nonullprovtypes

commit 7deeeca8ef04d2d776e38f33721ef24f3197255c
Author: Don Syme <dsyme@microsoft.com>
Date:   Tue Jun 24 19:53:03 2014 +0100

    Let provided types be non-nullable
上级 48f3fd6c
......@@ -741,12 +741,15 @@ Microsoft.FSharp.Core.AbstractClassAttribute: Void .ctor()
Microsoft.FSharp.Core.AllowNullLiteralAttribute: Boolean Equals(System.Object)
Microsoft.FSharp.Core.AllowNullLiteralAttribute: Boolean IsDefaultAttribute()
Microsoft.FSharp.Core.AllowNullLiteralAttribute: Boolean Match(System.Object)
Microsoft.FSharp.Core.AllowNullLiteralAttribute: Boolean Value
Microsoft.FSharp.Core.AllowNullLiteralAttribute: Boolean get_Value()
Microsoft.FSharp.Core.AllowNullLiteralAttribute: Int32 GetHashCode()
Microsoft.FSharp.Core.AllowNullLiteralAttribute: System.Object TypeId
Microsoft.FSharp.Core.AllowNullLiteralAttribute: System.Object get_TypeId()
Microsoft.FSharp.Core.AllowNullLiteralAttribute: System.String ToString()
Microsoft.FSharp.Core.AllowNullLiteralAttribute: System.Type GetType()
Microsoft.FSharp.Core.AllowNullLiteralAttribute: Void .ctor()
Microsoft.FSharp.Core.AllowNullLiteralAttribute: Void .ctor(Boolean)
Microsoft.FSharp.Core.AutoOpenAttribute: Boolean Equals(System.Object)
Microsoft.FSharp.Core.AutoOpenAttribute: Boolean IsDefaultAttribute()
Microsoft.FSharp.Core.AutoOpenAttribute: Boolean Match(System.Object)
......
......@@ -734,12 +734,15 @@ Microsoft.FSharp.Core.AbstractClassAttribute: Void .ctor()
Microsoft.FSharp.Core.AllowNullLiteralAttribute: Boolean Equals(System.Object)
Microsoft.FSharp.Core.AllowNullLiteralAttribute: Boolean IsDefaultAttribute()
Microsoft.FSharp.Core.AllowNullLiteralAttribute: Boolean Match(System.Object)
Microsoft.FSharp.Core.AllowNullLiteralAttribute: Boolean Value
Microsoft.FSharp.Core.AllowNullLiteralAttribute: Boolean get_Value()
Microsoft.FSharp.Core.AllowNullLiteralAttribute: Int32 GetHashCode()
Microsoft.FSharp.Core.AllowNullLiteralAttribute: System.Object TypeId
Microsoft.FSharp.Core.AllowNullLiteralAttribute: System.Object get_TypeId()
Microsoft.FSharp.Core.AllowNullLiteralAttribute: System.String ToString()
Microsoft.FSharp.Core.AllowNullLiteralAttribute: System.Type GetType()
Microsoft.FSharp.Core.AllowNullLiteralAttribute: Void .ctor()
Microsoft.FSharp.Core.AllowNullLiteralAttribute: Void .ctor(Boolean)
Microsoft.FSharp.Core.AutoOpenAttribute: Boolean Equals(System.Object)
Microsoft.FSharp.Core.AutoOpenAttribute: Boolean IsDefaultAttribute()
Microsoft.FSharp.Core.AutoOpenAttribute: Boolean Match(System.Object)
......
......@@ -127,8 +127,10 @@ namespace Microsoft.FSharp.Core
[<AttributeUsage(AttributeTargets.Class,AllowMultiple=false)>]
[<Sealed>]
type AllowNullLiteralAttribute() =
type AllowNullLiteralAttribute(value: bool) =
inherit System.Attribute()
member x.Value = value
new () = new AllowNullLiteralAttribute(true)
[<AttributeUsage(AttributeTargets.Field,AllowMultiple=false)>]
[<Sealed>]
......
......@@ -238,6 +238,13 @@ namespace Microsoft.FSharp.Core
/// <returns>AllowNullLiteralAttribute</returns>
new : unit -> AllowNullLiteralAttribute
/// <summary>Creates an instance of the attribute with the specified value</summary>
/// <returns>AllowNullLiteralAttribute</returns>
new : value: bool -> AllowNullLiteralAttribute
/// <summary>The value of the attribute, indicating whether the type allows the null literal or not</summary>
member Value: bool
/// <summary>Adding this attribute to a value causes it to be compiled as a CLI constant literal.</summary>
[<AttributeUsage (AttributeTargets.Field,AllowMultiple=false)>]
[<Sealed>]
......
......@@ -900,14 +900,7 @@ and CheckAttribs cenv env (attribs: Attribs) =
|> Seq.map fst
|> Seq.toList
// Filter for allowMultiple = false
|> List.filter (fun (tcref,m) ->
let allowMultiple =
Infos.AttributeChecking.TryBindTyconRefAttribute cenv.g m cenv.g.attrib_AttributeUsageAttribute tcref
(fun (_,named) -> named |> List.tryPick (function ("AllowMultiple",_,_,ILAttribElem.Bool res) -> Some res | _ -> None))
(fun (Attrib(_,_,_,named,_,_,_)) -> named |> List.tryPick (function AttribNamedArg("AllowMultiple",_,_,AttribBoolArg(res) ) -> Some res | _ -> None))
(fun _ -> None)
(allowMultiple <> Some(true)))
|> List.filter (fun (tcref,m) -> TryFindAttributeUsageAttribute cenv.g m tcref <> Some(true))
if cenv.reportErrors then
for (tcref,m) in duplicates do
errorR(Error(FSComp.SR.chkAttrHasAllowMultiFalse(tcref.DisplayName), m))
......@@ -1384,7 +1377,7 @@ let CheckEntityDefn cenv env (tycon:Entity) =
let zeroInitUnsafe = TryFindFSharpBoolAttribute cenv.g cenv.g.attrib_DefaultValueAttribute f.FieldAttribs
if zeroInitUnsafe = Some(true) then
let ty' = generalizedTyconRef (mkLocalTyconRef tycon)
if not (TypeHasDefaultValue cenv.g ty') then
if not (TypeHasDefaultValue cenv.g m ty') then
errorR(Error(FSComp.SR.chkValueWithDefaultValueMustHaveDefaultValue(), m));
)
match tycon.TypeAbbrev with (* And type abbreviations *)
......
......@@ -1585,7 +1585,7 @@ and SolveTypSupportsNull (csenv:ConstraintSolverEnv) ndeep m2 trace ty =
if isTyparTy g ty then
AddConstraint csenv ndeep m2 trace (destTyparTy g ty) (TyparConstraint.SupportsNull(m))
elif
TypeSatisfiesNullConstraint g ty then CompleteD
TypeSatisfiesNullConstraint g m ty then CompleteD
else
match ty with
| NullableTy g _ ->
......@@ -1757,7 +1757,7 @@ and SolveTypRequiresDefaultConstructor (csenv:ConstraintSolverEnv) ndeep m2 trac
let ty = stripTyEqnsAndMeasureEqns g typ
if isTyparTy g ty then
AddConstraint csenv ndeep m2 trace (destTyparTy g ty) (TyparConstraint.RequiresDefaultConstructor(m))
elif isStructTy g ty && TypeHasDefaultValue g ty then
elif isStructTy g ty && TypeHasDefaultValue g m ty then
CompleteD
elif
GetIntrinsicConstructorInfosOfType csenv.InfoReader m ty
......
......@@ -812,7 +812,7 @@ let mkTcGlobals (compilingFslib,sysCcu,ilg,fslibCcu,directoryToResolveRelativePa
let mk_MFCore_attrib nm : BuiltinAttribInfo =
AttribInfo(mkILTyRef(IlxSettings.ilxFsharpCoreLibScopeRef (), nm),mk_MFCore_tcref fslibCcu nm)
AttribInfo(mkILTyRef(IlxSettings.ilxFsharpCoreLibScopeRef (), FSharpLib.Core + "." + nm),mk_MFCore_tcref fslibCcu nm)
let mkAttrib (nm:string) scopeRef : BuiltinAttribInfo =
let path, typeName = splitILTypeName nm
......
......@@ -609,7 +609,7 @@ module internal ExtensionTyping =
abstract GetDefinitionLocationAttribute : provider:ITypeProvider -> (string * int * int) option
abstract GetXmlDocAttributes : provider:ITypeProvider -> string[]
abstract GetHasTypeProviderEditorHideMethodsAttribute : provider:ITypeProvider -> bool
abstract GetAttributeConstructorArgs: provider:ITypeProvider * attribName:string -> obj option list option
abstract GetAttributeConstructorArgs: provider:ITypeProvider * attribName:string -> (obj option list * (string * obj option) list) option
and ProvidedCustomAttributeProvider =
static member Create (attributes :(ITypeProvider -> System.Collections.Generic.IList<CustomAttributeData>)) : IProvidedCustomAttributeProvider =
......@@ -622,9 +622,15 @@ module internal ExtensionTyping =
attributes(provider)
|> Seq.tryFind (findAttribByName attribName)
|> Option.map (fun a ->
a.ConstructorArguments
|> Seq.toList
|> List.map (function Arg null -> None | Arg obj -> Some obj | _ -> None))
let ctorArgs =
a.ConstructorArguments
|> Seq.toList
|> List.map (function Arg null -> None | Arg obj -> Some obj | _ -> None)
let namedArgs =
a.NamedArguments
|> Seq.toList
|> List.map (fun arg -> arg.MemberName, match arg.TypedValue with Arg null -> None | Arg obj -> Some obj | _ -> None)
ctorArgs, namedArgs)
member __.GetHasTypeProviderEditorHideMethodsAttribute provider =
attributes(provider)
......
......@@ -178,7 +178,7 @@ module internal ExtensionTyping =
abstract GetHasTypeProviderEditorHideMethodsAttribute : provider:ITypeProvider -> bool
abstract GetDefinitionLocationAttribute : provider:ITypeProvider -> (string * int * int) option
abstract GetXmlDocAttributes : provider:ITypeProvider -> string[]
abstract GetAttributeConstructorArgs: provider:ITypeProvider * attribName:string -> obj option list option
abstract GetAttributeConstructorArgs: provider:ITypeProvider * attribName:string -> (obj option list * (string * obj option) list) option
and [<AllowNullLiteral; Sealed; Class>]
ProvidedAssembly =
......
......@@ -2496,29 +2496,6 @@ exception ObsoleteError of string * range
/// formats.
module AttributeChecking =
/// Analyze three cases for attributes declared on type definitions: IL-declared attributes, F#-declared attributes and
/// provided attributes.
//
// This is used for AttributeUsageAttribute, DefaultMemberAttribute and ConditionalAttribute (on attribute types)
let TryBindTyconRefAttribute g m (AttribInfo (atref,_) as args) (tcref:TyconRef) f1 f2 f3 =
ignore m; ignore f3
match metadataOfTycon tcref.Deref with
#if EXTENSIONTYPING
| ProvidedTypeMetadata info ->
let provAttribs = info.ProvidedType.PApply((fun a -> (a :> IProvidedCustomAttributeProvider)),m)
match provAttribs.PUntaint((fun a -> a.GetAttributeConstructorArgs(provAttribs.TypeProvider.PUntaintNoFailure(id), atref.FullName)),m) with
| Some args -> f3 args
| None -> None
#endif
| ILTypeMetadata (_,tdef) ->
match TryDecodeILAttribute g atref (Some(atref.Scope)) tdef.CustomAttrs with
| Some attr -> f1 attr
| _ -> None
| FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata ->
match TryFindFSharpAttribute g args tcref.Attribs with
| Some attr -> f2 attr
| _ -> None
/// Analyze three cases for attributes declared on methods: IL-declared attributes, F#-declared attributes and
/// provided attributes.
let BindMethInfoAttributes m minfo f1 f2 f3 =
......@@ -2553,7 +2530,7 @@ module AttributeChecking =
TryBindMethInfoAttribute g m attribSpec minfo
(function ([ILAttribElem.String (Some msg) ],_) -> Some msg | _ -> None)
(function (Attrib(_,_,[ AttribStringArg msg ],_,_,_,_)) -> Some msg | _ -> None)
(function [ Some ((:? string as msg) : obj) ] -> Some msg | _ -> None)
(function ([ Some ((:? string as msg) : obj) ],_) -> Some msg | _ -> None)
/// Check if a method has a specific attribute.
let MethInfoHasAttribute g m attribSpec minfo =
......@@ -2563,22 +2540,6 @@ module AttributeChecking =
(fun _ -> Some ())
|> Option.isSome
/// Try to find a specific attribute on a type definition, where the attribute accepts a string argument.
///
/// This is used to detect the 'DefaultMemberAttribute' and 'ConditionalAttribute' attributes (on type definitions)
let TryFindTyconRefStringAttribute g m attribSpec tcref =
TryBindTyconRefAttribute g m attribSpec tcref
(function ([ILAttribElem.String (Some(msg)) ],_) -> Some msg | _ -> None)
(function (Attrib(_,_,[ AttribStringArg(msg) ],_,_,_,_)) -> Some msg | _ -> None)
(function [ Some ((:? string as msg) : obj) ] -> Some msg | _ -> None)
/// Check if a type definition has a specific attribute
let TyconRefHasAttribute g m attribSpec tcref =
TryBindTyconRefAttribute g m attribSpec tcref
(fun _ -> Some ())
(fun _ -> Some ())
(fun _ -> Some ())
|> Option.isSome
/// Check IL attributes for 'ObsoleteAttribute', returning errors and warnings as data
......@@ -2652,13 +2613,13 @@ module AttributeChecking =
let private CheckProvidedAttributes g m (provAttribs: Tainted<IProvidedCustomAttributeProvider>) =
let (AttribInfo(tref,_)) = g.attrib_SystemObsolete
match provAttribs.PUntaint((fun a -> a.GetAttributeConstructorArgs(provAttribs.TypeProvider.PUntaintNoFailure(id), tref.FullName)),m) with
| Some [ Some (:? string as msg) ] -> WarnD(ObsoleteWarning(msg,m))
| Some [ Some (:? string as msg); Some (:?bool as isError) ] ->
| Some ([ Some (:? string as msg) ], _) -> WarnD(ObsoleteWarning(msg,m))
| Some ([ Some (:? string as msg); Some (:?bool as isError) ], _) ->
if isError then
ErrorD (ObsoleteError(msg,m))
else
WarnD (ObsoleteWarning(msg,m))
| Some [ None ] ->
| Some ([ None ], _) ->
WarnD(ObsoleteWarning("",m))
| Some _ ->
WarnD(ObsoleteWarning("",m))
......
......@@ -2470,7 +2470,7 @@ and TryDevirtualizeApplication cenv env (f,tyargs,args,m) =
// target type isn't 'NullNotLiked', i.e. that the target type is not an F# union, record etc.
// Note UnboxFast is just the .NET IL 'unbox.any' instruction.
| Expr.Val(v,_,_),[ty],_ when valRefEq cenv.g v cenv.g.unbox_vref &&
canUseUnboxFast cenv.g ty ->
canUseUnboxFast cenv.g m ty ->
Some(DevirtualizeApplication cenv env cenv.g.unbox_fast_vref ty tyargs args m)
......
......@@ -2554,6 +2554,68 @@ let TryFindILAttributeOpt attr attrs =
| Some (AttribInfo (atref,_)) -> HasILAttribute atref attrs
| _ -> false
/// Analyze three cases for attributes declared on type definitions: IL-declared attributes, F#-declared attributes and
/// provided attributes.
//
// This is used for AttributeUsageAttribute, DefaultMemberAttribute and ConditionalAttribute (on attribute types)
let TryBindTyconRefAttribute g (m:range) (AttribInfo (atref,_) as args) (tcref:TyconRef) f1 f2 f3 =
ignore m; ignore f3
match metadataOfTycon tcref.Deref with
#if EXTENSIONTYPING
| ProvidedTypeMetadata info ->
let provAttribs = info.ProvidedType.PApply((fun a -> (a :> IProvidedCustomAttributeProvider)),m)
match provAttribs.PUntaint((fun a -> a.GetAttributeConstructorArgs(provAttribs.TypeProvider.PUntaintNoFailure(id), atref.FullName)),m) with
| Some args -> f3 args
| None -> None
#endif
| ILTypeMetadata (_,tdef) ->
match TryDecodeILAttribute g atref (Some(atref.Scope)) tdef.CustomAttrs with
| Some attr -> f1 attr
| _ -> None
| FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata ->
match TryFindFSharpAttribute g args tcref.Attribs with
| Some attr -> f2 attr
| _ -> None
let TryFindTyconRefBoolAttribute g m attribSpec tcref =
TryBindTyconRefAttribute g m attribSpec tcref
(function
| ([ ],_) -> Some true
| ([ILAttribElem.Bool (v) ],_) -> Some v
| _ -> None)
(function
| (Attrib(_,_,[ ],_,_,_,_)) -> Some true
| (Attrib(_,_,[ AttribBoolArg v ],_,_,_,_)) -> Some v
| _ -> None)
(function
| ([ ],_) -> Some true
| ([ Some ((:? bool as v) : obj) ],_) -> Some v
| _ -> None)
let TryFindAttributeUsageAttribute g m tcref =
TryBindTyconRefAttribute g m g.attrib_AttributeUsageAttribute tcref
(fun (_,named) -> named |> List.tryPick (function ("AllowMultiple",_,_,ILAttribElem.Bool res) -> Some res | _ -> None))
(fun (Attrib(_,_,_,named,_,_,_)) -> named |> List.tryPick (function AttribNamedArg("AllowMultiple",_,_,AttribBoolArg(res) ) -> Some res | _ -> None))
(fun (_,named) -> named |> List.tryPick (function ("AllowMultiple", Some ((:? bool as res) : obj)) -> Some res | _ -> None))
/// Try to find a specific attribute on a type definition, where the attribute accepts a string argument.
///
/// This is used to detect the 'DefaultMemberAttribute' and 'ConditionalAttribute' attributes (on type definitions)
let TryFindTyconRefStringAttribute g m attribSpec tcref =
TryBindTyconRefAttribute g m attribSpec tcref
(function ([ILAttribElem.String (Some(msg)) ],_) -> Some msg | _ -> None)
(function (Attrib(_,_,[ AttribStringArg(msg) ],_,_,_,_)) -> Some msg | _ -> None)
(function ([ Some ((:? string as msg) : obj) ], _) -> Some msg | _ -> None)
/// Check if a type definition has a specific attribute
let TyconRefHasAttribute g m attribSpec tcref =
TryBindTyconRefAttribute g m attribSpec tcref
(fun _ -> Some ())
(fun _ -> Some ())
(fun _ -> Some ())
|> Option.isSome
//-------------------------------------------------------------------------
// List and reference types...
//-------------------------------------------------------------------------
......@@ -6841,28 +6903,34 @@ let TypeNullNever g ty =
(isStructTy g underlyingTy) ||
(isByrefTy g underlyingTy)
let TypeNullIsExtraValue g ty =
isILReferenceTy g ty ||
isDelegateTy g ty ||
(not (TypeNullNever g ty) &&
isAppTy g ty &&
TryFindFSharpBoolAttribute g g.attrib_AllowNullLiteralAttribute (tyconOfAppTy g ty).Attribs = Some(true))
/// Indicates if the type admits the use of 'null' as a value
let TypeNullIsExtraValue g m ty =
if isILReferenceTy g ty || isDelegateTy g ty then
// Putting AllowNullLiteralAttribute(false) on an IL or provided type means 'null' can't be used with that type
not (isAppTy g ty && TryFindTyconRefBoolAttribute g m g.attrib_AllowNullLiteralAttribute (tcrefOfAppTy g ty) = Some(false))
elif TypeNullNever g ty then
false
else
// Putting AllowNullLiteralAttribute(true) on an F# type means 'null' can be used with that type
isAppTy g ty && TryFindTyconRefBoolAttribute g m g.attrib_AllowNullLiteralAttribute (tcrefOfAppTy g ty) = Some(true)
let TypeNullIsTrueValue g ty =
(isAppTy g ty && IsUnionTypeWithNullAsTrueValue g (tyconOfAppTy g ty)) ||
(isUnitTy g ty)
let TypeNullNotLiked g ty =
not (TypeNullIsExtraValue g ty)
let TypeNullNotLiked g m ty =
not (TypeNullIsExtraValue g m ty)
&& not (TypeNullIsTrueValue g ty)
&& not (TypeNullNever g ty)
let TypeSatisfiesNullConstraint g ty =
TypeNullIsExtraValue g ty
let TypeSatisfiesNullConstraint g m ty =
TypeNullIsExtraValue g m ty
let rec TypeHasDefaultValue g ty =
let rec TypeHasDefaultValue g m ty =
let ty = stripTyEqnsAndMeasureEqns g ty
TypeSatisfiesNullConstraint g ty
TypeSatisfiesNullConstraint g m ty
|| (isStructTy g ty &&
// Is it an F# struct type?
(if isFSharpStructTy g ty then
......@@ -6873,9 +6941,9 @@ let rec TypeHasDefaultValue g ty =
// We can ignore fields with the DefaultValue(false) attribute
|> List.filter (fun fld -> not (TryFindFSharpBoolAttribute g g.attrib_DefaultValueAttribute fld.FieldAttribs = Some(false)))
flds |> List.forall (actualTyOfRecdField (mkTyconRefInst tcref tinst) >> TypeHasDefaultValue g)
flds |> List.forall (actualTyOfRecdField (mkTyconRefInst tcref tinst) >> TypeHasDefaultValue g m)
elif isTupleStructTy g ty then
destTupleTy g ty |> List.forall (TypeHasDefaultValue g)
destTupleTy g ty |> List.forall (TypeHasDefaultValue g m)
else
// All struct types defined in other .NET languages have a DefaultValue regardless of their
// instantiation
......@@ -6909,9 +6977,9 @@ let canUseTypeTestFast g ty =
not (TypeNullNever g ty)
// Can we use the fast helper for the 'LanguagePrimitives.IntrinsicFunctions.UnboxGeneric'?
let canUseUnboxFast g ty =
let canUseUnboxFast g m ty =
not (isTyparTy g ty) &&
not (TypeNullNotLiked g ty)
not (TypeNullNotLiked g m ty)
//--------------------------------------------------------------------------
......
......@@ -999,13 +999,13 @@ val ModuleNameIsMangled : TcGlobals -> Attribs -> bool
val CompileAsEvent : TcGlobals -> Attribs -> bool
val TypeNullIsExtraValue : TcGlobals -> TType -> bool
val TypeNullIsExtraValue : TcGlobals -> range -> TType -> bool
val TypeNullIsTrueValue : TcGlobals -> TType -> bool
val TypeNullNotLiked : TcGlobals -> TType -> bool
val TypeNullNotLiked : TcGlobals -> range -> TType -> bool
val TypeNullNever : TcGlobals -> TType -> bool
val TypeSatisfiesNullConstraint : TcGlobals -> TType -> bool
val TypeHasDefaultValue : TcGlobals -> TType -> bool
val TypeSatisfiesNullConstraint : TcGlobals -> range -> TType -> bool
val TypeHasDefaultValue : TcGlobals -> range -> TType -> bool
val isAbstractTycon : Tycon -> bool
......@@ -1112,7 +1112,7 @@ val mkCallGetGenericEREqualityComparer : TcGlobals -> range -> Expr
val mkCallGetGenericPEREqualityComparer : TcGlobals -> range -> Expr
val mkCallUnboxFast : TcGlobals -> range -> TType -> Expr -> Expr
val canUseUnboxFast : TcGlobals -> TType -> bool
val canUseUnboxFast : TcGlobals -> range -> TType -> bool
val mkCallDispose : TcGlobals -> range -> TType -> Expr -> Expr
val mkCallSeq : TcGlobals -> range -> TType -> Expr -> Expr
......@@ -1196,6 +1196,20 @@ val TryFindFSharpBoolAttribute : TcGlobals -> Env.BuiltinAttribInfo -> Attri
val TryFindFSharpStringAttribute : TcGlobals -> Env.BuiltinAttribInfo -> Attribs -> string option
val TryFindFSharpInt32Attribute : TcGlobals -> Env.BuiltinAttribInfo -> Attribs -> int32 option
/// Try to find a specific attribute on a type definition, where the attribute accepts a string argument.
///
/// This is used to detect the 'DefaultMemberAttribute' and 'ConditionalAttribute' attributes (on type definitions)
val TryFindTyconRefStringAttribute : TcGlobals -> range -> Env.BuiltinAttribInfo -> TyconRef -> string option
/// Try to find a specific attribute on a type definition, where the attribute accepts a bool argument.
val TryFindTyconRefBoolAttribute : TcGlobals -> range -> Env.BuiltinAttribInfo -> TyconRef -> bool option
/// Try to find a specific attribute on a type definition
val TyconRefHasAttribute : TcGlobals -> range -> Env.BuiltinAttribInfo -> TyconRef -> bool
/// Try to find the AttributeUsage attribute, looking for the value of the AllowMultiple named parameter
val TryFindAttributeUsageAttribute : TcGlobals -> range -> TyconRef -> bool option
#if EXTENSIONTYPING
/// returns Some(assemblyName) for success
val TryDecodeTypeProviderAssemblyAttr : ILGlobals -> ILAttribute -> string option
......
......@@ -2042,7 +2042,7 @@ module GeneralizationHelpers =
TrimUngeneralizableTypars genConstrainedTyparFlag inlineFlag generalizedTypars freeInEnv
/// Condense type variables in positive position
let CondenseTypars (cenv, denv:DisplayEnv, generalizedTypars: Typars, tauTy) =
let CondenseTypars (cenv, denv:DisplayEnv, generalizedTypars: Typars, tauTy, m) =
// The type of the value is ty11 * ... * ty1N -> ... -> tyM1 * ... * tyMM -> retTy
// This is computed REGARDLESS of the arity of the expression.
......@@ -2058,7 +2058,7 @@ module GeneralizationHelpers =
match tp.Constraints |> List.partition (function (TyparConstraint.CoercesTo _) -> true | _ -> false) with
| [TyparConstraint.CoercesTo(cxty,_)], others ->
// Throw away null constraints if they are implied
match others |> List.filter (function (TyparConstraint.SupportsNull(_)) -> not (TypeSatisfiesNullConstraint cenv.g cxty) | _ -> true) with
match others |> List.filter (function (TyparConstraint.SupportsNull(_)) -> not (TypeSatisfiesNullConstraint cenv.g m cxty) | _ -> true) with
| [] -> Some cxty
| _ -> None
| _ -> None
......@@ -2132,7 +2132,7 @@ module GeneralizationHelpers =
let ty = mkTyparTy tp
error(Error(FSComp.SR.tcNotSufficientlyGenericBecauseOfScope(NicePrint.prettyStringOfTy denv ty),m)))
let generalizedTypars = CondenseTypars(cenv,denv,generalizedTypars,tauTy)
let generalizedTypars = CondenseTypars(cenv, denv, generalizedTypars, tauTy, m)
let generalizedTypars =
if canInferTypars then generalizedTypars
......@@ -13905,8 +13905,8 @@ module EstablishTypeDefinitionCores = begin
let allowNullLiteralAttributeCheck() =
if hasAllowNullLiteralAttr then
tycon.TypeContents.tcaug_super |> Option.iter (fun ty -> if not (TypeNullIsExtraValue cenv.g ty) then errorR (Error(FSComp.SR.tcAllowNullTypesMayOnlyInheritFromAllowNullTypes(),m)))
tycon.ImmediateInterfaceTypesOfFSharpTycon |> List.iter (fun ty -> if not (TypeNullIsExtraValue cenv.g ty) then errorR (Error(FSComp.SR.tcAllowNullTypesMayOnlyInheritFromAllowNullTypes(),m)))
tycon.TypeContents.tcaug_super |> Option.iter (fun ty -> if not (TypeNullIsExtraValue cenv.g m ty) then errorR (Error(FSComp.SR.tcAllowNullTypesMayOnlyInheritFromAllowNullTypes(),m)))
tycon.ImmediateInterfaceTypesOfFSharpTycon |> List.iter (fun ty -> if not (TypeNullIsExtraValue cenv.g m ty) then errorR (Error(FSComp.SR.tcAllowNullTypesMayOnlyInheritFromAllowNullTypes(),m)))
let structLayoutAttributeCheck(allowed) =
......
......@@ -461,8 +461,8 @@ module SignatureConformance = begin
elif fNull && not aNull then
errorR(err(FSComp.SR.DefinitionsInSigAndImplNotCompatibleSignatureSaysNull))
let aNull2 = TypeNullIsExtraValue g (generalizedTyconRef (mkLocalTyconRef implTycon))
let fNull2 = TypeNullIsExtraValue g (generalizedTyconRef (mkLocalTyconRef implTycon))
let aNull2 = TypeNullIsExtraValue g m (generalizedTyconRef (mkLocalTyconRef implTycon))
let fNull2 = TypeNullIsExtraValue g m (generalizedTyconRef (mkLocalTyconRef implTycon))
if aNull2 && not fNull2 then
errorR(err(FSComp.SR.DefinitionsInSigAndImplNotCompatibleImplementationSaysNull2))
elif fNull2 && not aNull2 then
......@@ -2166,7 +2166,7 @@ let BuildMethodCall tcVal g amap isMutable m isProp minfo valUseFlags minst objA
// Build a 'call' to a struct default constructor
| DefaultStructCtor (g,typ) ->
if not (TypeHasDefaultValue g typ) then
if not (TypeHasDefaultValue g m typ) then
errorR(Error(FSComp.SR.tcDefaultStructConstructorCall(),m))
mkDefault (m,typ), typ)
......
......@@ -41,6 +41,11 @@ module Utils =
member __.ConstructorArguments = upcast [| CustomAttributeTypedArgument(typeof<string>, msg) |]
member __.NamedArguments = upcast [| |] }
let mkAllowNullLiteralValueAttributeData(value: bool) =
{ new CustomAttributeData() with
member __.Constructor = typeof<Microsoft.FSharp.Core.AllowNullLiteralAttribute>.GetConstructors().[0]
member __.ConstructorArguments = upcast [| CustomAttributeTypedArgument(typeof<bool>, value) |]
member __.NamedArguments = upcast [| |] }
type public Runtime() =
static member Id x = x
......@@ -232,8 +237,11 @@ type public Provider() =
yield TypeBuilder.CreateConstructor(theNestedType,(fun _ -> [| |])) :> MemberInfo
|]
and theType = TypeBuilder.CreateSimpleType(TypeContainer.Namespace(modul, namespaceName),className,members=allMembers,baseType=baseType)
and theNestedType = TypeBuilder.CreateSimpleType(TypeContainer.Type(theType),"NestedType",members=allMembersOfNestedType)
and theType = TypeBuilder.CreateSimpleType(TypeContainer.Namespace(modul, namespaceName),className,members=allMembers,baseType=baseType,
getCustomAttributes=(fun () -> [| mkAllowNullLiteralValueAttributeData(false) |]))
and theNestedType = TypeBuilder.CreateSimpleType(TypeContainer.Type(theType),"NestedType",members=allMembersOfNestedType,
getCustomAttributes=(fun () -> [| mkAllowNullLiteralValueAttributeData(true) |]))
theType
let helloWorldType = mkHelloWorldType rootNamespace "HelloWorldType" (typeof<obj>)
......
......@@ -111,6 +111,15 @@ module BasicErasedProvidedTypeTest =
[| 3;6 |]
check "cwkeonwe09a13355 - null attrib can't be used"
(null: FSharp.HelloWorld.HelloWorldType.NestedType) // should NOT give a type error - this explicitly has AllowNullLiteralAttribute(true), so a null literal is allowed
null
// should NOT give a type error - this doesn't have any attributes, and a null literal is allowed by default
check "cwkeonwe09a13355 - null attrib"
(null : FSharp.HelloWorld.HelloWorldSubType)
null
check "cwkeonwe09a13355"
(FSharp.HelloWorld.HelloWorldType.ReturnsEmptyNewArray())
[| |]
......
......@@ -1447,3 +1447,5 @@ neg1.fsx(448,9,448,107): typecheck error FS3148: Too many static parameters. Exp
neg1.fsx(449,105,449,110): typecheck error FS3083: The static parameter 'Count' has already been given a value
neg1.fsx(450,9,450,119): typecheck error FS3148: Too many static parameters. Expected at most 1 parameters, but got 0 unnamed and 2 named parameters.
neg1.fsx(455,14,455,18): typecheck error FS0043: The type 'FSharp.HelloWorld.HelloWorldType' does not have 'null' as a proper value
......@@ -449,3 +449,7 @@ module TooManyArgs =
FSharp.GoodProviderForNegativeStaticParameterTypeTests.HelloWorldTypeWithStaticInt32Parameter<3,Count=2>.StaticProperty1 |> ignore
FSharp.GoodProviderForNegativeStaticParameterTypeTests.HelloWorldTypeWithStaticInt32Parameter<Count=3,Count=2>.StaticProperty1 |> ignore
//FSharp.GoodProviderForNegativeStaticParameterTypeTests.HelloWorldTypeWithStaticStringParameter<s>.StaticProperty1 |> ignore
module NullLiteralNotAllowed =
let v = (null : FSharp.HelloWorld.HelloWorldType) // should give a type error - this explicitly has AllowNullLiteralAttribute(false), so a null literal is not allowed
......@@ -22,6 +22,12 @@ type public Runtime() =
module Utils =
let doEvil() = failwith "deliberate error for testing purposes"
let mkAllowNullLiteralValueAttributeData(value: bool) =
{ new CustomAttributeData() with
member __.Constructor = typeof<Microsoft.FSharp.Core.AllowNullLiteralAttribute>.GetConstructors().[0]
member __.ConstructorArguments = upcast [| CustomAttributeTypedArgument(typeof<bool>, value) |]
member __.NamedArguments = upcast [| |] }
[<TypeProvider>]
type public GoodProviderForNegativeTypeTests1() =
let modul = typeof<GoodProviderForNegativeTypeTests1>.Assembly.GetModules().[0]
......@@ -307,7 +313,8 @@ type public GoodProviderForNegativeStaticParameterTypeTests() =
and theType =
let container = TypeContainer.Namespace(modul, rootNamespace)
TypeBuilder.CreateSimpleType(container,"HelloWorldType",members=allMembers)
TypeBuilder.CreateSimpleType(container,"HelloWorldType",members=allMembers,
getCustomAttributes=(fun () -> [| mkAllowNullLiteralValueAttributeData(false) |]))
theType
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册