@@ -78,7 +78,7 @@ extern (C++) final class AliasThis : Dsymbol
7878 * Params:
7979 * sc = context
8080 * e = expression forming the `this`
81- * gag = if true do not print errors, return null instead
81+ * gag = do not print errors, return ` null` instead
8282 * findOnly = don't do further processing like resolving properties,
8383 * i.e. just return plain dotExp() result.
8484 * Returns:
@@ -93,7 +93,7 @@ Expression resolveAliasThis(Scope* sc, Expression e, bool gag = false, bool find
9393 {
9494 Loc loc = e.loc;
9595 Type tthis = (e.op == EXP .type ? e.type : null );
96- const flags = DotExpFlag.noAliasThis | (gag ? DotExpFlag.gag : 0 );
96+ const flags = cast ( DotExpFlag) (DotExpFlag .noAliasThis | (gag * DotExpFlag.gag) );
9797 uint olderrors = gag ? global.startGagging() : 0 ;
9898 e = dotExp(ad.type, sc, e, ad.aliasthis.ident, flags);
9999 if (! e || findOnly)
@@ -200,15 +200,29 @@ bool checkDeprecatedAliasThis(AliasThis at, const ref Loc loc, Scope* sc)
200200
201201/* *************************************
202202 * Check and set 'att' if 't' is a recursive 'alias this' type
203+ *
204+ * The goal is to prevent endless loops when there is a cycle in the alias this chain.
205+ * Since there is no multiple `alias this`, the chain either ends in a leaf,
206+ * or it loops back on itself as some point.
207+ *
208+ * Example: S0 -> (S1 -> S2 -> S3 -> S1)
209+ *
210+ * `S0` is not a recursive alias this, so this returns `false`, and a rewrite to `S1` can be tried.
211+ * `S1` is a recursive alias this type, but since `att` is initialized to `null`,
212+ * this still returns `false`, but `att1` is set to `S1`.
213+ * A rewrite to `S2` and `S3` can be tried, but when we want to try a rewrite to `S1` again,
214+ * we notice `att == t`, so we're back at the start of the loop, and this returns `true`.
215+ *
203216 * Params:
204- * att = type reference used to detect recursion
205- * t = 'alias this' type
217+ * att = type reference used to detect recursion. Should be initialized to `null`.
218+ * t = type of 'alias this' rewrite to attempt
206219 *
207220 * Returns:
208- * Whether the 'alias this' is recursive or not
221+ * `false` if the rewrite is safe, `true` if it would loop back around
209222 */
210223bool isRecursiveAliasThis (ref Type att, Type t)
211224{
225+ // printf("+isRecursiveAliasThis(att = %s, t = %s)\n", att ? att.toChars() : "null", t.toChars());
212226 auto tb = t.toBasetype();
213227 if (att && tb.equivalent(att))
214228 return true ;
0 commit comments