I’m developing a plugin that builds Rocq terms of a specific type (defined in a separate package) and adds them to the global environment as a definition. I’m using Smartlocate.global_constructor_with_alias
to get the constructors’ names and make constructor terms that I define as constant functions (otherwise the Synterp phase blows these up, leading me to think this is a bad design pattern) i.e.
let my_constructor () =
mkConstructU(
SmartLocate.global_constructor_with_alias
(Libnames.qualid_of_string "Foo.my_constructor"),
EInstance.empty)
I have a Loader.v
file for my plugin that looks like:
Require Export Foo.
Declare ML Module "myplugin.plugin".
and this builds fine.
However when I Require Import Loader.
in a different .v file, it generates a Nametab.GlobalizationError
exception that stems from the SmartLocate
function call. This exception disappears if I Require Import Foo.
before Require Import Loader.
With this situation my questions are:
-
What is happening here? My expectations are that when
Loader
is imported, it willExport Foo
before any of the plugin code is run, ensuring that the names I want to pass to theSmartlocate functions
are in the global environment, but that doesn’t seem to be the case. -
Is there a blessed way to programmatically import Rocq libraries/modules from the plugin itself?
-
Is this pattern of using
SmartLocate
to create a shallow embedding of the constructors I want to build inherently flawed? Is there a better way to go about this? (I’m also working on a MetaCoq version of this same plugin, which I understand to be able to handle these kinds of plugins better, but I’m just interested in learning how Rocq works)