<commit_before>// UNREVIEWED
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file implements type unification.

package types2

import "sort"

// The unifier maintains two separate sets of type parameters x and y
// which are used to resolve type parameters in the x and y arguments
// provided to the unify call. For unidirectional unification, only
// one of these sets (say x) is provided, and then type parameters are
// only resolved for the x argument passed to unify, not the y argument
// (even if that also contains possibly the same type parameters). This
// is crucial to infer the type parameters of self-recursive calls:
//
//	func f[type P](a P) { f(a) }
//
// For the call f(a) we want to infer that the type argument for P is P.
// During unification, the parameter type P must be resolved to the type
// parameter P ("x" side), but the argument type P must be left alone so
// that unification resolves the type parameter P to P.
//
// For bidirection unification, both sets are provided. This enables
// unification to go from argument to parameter type and vice versa.
// For constraint type inference, we use bidirectional unification
// where both the x and y type parameters are identical. This is done
// by setting up one of them (using init) and then assigning its value
// to the other.

// A unifier maintains the current type parameters for x and y
// and the respective types inferred for each type parameter.
// A unifier is created by calling newUnifier.
type unifier struct {
	check *Checker
	exact bool
	x, y  tparamsList // x and y must initialized via tparamsList.init
	types []Type      // inferred types, shared by x and y
}

// newUnifier returns a new unifier.
// If exact is set, unification requires unified types to match
// exactly. If exact is not set, a named type's underlying type
// is considered if unification would fail otherwise, and the
// direction of channels is ignored.
func newUnifier(check *Checker, exact bool) *unifier {
	u := &unifier{check: check, exact: exact}
	u.x.unifier = u
	u.y.unifier = u
	return u
}

// unify attempts to unify x and y and reports whether it succeeded.
func (u *unifier) unify(x, y Type) bool {
	return u.nify(x, y, nil)
}

// A tparamsList describes a list of type parameters and the types inferred for them.
type tparamsList struct {
	unifier *unifier
	tparams []*TypeName
	// For each tparams element, there is a corresponding type slot index in indices.
	// index  < 0: unifier.types[-index] == nil
	// index == 0: no type slot allocated yet
	// index  > 0: unifier.types[index] == typ
	// Joined tparams elements share the same type slot and thus have the same index.<commit_msg>[dev.typeparams] cmd/compile/internal/types2: review of unify.go<commit_after>// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file implements type unification.

package types2

import "sort"

// The unifier maintains two separate sets of type parameters x and y
// which are used to resolve type parameters in the x and y arguments
// provided to the unify call. For unidirectional unification, only
// one of these sets (say x) is provided, and then type parameters are
// only resolved for the x argument passed to unify, not the y argument
// (even if that also contains possibly the same type parameters). This
// is crucial to infer the type parameters of self-recursive calls:
//
//	func f[P any](a P) { f(a) }
//
// For the call f(a) we want to infer that the type argument for P is P.
// During unification, the parameter type P must be resolved to the type
// parameter P ("x" side), but the argument type P must be left alone so
// that unification resolves the type parameter P to P.
//
// For bidirection unification, both sets are provided. This enables
// unification to go from argument to parameter type and vice versa.
// For constraint type inference, we use bidirectional unification
// where both the x and y type parameters are identical. This is done
// by setting up one of them (using init) and then assigning its value
// to the other.

// A unifier maintains the current type parameters for x and y
// and the respective types inferred for each type parameter.
// A unifier is created by calling newUnifier.
type unifier struct {
	check *Checker
	exact bool
	x, y  tparamsList // x and y must initialized via tparamsList.init
	types []Type      // inferred types, shared by x and y
}

// newUnifier returns a new unifier.
// If exact is set, unification requires unified types to match
// exactly. If exact is not set, a named type's underlying type
// is considered if unification would fail otherwise, and the
// direction of channels is ignored.
func newUnifier(check *Checker, exact bool) *unifier {
	u := &unifier{check: check, exact: exact}
	u.x.unifier = u
	u.y.unifier = u
	return u
}

// unify attempts to unify x and y and reports whether it succeeded.
func (u *unifier) unify(x, y Type) bool {
	return u.nify(x, y, nil)
}

// A tparamsList describes a list of type parameters and the types inferred for them.
type tparamsList struct {
	unifier *unifier
	tparams []*TypeName
	// For each tparams element, there is a corresponding type slot index in indices.
	// index  < 0: unifier.types[-index-1] == nil
	// index == 0: no type slot allocated yet
	// index  > 0: unifier.types[index-1] == typ
	// Joined tparams elements share the same type slot and thus have the same index.
{'fraction_non_alphanumeric': 0.07681365576102418, 'fraction_numerical': 0.0033783783783783786, 'mean_word_length': 3.39453125, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3507024', 'n_tokens_mistral': 1574, 'n_tokens_neox': 1534, 'n_words': 858}