// Copyright 2025 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.

#![allow(unused_braces)]

#[macro_use]
extern crate zerocopy_renamed;

fn main() {}

// These tests cause errors which are generated by a later compilation pass than
// the other errors we generate, and so if they're compiled in the same file,
// the compiler will never get to that pass, and so we won't get the errors.

mod private {
    #[derive(TryFromBytes)]
    #[zerocopy(crate = "zerocopy_renamed")]
    pub struct StructWithNamedFields {
        pub a: u8,
        pub(self) b: u16,
    }

    const _: () = {
        let _: <StructWithNamedFields as zerocopy_renamed::HasField<
            _,
            _,
            //~[msrv]^ ERROR: type provided when a constant was expected
            { zerocopy_renamed::ident_id!(a) },
        >>::Type = 0u8;
        let _: <StructWithNamedFields as zerocopy_renamed::HasField<
            _,
            _,
            //~[msrv]^ ERROR: type provided when a constant was expected
            { zerocopy_renamed::ident_id!(b) },
        >>::Type = 0u16;
    };

    #[derive(TryFromBytes)]
    #[zerocopy(crate = "zerocopy_renamed")]
    pub struct StructWithAnonFields(pub u8, pub(self) u16);

    const _: () = {
        let _: <StructWithAnonFields as zerocopy_renamed::HasField<
            _,
            _,
            //~[msrv]^ ERROR: type provided when a constant was expected
            { zerocopy_renamed::ident_id!(0) },
        >>::Type = 0u8;
        let _: <StructWithAnonFields as zerocopy_renamed::HasField<
            _,
            _,
            //~[msrv]^ ERROR: type provided when a constant was expected
            { zerocopy_renamed::ident_id!(1) },
        >>::Type = 0u16;
    };

    #[derive(TryFromBytes)]
    #[zerocopy(crate = "zerocopy_renamed")]
    pub struct Union {
        pub a: u8,
        pub(self) b: u16,
    }

    const _: () = {
        let _: <Union as zerocopy_renamed::HasField<_, _, { zerocopy_renamed::ident_id!(a) }>>::Type = 0u8;
        //~[msrv]^ ERROR: type provided when a constant was expected
        let _: <Union as zerocopy_renamed::HasField<_, _, { zerocopy_renamed::ident_id!(b) }>>::Type = 0u16;
        //~[msrv]^ ERROR: type provided when a constant was expected
    };

    #[derive(TryFromBytes)]
    #[zerocopy(crate = "zerocopy_renamed")]
    #[repr(C)]
    pub enum Enum {
        A(u8, u16),
        B { a: u8, b: u16 },
    }

    const _: () = {
        let _: <Enum as zerocopy_renamed::HasField<_, _, { zerocopy_renamed::ident_id!(0) }>>::Type = 0u8;
        //~[msrv]^ ERROR: type provided when a constant was expected
        let _: <Enum as zerocopy_renamed::HasField<_, _, { zerocopy_renamed::ident_id!(1) }>>::Type = 0u16;
        //~[msrv]^ ERROR: type provided when a constant was expected

        let _: <Enum as zerocopy_renamed::HasField<_, _, { zerocopy_renamed::ident_id!(a) }>>::Type = 0u8;
        //~[msrv]^ ERROR: type provided when a constant was expected
        let _: <Enum as zerocopy_renamed::HasField<
            _,
            { zerocopy_renamed::ident_id!(B) },
            { zerocopy_renamed::ident_id!(b) },
        >>::Type = 0u16;
    };
}

use private::*;

const _: () = {
    let _: <StructWithNamedFields as zerocopy_renamed::HasField<
        _,
        _,
        //~[msrv]^ ERROR: type provided when a constant was expected
        { zerocopy_renamed::ident_id!(a) },
    >>::Type = 0u8;
    let _: <StructWithNamedFields as zerocopy_renamed::HasField<
        _,
        //~[stable, nightly]^ ERROR: type `private::_::_::_::ẕb` is private
        _,
        //~[msrv]^ ERROR: type provided when a constant was expected
        { zerocopy_renamed::ident_id!(b) },
    >>::Type = 0u16;
};

const _: () = {
    let _: <StructWithAnonFields as zerocopy_renamed::HasField<
        _,
        _,
        //~[msrv]^ ERROR: type provided when a constant was expected
        { zerocopy_renamed::ident_id!(0) },
    >>::Type = 0u8;
    let _: <StructWithAnonFields as zerocopy_renamed::HasField<
        _,
        //~[stable, nightly]^ ERROR: type `private::_::_::_::ẕ1` is private
        _,
        //~[msrv]^ ERROR: type provided when a constant was expected
        { zerocopy_renamed::ident_id!(1) },
    >>::Type = 0u16;
};

const _: () = {
    let _: <Union as zerocopy_renamed::HasField<_, _, { zerocopy_renamed::ident_id!(a) }>>::Type =
//~[msrv]^ ERROR: type provided when a constant was expected
        0u8;
    let _: <Union as zerocopy_renamed::HasField<_, _, { zerocopy_renamed::ident_id!(b) }>>::Type =
//~[msrv]^ ERROR: type provided when a constant was expected
//~[stable, nightly]^^ ERROR: type `private::_::_::_::ẕb` is private
        0u16;
};

const _: () = {
    let _: <Enum as zerocopy_renamed::HasField<_, _, { zerocopy_renamed::ident_id!(0) }>>::Type =
//~[msrv]^ ERROR: type provided when a constant was expected
        0u8;
    let _: <Enum as zerocopy_renamed::HasField<_, _, { zerocopy_renamed::ident_id!(1) }>>::Type =
//~[msrv]^ ERROR: type provided when a constant was expected
        0u16;

    let _: <Enum as zerocopy_renamed::HasField<_, _, { zerocopy_renamed::ident_id!(a) }>>::Type =
//~[msrv]^ ERROR: type provided when a constant was expected
        0u8;
    let _: <Enum as zerocopy_renamed::HasField<
        _,
        { zerocopy_renamed::ident_id!(B) },
        { zerocopy_renamed::ident_id!(b) },
    >>::Type = 0u16;
};
