mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-30 10:05:00 +01:00
When resolving a constraint type, compute the fixed point of the specified rewrite constraints, as requested by @josh11b in review of #2173 and tentatively agreed as our direction. If no such fixed point exists, detect that situation and diagnose the problem. The algorithm used here is to iteratively apply all rewrites to each rewrite constraint until either one of them refers to itself, which indicates there's a cycle in the rewrite graph, or the set of rewrites converges. This algorithm has some pathological inputs in which the runtime can grow exponentially in the size of the input (indeed, the fully-rewritten set of rewrites can grow exponentially in the size of the input, so this is unavoidable), so an iteration limit is also provided.
47 lines
1.5 KiB
Plaintext
47 lines
1.5 KiB
Plaintext
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
// AUTOUPDATE
|
|
// RUN: %{explorer-run}
|
|
// RUN: %{explorer-run-trace}
|
|
// CHECK:STDOUT: result: 0
|
|
|
|
package ExplorerTest api;
|
|
|
|
interface HasTypes {
|
|
let A:! Type;
|
|
let B:! Type;
|
|
let C:! Type;
|
|
let D:! Type;
|
|
let E:! Type;
|
|
let F:! Type;
|
|
}
|
|
|
|
interface HasParams(A:! Type, B:! Type, C:! Type, D:! Type) {
|
|
let V:! HasTypes;
|
|
}
|
|
|
|
// Here we discover that there is a rewrite for `HasParams(...).V` only after
|
|
// substitution converts each one to `HasParam(X, X, X, X).V`.
|
|
fn F[X:! (HasTypes & HasParams(.Self, .Self, .Self, .Self)) where
|
|
.Self is HasParams(.A, .A, .A, .A) and
|
|
.Self is HasParams(.B, .B, .B, .B) and
|
|
.Self is HasParams(.C, .C, .C, .C) and
|
|
.Self is HasParams(.D, .D, .D, .D) and
|
|
.Self is HasParams(.E, .E, .E, .E) and
|
|
.F = .Self.(HasParams(.E, .E, .E, .E).V).A and
|
|
.E = .Self.(HasParams(.D, .D, .D, .D).V).A and
|
|
.D = .Self.(HasParams(.C, .C, .C, .C).V).A and
|
|
.C = .Self.(HasParams(.B, .B, .B, .B).V).A and
|
|
.B = .Self.(HasParams(.A, .A, .A, .A).V).A and
|
|
.A = .Self and .V = .Self](x: X) -> X.F { return x; }
|
|
|
|
impl i32 as HasTypes
|
|
where .A = .B and .B = .C and .C = .D and .D = .E and .E = .F and .F = i32 {}
|
|
impl i32 as HasParams(i32, i32, i32, i32) where .V = i32 {}
|
|
|
|
fn Main() -> i32 {
|
|
return F(0);
|
|
}
|