Skip to content

Commit b7a91ec

Browse files
committed
Make <type-error> conform better to the DRM
While looking at getting rid of the `<format-string-condition>` alias for `<simple-condition>` I ran into recursive errors in the test suite due to the generic tests for conditions trying to make a `<type-error>` without init args. * Rather than subclassing `(<error>, <format-string-condition>)` and having a make method that also creates the right values for `format-string:` and format-arguments:, just subclass `<error>` (as specified by the DRM) and keep the already existing condition-to-string method. * Make both value: and type: be required init keywords. Potentially controversial since they're not specified as required in the DRM, but the error is meaningless without these slots set and this would have uncovered the test suite bug right away. * Add `make-condition(<type-error>)` method in dylan-test-suite that passes value: and type: init args. * Treat `<slot-type-error>` similarly to `<type-error>`
1 parent 54f53bb commit b7a91ec

File tree

6 files changed

+40
-30
lines changed

6 files changed

+40
-30
lines changed

documentation/source/library-reference/common-dylan/common-extensions.rst

+13-4
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ The extensions are:
132132
.. generic-function:: condition-to-string
133133
:open:
134134

135-
Returns a string representation of a condition object.
135+
Returns a :drm:`<string>` representation of a condition object.
136136

137137
:signature: condition-to-string *condition* => *string*
138138

@@ -142,9 +142,18 @@ The extensions are:
142142
:description:
143143

144144
Returns a string representation of a general instance of
145-
:drm:`<condition>`. There is a method on
146-
:class:`<format-string-condition>` and method on
147-
:drm:`<type-error>`.
145+
:drm:`<condition>`.
146+
147+
For many condition classes it is sufficient to subclass
148+
:drm:`<simple-error>`, :drm:`<simple-warning>`, or :drm:`<simple-restart>`
149+
and to use the ``format-string:`` and ``format-arguments:`` init keywords
150+
they provide (via their superclass :class:`<simple-condition>`) in order
151+
to control how the error is displayed to the user. However, in cases where
152+
that is insufficient, this method should be implemented.
153+
154+
:seealso:
155+
156+
- :class:`<simple-condition>`
148157

149158
.. macro:: debug-assert
150159
:statement:

sources/common-dylan/format.dylan

+11
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,17 @@ define method condition-to-string
595595
type-error-expected-type(error))
596596
end method condition-to-string;
597597

598+
define method condition-to-string
599+
(err :: <slot-type-error>) => (s :: <string>)
600+
let descriptor = err.slot-type-error-slot-descriptor;
601+
format-to-string("Incorrect type for the %= init-keyword to %=. "
602+
"The given value, %=, is not of type %=.",
603+
descriptor.init-keyword,
604+
descriptor.slot-owner,
605+
err.type-error-value,
606+
err.type-error-expected-type)
607+
end method;
608+
598609
define method print-pretty-name
599610
(buffer :: <string-buffer>, condition :: <condition>)
600611
=> ()

sources/common-dylan/tests/condition-test-utilities.dylan

+6
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ define method test-condition (condition :: <type-error>) => ()
6666
))
6767
end method test-condition;
6868

69+
define method make-condition (class == <type-error>) => (c :: <type-error>)
70+
make(<type-error>,
71+
value: #"type-error-value",
72+
type: <string>)
73+
end method;
74+
6975
define method test-condition (condition :: <simple-warning>) => ()
7076
next-method();
7177
do(method (function) function(condition) end,

sources/dylan/class.dylan

-13
Original file line numberDiff line numberDiff line change
@@ -240,19 +240,6 @@ define class <slot-type-error> (<type-error>)
240240
required-init-keyword: slot-descriptor:;
241241
end;
242242

243-
define method make
244-
(class == <slot-type-error>, #rest keys, #key value, type, slot-descriptor)
245-
=> (error :: <slot-type-error>)
246-
apply(next-method, class,
247-
format-string: "Incorrect type for the %= init-keyword to %=. "
248-
"The given value, %=, is not of type %=.",
249-
format-arguments: list(slot-descriptor.init-keyword,
250-
slot-descriptor.slot-owner,
251-
value,
252-
slot-descriptor.slot-type),
253-
keys)
254-
end method make;
255-
256243
define function keyword-value
257244
(descriptor :: <slot-descriptor>, iclass :: <implementation-class>,
258245
init-args :: <simple-object-vector>)

sources/dylan/condition-extras.dylan

+3-12
Original file line numberDiff line numberDiff line change
@@ -89,20 +89,11 @@ end method abort;
8989

9090
/// TYPE-ERRORS
9191

92-
define open class <type-error> (<error>, <format-string-condition>) // Should be sealed?
93-
constant slot type-error-value, init-keyword: value:;
94-
constant slot type-error-expected-type :: <type>, init-keyword: type:;
92+
define sealed class <type-error> (<error>)
93+
constant slot type-error-value, required-init-keyword: value:;
94+
constant slot type-error-expected-type :: <type>, required-init-keyword: type:;
9595
end class <type-error>;
9696

97-
define method make
98-
(class == <type-error>, #rest keys, #key value, type)
99-
=> (error :: <type-error>)
100-
apply(next-method, class,
101-
format-string: "%= is not of type %=",
102-
format-arguments: vector(value, type),
103-
keys)
104-
end method make;
105-
10697
define inline method check-type (value, type)
10798
unless (instance?(value, type))
10899
type-check-error(value, type)

sources/dylan/tests/specification.dylan

+7-1
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ define interface-specification-suite dylan-conditions-specification-suite ()
238238
open abstract class <serious-condition> (<condition>);
239239
sealed instantiable class <simple-error> (<error>);
240240
sealed instantiable class <simple-warning> (<warning>);
241-
sealed instantiable class <type-error> (<error>);
241+
sealed instantiable class <type-error> (<error>); // make-test-instance method below.
242242
open abstract class <warning> (<condition>);
243243

244244
/// Restarts
@@ -286,6 +286,12 @@ define interface-specification-suite dylan-conditions-specification-suite ()
286286
expected-to-fail-reason: "https://github.com/dylan-lang/opendylan/issues/1295";
287287
end dylan-conditions-specification-suite;
288288

289+
define sideways method make-test-instance (class == <type-error>) => (err :: <type-error>)
290+
make(<type-error>,
291+
value: #"type-error-value",
292+
type: <string>)
293+
end method;
294+
289295
//--- Bindings not defined by the DRM
290296
//---*** Are there any others?
291297

0 commit comments

Comments
 (0)