================================================================================
The unit type
================================================================================

type A = ();

--------------------------------------------------------------------------------

(source_file
  (type_item
    (type_identifier)
    (unit_type)))

================================================================================
Tuple types
================================================================================

type A = (i32, String);

--------------------------------------------------------------------------------

(source_file
  (type_item
    (type_identifier)
    (tuple_type
      (primitive_type)
      (type_identifier))))

================================================================================
Reference types
================================================================================

type A = &B;
type C = &'a str;
type D = &'a mut str;

--------------------------------------------------------------------------------

(source_file
  (type_item
    (type_identifier)
    (reference_type
      (type_identifier)))
  (type_item
    (type_identifier)
    (reference_type
      (lifetime
        (identifier))
      (primitive_type)))
  (type_item
    (type_identifier)
    (reference_type
      (lifetime
        (identifier))
      (mutable_specifier)
      (primitive_type))))

================================================================================
Raw pointer types
================================================================================

type A = *mut B;
type C = *const str;

--------------------------------------------------------------------------------

(source_file
  (type_item
    (type_identifier)
    (pointer_type
      (mutable_specifier)
      (type_identifier)))
  (type_item
    (type_identifier)
    (pointer_type
      (primitive_type))))

================================================================================
Generic types
================================================================================

type A = B<C>;
type D = E<F, str>;
type G = H<'a, I>;
type J = H<K=L>;
pub struct G<T, K>(std::marker::PhantomData::<(T, K)>);
pub struct H(epsilon::Foo::<>);
type K = u8<>;

--------------------------------------------------------------------------------

(source_file
  (type_item
    (type_identifier)
    (generic_type
      (type_identifier)
      (type_arguments
        (type_identifier))))
  (type_item
    (type_identifier)
    (generic_type
      (type_identifier)
      (type_arguments
        (type_identifier)
        (primitive_type))))
  (type_item
    (type_identifier)
    (generic_type
      (type_identifier)
      (type_arguments
        (lifetime
          (identifier))
        (type_identifier))))
  (type_item
    (type_identifier)
    (generic_type
      (type_identifier)
      (type_arguments
        (type_binding
          (type_identifier)
          (type_identifier)))))
  (struct_item
    (visibility_modifier)
    (type_identifier)
    (type_parameters
      (type_parameter
        (type_identifier))
      (type_parameter
        (type_identifier)))
    (ordered_field_declaration_list
      (generic_type_with_turbofish
        (scoped_identifier
          (scoped_identifier
            (identifier)
            (identifier))
          (identifier))
        (type_arguments
          (tuple_type
            (type_identifier)
            (type_identifier))))))
  (struct_item
    (visibility_modifier)
    (type_identifier)
    (ordered_field_declaration_list
      (generic_type_with_turbofish
        (scoped_identifier
          (identifier)
          (identifier))
        (type_arguments))))
  (type_item
    (type_identifier)
    (generic_type
      (primitive_type)
      (type_arguments))))

================================================================================
Scoped types
================================================================================

type A = B::C;
type D = E::F::G;
type H = I::J<K>;
type L = M<N>::O;

--------------------------------------------------------------------------------

(source_file
  (type_item
    (type_identifier)
    (scoped_type_identifier
      (identifier)
      (type_identifier)))
  (type_item
    (type_identifier)
    (scoped_type_identifier
      (scoped_identifier
        (identifier)
        (identifier))
      (type_identifier)))
  (type_item
    (type_identifier)
    (generic_type
      (scoped_type_identifier
        (identifier)
        (type_identifier))
      (type_arguments
        (type_identifier))))
  (type_item
    (type_identifier)
    (scoped_type_identifier
      (generic_type
        (type_identifier)
        (type_arguments
          (type_identifier)))
      (type_identifier))))

================================================================================
Array types
================================================================================

type A = [B; 4];
type C = &[D];

--------------------------------------------------------------------------------

(source_file
  (type_item
    (type_identifier)
    (array_type
      (type_identifier)
      (integer_literal)))
  (type_item
    (type_identifier)
    (reference_type
      (array_type
        (type_identifier)))))

================================================================================
Function types
================================================================================

fn high_order1(value: i32, f: fn(i32)) -> i32 {}

fn high_order2(value: i32, f: fn(i32) -> i32) -> i32 {
    f(value)
}

fn high_order3(value: i32, f: &FnOnce(i32) -> i32) -> i32 {
    f(value)
}

type F = for<'a, 'b> fn(x: &'a A, y: &'a mut B<'i, 't>,) -> C;

--------------------------------------------------------------------------------

(source_file
  (function_item
    (identifier)
    (parameters
      (parameter
        (identifier)
        (primitive_type))
      (parameter
        (identifier)
        (function_type
          (parameters
            (primitive_type)))))
    (primitive_type)
    (block))
  (function_item
    (identifier)
    (parameters
      (parameter
        (identifier)
        (primitive_type))
      (parameter
        (identifier)
        (function_type
          (parameters
            (primitive_type))
          (primitive_type))))
    (primitive_type)
    (block
      (call_expression
        (identifier)
        (arguments
          (identifier)))))
  (function_item
    (identifier)
    (parameters
      (parameter
        (identifier)
        (primitive_type))
      (parameter
        (identifier)
        (reference_type
          (function_type
            (type_identifier)
            (parameters
              (primitive_type))
            (primitive_type)))))
    (primitive_type)
    (block
      (call_expression
        (identifier)
        (arguments
          (identifier)))))
  (type_item
    (type_identifier)
    (higher_ranked_trait_bound
      (type_parameters
        (lifetime_parameter
          (lifetime
            (identifier)))
        (lifetime_parameter
          (lifetime
            (identifier))))
      (function_type
        (parameters
          (parameter
            (identifier)
            (reference_type
              (lifetime
                (identifier))
              (type_identifier)))
          (parameter
            (identifier)
            (reference_type
              (lifetime
                (identifier))
              (mutable_specifier)
              (generic_type
                (type_identifier)
                (type_arguments
                  (lifetime
                    (identifier))
                  (lifetime
                    (identifier)))))))
        (type_identifier)))))

================================================================================
Unsafe and extern function types
================================================================================

type a = extern "C" fn(*mut c_void);
type b = unsafe extern "C" fn() -> *mut c_void;

--------------------------------------------------------------------------------

(source_file
  (type_item
    (type_identifier)
    (function_type
      (function_modifiers
        (extern_modifier
          (string_literal
            (string_content))))
      (parameters
        (pointer_type
          (mutable_specifier)
          (type_identifier)))))
  (type_item
    (type_identifier)
    (function_type
      (function_modifiers
        (extern_modifier
          (string_literal
            (string_content))))
      (parameters)
      (pointer_type
        (mutable_specifier)
        (type_identifier)))))

================================================================================
Trait objects
================================================================================

type a = Box<Something + 'a>;
type b = Rc<dyn Something>;
type c = A<&dyn Fn(&B) -> C>;

--------------------------------------------------------------------------------

(source_file
  (type_item
    (type_identifier)
    (generic_type
      (type_identifier)
      (type_arguments
        (bounded_type
          (type_identifier)
          (lifetime
            (identifier))))))
  (type_item
    (type_identifier)
    (generic_type
      (type_identifier)
      (type_arguments
        (dynamic_type
          (type_identifier)))))
  (type_item
    (type_identifier)
    (generic_type
      (type_identifier)
      (type_arguments
        (reference_type
          (dynamic_type
            (function_type
              (type_identifier)
              (parameters
                (reference_type
                  (type_identifier)))
              (type_identifier))))))))

================================================================================
Higher-ranked trait bounds
================================================================================

pub struct Bar<'a> {
    pub baz: &'a (dyn Unpin + for<'b> Trait<'b>),
}

type F = for<> (C,D);

--------------------------------------------------------------------------------

(source_file
  (struct_item
    (visibility_modifier)
    (type_identifier)
    (type_parameters
      (lifetime_parameter
        (lifetime
          (identifier))))
    (field_declaration_list
      (field_declaration
        (visibility_modifier)
        (field_identifier)
        (reference_type
          (lifetime
            (identifier))
          (tuple_type
            (bounded_type
              (dynamic_type
                (type_identifier))
              (higher_ranked_trait_bound
                (type_parameters
                  (lifetime_parameter
                    (lifetime
                      (identifier))))
                (generic_type
                  (type_identifier)
                  (type_arguments
                    (lifetime
                      (identifier)))))))))))
  (type_item
    (type_identifier)
    (higher_ranked_trait_bound
      (type_parameters)
      (tuple_type
        (type_identifier)
        (type_identifier)))))

================================================================================
Type cast expressions with generics
================================================================================

a as B<C>;
d as *mut E<<F as E>::G>;

--------------------------------------------------------------------------------

(source_file
  (expression_statement
    (type_cast_expression
      (identifier)
      (generic_type
        (type_identifier)
        (type_arguments
          (type_identifier)))))
  (expression_statement
    (type_cast_expression
      (identifier)
      (pointer_type
        (mutable_specifier)
        (generic_type
          (type_identifier)
          (type_arguments
            (scoped_type_identifier
              (bracketed_type
                (qualified_type
                  (type_identifier)
                  (type_identifier)))
              (type_identifier))))))))

================================================================================
Unsafe binders
================================================================================

pub fn my_fun() -> for<'a> fn(unsafe<'b, 'c> (&'a i32, &'b i32)) { todo!() }

--------------------------------------------------------------------------------

(source_file
  (function_item
    (visibility_modifier)
    (identifier)
    (parameters)
    (higher_ranked_trait_bound
      (type_parameters
        (lifetime_parameter
          (lifetime
            (identifier))))
      (function_type
        (parameters
          (unsafe_bound_type
            (lifetime
              (identifier))
            (lifetime
              (identifier))
            (tuple_type
              (reference_type
                (lifetime
                  (identifier))
                (primitive_type))
              (reference_type
                (lifetime
                  (identifier))
                (primitive_type)))))))
    (block
      (macro_invocation
        (identifier)
        (token_tree)))))
