| 
4668 | 4668 | 
 
  | 
4669 | 4669 | (defonce  | 
4670 | 4670 |   ^{:private true  | 
4671 |  | -     :doc "the set of paths currently being loaded by this thread"}  | 
4672 |  | -  *pending-paths* #{})  | 
 | 4671 | +     :doc "A stack of paths currently being loaded by this thread"}  | 
 | 4672 | +  *pending-paths* ())  | 
4673 | 4673 | 
 
  | 
4674 | 4674 | (defonce  | 
4675 | 4675 |   ^{:private true :doc  | 
 | 
4803 | 4803 |           (doseq [arg args]  | 
4804 | 4804 |             (apply load-lib prefix (prependss arg opts))))))))  | 
4805 | 4805 | 
 
  | 
4806 |  | -;; Public  | 
 | 4806 | +(defn- check-cyclic-dependency  | 
 | 4807 | +  "Detects and rejects non-trivial cyclic load dependencies. The  | 
 | 4808 | +  exception message shows the dependency chain with the cycle  | 
 | 4809 | +  highlighted. Ignores the trivial case of a file attempting to load  | 
 | 4810 | +  itself because that can occur when a gen-class'd class loads its  | 
 | 4811 | +  implementation."  | 
 | 4812 | +  [path]  | 
 | 4813 | +  (when (some #{path} (rest *pending-paths*))  | 
 | 4814 | +    (let [pending (map #(if (= % path) (str "[ " % " ]") %)  | 
 | 4815 | +                       (cons path *pending-paths*))  | 
 | 4816 | +          chain (apply str (interpose "->" pending))]  | 
 | 4817 | +      (throw (Exception. (str "Cyclic load dependency: " chain))))))  | 
4807 | 4818 | 
 
  | 
 | 4819 | +;; Public  | 
4808 | 4820 | 
 
  | 
4809 | 4821 | (defn require  | 
4810 | 4822 |   "Loads libs, skipping any that are already loaded. Each argument is  | 
 | 
4897 | 4909 |       (when *loading-verbosely*  | 
4898 | 4910 |         (printf "(clojure.core/load \"%s\")\n" path)  | 
4899 | 4911 |         (flush))  | 
4900 |  | -;      (throw-if (*pending-paths* path)  | 
4901 |  | -;                "cannot load '%s' again while it is loading"  | 
4902 |  | -;                path)  | 
4903 |  | -      (when-not (*pending-paths* path)  | 
 | 4912 | +      (check-cyclic-dependency path)  | 
 | 4913 | +      (when-not (= path (first *pending-paths*))  | 
4904 | 4914 |         (binding [*pending-paths* (conj *pending-paths* path)]  | 
4905 |  | -          (clojure.lang.RT/load  (.substring path 1)))))))  | 
 | 4915 | +          (clojure.lang.RT/load (.substring path 1)))))))  | 
4906 | 4916 | 
 
  | 
4907 | 4917 | (defn compile  | 
4908 | 4918 |   "Compiles the namespace named by the symbol lib into a set of  | 
 | 
0 commit comments