@@ -3004,8 +3004,8 @@ let isByrefTyconRef (g: TcGlobals) (tcref: TyconRef) =
30043004let isByrefLikeTyconRef ( g : TcGlobals ) m ( tcref : TyconRef ) =
30053005 tcref.CanDeref &&
30063006 match tcref.TryIsByRefLike with
3007- | Some res -> res
3008- | None ->
3007+ | ValueSome res -> res
3008+ | _ ->
30093009 let res =
30103010 isByrefTyconRef g tcref ||
30113011 ( isStructTyconRef tcref && TyconRefHasAttribute g m g.attrib_ IsByRefLikeAttribute tcref)
@@ -5941,34 +5941,53 @@ let mkAndSimplifyMatch spBind exprm matchm ty tree targets =
59415941//-------------------------------------------------------------------------
59425942
59435943type Mutates = AddressOfOp | DefinitelyMutates | PossiblyMutates | NeverMutates
5944- exception DefensiveCopyWarning of string * range
5944+ exception DefensiveCopyWarning of string * range
59455945
59465946let isRecdOrStructTyconRefAssumedImmutable ( g : TcGlobals ) ( tcref : TyconRef ) =
59475947 tcref.CanDeref &&
59485948 not ( isRecdOrUnionOrStructTyconRefDefinitelyMutable tcref) ||
5949- tyconRefEq g tcref g.decimal_ tcr ||
5949+ tyconRefEq g tcref g.decimal_ tcr ||
59505950 tyconRefEq g tcref g.date_ tcr
59515951
5952- let isRecdOrStructTyconRefReadOnly ( g : TcGlobals ) m ( tcref : TyconRef ) =
5952+ let isTyconRefReadOnly g m ( tcref : TyconRef ) =
59535953 tcref.CanDeref &&
59545954 match tcref.TryIsReadOnly with
5955- | Some res -> res
5956- | None ->
5957- let isImmutable = isRecdOrStructTyconRefAssumedImmutable g tcref
5958- let hasAttrib = TyconRefHasAttribute g m g.attrib_ IsReadOnlyAttribute tcref
5959- let res = isImmutable || hasAttrib
5955+ | ValueSome res -> res
5956+ | _ ->
5957+ let res = TyconRefHasAttribute g m g.attrib_ IsReadOnlyAttribute tcref
59605958 tcref.SetIsReadOnly res
59615959 res
59625960
5963- let isRecdOrStructTyReadOnly ( g : TcGlobals ) m ty =
5961+ let isTyconRefAssumedReadOnly g ( tcref : TyconRef ) =
5962+ tcref.CanDeref &&
5963+ match tcref.TryIsAssumedReadOnly with
5964+ | ValueSome res -> res
5965+ | _ ->
5966+ let res = isRecdOrStructTyconRefAssumedImmutable g tcref
5967+ tcref.SetIsAssumedReadOnly res
5968+ res
5969+
5970+ let isRecdOrStructTyconRefReadOnlyAux g m isInref ( tcref : TyconRef ) =
5971+ if isInref && tcref.IsILStructOrEnumTycon then
5972+ isTyconRefReadOnly g m tcref
5973+ else
5974+ isTyconRefReadOnly g m tcref || isTyconRefAssumedReadOnly g tcref
5975+
5976+ let isRecdOrStructTyconRefReadOnly g m tcref =
5977+ isRecdOrStructTyconRefReadOnlyAux g m false tcref
5978+
5979+ let isRecdOrStructTyReadOnlyAux ( g : TcGlobals ) m isInref ty =
59645980 match tryDestAppTy g ty with
59655981 | ValueNone -> false
5966- | ValueSome tcref -> isRecdOrStructTyconRefReadOnly g m tcref
5982+ | ValueSome tcref -> isRecdOrStructTyconRefReadOnlyAux g m isInref tcref
5983+
5984+ let isRecdOrStructTyReadOnly g m ty =
5985+ isRecdOrStructTyReadOnlyAux g m false ty
59675986
5968- let CanTakeAddressOf g m ty mut =
5987+ let CanTakeAddressOf g m isInref ty mut =
59695988 match mut with
59705989 | NeverMutates -> true
5971- | PossiblyMutates -> isRecdOrStructTyReadOnly g m ty
5990+ | PossiblyMutates -> isRecdOrStructTyReadOnlyAux g m isInref ty
59725991 | DefinitelyMutates -> false
59735992 | AddressOfOp -> true // you can take the address but you might get a (readonly) inref<T> as a result
59745993
@@ -5996,7 +6015,7 @@ let CanTakeAddressOfImmutableVal (g: TcGlobals) m (vref: ValRef) mut =
59966015 // || valRefInThisAssembly g.compilingFslib vref
59976016 // This is because we don't actually guarantee to generate static backing fields for all values like these, e.g. simple constants "let x = 1".
59986017 // We always generate a static property but there is no field to take an address of
5999- CanTakeAddressOf g m vref.Type mut
6018+ CanTakeAddressOf g m false vref.Type mut
60006019
60016020let MustTakeAddressOfVal ( g : TcGlobals ) ( vref : ValRef ) =
60026021 vref.IsMutable &&
@@ -6008,7 +6027,7 @@ let MustTakeAddressOfByrefGet (g: TcGlobals) (vref: ValRef) =
60086027
60096028let CanTakeAddressOfByrefGet ( g : TcGlobals ) ( vref : ValRef ) mut =
60106029 isInByrefTy g vref.Type &&
6011- CanTakeAddressOf g vref.Range ( destByrefTy g vref.Type) mut
6030+ CanTakeAddressOf g vref.Range true ( destByrefTy g vref.Type) mut
60126031
60136032let MustTakeAddressOfRecdField ( rfref : RecdField ) =
60146033 // Static mutable fields must be private, hence we don't have to take their address
@@ -6021,14 +6040,18 @@ let CanTakeAddressOfRecdFieldRef (g: TcGlobals) m (rfref: RecdFieldRef) tinst mu
60216040 // We only do this if the field is defined in this assembly because we can't take addresses across assemblies for immutable fields
60226041 entityRefInThisAssembly g.compilingFslib rfref.TyconRef &&
60236042 not rfref.RecdField.IsMutable &&
6024- CanTakeAddressOf g m ( actualTyOfRecdFieldRef rfref tinst) mut
6043+ CanTakeAddressOf g m false ( actualTyOfRecdFieldRef rfref tinst) mut
60256044
60266045let CanTakeAddressOfUnionFieldRef ( g : TcGlobals ) m ( uref : UnionCaseRef ) cidx tinst mut =
60276046 // We only do this if the field is defined in this assembly because we can't take addresses across assemblies for immutable fields
60286047 entityRefInThisAssembly g.compilingFslib uref.TyconRef &&
60296048 let rfref = uref.FieldByIndex cidx
60306049 not rfref.IsMutable &&
6031- CanTakeAddressOf g m ( actualTyOfUnionFieldRef uref cidx tinst) mut
6050+ CanTakeAddressOf g m false ( actualTyOfUnionFieldRef uref cidx tinst) mut
6051+
6052+ let mkDerefAddrExpr mAddrGet expr mExpr exprTy =
6053+ let v , _ = mkCompGenLocal mAddrGet " byrefReturn" exprTy
6054+ mkCompGenLet mExpr v expr ( mkAddrGet mAddrGet ( mkLocalValRef v))
60326055
60336056/// Make the address-of expression and return a wrapper that adds any allocated locals at an appropriate scope.
60346057/// Also return a flag that indicates if the resulting pointer is a not a pointer where writing is allowed and will
@@ -6166,8 +6189,12 @@ let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress
61666189 // Take a defensive copy
61676190 let tmp , _ =
61686191 match mut with
6169- | NeverMutates -> mkCompGenLocal m " copyOfStruct" ty
6192+ | NeverMutates -> mkCompGenLocal m " copyOfStruct" ty
61706193 | _ -> mkMutableCompGenLocal m " copyOfStruct" ty
6194+
6195+ // This local is special in that it ignore byref scoping rules.
6196+ tmp.SetIgnoresByrefScope()
6197+
61716198 let readonly = true
61726199 let writeonly = false
61736200 Some ( tmp, expr), ( mkValAddr m readonly ( mkLocalValRef tmp)), readonly, writeonly
0 commit comments