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

// embedded types

package decls3

// fields with the same name at the same level cancel each other out

func _() {
	type (
		T1 struct { X int }
		T2 struct { X int }
		T3 struct { T1; T2 } // X is embedded twice at the same level via T1->X, T2->X
	)

	var t T3
	_ = t /* ERROR "no single field or method" */ .X
}

func _() {
	type (
		T1 struct { X int }
		T2 struct { T1 }
		T3 struct { T1 }
		T4 struct { T2; T3 } // X is embedded twice at the same level via T2->T1->X, T3->T1->X
	)

	var t T4
	_ = t /* ERROR "no single field or method" */ .X
}

func issue4355() {
	type (
	    T1 struct {X int}
	    T2 struct {T1}
	    T3 struct {T2}
	    T4 struct {T2}
	    T5 struct {T3; T4} // X is embedded twice at the same level via T3->T2->T1->X, T4->T2->T1->X
	)	

	var t T5
	_ = t /* ERROR "no single field or method" */ .X
}

// Embedded fields can be predeclared types.

func _() {
	type T0 struct{
		int
		float32
		f int
	}
	var x T0
	_ = x.int
	_ = x.float32
	_ = x.f

	type T1 struct{
		T0
	}
	var y T1
	_ = y.int
	_ = y.float32
	_ = y.f
}

// Borrowed from the FieldByName test cases in reflect/all_test.go.

type D1 struct {
	d int
}
type D2 struct {
	d int
}

type S0 struct {
	A, B, C int
	D1
	D2
}

type S1 struct {
	B int
	S0
}

type S2 struct {
	A int
	*S1
}

type S1x struct {
	S1
}

type S1y struct {
	S1
}

type S3 struct {
	S1x
	S2
	D, E int
	*S1y
}

type S4 struct {
	*S4
	A int
}

// The X in S6 and S7 annihilate, but they also block the X in S8.S9.
type S5 struct {
	S6
	S7
	S8
}

type S6 struct {
	X int
}

type S7 S6

type S8 struct {
	S9
}

type S9 struct {
	X int
	Y int
}

// The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9.
type S10 struct {
	S11
	S12
	S13
}

type S11 struct {
	S6
}

type S12 struct {
	S6
}

type S13 struct {
	S8
}

func _() {
	_ = struct /* ERROR "no single field or method" */ {}{}.Foo
	_ = S0{}.A
	_ = S0 /* ERROR "no single field or method" */ {}.D
	_ = S1{}.A
	_ = S1{}.B
	_ = S1{}.S0
	_ = S1{}.C
	_ = S2{}.A
	_ = S2{}.S1
	_ = S2{}.B
	_ = S2{}.C
	_ = S2 /* ERROR "no single field or method" */ {}.D
	_ = S3 /* ERROR "no single field or method" */ {}.S1
	_ = S3{}.A
	_ = S3 /* ERROR "no single field or method" */ {}.B
	_ = S3{}.D
	_ = S3{}.E
	_ = S4{}.A
	_ = S4 /* ERROR "no single field or method" */ {}.B
	_ = S5 /* ERROR "no single field or method" */ {}.X
	_ = S5{}.Y
	_ = S10 /* ERROR "no single field or method" */ {}.X
	_ = S10{}.Y
}

// Borrowed from the FieldByName benchmark in reflect/all_test.go.

type R0 struct {
	*R1
	*R2
	*R3
	*R4
}

type R1 struct {
	*R5
	*R6
	*R7
	*R8
}

type R2 R1
type R3 R1
type R4 R1

type R5 struct {
	*R9
	*R10
	*R11
	*R12
}

type R6 R5
type R7 R5
type R8 R5

type R9 struct {
	*R13
	*R14
	*R15
	*R16
}

type R10 R9
type R11 R9
type R12 R9

type R13 struct {
	*R17
	*R18
	*R19
	*R20
}

type R14 R13
type R15 R13
type R16 R13

type R17 struct {
	*R21
	*R22
	*R23
	*R24
}

type R18 R17
type R19 R17
type R20 R17

type R21 struct {
	X int
}

type R22 R21
type R23 R21
type R24 R21

var _ = R0 /* ERROR "no single field or method" */ {}.X