Get Actor (not class) canister principal in non-async context

How do I allow for a self reference to an actor to get its principal when not directly in an async/shared method
The example below is run through an http router and eventually is called, but the compiler gives me an error definedness error [M0016], cannot use Actor before Actor has been defined
but is fine if that Actor is referenced in the http_request/_update
@claudio @ggreif

Even if i switch it to an actor class and use this, it gives me the error definedness error [M0016], cannot use get before this has been defined on the |> _.getAsync("/hash", getCanisterHashAsync)

actor Actor {
    private func get(_ : Route.RouteContext) : async* Route.RouteResult {
        let ic = actor ("aaaaa-aa") : IC;
        let result = await ic.canister_info({
            canister_id = Principal.fromActor(Actor); // error - definedness error [M0016], cannot use Actor before Actor has been defined
            num_requested_changes = ?0;
        });
       ...
    };

    let pipeline = HttpPipeline.empty()
    // Router
    |> HttpRouter.use(
        _,
        HttpRouter.RouterBuilder()
        |> _.getAsync("/hash", get)
        |> _.build(),
    )
    |> HttpPipeline.build(_);

    public query func http_request(request : Http.RawQueryHttpRequest) : async Http.RawQueryHttpResponse {
        pipeline.http_request(request);
    };

    public func http_request_update(req : Http.RawUpdateHttpRequest) : async Http.RawUpdateHttpResponse {
        await* pipeline.http_request_update(req);
    };

};

I stripped it down to

import Principal "mo:base/Principal";

actor Actor {
    let canister_id = Principal.fromActor(Actor);

    private func get(_ : Int) : async* () {
        let result = {
            canister_id;
            num_requested_changes = ?0;
        };
    };
};

Which moc do you use? It works in the Playground.

im using dfx v0.24.3

When i copy/paste this in instead of mine I still get the erro

Stderr:
/home/gekctek/git/motoko_http/examples/basic/main.mo:138.18-138.21: warning [M0194], unused identifier get (delete or rename to wildcard `_` or `_get`)
/home/gekctek/git/motoko_http/examples/basic/main.mo:139.13-139.19: warning [M0194], unused identifier result (delete or rename to wildcard `_` or `_result`)
/home/gekctek/git/motoko_http/examples/basic/main.mo:135.1-144.2: definedness error [M0016], cannot use Actor before Actor has been defined

That is moc 0.13.4 IIRC. So the above is available since 0.13.2. You can do that workaround too. But upon reflecting, there might be a bug still lurking, as your code is morally fine. Can you strip it down and file an issue? Then we’ll look into it.

What does $(dfx cache show)/moc --version say? (You might want do dfx cache install beforehand…)

❯ $(dfx cache show)/moc --version
Motoko compiler 0.13.4 (source cphia92h-ww0hpm9k-jlgzh3ln-3mnqdwxq)

So, im not sure whats going on here, but i commented out the mops dependencies one by one and when i comment out the dev dependency test it compiles just fine

[package]
name = "http"
version = "0.0.1"
description = "A collection of HTTP tools to make http requests easy to use"
repository = "https://github.com/edjcase/motoko_http"
keywords = ["http", "router", "parser", "middleware", "web", "pipeline"]
license = "MIT"

[dependencies]
base = "0.14.0"
itertools = "0.2.2"
json = "1.0.0"
xtended-text = "1.0.0"
xtended-numbers = "0.3.1"
glob = "0.0.1"

[dev-dependencies]
# test = "2.0.0"

@ZenVoich any thoughts on why this would be a thing?

That would be weird. I did

$ dfxvm default 0.24.3
info: using existing install for dfx 0.24.3
info: set default version to dfx 0.24.3

$(dfx cache show)/moc --version
Motoko compiler 0.13.4 (source dbxci4cq-zk2bhl2g-gxc564v5-ilxpj21z)

$ cat test.mo
import Principal "mo:base/Principal";

actor Actor {
    let canister_id = Principal.fromActor(Actor);

    private func get(_ : Int) : async* () {
        let result = {
            canister_id;
            num_requested_changes = ?0;
        };
    };
};

$(dfx cache show)/moc -c test.mo --package base $(dfx cache show)/base
test.mo:6.18-6.21: warning [M0194], unused identifier get (delete or rename to wildcard `_` or `_get`)
test.mo:7.13-7.19: warning [M0194], unused identifier result (delete or rename to wildcard `_` or `_result`)

… and it compiles!

I bet it is a moc-wrapper-related issue. Please check echo $DFX_MOC_PATH.

There it is
When I comment out test = "2.0.0" I get 0.13.4
When i uncomment test = "2.0.0" I get 0.12.1

Updating MOPS to the latest version fixed the issue

@ZenVoich What does mops do?
Is it if there are any dev-dependencies something changes?

Mops caches resolved moc path to .mops/moc-<os>-<mops.tom-hash> file to reduce overhead reading config and detecting required moc version. So I suppose you updated dfx, but mops do not know that cache must be invalidated, and when you removed test mops computed a new cache file because <mops.tom-hash> changed.

I’ll consider including the dfx version in the cache file name.

For now you can just remove .mops folder or .mops/moc-* files.

Or you can specify moc version in [toolchain] section:

[toolchain]
moc = '0.13.4'