schema compile FEATURE check only xpaths with all implemented modules
diff --git a/src/schema_compile.c b/src/schema_compile.c
index 4b0e796..5b01287 100644
--- a/src/schema_compile.c
+++ b/src/schema_compile.c
@@ -1373,6 +1373,53 @@
 }
 
 /**
+ * @brief Check parsed expression for any prefixes of unimplemented modules.
+ *
+ * @param[in] ctx libyang context.
+ * @param[in] expr Parsed expression.
+ * @param[in] format Prefix format.
+ * @param[in] prefix_data Format-specific data (see ::ly_resolve_prefix()).
+ * @param[out] mod_p Optional module that is not implemented.
+ * @return Whether all the found modules are implemented or at least one is not.
+ */
+static ly_bool
+lys_compile_expr_target_is_implemented(const struct ly_ctx *ctx, const struct lyxp_expr *expr, LY_PREFIX_FORMAT format,
+        void *prefix_data, const struct lys_module **mod_p)
+{
+    uint32_t i;
+    const char *ptr, *start;
+    const struct lys_module *mod;
+
+    for (i = 0; i < expr->used; ++i) {
+        if ((expr->tokens[i] != LYXP_TOKEN_NAMETEST) && (expr->tokens[i] != LYXP_TOKEN_LITERAL)) {
+            /* token cannot have a prefix */
+            continue;
+        }
+
+        start = expr->expr + expr->tok_pos[i];
+        if (!(ptr = ly_strnchr(start, ':', expr->tok_len[i]))) {
+            /* token without a prefix */
+            continue;
+        }
+
+        if (!(mod = ly_resolve_prefix(ctx, start, ptr - start, format, prefix_data))) {
+            /* unknown prefix, do not care right now */
+            continue;
+        }
+
+        if (!mod->implemented) {
+            /* unimplemented module found */
+            if (mod_p) {
+                *mod_p = mod;
+            }
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+/**
  * @brief Check when/must expressions of a node on a complete compiled schema tree.
  *
  * @param[in] ctx Compile context.
@@ -1390,6 +1437,7 @@
     struct lysc_must *musts = NULL;
     LY_ERR ret = LY_SUCCESS;
     const struct lysc_node *op;
+    const struct lys_module *mod;
 
     memset(&tmp_set, 0, sizeof tmp_set);
     opts = LYXP_SCNODE_SCHEMA;
@@ -1444,8 +1492,16 @@
         break;
     }
 
-    /* check "when" */
     LY_ARRAY_FOR(when, u) {
+        /* first check whether all the referenced modules are implemented */
+        if (!lys_compile_expr_target_is_implemented(ctx->ctx, when[u]->cond, LY_PREF_SCHEMA_RESOLVED,
+                when[u]->prefixes, &mod)) {
+            LOGWRN(ctx->ctx, "When condition \"%s\" check skipped because referenced module \"%s\" is not implemented.",
+                    when[u]->cond->expr, mod->name);
+            continue;
+        }
+
+        /* check "when" */
         ret = lyxp_atomize(when[u]->cond, node->module, LY_PREF_SCHEMA_RESOLVED, when[u]->prefixes, when[u]->context,
                 &tmp_set, opts);
         if (ret != LY_SUCCESS) {
@@ -1482,8 +1538,16 @@
     }
 
 check_musts:
-    /* check "must" */
     LY_ARRAY_FOR(musts, u) {
+        /* first check whether all the referenced modules are implemented */
+        if (!lys_compile_expr_target_is_implemented(ctx->ctx, musts[u].cond, LY_PREF_SCHEMA_RESOLVED,
+                musts[u].prefixes, &mod)) {
+            LOGWRN(ctx->ctx, "Must condition \"%s\" check skipped because referenced module \"%s\" is not implemented.",
+                    musts[u].cond->expr, mod->name);
+            continue;
+        }
+
+        /* check "must" */
         ret = lyxp_atomize(musts[u].cond, node->module, LY_PREF_SCHEMA_RESOLVED, musts[u].prefixes, node, &tmp_set, opts);
         if (ret != LY_SUCCESS) {
             LOGVAL(ctx->ctx, LY_VLOG_LYSC, node, LYVE_SEMANTICS, "Invalid must restriction \"%s\".", musts[u].cond->expr);