diff --git a/theories/algebra/coPset.v b/theories/algebra/coPset.v
index 2cb16063ad1fa2090bf104b3545579b18b1b49ec..796e00b7af72f9c3b2823b39806a112edaa44e77 100644
--- a/theories/algebra/coPset.v
+++ b/theories/algebra/coPset.v
@@ -51,3 +51,74 @@ Proof.
   by apply: (cmra_core_mono(A:=set_disjUR coPset)).
   Unshelve. exact (SetDisj ∅).
 Qed.
+
+(* Problem based on a failure in `namespace_map`. The goal also fails
+to typecheck if we replace [set_disj coPset] by [nat]. (The goal
+typechecks in branch `swasey/sets`.) *)
+Module Discrete_problem.
+Record my_prod {A : Type} := MyProd { my_l : A; my_r : set_disj coPset }.
+Arguments my_prod : clear implicits.
+Arguments MyProd {_} _ _.
+Definition my_inl {A : cmraT} (a : A) : my_prod A := MyProd a ε.
+Section ofe.
+  Context {A : ofeT}.
+  Instance my_dist : Dist (my_prod A) := λ n x y,
+    my_l x ≡{n}≡ my_l y ∧ my_r x = my_r y.
+  Instance my_equiv : Equiv (my_prod A) := λ x y,
+    my_l x ≡ my_l y ∧ my_r x = my_r y.
+  Lemma my_prod_ofe_mixin : OfeMixin (my_prod A).
+  Proof. by apply (iso_ofe_mixin (λ x, (my_l x, my_r x))). Qed.
+  Canonical Structure my_prodO := OfeT (my_prod A) my_prod_ofe_mixin.
+End ofe.
+Arguments my_prodO : clear implicits.
+Fail Goal ∀ {A : cmraT} (a : A), Discrete a → Discrete (my_inl a).
+Goal ∀ {A : cmraT} (a : A), @Discrete A a → @Discrete (my_prodO A) (my_inl a).
+Abort.
+End Discrete_problem.
+
+(* Here's another problem based on a failure in `namespace_map`. In
+that file, we can't apply the smart constructor [CmraT] because, it
+seems, Coq cannot infer an [OfeMixin] for [namespace_map A] which is a
+record type isomorphic to [(A * set_disj coPset)]. The following may
+be a red herring. *)
+Section prod_cmra_coPset.
+  Context {A : cmraT}.
+
+  (* We can infer mixins for [A] and [set_disj positive]. *)
+  Goal ofe_mixin (cmra_ofeO A) = ofe_mixin_of A.
+  Proof. done. Qed.
+  Goal ofe_mixin (set_disjO positive) = ofe_mixin_of (set_disj positive).
+  Proof. done. Qed.
+
+  (* We cannot infer the mixin for their product. *)
+  Set Printing All.
+  Fail Eval hnf in ofe_mixin_of (A * set_disj positive)%type.
+  (*
+    The command has indeed failed with message:
+    In environment
+    A : cmraT
+    The term "@id (ofe_car ?Ac)" has type
+    "forall _ : ofe_car ?Ac, ofe_car ?Ac" while it is expected to have type
+    "forall _ : ofe_car ?Ac, prod (cmra_car A) (set_disj positive)".
+  *)
+  Unset Printing All.
+
+  (* Aside...*)
+  Eval hnf in ofe_mixin_of (cmra_ofeO A * set_disj positive)%type.
+
+  (* We can infer a product mixin when the types are concrete. *)
+  Eval hnf in ofe_mixin_of (nat * set_disj positive)%type.
+End prod_cmra_coPset.
+(* A guess: unification and canonical structures don't trigger
+typeclass resolution (which seems to be triggered in an ad hoc
+fashion) and that leads to problems. *)
+(* A different guess: our smart constructors aren't smart enough. (They
+look fine to me.) This seems to have nothing to do with defining a type
+that assumes a canonical structure on one of its parameters (as
+discussed in
+[`ssreflect.v:313`](https://gitlab.com/coq/coq/-/blob/master/theories/ssr/ssreflect.v#L313)
+and
+[`ssrfun.v:85`](https://gitlab.com/coq/coq/-/blob/master/theories/ssr/ssrfun.v#L85)).
+How does our canonical structure subclassing [cmraT <: ofeT] compare
+to such things in ssr?
+*)
diff --git a/theories/algebra/namespace_map.v b/theories/algebra/namespace_map.v
index 6b3964dce63e71d46ef08f40346e917a939f764b..78c72d56c2d9bf287917727af6039b19bf806ce4 100644
--- a/theories/algebra/namespace_map.v
+++ b/theories/algebra/namespace_map.v
@@ -65,11 +65,11 @@ Canonical Structure namespace_mapO :=
   OfeT (namespace_map A) namespace_map_ofe_mixin.
 
 Global Instance NamespaceMap_discrete a b :
-  Discrete a → Discrete b → Discrete (NamespaceMap a b).
-Proof. intros ?? [??] [??]; split; unfold_leibniz; by eapply discrete. Qed.
+  Discrete a → Discrete (NamespaceMap a b).
+Proof. intros ? [??] [??]; split; unfold_leibniz. by eapply discrete. done. Qed.
 Global Instance namespace_map_ofe_discrete :
   OfeDiscrete A → OfeDiscrete namespace_mapO.
-Proof. intros ? [??]; apply _. Qed.
+Proof. intros ? [??]. apply _. Qed.
 End ofe.
 
 Arguments namespace_mapO : clear implicits.
@@ -86,11 +86,52 @@ Global Instance namespace_map_data_proper N :
   Proper ((≡) ==> (≡)) (@namespace_map_data A N).
 Proof. solve_proper. Qed.
 
+(* The problem with the following discrete instances isn't a failed TC
+search. *)
+Section diagnose.
+  Context (N : namespace) (a : A).
+
+  (* Here is one problem. The typeclass [Discrete] is indexed by [{B :
+  ofeT} (b : ofe_car B)], and we're passing it only [a : A] in context
+  [A : cmraT]. Rather than infer the canonical [B := cmra_ofeO A :
+  ofeT], Coq complains that `The term "a" has type "cmra_car A" while
+  it is expected to have type "ofe_car ?A".` *)
+  Fail Check Discrete a.
+  (* Coq knows how to compute the OFE for [A], it just doesn't try: *)
+  Check @Discrete A a.
+
+  (* This *seems* independent of the disjoint union RA. That's odd, as
+  the code "works" when that RA is defined differently. I can guess
+  what might be going on. Coq isn't trying to type [Discrete a] in
+  isolation, it's also trying to type [Discrete (namespace_map_data N
+  a)] which *does* depend on the disjoint union RA. One could imagine
+  Coq adjusting the type-checking problem for the former based on what
+  it learns when type-checking the latter. *)
+
+  (* The other [Discrete] assumption seems to have
+  context [namespace_map_data N a : namespace_map A]
+  and Coq fails to infer the canonical OFE [B := namespace_mapO A]. *)
+
+  Check namespace_map_data N a.	(* : namespace_map A *)
+  (* Here Coq doesn't coerce [namespace_map A] to [ofe_car ?B]. *)
+  Fail Check Discrete (namespace_map_data N a).
+  (* Here Coq doesn't like that we're suppying [@Discrete] with a
+  [Type] rather than an [ofeT]. *)
+  Fail Check @Discrete (namespace_map A) (namespace_map_data N a).
+  Check @Discrete (namespace_mapO A) (namespace_map_data N a).
+  (* FWIW, [Print Canonical Projections] reports the projection
+  `namespace_map <- ofe_car ( namespace_mapO )`. *)
+End diagnose.
+
+Fail
+Global Instance namespace_map_data_discrete N a :
+  Discrete a → Discrete (namespace_map_data N a).
 Global Instance namespace_map_data_discrete N a :
   @Discrete A a → @Discrete (namespace_mapO A) (namespace_map_data N a).
 Proof. intros. apply NamespaceMap_discrete; apply _. Qed.
-Global Instance namespace_map_token_discrete E :
-  @Discrete (namespace_mapO A) (@namespace_map_token A E).
+Fail
+Global Instance namespace_map_token_discrete E : Discrete (@namespace_map_token A E).
+Global Instance namespace_map_token_discrete E : @Discrete (namespace_mapO A) (@namespace_map_token A E).
 Proof. intros. apply NamespaceMap_discrete; apply _. Qed.
 
 Instance namespace_map_valid : Valid (namespace_map A) := λ x,
@@ -154,6 +195,11 @@ Proof.
   - eauto.
   - by intros n x y1 y2 [Hy Hy']; split; simpl; rewrite ?Hy ?Hy'.
   - Fail solve_proper.
+    (*solve_proper_prepare. f_equiv.*)
+    (* In context, we have [A : cmraT] and [x, y : namespace_map A]
+    and [H : x ≡{n}≡ y] (based on [ofe_dist (namespace_mapO (cmra_ofeO
+    A))]). Our goal is [core (namespace_map_data_proj x) ≡{n}≡ core
+    (namespace_map_data_proj y)] *)
     intros n x1 x2 [Hx Hx']. solve_proper_prepare. by rewrite Hx.
   - intros n [m1 [E1|]] [m2 [E2|]] [Hm ?]=> // -[??]; split; simplify_eq/=.
     + by rewrite -Hm.
@@ -198,9 +244,11 @@ Proof.
       as (E1&E2&?&?&?); auto using namespace_map_token_proj_validN.
     by exists (NamespaceMap m1 E1), (NamespaceMap m2 E2).
 Qed.
-
+Fail
 Canonical Structure namespace_mapR :=
   CmraT (namespace_map A) namespace_map_cmra_mixin.
+Canonical Structure namespace_mapR :=
+  CmraT (namespace_map (cmra_ofeO A)) namespace_map_cmra_mixin.
 
 Global Instance namespace_map_cmra_discrete :
   CmraDiscrete A → CmraDiscrete namespace_mapR.