diff --git a/theories/lang/lib/lock.v b/theories/lang/lib/lock.v index da77afe2a4ec222e5fe061e039578432c0cab97c..74c6b1c953f5f20646e5909da8b70e90efd55079 100644 --- a/theories/lang/lib/lock.v +++ b/theories/lang/lib/lock.v @@ -27,7 +27,7 @@ Section proof. Definition locked (γ : gname): iProp Σ := own γ (Excl ()). - Global Instance lock_inv_ne γ l : NonExpansive (lock_proto γ l). + Global Instance lock_proto_ne γ l : NonExpansive (lock_proto γ l). Proof. solve_proper. Qed. Global Instance locked_timeless γ : TimelessP (locked γ). diff --git a/theories/typing/lib/mutex/mutex.v b/theories/typing/lib/mutex/mutex.v index 537e04848d0591151f78c0a478ca58bafd72df80..8d83630d44cd77544bbf2b043eae828ced9d9ca5 100644 --- a/theories/typing/lib/mutex/mutex.v +++ b/theories/typing/lib/mutex/mutex.v @@ -87,6 +87,20 @@ Section mutex. Global Instance mutex_wf ty `{!TyWf ty} : TyWf (mutex ty) := { ty_lfts := ty.(ty_lfts); ty_wf_E := ty.(ty_wf_E) }. + Global Instance mutex_type_ne : TypeNonExpansive mutex. + Proof. + constructor; + solve_proper_core ltac:(fun _ => exact: type_dist2_S || + f_type_equiv || f_contractive || f_equiv). + Qed. + + Global Instance mutex_ne : NonExpansive mutex. + Proof. + constructor; solve_proper_core ltac:(fun _ => (eapply ty_size_ne; try reflexivity) || f_equiv). + Qed. + + (* TODO: compat with eqtype, Send+Sync if ty is Send. *) + End mutex. Section code. @@ -174,4 +188,41 @@ Section code. iApply type_jump; solve_typing. Qed. + Definition mutex_get_mut : val := + funrec: <> ["m"] := + let: "m'" := !"m" in + "m" <- ("m'" +â‚— #1);; + return: ["m"]. + + Lemma mutex_get_mut_type ty `{!TyWf ty} : + typed_val mutex_get_mut (fn(∀ α, ∅; &uniq{α} mutex ty) → &uniq{α} ty). + Proof. + intros E L. iApply type_fn; [solve_typing..|]. iIntros "/= !#". + iIntros (α Ï ret arg); inv_vec arg=>m; simpl_subst. + iApply type_deref; [solve_typing..|]; iIntros (m'); simpl_subst. + (* Go to Iris *) + iIntros (tid) "#LFT #HE Hna HL Hk [Hm [Hm' _]]". + rewrite !tctx_hasty_val [[m]]lock. + destruct m' as [[|lm'|]|]; try done. simpl. + iMod (lctx_lft_alive_tok α with "HE HL") as (qα) "(Hα & HL & Hclose1)"; + [solve_typing..|]. + iMod (bor_acc_cons with "LFT Hm' Hα") as "[Hm' Hclose2]"; first done. + wp_op. iDestruct "Hm'" as (vl) "[H↦ Hm']". + destruct vl as [|[[|m'|]|] vl]; try done. simpl. + iDestruct (heap_mapsto_vec_cons with "H↦") as "[H↦1 H↦2]". + iDestruct "Hm'" as "[% Hvl]". + iMod ("Hclose2" $! (shift_loc lm' 1 ↦∗: ty_own ty tid)%I with "[H↦1] [H↦2 Hvl]") as "[Hbor Hα]". + { iIntros "!> Hlm' !>". iNext. clear vl. iDestruct "Hlm'" as (vl) "[H↦ Hlm']". + iExists (_ :: _). rewrite heap_mapsto_vec_cons. do 2 iFrame. done. } + { iExists vl. iFrame. } + iMod ("Hclose1" with "Hα HL") as "HL". + (* Switch back to typing mode. *) + iApply (type_type _ _ _ [ m â— own_ptr _ _; #(shift_loc lm' 1) â— &uniq{α} ty] + with "[] LFT HE Hna HL Hk"); last first. + { rewrite tctx_interp_cons tctx_interp_singleton tctx_hasty_val tctx_hasty_val' //. + unlock. iFrame. } + iApply type_assign; [solve_typing..|]. + iApply type_jump; solve_typing. + Qed. + End code. diff --git a/theories/typing/lib/mutex/mutexguard.v b/theories/typing/lib/mutex/mutexguard.v index 64050f8493240edc0ae58b4a6a45316b8e38a8db..66a94e0da26cd239cc151f782597323caccaacfa 100644 --- a/theories/typing/lib/mutex/mutexguard.v +++ b/theories/typing/lib/mutex/mutexguard.v @@ -79,6 +79,18 @@ Section mguard. Global Instance mutexguard_wf α ty `{!TyWf ty} : TyWf (mutexguard α ty) := { ty_lfts := [α]; ty_wf_E := ty.(ty_wf_E) ++ ty.(ty_outlives_E) α }. + Global Instance mutexguard_type_contractive α : TypeContractive (mutexguard α). + Proof. + constructor; + solve_proper_core ltac:(fun _ => f_type_equiv || f_contractive || f_equiv + || exact: type_dist2_S). + Qed. + Global Instance mutexguard_ne α : NonExpansive (mutexguard α). + Proof. apply type_contractive_ne, _. Qed. + + (* TODO: compat with lft_incl and eqtype. + MutexGuard is Sync if T is Send. *) + End mguard. Section code. @@ -255,4 +267,7 @@ Section code. iApply type_jump; solve_typing. Qed. + (* TODO: + Should we do try_lock? + *) End code. diff --git a/theories/typing/lib/rwlock/rwlockreadguard.v b/theories/typing/lib/rwlock/rwlockreadguard.v index 3f44a88e8d599be379c2eae4b57633218ad58169..e21b832db4572cca59bddef14991fea16e7d788e 100644 --- a/theories/typing/lib/rwlock/rwlockreadguard.v +++ b/theories/typing/lib/rwlock/rwlockreadguard.v @@ -112,6 +112,8 @@ Section rwlockreadguard. lctx_lft_eq E L α1 α2 → eqtype E L ty1 ty2 → eqtype E L (rwlockreadguard α1 ty1) (rwlockreadguard α2 ty2). Proof. intros. by eapply rwlockreadguard_proper. Qed. + + (* TODO: In Rust, the read guard is Sync if ty is Send+Sync. *) End rwlockreadguard. Hint Resolve rwlockreadguard_mono' rwlockreadguard_proper' : lrust_typing. diff --git a/theories/typing/lib/rwlock/rwlockwriteguard.v b/theories/typing/lib/rwlock/rwlockwriteguard.v index 9da6cf5008effcd6916818affd5c5eafddf605b3..400022088ee7966bcb1b2c3af170eb8f8a20020f 100644 --- a/theories/typing/lib/rwlock/rwlockwriteguard.v +++ b/theories/typing/lib/rwlock/rwlockwriteguard.v @@ -115,6 +115,8 @@ Section rwlockwriteguard. lctx_lft_eq E L α1 α2 → eqtype E L ty1 ty2 → eqtype E L (rwlockwriteguard α1 ty1) (rwlockwriteguard α2 ty2). Proof. intros. by eapply rwlockwriteguard_proper. Qed. + + (* TODO: In Rust, the read guard is Sync if ty is Send+Sync. *) End rwlockwriteguard. Hint Resolve rwlockwriteguard_mono' rwlockwriteguard_proper' : lrust_typing. diff --git a/theories/typing/lib/spawn.v b/theories/typing/lib/spawn.v index 8f2715c72ff4ce71959582900109e4e1d18a9770..aa8eb563b2fba3e6a8171c05d8cc1b3670e9af14 100644 --- a/theories/typing/lib/spawn.v +++ b/theories/typing/lib/spawn.v @@ -56,6 +56,9 @@ Section join_handle. Qed. Global Instance join_handle_ne : NonExpansive join_handle. Proof. apply type_contractive_ne, _. Qed. + + (* TODO: Looks like in Rust, we have T: Send -> JoinHandle<T>: Send and + T:Sync -> JoinHandle<T>: Sync. *) End join_handle. Section spawn.