perf(lang): Defer generic signature substitution

067b5f48a1c9a56ce9455180e1911367f0bd219913a2355781f54e67fa619293
Resolve rooted and cached generic function applications before substituting the function signature. Only symbolic dependency edges need the separately applied signature.
Alexis Sellier committed ago 1 parent 2ef85b93
lib/std/lang/resolver.rad +4 -4
4219 4219
                }
4220 4220
            }
4221 4221
        }
4222 4222
        args.append(allocType(self, argType), a);
4223 4223
    }
4224 -
    let sub = Substitution { params: template.params, args: &args[..] };
4225 -
    let applied = try substituteType(self, Type::Fn(signature), &sub, node);
4226 -
    let case Type::Fn(appliedFn) = applied
4227 -
        else throw emitError(self, node, ErrorKind::Internal);
4228 4224
    if rooted {
4229 4225
        if caller <> nil {
4230 4226
            throw emitError(self, node, ErrorKind::GenericConcreteArgumentsRequired);
4231 4227
        }
4232 4228
        let specialization = try internGenericFnSpecialization(
4245 4241
            set self.nodeData.entries[node.id].extra =
4246 4242
                NodeExtra::GenericFnCall(existing);
4247 4243
            return existing.fnType;
4248 4244
        }
4249 4245
    }
4246 +
    let sub = Substitution { params: template.params, args: &args[..] };
4247 +
    let applied = try substituteType(self, Type::Fn(signature), &sub, node);
4248 +
    let case Type::Fn(appliedFn) = applied
4249 +
        else throw emitError(self, node, ErrorKind::Internal);
4250 4250
    recordGenericFnDependency(
4251 4251
        self, node, caller, templateSym, &args[..], appliedFn
4252 4252
    );
4253 4253
    return appliedFn;
4254 4254
}