@@ -121,6 +121,7 @@ type WriterState =
121121 onlerefs: Table < int * int []>
122122 osimpletys: Table < int >
123123 oglobals: TcGlobals
124+ mutable isStructThisArgPos: bool
124125 ofile: string
125126/// Indicates if we are using in-memory format, where we store XML docs as well
126127 oInMem: bool
@@ -709,7 +710,8 @@ let pickleObjWithDanglingCcus inMem file g scope p x =
709710 osimpletys= Table<_>. Create" osimpletys"
710711 oglobals= g
711712 ofile= file
712- oInMem= inMem}
713+ oInMem= inMem
714+ isStructThisArgPos= false }
713715 p x st1
714716let sizes =
715717 st1.otycons.Size,
@@ -731,7 +733,8 @@ let pickleObjWithDanglingCcus inMem file g scope p x =
731733 osimpletys= Table<_>. Create" osimpletys (fake)"
732734 oglobals= g
733735 ofile= file
734- oInMem= inMem}
736+ oInMem= inMem
737+ isStructThisArgPos= false }
735738 p_ tup7
736739( p_ array p_ encoded_ ccuref)
737740( p_ tup3 p_ int p_ int p_ int)
@@ -1268,6 +1271,13 @@ let p_tys = (p_list p_ty)
12681271
12691272let fill_p_attribs , p_attribs = p_ hole()
12701273
1274+ // In F# 4.5, the type of the "this" pointer for structs is considered to be inref for the purposes of checking the implementation
1275+ // of the struct. However for backwards compat reaons we can't serialize this as the type.
1276+ let checkForInRefStructThisArg st ty =
1277+ let g = st.oglobals
1278+ let _ , tauTy = tryDestForallTy g ty
1279+ isFunTy g tauTy&& isFunTy g( rangeOfFunTy g tauTy) && isInByrefTy g( domainOfFunTy g tauTy)
1280+
12711281let p_nonlocal_val_ref ( nlv : NonLocalValOrMemberRef ) st =
12721282let a = nlv.EnclosingEntity
12731283let key = nlv.ItemKey
@@ -1277,7 +1287,13 @@ let p_nonlocal_val_ref (nlv:NonLocalValOrMemberRef) st =
12771287 p_ bool pkey.MemberIsOverride st
12781288 p_ string pkey.LogicalName st
12791289 p_ int pkey.TotalArgCount st
1290+ let isStructThisArgPos =
1291+ match key.TypeForLinkagewith
1292+ | None-> false
1293+ | Some ty-> checkForInRefStructThisArg st ty
1294+ st.isStructThisArgPos<- isStructThisArgPos
12801295 p_ option p_ ty key.TypeForLinkage st
1296+ st.isStructThisArgPos<- false
12811297
12821298let rec p_vref ctxt x st =
12831299match xwith
@@ -1539,6 +1555,7 @@ let u_tyar_specs = (u_list u_tyar_spec)
15391555
15401556let _ = fill_ p_ ty( fun ty st ->
15411557let ty = stripTyparEqns ty
1558+ let ty = if isInByrefTy st.oglobals ty&& st.isStructThisArgPosthen destByrefTy st.oglobals tyelse ty
15421559match tywith
15431560| TType_ tuple( tupInfo, l) ->
15441561if evalTupInfoIsStruct tupInfothen
@@ -1547,7 +1564,11 @@ let _ = fill_p_ty (fun ty st ->
15471564 p_ byte0 st; p_ tys l st
15481565| TType_ app( ERefNonLocal nleref,[]) -> p_ byte1 st; p_ simpletyp nleref st
15491566| TType_ app( tc, tinst) -> p_ byte2 st; p_ tup2( p_ tcref" typ" ) p_ tys( tc, tinst) st
1550- | TType_ fun( d, r) -> p_ byte3 st; p_ tup2 p_ ty p_ ty( d, r) st
1567+ | TType_ fun( d, r) ->
1568+ p_ byte3 st
1569+ p_ ty d st
1570+ st.isStructThisArgPos<- false
1571+ p_ ty r st
15511572| TType_ var r-> p_ byte4 st; p_ tpref r st
15521573| TType_ forall( tps, r) -> p_ byte5 st; p_ tup2 p_ tyar_ specs p_ ty( tps, r) st
15531574| TType_ measure unt-> p_ byte6 st; p_ measure_ expr unt st
@@ -1815,7 +1836,12 @@ and p_ValData x st =
18151836 p_ option p_ string x.ValCompiledName st
18161837// only keep range information on published values, not on optimization data
18171838 p_ ranges( x.ValReprInfo|> Option.map( fun _ -> x.val_ range, x.DefinitionRange)) st
1839+
1840+ let isStructThisArgPos = x.IsMember&& checkForInRefStructThisArg st x.Type
1841+ st.isStructThisArgPos<- isStructThisArgPos
18181842 p_ ty x.val_ type st
1843+ st.isStructThisArgPos<- false
1844+
18191845 p_ int64 x.val_ flags.PickledBits st
18201846 p_ option p_ member_ info x.MemberInfo st
18211847 p_ attribs x.Attribs st