@@ -85,14 +85,19 @@ let std-infer-expr(tctx: Maybe<TypeContext>, term: AST, is-scoped: Bool, used: I
8585 add-concrete-type-instance(tt, term);
8686 (tctx, let new-t) = std-infer-expr(tctx, t, false, Tail, tt);
8787 if not(is(t,new-t)) then { t = new-t; term = mk-app(asc, mk-app(t, mk-atype(tt))); };
88+ let is-nullary = false;
8889 if typeof-term(t).is-arrow and not(tt.is-arrow) and non-zero(var-name-if-var-or-lit(t)) {
90+ # This case exists for nullary constructors like TAny : Type
8991 let ftype = tctx.find-callable( var-name-if-var-or-lit(t), t0(c"Nil"), term, tt ).direct-type;
9092 tctx = tctx.ascript(term, ftype);
93+ is-nullary = true;
94+ } else if typeof-term(t) == type-any-arrow {
95+ tctx = tctx.ascript(term, tt);
9196 } else {
9297 tctx = tctx.ascript(term, typeof-term(t));
9398 };
9499 let direct-tctx = tctx.get-or(mk-tctx());
95- if not(direct-tctx.is-blob or typeof-term(t). is-arrow ) {
100+ if not(direct-tctx.is-blob or is-nullary ) {
96101 # TODO: remove the special exception for "Arrows" here, which is a workaround for raw constructors
97102 # frontend is producing ((None : TContext?)()) instead of (None() : TContext?)
98103 # the return hint stuff is working, so all the hard work is done. I think only the frontend needs to change
@@ -225,29 +230,55 @@ let std-infer-expr(tctx: Maybe<TypeContext>, term: AST, is-scoped: Bool, used: I
225230 };
226231 );
227232 Var{key2=key, token=token} => (
228- (tctx, let vt) = typeof-var(term, tctx, key2, hint.is-t(c"MustNotFresh",0) or hint.is-t(c"TailPosition",0));
229- vt = tctx.with-phi(vt, term);
230- mark-var-to-def-todo(tctx, key2, ta, term);
231- # TailPosition LocalVariables don't need to be retained because +1/-1 retain/release cancels itself out
232- if not(hint.is-t(c"TailPosition",0) and vt.is-t(c"LocalVariable",0))
233- and not(hint.is-t(c"MustNotRetain",0))
234- and not(tctx.get-or(mk-tctx()).is-blob) {
235- tctx = tctx.ascript(term, vt);
236- (tctx, term) = maybe-retain(tctx, term);
237- } else {
238- tctx = tctx.ascript(term, vt);
233+ let rewritten = false;
234+ if not non-zero(hint) {
235+ for list Tuple{sfxs1=first, sfxtt1=second} in parse-suffixes {
236+ if key2.has-suffix(sfxs1) {
237+ let lpfx1 = key2.remove-suffix(sfxs1).get-or(c"");
238+ term = mk-app( mk-lit(c":",with-key(token,c":")), mk-app( mk-lit(lpfx1,with-key(token,lpfx1)), mk-atype(sfxtt1) ) );
239+ (tctx, term) = std-infer-expr(tctx, term, is-scoped, used, ta);
240+ rewritten = true;
241+ }
242+ }
243+ };
244+ if not rewritten {
245+ (tctx, let vt) = typeof-var(term, tctx, key2, hint.is-t(c"MustNotFresh",0) or hint.is-t(c"TailPosition",0));
246+ vt = tctx.with-phi(vt, term);
247+ mark-var-to-def-todo(tctx, key2, ta, term);
248+ # TailPosition LocalVariables don't need to be retained because +1/-1 retain/release cancels itself out
249+ if not(hint.is-t(c"TailPosition",0) and vt.is-t(c"LocalVariable",0))
250+ and not(hint.is-t(c"MustNotRetain",0))
251+ and not(tctx.get-or(mk-tctx()).is-blob) {
252+ tctx = tctx.ascript(term, vt);
253+ (tctx, term) = maybe-retain(tctx, term);
254+ } else {
255+ tctx = tctx.ascript(term, vt);
256+ };
239257 };
240258 );
241259 Lit{key3=key, token=token} => (
242- if hint.is-t(c"Literal",0) {
243- tctx = tctx.ascript(term,hint);
244- } else if not(non-zero(typeof-term(term))) {
245- if hint.is-t(c"HashtableEq",2) and hint.is-datatype and key3==c"HashtableEqEOF"
246- then {
247- (tctx, let lit-tt) = tctx.apply-callable(key3, t0(c"Nil"), term, hint);
248- tctx = tctx.ascript(term, lit-tt);
249- } else {
250- tctx = tctx.ascript(term, t2(c"Arrow",t0(c"Any"),t0(c"Any")));
260+ let rewritten = false;
261+ if not non-zero(hint) {
262+ for list Tuple{sfxs2=first, sfxtt2=second} in parse-suffixes {
263+ if key3.has-suffix(sfxs2) {
264+ let lpfx2 = key3.remove-suffix(sfxs2).get-or(c"");
265+ term = mk-app( mk-lit(c":",with-key(token,c":")), mk-app( mk-lit(lpfx2,with-key(token,lpfx2)), mk-atype(sfxtt2) ) );
266+ (tctx, term) = std-infer-expr(tctx, term, is-scoped, used, ta);
267+ rewritten = true;
268+ }
269+ }
270+ };
271+ if not rewritten {
272+ if hint.is-t(c"Literal",0) {
273+ tctx = tctx.ascript(term,hint);
274+ } else if not(non-zero(typeof-term(term))) {
275+ if hint.is-t(c"HashtableEq",2) and hint.is-datatype and key3==c"HashtableEqEOF"
276+ then {
277+ (tctx, let lit-tt) = tctx.apply-callable(key3, t0(c"Nil"), term, hint);
278+ tctx = tctx.ascript(term, lit-tt);
279+ } else {
280+ tctx = tctx.ascript(term, type-any-arrow);
281+ }
251282 }
252283 }
253284 );
0 commit comments