Skip to content
This repository has been archived by the owner on Jan 12, 2024. It is now read-only.

Commit

Permalink
only check cycles where every callable is type parameterized (#1411)
Browse files Browse the repository at this point in the history
Co-authored-by: Bettina Heim <beheim@microsoft.com>
  • Loading branch information
bettinaheim and Bettina Heim authored Apr 14, 2022
1 parent 59be764 commit a268b34
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 5 deletions.
8 changes: 6 additions & 2 deletions src/QsCompiler/CompilationManager/TypeChecking.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1912,8 +1912,12 @@ bool InvalidCharacteristicsOrSupportedFunctors(params QsFunctor[] functors) =>
private static void UpdateDiagnosticsWithCycleVerification(CompilationUnit compilation, List<Diagnostic> diagnostics, ImmutableDictionary<QsQualifiedName, CallableDeclarationHeader> callableDeclarations)
{
// Need to consider the whole compilation to detect cycles
var callGraph = new CallGraph(compilation.GetCallables().Values);
foreach (var (diag, parent) in callGraph.VerifyAllCycles())
var callables = compilation.GetCallables();
var callGraph = new CallGraph(callables.Values);
bool CycleSelector(ImmutableArray<CallGraphNode> cycle) => // only cycles where all callables are type parameterized need to be checked
!cycle.Any(node => callables.TryGetValue(node.CallableName, out var decl) && decl.Signature.TypeParameters.IsEmpty);

foreach (var (diag, parent) in callGraph.VerifyAllCycles(CycleSelector))
{
// Only keep diagnostics for callables that are currently available in the editor
if (callableDeclarations.TryGetValue(parent, out var info))
Expand Down
10 changes: 7 additions & 3 deletions src/QsCompiler/Transformations/CallGraph/CallGraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,18 +133,22 @@ public CallGraph(QsCompilation compilation, bool trim = false)
/// Invalid cycles are those that cause type parameters to be mapped to
/// other type parameters of the same callable (constricting resolutions)
/// or to a type containing a nested reference to the same type parameter,
/// i.e Foo.A -> Foo.A[].
/// i.e Foo.A -> Foo.A[]. If a <paramref name="cycleSelector"/> is given,
/// checks only the cycles for which it returns true.
/// Returns an enumerable of tuples for each edge of each invalid cycle found,
/// each tuple containing a diagnostic and the callable name where the diagnostic
/// should be placed.
/// </summary>
public IEnumerable<(QsCompilerDiagnostic, QsQualifiedName)> VerifyAllCycles()
public IEnumerable<(QsCompilerDiagnostic, QsQualifiedName)> VerifyAllCycles(Func<ImmutableArray<CallGraphNode>, bool>? cycleSelector)
{
cycleSelector ??= _ => true;
var diagnostics = new List<(QsCompilerDiagnostic, QsQualifiedName)>();

if (this.Nodes.Any())
{
var cycles = this.GetCallCycles().SelectMany(x => CartesianProduct(this.GetEdgesWithNames(x).Reverse()));
var cycles = this.GetCallCycles()
.Where(cycleSelector)
.SelectMany(x => CartesianProduct(this.GetEdgesWithNames(x).Reverse()));
foreach (var cycle in cycles)
{
var combination = new TypeResolutionCombination(cycle.Select(edge => edge.Item1.ParamResolutions));
Expand Down

0 comments on commit a268b34

Please sign in to comment.