dfinity / motoko

Simple high-level language for writing Internet Computer canisters

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Motoko 0.11 `<system>` not working for class bodies?

Gekctek opened this issue · comments

From what I understand the classes should just put a type as the first type and calling system functions should work.
But I have this code and

public class Dao<system, TProposalContent>(
        data : StableData<TProposalContent>,
        onExecute : Proposal<TProposalContent> -> async* (),
        onReject : Proposal<TProposalContent> -> async* (),
    ) {
     // ....

        public func resetEndTimers<system>() {
            for (proposal in proposals.vals()) {
                switch (proposal.endTimerId) {
                    case (null) ();
                    case (?id) Timer.cancelTimer(id);
                };
                proposal.endTimerId := null;
                if (proposal.status == #open) {
                    let proposalDurationNanoseconds = durationToNanoseconds(proposalDuration);
                    let endTimerId = createEndTimer<system>(proposal.id, proposalDurationNanoseconds);
                    proposal.endTimerId := ?endTimerId;
                };
            };
        };
// ...
        resetEndTimers<system>(); // Always reset end timers on init

It gives me an error with resetEndTimers about system capability required, but not available
image

Am I doing this right? It seems from the docs that classes are allowed

Yes, I think that's a bug. Thanks for reporting it!

A temporary workaround might be to define the class as a type definition, without the system parameter, and a function, with the parameter returning an object. But I haven't actually tried that.

Right, I believe this currently only works with actor. Thanks for the report!

This is a bit weird, as only method calls are flagged, calls to top-level functions not!

import { debugPrint; setTimer } = "mo:⛔";

class Sys<system>() {

    func indirect<system>() {
        ignore setTimer<system>(0, false, func () : async () { debugPrint "YEPYEP!" });
    };
    
    ignore setTimer<system>(0, false, func () : async () { debugPrint "YEP!" }); // No error
    indirect<system>(); // Error!!
}

@Gekctek try to prepend ignore to the problematic line as a workaround. This puts the type checker into checking mode (as opposed to inferring mode), and that may be the crucial difference.

@Gekctek 0.11.1 will have the fix of #4453, and then you can remove the workaround I suggested above.