Update intrinsics def file to be more explicit.

This Cl updates the `def` syntax to make the implicit parameters more
explicit. This makes the file easier to read (removes the `[]` syntax)
and also removes the implicit parameters from within the function
signature which also enhances readability.

Change-Id: I8a8f5e1cf78b025ed3c680c08ba0fc304e8c7f21
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/202434
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/tools/src/tint/intrinsic/lexer/lexer.go b/tools/src/tint/intrinsic/lexer/lexer.go
index 7aefb2e..d40e2bc 100644
--- a/tools/src/tint/intrinsic/lexer/lexer.go
+++ b/tools/src/tint/intrinsic/lexer/lexer.go
@@ -125,6 +125,8 @@
 					l.tok(n, tok.Match)
 				case "import":
 					l.tok(n, tok.Import)
+				case "implicit":
+					l.tok(n, tok.Implicit)
 				default:
 					l.tok(n, tok.Identifier)
 				}
diff --git a/tools/src/tint/intrinsic/parser/parser.go b/tools/src/tint/intrinsic/parser/parser.go
index fb06b75..e1d58ff 100644
--- a/tools/src/tint/intrinsic/parser/parser.go
+++ b/tools/src/tint/intrinsic/parser/parser.go
@@ -65,6 +65,7 @@
 
 func (p *parser) parse(out *ast.AST) error {
 	var attributes ast.Attributes
+	var implicitParams []ast.TemplateParam
 	for p.err == nil {
 		t := p.peek(0)
 		if t == nil {
@@ -77,32 +78,56 @@
 			if len(attributes) > 0 {
 				p.err = fmt.Errorf("%v unexpected attribute", attributes[0].Source)
 			}
+			if len(implicitParams) > 0 {
+				p.err = fmt.Errorf("%v unexpected implicitParams", implicitParams[0].Source)
+			}
 			out.Enums = append(out.Enums, p.enumDecl())
 		case tok.Match:
 			if len(attributes) > 0 {
 				p.err = fmt.Errorf("%v unexpected attribute", attributes[0].Source)
 			}
+			if len(implicitParams) > 0 {
+				p.err = fmt.Errorf("%v unexpected implicitParams", implicitParams[0].Source)
+			}
 			out.Matchers = append(out.Matchers, p.matcherDecl())
 		case tok.Import:
 			if len(attributes) > 0 {
 				p.err = fmt.Errorf("%v unexpected attribute", attributes[0].Source)
 			}
+			if len(implicitParams) > 0 {
+				p.err = fmt.Errorf("%v unexpected implicitParams", implicitParams[0].Source)
+			}
 			p.importDecl(out)
 		case tok.Type:
+			if len(implicitParams) > 0 {
+				p.err = fmt.Errorf("%v unexpected implicitParams", implicitParams[0].Source)
+			}
 			out.Types = append(out.Types, p.typeDecl(attributes))
 			attributes = nil
 		case tok.Function:
-			out.Builtins = append(out.Builtins, p.builtinDecl(attributes))
+			out.Builtins = append(out.Builtins, p.builtinDecl(attributes, implicitParams))
 			attributes = nil
+			implicitParams = nil
 		case tok.Operator:
-			out.Operators = append(out.Operators, p.operatorDecl(attributes))
+			out.Operators = append(out.Operators, p.operatorDecl(attributes, implicitParams))
 			attributes = nil
+			implicitParams = nil
 		case tok.Constructor:
-			out.Constructors = append(out.Constructors, p.constructorDecl(attributes))
+			out.Constructors = append(out.Constructors, p.constructorDecl(attributes, implicitParams))
 			attributes = nil
+			implicitParams = nil
 		case tok.Converter:
-			out.Converters = append(out.Converters, p.converterDecl(attributes))
+			out.Converters = append(out.Converters, p.converterDecl(attributes, implicitParams))
 			attributes = nil
+			implicitParams = nil
+		case tok.Implicit:
+			p.expect(tok.Implicit, "implicit")
+			p.expect(tok.Lparen, "implicit template parameter list")
+			for p.err == nil && p.peekIs(0, tok.Identifier) {
+				implicitParams = append(implicitParams, p.templateParam())
+			}
+			p.expect(tok.Rparen, "implicit template parameter list")
+
 		default:
 			p.err = fmt.Errorf("%v unexpected token '%v'", t.Source, t.Kind)
 		}
@@ -219,7 +244,7 @@
 	return out
 }
 
-func (p *parser) builtinDecl(decos ast.Attributes) ast.IntrinsicDecl {
+func (p *parser) builtinDecl(decos ast.Attributes, implicitParams []ast.TemplateParam) ast.IntrinsicDecl {
 	p.expect(tok.Function, "function declaration")
 	name := p.expect(tok.Identifier, "function name")
 	f := ast.IntrinsicDecl{
@@ -228,7 +253,8 @@
 		Attributes: decos,
 		Name:       string(name.Runes),
 	}
-	f.ExplicitTemplateParams, f.ImplicitTemplateParams = p.intrinsicTemplateParams()
+	f.ExplicitTemplateParams = p.intrinsicTemplateParams()
+	f.ImplicitTemplateParams = implicitParams
 	f.Parameters = p.parameters()
 	if p.match(tok.Arrow) != nil {
 		ret := p.templatedName()
@@ -237,7 +263,7 @@
 	return f
 }
 
-func (p *parser) operatorDecl(decos ast.Attributes) ast.IntrinsicDecl {
+func (p *parser) operatorDecl(decos ast.Attributes, implicitParams []ast.TemplateParam) ast.IntrinsicDecl {
 	p.expect(tok.Operator, "operator declaration")
 	name := p.next()
 	f := ast.IntrinsicDecl{
@@ -246,7 +272,8 @@
 		Attributes: decos,
 		Name:       string(name.Runes),
 	}
-	f.ExplicitTemplateParams, f.ImplicitTemplateParams = p.intrinsicTemplateParams()
+	f.ExplicitTemplateParams = p.intrinsicTemplateParams()
+	f.ImplicitTemplateParams = implicitParams
 	f.Parameters = p.parameters()
 	if p.match(tok.Arrow) != nil {
 		ret := p.templatedName()
@@ -255,7 +282,7 @@
 	return f
 }
 
-func (p *parser) constructorDecl(decos ast.Attributes) ast.IntrinsicDecl {
+func (p *parser) constructorDecl(decos ast.Attributes, implicitParams []ast.TemplateParam) ast.IntrinsicDecl {
 	p.expect(tok.Constructor, "constructor declaration")
 	name := p.next()
 	f := ast.IntrinsicDecl{
@@ -264,7 +291,8 @@
 		Attributes: decos,
 		Name:       string(name.Runes),
 	}
-	f.ExplicitTemplateParams, f.ImplicitTemplateParams = p.intrinsicTemplateParams()
+	f.ExplicitTemplateParams = p.intrinsicTemplateParams()
+	f.ImplicitTemplateParams = implicitParams
 	f.Parameters = p.parameters()
 	if p.match(tok.Arrow) != nil {
 		ret := p.templatedName()
@@ -273,7 +301,7 @@
 	return f
 }
 
-func (p *parser) converterDecl(decos ast.Attributes) ast.IntrinsicDecl {
+func (p *parser) converterDecl(decos ast.Attributes, implicitParams []ast.TemplateParam) ast.IntrinsicDecl {
 	p.expect(tok.Converter, "converter declaration")
 	name := p.next()
 	f := ast.IntrinsicDecl{
@@ -282,7 +310,8 @@
 		Attributes: decos,
 		Name:       string(name.Runes),
 	}
-	f.ExplicitTemplateParams, f.ImplicitTemplateParams = p.intrinsicTemplateParams()
+	f.ExplicitTemplateParams = p.intrinsicTemplateParams()
+	f.ImplicitTemplateParams = implicitParams
 	f.Parameters = p.parameters()
 	if p.match(tok.Arrow) != nil {
 		ret := p.templatedName()
@@ -371,20 +400,14 @@
 	return t
 }
 
-func (p *parser) intrinsicTemplateParams() (explicit, implicit []ast.TemplateParam) {
+func (p *parser) intrinsicTemplateParams() (explicit []ast.TemplateParam) {
 	if p.match(tok.Lt) != nil { // <...>
 		for p.err == nil && p.peekIs(0, tok.Identifier) {
 			explicit = append(explicit, p.templateParam())
 		}
 		p.expect(tok.Gt, "explicit template parameter list")
 	}
-	if p.match(tok.Lbracket) != nil { // [...]
-		for p.err == nil && p.peekIs(0, tok.Identifier) {
-			implicit = append(implicit, p.templateParam())
-		}
-		p.expect(tok.Rbracket, "implicit template parameter list")
-	}
-	return explicit, implicit
+	return explicit
 }
 
 func (p *parser) templateParam() ast.TemplateParam {
diff --git a/tools/src/tint/intrinsic/parser/parser_test.go b/tools/src/tint/intrinsic/parser/parser_test.go
index 21b4e92..cdf34b6 100644
--- a/tools/src/tint/intrinsic/parser/parser_test.go
+++ b/tools/src/tint/intrinsic/parser/parser_test.go
@@ -290,7 +290,7 @@
 			},
 		}, { ///////////////////////////////////////////////////////////////////
 			fileutils.ThisLine(),
-			"fn F[A : B<C>]()",
+			"implicit(A : B<C>) fn F()",
 			ast.AST{
 				Builtins: []ast.IntrinsicDecl{{
 					Kind: ast.Builtin,
@@ -311,7 +311,7 @@
 			},
 		}, { ///////////////////////////////////////////////////////////////////
 			fileutils.ThisLine(),
-			"fn F[T](a: X, b: Y<T>)",
+			"implicit(T) fn F(a: X, b: Y<T>)",
 			ast.AST{
 				Builtins: []ast.IntrinsicDecl{{
 					Kind: ast.Builtin,
@@ -330,7 +330,7 @@
 			},
 		}, { ///////////////////////////////////////////////////////////////////
 			fileutils.ThisLine(),
-			"fn F<A>[B: C<D>]()",
+			"implicit(B: C<D>) fn F<A>()",
 			ast.AST{
 				Builtins: []ast.IntrinsicDecl{{
 					Kind: ast.Builtin,
@@ -354,7 +354,7 @@
 			},
 		}, { ///////////////////////////////////////////////////////////////////
 			fileutils.ThisLine(),
-			"fn F[T](a: X, b: Y<T>)",
+			"implicit(T) fn F(a: X, b: Y<T>)",
 			ast.AST{
 				Builtins: []ast.IntrinsicDecl{{
 					Kind: ast.Builtin,
@@ -511,7 +511,7 @@
 			},
 		}, { ///////////////////////////////////////////////////////////////////
 			fileutils.ThisLine(),
-			"op F[A : B<C>]()",
+			"implicit(A : B<C>) op F()",
 			ast.AST{
 				Operators: []ast.IntrinsicDecl{{
 					Kind: ast.Operator,
@@ -531,7 +531,7 @@
 			},
 		}, { ///////////////////////////////////////////////////////////////////
 			fileutils.ThisLine(),
-			"op F[T](a: X, b: Y<T>)",
+			"implicit(T) op F(a: X, b: Y<T>)",
 			ast.AST{
 				Operators: []ast.IntrinsicDecl{{
 					Kind: ast.Operator,
@@ -550,7 +550,7 @@
 			},
 		}, { ///////////////////////////////////////////////////////////////////
 			fileutils.ThisLine(),
-			"op F<A : B<C> >[D]()",
+			"implicit(D) op F<A : B<C> >()",
 			ast.AST{
 				Operators: []ast.IntrinsicDecl{{
 					Kind: ast.Operator,
diff --git a/tools/src/tint/intrinsic/resolver/resolver_test.go b/tools/src/tint/intrinsic/resolver/resolver_test.go
index f32c774..d507f52 100644
--- a/tools/src/tint/intrinsic/resolver/resolver_test.go
+++ b/tools/src/tint/intrinsic/resolver/resolver_test.go
@@ -73,7 +73,7 @@
 			`fn f()`,
 			success,
 		}, {
-			`fn f[T]()`,
+			`implicit(T) fn f()`,
 			success,
 		}, {
 			`
@@ -83,34 +83,34 @@
 		}, {
 			`
 type f32
-fn f[N: num]()`,
+implicit(N: num) fn f()`,
 			success,
 		}, {
 			`
 enum e { a b c }
-fn f[N: e]()`,
+implicit(N: e) fn f()`,
 			success,
 		}, {
 			`
 type f32
-fn f[T](T) -> f32`,
+implicit(T) fn f(T) -> f32`,
 			success,
 		}, {
 			`
 type f32
-fn f<T: f32>[N: num]()`,
+implicit(N: num) fn f<T: f32>()`,
 			success,
 		}, {
 			`
 type f32
-fn f[T: f32](T: f32) -> f32`,
+implicit(T: f32) fn f(T: f32) -> f32`,
 			success,
 		}, {
 			`
 type f32
 type P<T>
 match m: f32
-fn f[T: m](P<T>) -> T`,
+implicit(T: m) fn f(P<T>) -> T`,
 			success,
 		}, {
 			`
@@ -142,21 +142,21 @@
 		}, {
 			`
 type T<E: num>
-fn f[E: num](T<E>)`,
+implicit(E: num) fn f(T<E>)`,
 			success,
 		}, {
-			`fn f[T](T)`,
+			`implicit(T) fn f(T)`,
 			success,
 		}, {
 			`
 enum e { a b }
-fn f[E: e]()`,
+implicit(E: e) fn f()`,
 			success,
 		}, {
 			`
 enum e { a b }
 match m: e.a | e.b
-fn f[E: m]()`,
+implicit(E: m) fn f()`,
 			success,
 		}, {
 			`
@@ -171,7 +171,7 @@
 type c
 match S: a | b | c
 type V<N: num, T>
-fn f<I: V<N, T> >[N: num, T: S, U: S](V<N, U>) -> I`,
+implicit(N: num, T: S, U: S) fn f<I: V<N, T> >(V<N, U>) -> I`,
 			success,
 		}, {
 			`
@@ -322,8 +322,8 @@
 			`fn f() -> u`,
 			`file.txt:1:11 cannot resolve 'u'`,
 		}, {
-			`fn f[T: u]()`,
-			`file.txt:1:9 cannot resolve 'u'`,
+			`implicit(T: u) fn f()`,
+			`file.txt:1:13 cannot resolve 'u'`,
 		}, {
 			`
 enum e { a }
@@ -337,8 +337,8 @@
 		}, {
 			`
 type x
-fn f[T](T<x>)`,
-			`file.txt:2:9 'T' template parameters do not accept template arguments`,
+implicit(T) fn f(T<x>)`,
+			`file.txt:2:18 'T' template parameters do not accept template arguments`,
 		}, {
 			`
 type A<N: num>
@@ -370,8 +370,8 @@
 type P<N: num>
 enum E { a b }
 match m: E.a | E.b
-fn f[M: m](P<M>)`,
-			`file.txt:4:14 cannot use template enum 'E' as template number`,
+implicit(M: m) fn f(P<M>)`,
+			`file.txt:4:23 cannot use template enum 'E' as template number`,
 		}, {
 			`
 type i
@@ -395,8 +395,8 @@
 		}, {
 			`
 type x
-op << [T](T<x>)`,
-			`file.txt:2:11 'T' template parameters do not accept template arguments`,
+implicit(T) op << (T<x>)`,
+			`file.txt:2:20 'T' template parameters do not accept template arguments`,
 		}, {
 			`
 type A<N: num>
@@ -435,8 +435,8 @@
 type P<N: num>
 enum E { a b }
 match m: E.a | E.b
-op << [M: m](P<M>)`,
-			`file.txt:4:16 cannot use template enum 'E' as template number`,
+implicit(M: m) op << (P<M>)`,
+			`file.txt:4:25 cannot use template enum 'E' as template number`,
 		}, {
 			`
 type i
@@ -451,8 +451,8 @@
 		}, {
 			`
 type x
-ctor F[T](T<x>)`,
-			`file.txt:2:11 'T' template parameters do not accept template arguments`,
+implicit(T) ctor F(T<x>)`,
+			`file.txt:2:20 'T' template parameters do not accept template arguments`,
 		}, {
 			`
 type A<N: num>
@@ -491,8 +491,8 @@
 type P<N: num>
 enum E { a b }
 match m: E.a | E.b
-ctor F[M: m](P<M>)`,
-			`file.txt:4:16 cannot use template enum 'E' as template number`,
+implicit(M: m) ctor F(P<M>)`,
+			`file.txt:4:25 cannot use template enum 'E' as template number`,
 		}, {
 			`
 conv F()`,
@@ -516,8 +516,8 @@
 		}, {
 			`
 type x
-conv F[T](T<x>)`,
-			`file.txt:2:11 'T' template parameters do not accept template arguments`,
+implicit(T) conv F(T<x>)`,
+			`file.txt:2:20 'T' template parameters do not accept template arguments`,
 		}, {
 			`
 type A<N: num>
@@ -556,8 +556,8 @@
 type P<N: num>
 enum E { a b }
 match m: E.a | E.b
-conv F[M: m](P<M>)`,
-			`file.txt:4:16 cannot use template enum 'E' as template number`,
+implicit(M: m) conv F(P<M>)`,
+			`file.txt:4:25 cannot use template enum 'E' as template number`,
 		}, {
 			`
 @must_use fn f()`,
@@ -590,9 +590,9 @@
 			`file.txt:4:6 explicit number template parameters are not supported`,
 		}, {
 			`
-fn f<T>[T]()`,
-			`file.txt:1:6 'T' already declared
-First declared here: file.txt:1:9`,
+implicit(T) fn f<T>()`,
+			`file.txt:1:18 'T' already declared
+First declared here: file.txt:1:10`,
 		},
 	} {
 
diff --git a/tools/src/tint/intrinsic/tok/tok.go b/tools/src/tint/intrinsic/tok/tok.go
index d9711fc..02532bf 100644
--- a/tools/src/tint/intrinsic/tok/tok.go
+++ b/tools/src/tint/intrinsic/tok/tok.go
@@ -43,6 +43,7 @@
 	String       Kind = "string"
 	Match        Kind = "match"
 	Import       Kind = "import"
+	Implicit     Kind = "implicit"
 	Function     Kind = "fn"
 	Operator     Kind = "op"
 	Constructor  Kind = "ctor"