From 68fe71f0153bb6062754442c0a61c075b58fd9bc Mon Sep 17 00:00:00 2001 From: Rich Hickey Date: Wed, 1 Jun 2016 09:47:14 -0400 Subject: [PATCH] explain tail of single-pred cat --- src/clj/clojure/spec.clj | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/clj/clojure/spec.clj b/src/clj/clojure/spec.clj index 02c4675164..b3dfe468e3 100644 --- a/src/clj/clojure/spec.clj +++ b/src/clj/clojure/spec.clj @@ -1168,8 +1168,8 @@ by ns-syms. Idempotent." (defn- op-explain [form p path via in input] ;;(prn {:form form :p p :path path :input input}) (let [[x :as input] input - via (if-let [name (spec-name p)] (conj via name) via) {:keys [::op ps ks forms splice p1 p2] :as p} (reg-resolve p) + via (if-let [name (spec-name p)] (conj via name) via) insufficient (fn [path form] {path {:reason "Insufficient input" :pred (abbrev form) @@ -1189,13 +1189,13 @@ by ns-syms. Idempotent." (if-let [p1 (deriv p1 x)] (explain-pred-list forms ps path via in (preturn p1)) (op-explain (op-describe p1) p1 path via in input))) - ::pcat (let [[pred k form] (->> (map vector - ps - (c/or (seq ks) (repeat nil)) - (c/or (seq forms) (repeat nil))) - (remove (fn [[p]] - (accept-nil? p))) - first) + ::pcat (let [pkfs (map vector + ps + (c/or (seq ks) (repeat nil)) + (c/or (seq forms) (repeat nil))) + [pred k form] (if (= 1 (count pkfs)) + (first pkfs) + (first (remove (fn [[p]] (accept-nil? p)) pkfs))) path (if k (conj path k) path) form (c/or form (op-describe pred))] (if (c/and (empty? input) (not pred)) @@ -1278,11 +1278,13 @@ by ns-syms. Idempotent." (if-let [dp (deriv p x)] (recur dp xs (inc i)) (if (accept? p) - {path {:reason "Extra input" - :pred (abbrev (op-describe re)) - :val data - :via via - :in (conj in i)}} + (if (= (::op p) ::pcat) + (op-explain (op-describe p) p path via (conj in i) (seq data)) + {path {:reason "Extra input" + :pred (abbrev (op-describe re)) + :val data + :via via + :in (conj in i)}}) (c/or (op-explain (op-describe p) p path via (conj in i) (seq data)) {path {:reason "Extra input" :pred (abbrev (op-describe p))