diff --git a/src/FSharp.Core/event.fs b/src/FSharp.Core/event.fs index 483ea38d64f..69a9fc53918 100644 --- a/src/FSharp.Core/event.fs +++ b/src/FSharp.Core/event.fs @@ -83,7 +83,7 @@ type EventWrapper<'Delegate, 'Args> = delegate of 'Delegate * objnull * 'Args -> type Event<'Delegate, 'Args when 'Delegate: delegate<'Args, unit> and 'Delegate :> System.Delegate and 'Delegate: not struct>() = - let mutable multicast: 'Delegate = Unchecked.defaultof<_> + let mutable multicast: 'Delegate | null = Unchecked.defaultof<_> static let mi, argTypes = let instanceBindingFlags = @@ -149,12 +149,18 @@ type Event<'Delegate, 'Args Atomic.setWith (fun value -> System.Delegate.Combine(value, d) :?> 'Delegate) &multicast member e.RemoveHandler(d) = - Atomic.setWith (fun value -> System.Delegate.Remove(value, d) :?> 'Delegate) &multicast + Atomic.setWith (fun value -> + match System.Delegate.Remove(value, d) with + | null -> null + | result -> result :?> 'Delegate) &multicast interface System.IObservable<'Args> with member e.Subscribe(observer) = let obj = new EventDelegee<'Args>(observer) - let h = Delegate.CreateDelegate(typeof<'Delegate>, obj, invokeInfo) :?> 'Delegate + let h = + match Delegate.CreateDelegate(typeof<'Delegate>, obj, invokeInfo) with + | null -> null + | result -> result :?> 'Delegate (e :?> IDelegateEvent<'Delegate>).AddHandler(h) @@ -166,7 +172,7 @@ type Event<'Delegate, 'Args [] type Event<'T> = - val mutable multicast: Handler<'T> + val mutable multicast: Handler<'T> | null new() = { multicast = null } member x.Trigger(arg: 'T) = @@ -183,7 +189,10 @@ type Event<'T> = Atomic.setWith (fun value -> System.Delegate.Combine(value, d) :?> Handler<'T>) &x.multicast member e.RemoveHandler(d) = - Atomic.setWith (fun value -> System.Delegate.Remove(value, d) :?> Handler<'T>) &x.multicast + Atomic.setWith (fun value -> + match System.Delegate.Remove(value, d) with + | null -> null + | result -> result :?> Handler<'T>) &x.multicast interface System.IObservable<'T> with member e.Subscribe(observer) = let h = new Handler<_>(fun sender args -> observer.OnNext(args)) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/Files/EventNullabilityTest.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/Files/EventNullabilityTest.fs new file mode 100644 index 00000000000..e8795b28e70 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/Files/EventNullabilityTest.fs @@ -0,0 +1,10 @@ +namespace Nullness + +open System.ComponentModel + +type XViewModel() = + let propertyChanged = Event() + + interface INotifyPropertyChanged with + [] + member this.PropertyChanged = propertyChanged.Publish \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs index ced7e02fdca..4de226d0cdb 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs @@ -1540,4 +1540,21 @@ let main _ = |> compile //|> verifyIL ["abc"] |> run - |> verifyOutputContains [|"Test true;,1 true,2 true,3 true,4 true,5 true,6 false,7 true,8 false,9 false,10 false,11 false,12 true"|] \ No newline at end of file + |> verifyOutputContains [|"Test true;,1 true,2 true,3 true,4 true,5 true,6 false,7 true,8 false,9 false,10 false,11 false,12 true"|] + +[] +let ``INotifyPropertyChanged with Event using PropertyChangedEventHandler`` () = + FSharp """namespace Nullness + +open System.ComponentModel + +type XViewModel() = + let propertyChanged = Event() + + interface INotifyPropertyChanged with + [] + member this.PropertyChanged = propertyChanged.Publish +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed \ No newline at end of file