// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
// Source: ../../cmd/compile/internal/types2/cycles.go

// Copyright 2025 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.

package types

import 

// directCycles searches for direct cycles among package level type declarations.
// See directCycle for details.
func ( *Checker) () {
	 := make(map[*TypeName]int)
	for ,  := range .objList {
		if ,  := .(*TypeName);  {
			.directCycle(, )
		}
	}
}

// directCycle checks if the declaration of the type given by tname contains a direct cycle.
// A direct cycle exists if the path from tname's declaration's RHS leads from type name to
// type name and eventually ends up on that path again, via regular or alias declarations;
// in other words if there are no type literals (or basic types) on the path, and the path
// doesn't end in an undeclared object.
// If a cycle is detected, a cycle error is reported and the type at the start of the cycle
// is marked as invalid.
//
// The pathIdx map tracks which type names have been processed. An entry can be
// in 1 of 3 states as used in a typical 3-state (white/grey/black) graph marking
// algorithm for cycle detection:
//
//   - entry not found: tname has not been seen before (white)
//   - value is >= 0  : tname has been seen but is not done (grey); the value is the path index
//   - value is <  0  : tname has been seen and is done (black)
//
// When directCycle returns, the pathIdx entries for all type names on the path
// that starts at tname are marked black, regardless of whether there was a cycle.
// This ensures that a type name is traversed only once.
func ( *Checker) ( *TypeName,  map[*TypeName]int) {
	if debug && .conf._Trace {
		.trace(.Pos(), "-- check direct cycle for %s", )
	}

	var  []*TypeName
	for {
		,  := []
		if  < 0 {
			// tname is marked black - do not traverse it again.
			// (start can only be < 0 if it was found in the first place)
			break
		}

		if  {
			// tname is marked grey - we have a cycle on the path beginning at start.
			// Mark tname as invalid.
			.setType(Typ[Invalid])

			// collect type names on cycle
			var  []Object
			for ,  := range [:] {
				 = append(, )
			}

			.cycleError(, firstInSrc())
			break
		}

		// tname is marked white - mark it grey and add it to the path.
		[] = len()
		 = append(, )

		// For direct cycle detection, we don't care about whether we have an alias or not.
		// If the associated type is not a name, we're at the end of the path and we're done.
		,  := .objMap[].tdecl.Type.(*ast.Ident)
		if ! {
			break
		}

		// Determine the RHS type. If it is not found in the package scope, we either
		// have an error (which will be reported later), or the type exists elsewhere
		// (universe scope, file scope via dot-import) and a cycle is not possible in
		// the first place. If it is not a type name, we cannot have a direct cycle
		// either. In all these cases we can stop.
		,  := .pkg.scope.Lookup(.Name).(*TypeName)
		if ! {
			break
		}

		// Otherwise, continue with the RHS.
		 = 
	}

	// Mark all traversed type names black.
	// (ensure that pathIdx doesn't contain any grey entries upon returning)
	for ,  := range  {
		[] = -1
	}

	if debug {
		for ,  := range  {
			assert( < 0)
		}
	}
}

// isComplete returns whether a type is complete (i.e. up to having an underlying type).
// Incomplete types will panic if [Type.Underlying] is called on them.
func ( *Checker) ( Type) bool {
	var (
		 Object
		 Type
	)
	switch t := .(type) {
	case *Alias:
		 = .obj
		 = .fromRHS
	case *Named:
		 = .obj
		 = .fromRHS
	default:
		return true
	}

	if ,  := .objPathIdx[];  {
		 := .objPath[:]
		.cycleError(, firstInSrc())
		return false
	}

	// We must walk through names because we permit certain cycles of names.
	// Consider:
	//
	//   type A B
	//   type B [unsafe.Sizeof(A{})]int
	//
	// starting at B. At the site of A{}, A has no underlying type, and so a
	// cycle must be reported.
	return .()
}