How can I satisfy the compiler?

I get warnings every time I compile, currently:

Warning: stdlib.dg, line 5975: Parameter #2 of ($ is worn by $ top-down) can be
(partially) unbound, which violates the interface declaration at
stdlib.dg:5978.
Warning: stdlib.dg, line 5975: Parameter #2 of ($ is worn by $ top-down) can be
(partially) unbound, which violates the interface declaration at
stdlib.dg:5978.

Per dialogc -vvv, this is the issue:

(interface ($>Obj is worn by $>Actor))

($Obj is worn by $Actor)
	(if) (bound $Obj) (then)
		($Obj is $Rel $Parent)
		(if) ($Rel = #wornby) (then)
			($Parent = $Actor)
		(else)
			($Rel = #under)
			($Parent is worn by $Actor)
		(endif)
	(else)
		*($Obj is worn by $Actor top-down) %% THIS LINE
	(endif)

(interface ($>Obj is worn by $<Actor top-down))

($Obj is worn by $Actor top-down)
	*($Cover is #wornby $Actor)
	{
		($Obj = $Cover)
	(or)
		*($Obj is recursively #under $Cover top-down)
	}

The flagged line is the problem: the interface for ($ is worn by $) doesn’t require either of the parameters to be bound, so the compiler isn’t convinced that the second parameter to ($ is worn by $ top-down) is bound.

Is there any way to get rid of this warning? I tried adding (bound $Actor) before the multi-query, but that didn’t do it.

2 Likes

When has this error appeared? After writing some clothing related code?
If not, this particular error can creep up for some surprising reasons. Usually it comes down to unconventional usage of some library rules, e.g. using (recover implicit action [] $ into []) in reverse to convert [take #coin] into [take []], or closures. The fragment below from my ongoing work gives the exact same error if I remove (nonempty $) clause:

(make appearances $Rel $Loc (nonempty $Policy))
	(exhaust) {
		*($Object is $Rel $Loc)
		~($Object is hidden)
		(query $Policy $Object)
		(par)
		(appearance $Object $Rel $Loc)
		(notice $Object)
	}
1 Like

Unfortunately, there’s no clothing in the game at all. I’d cut out that whole section of the library if I didn’t think it would break something else depending on it in an unusual way.

Since the error does not give the exact place in the code that leads to this error, it can be difficult to locate the offending line. Trying to revert your changes and make the error go away in the debugger is the only way I know of to locate where it happens.

Edit: If it is closure related, checking (nonempty $Closure) like I did gets rid of the error. If it is about using a library rule with some unbound parameter while it is used in the library always with a bound parameter, a strategic placement of (fully bound $) can get rid of the error.
In the example I gave above about (recover implicit action ...) no amount fully bound checking get rid of this error. In this case the only way to remove the warnings is to rewrite an exact copy of the rule but changing its name, an using that rule instead of the library one.

Will it have any repercussions if I just ignore the warning? I was trying to silence it for the sake of automated build tools rather than because I thought it would affect anything in the game (since, no clothing), but if it can be affected by seemingly unrelated things like that, now I’m worried about spooky action at a distance getting into my code somewhere else…

If it seems unrelated to clothing, it might have no consequences. I can take a look at your code if you want. Maybe you have found a third way to trigger that error.

I have checked the code around the library and I believe this a bug in the library. This passage from the manual (Clothing)

Use ($ is worn by $) to check whether an object is currently worn by somebody, at any level of nesting.

is not commensurate with the interface declaration

(interface ($>Obj is worn by $<Actor top-down))

Either the interface should be

(interface ($>Obj is worn by $Actor top-down))

or the definition of ($Obj is worn by $Actor) needs to be corrected to this:

($Obj is worn by $Actor)
	(if) (bound $Obj) (then)
		($Obj is $Rel $Parent)
		(if) ($Rel = #wornby) (then)
			($Parent = $Actor)
		(else)
			($Rel = #under)
			($Parent is worn by $Actor)
		(endif)
	(elseif) (fully bound $Actor) (then)
		*($Obj is worn by $Actor top-down)
	(else)
		(fail)
	(endif)

And that passage in the manual needs to be changed to reflect that either one of the parameters can be unbound, but not both at the same time.

Edit: Forgot to add that the rule ($Obj is worn by $Actor top-down) works just fine with both parameters unbound, and it returns all things worn if queried multi. It is just the interface declaration that is faulty.

Edit 2: Now that I delved and tested a bit more, I am more inclined to believe that this was a simple typo in the interface declarations and both bottom up and top down interfaces should have been like

(interface ($>Obj is worn by $>Actor top-down))
...
(interface ($>Obj is worn by $>Actor bottom-up))

because both rules process unbound second parameter gracefully and guarantee that upon successful return that parameter is always fully bound.

2 Likes

Oh, of course, I should have made the check be (fully bound $). That makes sense!

1 Like