/* Rust language support routines for GDB, the GNU debugger.

   Copyright (C) 2016-2025 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */



#include "block.h"
#include "c-lang.h"
#include "charset.h"
#include "cp-support.h"
#include "demangle.h"
#include "event-top.h"
#include "gdbarch.h"
#include "infcall.h"
#include "objfiles.h"
#include "rust-lang.h"
#include "typeprint.h"
#include "valprint.h"
#include "varobj.h"
#include <algorithm>
#include <string>
#include <vector>
#include "cli/cli-style.h"
#include "parser-defs.h"
#include "rust-exp.h"

/* See rust-lang.h.  */

const char *
rust_last_path_segment (const char *path)
{
  const char *result = strrchr (path, ':');

  if (result == NULL)
    return path;
  return result + 1;
}

/* See rust-lang.h.  */

std::string
rust_crate_for_block (const struct block *block)
{
  const char *scope = block->scope ();

  if (scope[0] == '\0')
    return std::string ();

  return std::string (scope, cp_find_first_component (scope));
}

/* Return true if TYPE, which must be a struct type, represents a Rust
   enum.  */

static bool
rust_enum_p (struct type *type)
{
  /* is_dynamic_type will return true if any field has a dynamic
     attribute -- but we only want to check the top level.  */
  return TYPE_HAS_VARIANT_PARTS (type);
}

/* Return true if TYPE, which must be an already-resolved enum type,
   has no variants.  */

static bool
rust_empty_enum_p (const struct type *type)
{
  return type->num_fields () == 0;
}

/* Given an already-resolved enum type and contents, find which
   variant is active.  */

static int
rust_enum_variant (struct type *type)
{
  /* The active variant is simply the first non-artificial field.  */
  for (int i = 0; i < type->num_fields (); ++i)
    if (!type->field (i).is_artificial ())
      return i;

  /* Perhaps we could get here by trying to print an Ada variant
     record in Rust mode.  Unlikely, but an error is safer than an
     assert.  */
  error (_("Could not find active enum variant"));
}

/* See rust-lang.h.  */

bool
rust_tuple_type_p (struct type *type)
{
  /* The current implementation is a bit of a hack, but there's
     nothing else in the debuginfo to distinguish a tuple from a
     struct.  */
  return (type->code () == TYPE_CODE_STRUCT
	  && type->name () != NULL
	  && type->name ()[0] == '(');
}

/* Return true if all non-static fields of a structlike type are in a
   sequence like 0, 1, 2.  "__" prefixes are also accepted -- rustc
   emits "__0" but gccrs emits "0".  */

static bool
rust_underscore_fields (struct type *type)
{
  int field_number = 0;

  if (type->code () != TYPE_CODE_STRUCT)
    return false;
  for (const auto &field : type->fields ())
    {
      if (!field.is_static ())
	{
	  char buf[20];

	  xsnprintf (buf, sizeof (buf), "%d", field_number);

	  const char *field_name = field.name ();
	  if (startswith (field_name, "__"))
	    field_name += 2;
	  if (strcmp (buf, field_name) != 0)
	    return false;
	  field_number++;
	}
    }
  return true;
}

/* See rust-lang.h.  */

bool
rust_tuple_struct_type_p (struct type *type)
{
  /* This is just an approximation until DWARF can represent Rust more
     precisely.  We exclude zero-length structs because they may not
     be tuple structs, and there's no way to tell.  */
  return type->num_fields () > 0 && rust_underscore_fields (type);
}

/* Return true if TYPE is "slice-like"; false otherwise.  */

static bool
rust_slice_type_p (const struct type *type)
{
  if (type->code () == TYPE_CODE_STRUCT
      && type->name () != NULL
      && type->num_fields () == 2)
    {
      /* The order of fields doesn't matter.  While it would be nice
	 to check for artificiality here, the Rust compiler doesn't
	 emit this information.  */
      const char *n1 = type->field (0).name ();
      const char *n2 = type->field (1).name ();
      return ((streq (n1, "data_ptr") && streq (n2, "length"))
	      || (streq (n2, "data_ptr") && streq (n1, "length")));
    }
  return false;
}

/* Return true if TYPE is a range type, otherwise false.  */

static bool
rust_range_type_p (struct type *type)
{
  if (type->code () != TYPE_CODE_STRUCT
      || type->num_fields () > 2
      || type->name () == NULL
      || strstr (type->name (), "::Range") == NULL)
    return false;

  if (type->num_fields () == 0)
    return true;

  int field_num = 0;
  if (strcmp (type->field (0).name (), "start") == 0)
    {
      if (type->num_fields () == 1)
	return true;
      field_num = 1;
    }
  else if (type->num_fields () == 2)
    {
      /* First field had to be "start".  */
      return false;
    }

  return strcmp (type->field (field_num).name (), "end") == 0;
}

/* Return true if TYPE is an inclusive range type, otherwise false.
   This is only valid for types which are already known to be range
   types.  */

static bool
rust_inclusive_range_type_p (struct type *type)
{
  return (strstr (type->name (), "::RangeInclusive") != NULL
	  || strstr (type->name (), "::RangeToInclusive") != NULL);
}

/* Return true if TYPE seems to be the type "u8", otherwise false.  */

static bool
rust_u8_type_p (struct type *type)
{
  return (type->code () == TYPE_CODE_INT
	  && type->is_unsigned ()
	  && type->length () == 1);
}

/* Return true if TYPE is a Rust character type.  */

static bool
rust_chartype_p (struct type *type)
{
  return (type->code () == TYPE_CODE_CHAR
	  && type->length () == 4
	  && type->is_unsigned ());
}

/* If VALUE represents a trait object pointer, return the underlying
   pointer with the correct (i.e., runtime) type.  Otherwise, return
   NULL.  */

static struct value *
rust_get_trait_object_pointer (struct value *value)
{
  struct type *type = check_typedef (value->type ());

  if (type->code () != TYPE_CODE_STRUCT || type->num_fields () != 2)
    return NULL;

  /* Try to be a bit resilient if the ABI changes.  */
  int vtable_field = 0;
  for (int i = 0; i < 2; ++i)
    {
      if (strcmp (type->field (i).name (), "vtable") == 0)
	vtable_field = i;
      else if (strcmp (type->field (i).name (), "pointer") != 0)
	return NULL;
    }

  CORE_ADDR vtable = value_as_address (value_field (value, vtable_field));
  struct symbol *symbol = find_symbol_at_address (vtable);
  if (symbol == NULL || symbol->subclass != SYMBOL_RUST_VTABLE)
    return NULL;

  struct rust_vtable_symbol *vtable_sym
    = static_cast<struct rust_vtable_symbol *> (symbol);
  struct type *pointer_type = lookup_pointer_type (vtable_sym->concrete_type);
  return value_cast (pointer_type, value_field (value, 1 - vtable_field));
}

/* Find and possibly rewrite the unsized part of a slice-like type.

   This function has two modes.  If the out parameters are both NULL,
   it will return true if an unsized member of IN_TYPE is found.

   If the out parameters are both non-NULL, it will do the same, but
   will also rewrite the unsized member's type to be an array of the
   appropriate type.  BOUND is the upper bound of the new array.

   See convert_slice to understand the different kinds of unsized type
   and how they are represented.
*/
static bool
rewrite_slice_type (struct type *in_type, struct type **new_type,
		    LONGEST bound, ULONGEST *additional_length)
{
  if (in_type->code () != TYPE_CODE_STRUCT)
    return false;

  unsigned nfields = in_type->num_fields ();
  if (nfields == 0)
    return false;

  struct type *rewritten;
  const field &field = in_type->field (nfields - 1);
  struct type *field_type = field.type ();
  if (field.loc_kind () == FIELD_LOC_KIND_BITPOS
      && field.loc_bitpos () == 8 * in_type->length ())
    {
      if (additional_length == nullptr)
	return true;
      rewritten = lookup_array_range_type (field_type, 0, bound);
      *additional_length = rewritten->length ();
    }
  else
    {
    if (!rewrite_slice_type (field_type, &rewritten, bound,
			     additional_length))
	return false;
      if (additional_length == nullptr)
	return true;
    }

  struct type *result = copy_type (in_type);
  result->copy_fields (in_type);
  result->field (nfields - 1).set_type (rewritten);
  result->set_length (result->length () + *additional_length);

  *new_type = result;
  return true;
}

/* Convert a Rust slice to its "true" representation.

   The Rust compiler emits slices as "fat" pointers like:

   struct { payload *data_ptr; usize length }

   Any sort of unsized type is emitted this way.

   If 'payload' is a struct type, then it must be searched to see if
   the trailing field is unsized.  This has to be done recursively (as
   in, if the final field in the struct type itself has struct type,
   then that type must be searched).  In this scenario, the unsized
   field can be recognized because it does not contribute to the
   type's size.

   If 'payload' does not have a trailing unsized type, or if it is not
   of struct type, then this slice is "array-like".  In this case
   rewriting will return an array.
*/
static struct value *
convert_slice (struct value *val)
{
  struct type *type = check_typedef (val->type ());
  /* This must have been checked by the caller.  */
  gdb_assert (rust_slice_type_p (type));

  struct value *len = value_struct_elt (&val, {}, "length", nullptr,
					"slice");
  LONGEST llen = value_as_long (len);

  struct value *ptr = value_struct_elt (&val, {}, "data_ptr", nullptr,
					"slice");
  struct type *original_type = ptr->type ()->target_type ();
  ULONGEST new_length_storage = 0;
  struct type *new_type = nullptr;
  if (!rewrite_slice_type (original_type, &new_type, llen - 1,
			   &new_length_storage))
    new_type = lookup_array_range_type (original_type, 0, llen - 1);

  struct value *result = value::allocate_lazy (new_type);
  result->set_lval (lval_memory);
  result->set_address (value_as_address (ptr));
  result->fetch_lazy ();

  return result;
}

/* If TYPE is an array-like slice, return the element type; otherwise
   return NULL.  */
static struct type *
rust_array_like_element_type (struct type *type)
{
  /* Caller must check this.  */
  gdb_assert (rust_slice_type_p (type));
  for (const auto &field : type->fields ())
    {
      if (strcmp (field.name (), "data_ptr") == 0)
	{
	  struct type *base_type = field.type ()->target_type ();
	  if (rewrite_slice_type (base_type, nullptr, 0, nullptr))
	    return nullptr;
	  return base_type;
	}
    }
  return nullptr;
}



/* See language.h.  */

void
rust_language::printstr (struct ui_file *stream, struct type *type,
			 const gdb_byte *string, unsigned int length,
			 const char *user_encoding, int force_ellipses,
			 const struct value_print_options *options) const
{
  /* Rust always uses UTF-8, but let the caller override this if need
     be.  */
  const char *encoding = user_encoding;
  if (user_encoding == NULL || !*user_encoding)
    {
      /* In Rust strings, characters are "u8".  */
      if (rust_u8_type_p (type))
	encoding = "UTF-8";
      else
	{
	  /* This is probably some C string, so let's let C deal with
	     it.  */
	  language_defn::printstr (stream, type, string, length,
				   user_encoding, force_ellipses,
				   options);
	  return;
	}
    }

  /* This is not ideal as it doesn't use our character printer.  */
  generic_printstr (stream, type, string, length, encoding, force_ellipses,
		    '"', 0, options);
}



static const struct generic_val_print_decorations rust_decorations =
{
  /* Complex isn't used in Rust, but we provide C-ish values just in
     case.  */
  "",
  " + ",
  " * I",
  "true",
  "false",
  "()",
  "[",
  "]"
};

/* See rust-lang.h.  */

struct value *
rust_slice_to_array (struct value *val)
{
  val = convert_slice (val);
  if (val->type ()->code () != TYPE_CODE_ARRAY)
    return nullptr;
  return val;
}

/* Helper function to print a slice.  */

void
rust_language::val_print_slice
     (struct value *val, struct ui_file *stream, int recurse,
      const struct value_print_options *options) const
{
  struct type *orig_type = check_typedef (val->type ());

  val = convert_slice (val);
  struct type *type = check_typedef (val->type ());

  /* &str is handled here; but for all other slice types it is fine to
     simply print the contents.  */
  if (orig_type->name () != nullptr
      && strcmp (orig_type->name (), "&str") == 0)
    {
      LONGEST low_bound, high_bound;
      if (get_array_bounds (type, &low_bound, &high_bound))
	{
	  val_print_string (type->target_type (), "UTF-8",
			    val->address (), high_bound - low_bound + 1,
			    stream, options);
	  return;
	}
    }

  /* Print the slice type here.  This was gdb's historical behavior
     (from before unsized types were generically handled) and helps
     make it clear that the user is seeing a slice, not an array.
     Only arrays must be handled as the other cases are handled by
     value_print_inner.  */
  if (type->code () == TYPE_CODE_ARRAY)
    {
      type_print (orig_type, "", stream, -1);
      gdb_printf (stream, " ");
    }

  value_print_inner (val, stream, recurse, options);
}

/* See rust-lang.h.  */

void
rust_language::val_print_struct
	(struct value *val, struct ui_file *stream, int recurse,
	 const struct value_print_options *options) const
{
  int first_field;
  struct type *type = check_typedef (val->type ());

  if (rust_slice_type_p (type))
    {
      val_print_slice (val, stream, recurse, options);
      return;
    }

  bool is_tuple = rust_tuple_type_p (type);
  bool is_tuple_struct = !is_tuple && rust_tuple_struct_type_p (type);
  struct value_print_options opts;

  if (!is_tuple)
    {
      if (type->name () != NULL)
	gdb_printf (stream, "%s", type->name ());

      if (type->num_fields () == 0)
	return;

      if (type->name () != NULL)
	gdb_puts (" ", stream);
    }

  if (is_tuple || is_tuple_struct)
    gdb_puts ("(", stream);
  else
    gdb_puts ("{", stream);

  opts = *options;
  opts.deref_ref = false;

  first_field = 1;
  for (int i = 0; i < type->num_fields (); ++i)
    {
      if (type->field (i).is_static ())
	continue;

      if (!first_field)
	gdb_puts (",", stream);

      if (options->prettyformat)
	{
	  gdb_puts ("\n", stream);
	  print_spaces (2 + 2 * recurse, stream);
	}
      else if (!first_field)
	gdb_puts (" ", stream);

      first_field = 0;

      if (!is_tuple && !is_tuple_struct)
	{
	  fputs_styled (type->field (i).name (),
			variable_name_style.style (), stream);
	  gdb_puts (": ", stream);
	}

      common_val_print (value_field (val, i), stream, recurse + 1, &opts,
			this);
    }

  if (options->prettyformat)
    {
      gdb_puts ("\n", stream);
      print_spaces (2 * recurse, stream);
    }

  if (is_tuple || is_tuple_struct)
    gdb_puts (")", stream);
  else
    gdb_puts ("}", stream);
}

/* See rust-lang.h.  */

void
rust_language::print_enum (struct value *val, struct ui_file *stream,
			   int recurse,
			   const struct value_print_options *options) const
{
  struct value_print_options opts = *options;
  struct type *type = check_typedef (val->type ());

  opts.deref_ref = false;

  gdb_assert (rust_enum_p (type));
  gdb::array_view<const gdb_byte> view
    (val->contents_for_printing ().data (),
     val->type ()->length ());
  type = resolve_dynamic_type (type, view, val->address ());

  if (rust_empty_enum_p (type))
    {
      /* Print the enum type name here to be more clear.  */
      gdb_printf (stream, _("%s {%p[<No data fields>%p]}"),
		  type->name (),
		  metadata_style.style ().ptr (), nullptr);
      return;
    }

  int variant_fieldno = rust_enum_variant (type);
  val = val->primitive_field (0, variant_fieldno, type);
  struct type *variant_type = type->field (variant_fieldno).type ();

  int nfields = variant_type->num_fields ();

  bool is_tuple = rust_tuple_struct_type_p (variant_type);

  gdb_printf (stream, "%s", variant_type->name ());
  if (nfields == 0)
    {
      /* In case of a nullary variant like 'None', just output
	 the name. */
      return;
    }

  /* In case of a non-nullary variant, we output 'Foo(x,y,z)'. */
  if (is_tuple)
    gdb_printf (stream, "(");
  else
    {
      /* struct variant.  */
      gdb_printf (stream, "{");
    }

  bool first_field = true;
  for (int j = 0; j < nfields; j++)
    {
      if (!first_field)
	gdb_puts (", ", stream);
      first_field = false;

      if (!is_tuple)
	gdb_printf (stream, "%ps: ",
		    styled_string (variable_name_style.style (),
				   variant_type->field (j).name ()));

      common_val_print (value_field (val, j), stream, recurse + 1, &opts,
			this);
    }

  if (is_tuple)
    gdb_puts (")", stream);
  else
    gdb_puts ("}", stream);
}

/* See language.h.  */

void
rust_language::value_print_inner
	(struct value *val, struct ui_file *stream, int recurse,
	 const struct value_print_options *options) const
{
  struct value_print_options opts = *options;
  opts.deref_ref = true;

  if (opts.prettyformat == Val_prettyformat_default)
    opts.prettyformat = (opts.prettyformat_structs
			 ? Val_prettyformat : Val_no_prettyformat);

  struct type *type = check_typedef (val->type ());
  switch (type->code ())
    {
    case TYPE_CODE_PTR:
      {
	LONGEST low_bound, high_bound;

	if (type->target_type ()->code () == TYPE_CODE_ARRAY
	    && rust_u8_type_p (type->target_type ()->target_type ())
	    && get_array_bounds (type->target_type (), &low_bound,
				 &high_bound))
	  {
	    /* We have a pointer to a byte string, so just print
	       that.  */
	    struct type *elttype = check_typedef (type->target_type ());
	    CORE_ADDR addr = value_as_address (val);
	    struct gdbarch *arch = type->arch ();

	    if (opts.addressprint)
	      {
		gdb_puts (paddress (arch, addr), stream);
		gdb_puts (" ", stream);
	      }

	    gdb_puts ("b", stream);
	    val_print_string (elttype->target_type (), "ASCII", addr,
			      high_bound - low_bound + 1, stream,
			      &opts);
	    break;
	  }
      }
      goto generic_print;

    case TYPE_CODE_INT:
      /* Recognize the unit type.  */
      if (type->is_unsigned () && type->length () == 0
	  && type->name () != NULL && strcmp (type->name (), "()") == 0)
	{
	  gdb_puts ("()", stream);
	  break;
	}
      goto generic_print;

    case TYPE_CODE_STRING:
      {
	LONGEST low_bound, high_bound;

	if (!get_array_bounds (type, &low_bound, &high_bound))
	  error (_("Could not determine the array bounds"));

	/* If we see a plain TYPE_CODE_STRING, then we're printing a
	   byte string, hence the choice of "ASCII" as the
	   encoding.  */
	gdb_puts ("b", stream);
	printstr (stream, type->target_type (),
		  val->contents_for_printing ().data (),
		  high_bound - low_bound + 1, "ASCII", 0, &opts);
      }
      break;

    case TYPE_CODE_ARRAY:
      {
	LONGEST low_bound, high_bound;

	if (get_array_bounds (type, &low_bound, &high_bound)
	    && high_bound - low_bound + 1 == 0)
	  gdb_puts ("[]", stream);
	else
	  goto generic_print;
      }
      break;

    case TYPE_CODE_UNION:
      /* Untagged unions are printed as if they are structs.  Since
	 the field bit positions overlap in the debuginfo, the code
	 for printing a union is same as that for a struct, the only
	 difference is that the input type will have overlapping
	 fields.  */
      val_print_struct (val, stream, recurse, &opts);
      break;

    case TYPE_CODE_STRUCT:
      if (rust_enum_p (type))
	print_enum (val, stream, recurse, &opts);
      else
	val_print_struct (val, stream, recurse, &opts);
      break;

    default:
    generic_print:
      /* Nothing special yet.  */
      generic_value_print (val, stream, recurse, &opts, &rust_decorations);
    }
}

/* See language.h.  */

void
rust_language::value_print
	(struct value *val, struct ui_file *stream,
	 const struct value_print_options *options) const
{
  value_print_options opts = *options;
  opts.deref_ref = true;

  struct type *type = check_typedef (val->type ());
  if (type->is_pointer_or_reference ())
    {
      gdb_printf (stream, "(");
      type_print (val->type (), "", stream, -1);
      gdb_printf (stream, ") ");
    }

  return common_val_print (val, stream, 0, &opts, this);
}



static void
rust_internal_print_type (struct type *type, const char *varstring,
			  struct ui_file *stream, int show, int level,
			  const struct type_print_options *flags,
			  bool for_rust_enum, print_offset_data *podata);

/* Print a struct or union typedef.  */
static void
rust_print_struct_def (struct type *type, const char *varstring,
		       struct ui_file *stream, int show, int level,
		       const struct type_print_options *flags,
		       bool for_rust_enum, print_offset_data *podata)
{
  /* Print a tuple type simply.  */
  if (rust_tuple_type_p (type))
    {
      gdb_puts (type->name (), stream);
      return;
    }

  /* If we see a base class, delegate to C.  */
  if (TYPE_N_BASECLASSES (type) > 0)
    c_print_type (type, varstring, stream, show, level, language_rust, flags);

  if (flags->print_offsets)
    {
      /* Temporarily bump the level so that the output lines up
	 correctly.  */
      level += 2;
    }

  /* Compute properties of TYPE here because, in the enum case, the
     rest of the code ends up looking only at the variant part.  */
  const char *tagname = type->name ();
  bool is_tuple_struct = rust_tuple_struct_type_p (type);
  bool is_tuple = rust_tuple_type_p (type);
  bool is_enum = rust_enum_p (type);

  if (for_rust_enum)
    {
      /* Already printing an outer enum, so nothing to print here.  */
    }
  else
    {
      /* This code path is also used by unions and enums.  */
      if (is_enum)
	{
	  gdb_puts ("enum ", stream);
	  dynamic_prop *prop = type->dyn_prop (DYN_PROP_VARIANT_PARTS);
	  if (prop != nullptr && prop->kind () == PROP_TYPE)
	    type = prop->original_type ();
	}
      else if (type->code () == TYPE_CODE_STRUCT)
	gdb_puts ("struct ", stream);
      else
	gdb_puts ("union ", stream);

      if (tagname != NULL)
	gdb_puts (tagname, stream);
    }

  if (type->num_fields () == 0 && !is_tuple)
    return;
  if (for_rust_enum && !flags->print_offsets)
    gdb_puts (is_tuple_struct ? "(" : "{", stream);
  else
    gdb_puts (is_tuple_struct ? " (\n" : " {\n", stream);

  /* When printing offsets, we rearrange the fields into storage
     order.  This lets us show holes more clearly.  We work using
     field indices here because it simplifies calls to
     print_offset_data::update below.  */
  std::vector<int> fields;
  for (int i = 0; i < type->num_fields (); ++i)
    {
      if (type->field (i).is_static ())
	continue;
      if (is_enum && type->field (i).is_artificial ())
	continue;
      fields.push_back (i);
    }
  if (flags->print_offsets)
    std::sort (fields.begin (), fields.end (),
	       [&] (int a, int b)
	       {
		 return (type->field (a).loc_bitpos ()
			 < type->field (b).loc_bitpos ());
	       });

  for (int i : fields)
    {
      QUIT;

      gdb_assert (!type->field (i).is_static ());
      gdb_assert (! (is_enum && type->field (i).is_artificial ()));

      if (flags->print_offsets)
	podata->update (type, i, stream);

      /* We'd like to print "pub" here as needed, but rustc
	 doesn't emit the debuginfo, and our types don't have
	 cplus_struct_type attached.  */

      /* For a tuple struct we print the type but nothing
	 else.  */
      if (!for_rust_enum || flags->print_offsets)
	print_spaces (level + 2, stream);
      if (is_enum)
	fputs_styled (type->field (i).name (), variable_name_style.style (),
		      stream);
      else if (!is_tuple_struct)
	gdb_printf (stream, "%ps: ",
		    styled_string (variable_name_style.style (),
				   type->field (i).name ()));

      rust_internal_print_type (type->field (i).type (), NULL,
				stream, (is_enum ? show : show - 1),
				level + 2, flags, is_enum, podata);
      if (!for_rust_enum || flags->print_offsets)
	gdb_puts (",\n", stream);
      /* Note that this check of "I" is ok because we only sorted the
	 fields by offset when print_offsets was set, so we won't take
	 this branch in that case.  */
      else if (i + 1 < type->num_fields ())
	gdb_puts (", ", stream);
    }

  if (flags->print_offsets)
    {
      /* Undo the temporary level increase we did above.  */
      level -= 2;
      podata->finish (type, level, stream);
      print_spaces (print_offset_data::indentation, stream);
      if (level == 0)
	print_spaces (2, stream);
    }
  if (!for_rust_enum || flags->print_offsets)
    print_spaces (level, stream);
  gdb_puts (is_tuple_struct ? ")" : "}", stream);
}

/* la_print_type implementation for Rust.  */

static void
rust_internal_print_type (struct type *type, const char *varstring,
			  struct ui_file *stream, int show, int level,
			  const struct type_print_options *flags,
			  bool for_rust_enum, print_offset_data *podata)
{
  QUIT;
  if (show <= 0
      && type->name () != NULL)
    {
      /* Rust calls the unit type "void" in its debuginfo,
	 but we don't want to print it as that.  */
      if (type->code () == TYPE_CODE_VOID)
	gdb_puts ("()", stream);
      else
	gdb_puts (type->name (), stream);
      return;
    }

  type = check_typedef (type);
  switch (type->code ())
    {
    case TYPE_CODE_VOID:
      /* If we have an enum, we've already printed the type's
	 unqualified name, and there is nothing else to print
	 here.  */
      if (!for_rust_enum)
	gdb_puts ("()", stream);
      break;

    case TYPE_CODE_FUNC:
      /* Delegate varargs to the C printer.  */
      if (type->has_varargs ())
	goto c_printer;

      gdb_puts ("fn ", stream);
      if (varstring != NULL)
	gdb_puts (varstring, stream);
      gdb_puts ("(", stream);
      for (int i = 0; i < type->num_fields (); ++i)
	{
	  QUIT;
	  if (i > 0)
	    gdb_puts (", ", stream);
	  rust_internal_print_type (type->field (i).type (), "", stream,
				    -1, 0, flags, false, podata);
	}
      gdb_puts (")", stream);
      /* If it returns unit, we can omit the return type.  */
      if (type->target_type ()->code () != TYPE_CODE_VOID)
	{
	  gdb_puts (" -> ", stream);
	  rust_internal_print_type (type->target_type (), "", stream,
				    -1, 0, flags, false, podata);
	}
      break;

    case TYPE_CODE_ARRAY:
      {
	LONGEST low_bound, high_bound;

	gdb_puts ("[", stream);
	rust_internal_print_type (type->target_type (), NULL,
				  stream, show - 1, level, flags, false,
				  podata);

	if (type->bounds ()->high.kind () == PROP_LOCEXPR
	    || type->bounds ()->high.kind () == PROP_LOCLIST)
	  gdb_printf (stream, "; variable length");
	else if (get_array_bounds (type, &low_bound, &high_bound))
	  gdb_printf (stream, "; %s",
		      plongest (high_bound - low_bound + 1));
	gdb_puts ("]", stream);
      }
      break;

    case TYPE_CODE_UNION:
    case TYPE_CODE_STRUCT:
      rust_print_struct_def (type, varstring, stream, show, level, flags,
			     for_rust_enum, podata);
      break;

    case TYPE_CODE_ENUM:
      {
	int len = 0;

	gdb_puts ("enum ", stream);
	if (type->name () != NULL)
	  {
	    gdb_puts (type->name (), stream);
	    gdb_puts (" ", stream);
	    len = strlen (type->name ());
	  }
	gdb_puts ("{\n", stream);

	for (const auto &field : type->fields ())
	  {
	    const char *name = field.name ();

	    QUIT;

	    if (len > 0
		&& strncmp (name, type->name (), len) == 0
		&& name[len] == ':'
		&& name[len + 1] == ':')
	      name += len + 2;
	    gdb_printf (stream, "%*s%ps,\n",
			level + 2, "",
			styled_string (variable_name_style.style (),
				       name));
	  }

	gdb_puts ("}", stream);
      }
      break;

    case TYPE_CODE_PTR:
      {
	if (type->name () != nullptr)
	  gdb_puts (type->name (), stream);
	else
	  {
	    /* We currently can't distinguish between pointers and
	       references.  */
	    gdb_puts ("*mut ", stream);
	    type_print (type->target_type (), "", stream, 0);
	  }
      }
      break;

    default:
    c_printer:
      c_print_type (type, varstring, stream, show, level, language_rust,
		    flags);
    }
}



/* Like arch_composite_type, but uses TYPE to decide how to allocate
   -- either on an obstack or on a gdbarch.  */

static struct type *
rust_composite_type (struct type *original,
		     const char *name,
		     const char *field1, struct type *type1,
		     const char *field2, struct type *type2)
{
  struct type *result = type_allocator (original).new_type ();
  int i, nfields, bitpos;

  nfields = 0;
  if (field1 != NULL)
    ++nfields;
  if (field2 != NULL)
    ++nfields;

  result->set_code (TYPE_CODE_STRUCT);
  result->set_name (name);

  result->alloc_fields (nfields);

  i = 0;
  bitpos = 0;
  if (field1 != NULL)
    {
      struct field *field = &result->field (i);

      field->set_loc_bitpos (bitpos);
      bitpos += type1->length () * TARGET_CHAR_BIT;

      field->set_name (field1);
      field->set_type (type1);
      ++i;
    }
  if (field2 != NULL)
    {
      struct field *field = &result->field (i);
      unsigned align = type_align (type2);

      if (align != 0)
	{
	  int delta;

	  align *= TARGET_CHAR_BIT;
	  delta = bitpos % align;
	  if (delta != 0)
	    bitpos += align - delta;
	}
      field->set_loc_bitpos (bitpos);

      field->set_name (field2);
      field->set_type (type2);
      ++i;
    }

  if (i > 0)
    result->set_length (result->field (i - 1).loc_bitpos () / TARGET_CHAR_BIT
			+ result->field (i - 1).type ()->length ());
  return result;
}

/* See rust-lang.h.  */

struct type *
rust_slice_type (const char *name, struct type *elt_type,
		 struct type *usize_type)
{
  struct type *type;

  elt_type = lookup_pointer_type (elt_type);
  type = rust_composite_type (elt_type, name,
			      "data_ptr", elt_type,
			      "length", usize_type);

  return type;
}



namespace expr
{

struct value *
rust_range_operation::evaluate (struct type *expect_type,
				struct expression *exp,
				enum noside noside)
{
  auto kind = std::get<0> (m_storage);
  value *low = nullptr;
  if (std::get<1> (m_storage) != nullptr)
    low = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
  value *high = nullptr;
  if (std::get<2> (m_storage) != nullptr)
    high = std::get<2> (m_storage)->evaluate (nullptr, exp, noside);

  struct value *addrval, *result;
  CORE_ADDR addr;
  struct type *range_type;
  struct type *index_type;
  struct type *temp_type;
  const char *name;

  bool inclusive = !(kind & RANGE_HIGH_BOUND_EXCLUSIVE);

  if (low == NULL)
    {
      if (high == NULL)
	{
	  index_type = NULL;
	  name = "std::ops::RangeFull";
	}
      else
	{
	  index_type = high->type ();
	  name = (inclusive
		  ? "std::ops::RangeToInclusive" : "std::ops::RangeTo");
	}
    }
  else
    {
      if (high == NULL)
	{
	  index_type = low->type ();
	  name = "std::ops::RangeFrom";
	}
      else
	{
	  if (!types_equal (low->type (), high->type ()))
	    error (_("Range expression with different types"));
	  index_type = low->type ();
	  name = inclusive ? "std::ops::RangeInclusive" : "std::ops::Range";
	}
    }

  /* If we don't have an index type, just allocate this on the
     arch.  Here any type will do.  */
  temp_type = (index_type == NULL
	       ? language_bool_type (exp->language_defn, exp->gdbarch)
	       : index_type);
  /* It would be nicer to cache the range type.  */
  range_type = rust_composite_type (temp_type, name,
				    low == NULL ? NULL : "start", index_type,
				    high == NULL ? NULL : "end", index_type);

  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    return value::zero (range_type, lval_memory);

  addrval = value_allocate_space_in_inferior (range_type->length ());
  addr = value_as_long (addrval);
  result = value_at_lazy (range_type, addr);

  if (low != NULL)
    {
      struct value *start = value_struct_elt (&result, {}, "start", NULL,
					      "range");

      value_assign (start, low);
    }

  if (high != NULL)
    {
      struct value *end = value_struct_elt (&result, {}, "end", NULL,
					    "range");

      value_assign (end, high);
    }

  result = value_at_lazy (range_type, addr);
  return result;
}

} /* namespace expr */

/* A helper function to compute the range and kind given a range
   value.  TYPE is the type of the range value.  RANGE is the range
   value.  LOW, HIGH, and KIND are out parameters.  The LOW and HIGH
   parameters might be filled in, or might not be, depending on the
   kind of range this is.  KIND will always be set to the appropriate
   value describing the kind of range, and this can be used to
   determine whether LOW or HIGH are valid.  */

static void
rust_compute_range (struct type *type, struct value *range,
		    LONGEST *low, LONGEST *high,
		    range_flags *kind)
{
  int i;

  *low = 0;
  *high = 0;
  *kind = RANGE_LOW_BOUND_DEFAULT | RANGE_HIGH_BOUND_DEFAULT;

  if (type->num_fields () == 0)
    return;

  i = 0;
  if (strcmp (type->field (0).name (), "start") == 0)
    {
      *kind = RANGE_HIGH_BOUND_DEFAULT;
      *low = value_as_long (value_field (range, 0));
      ++i;
    }
  if (type->num_fields () > i
      && strcmp (type->field (i).name (), "end") == 0)
    {
      *kind = (*kind == (RANGE_LOW_BOUND_DEFAULT | RANGE_HIGH_BOUND_DEFAULT)
	       ? RANGE_LOW_BOUND_DEFAULT : RANGE_STANDARD);
      *high = value_as_long (value_field (range, i));

      if (rust_inclusive_range_type_p (type))
	++*high;
    }
}

namespace expr
{

struct value *
rust_subscript_operation::subscript (struct expression *exp,
				     enum noside noside, bool for_addr)
{
  value *lhs = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
  value *rhs = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);

  struct value *result;
  struct type *rhstype;
  LONGEST low, high_bound;
  /* Initialized to appease the compiler.  */
  range_flags kind = RANGE_LOW_BOUND_DEFAULT | RANGE_HIGH_BOUND_DEFAULT;
  LONGEST high = 0;
  bool want_slice = false;

  rhstype = check_typedef (rhs->type ());
  if (rust_range_type_p (rhstype))
    {
      if (!for_addr)
	error (_("Can't take slice of array without '&'"));
      rust_compute_range (rhstype, rhs, &low, &high, &kind);
      want_slice = true;
    }
  else
    low = value_as_long (rhs);

  struct type *type = check_typedef (lhs->type ());
  struct type *orig_type = type;
  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    {
      struct type *base_type = nullptr;
      if (type->code () == TYPE_CODE_ARRAY)
	base_type = type->target_type ();
      else if (rust_slice_type_p (type))
	{
	  base_type = rust_array_like_element_type (type);
	  if (base_type == nullptr)
	    error (_("Cannot subscript non-array-like slice"));
	}
      else if (type->code () == TYPE_CODE_PTR)
	base_type = type->target_type ();
      else
	error (_("Cannot subscript non-array type"));

      struct type *new_type;
      if (want_slice)
	{
	  if (rust_slice_type_p (type))
	    new_type = type;
	  else
	    {
	      struct type *usize
		= language_lookup_primitive_type (exp->language_defn,
						  exp->gdbarch,
						  "usize");
	      new_type = rust_slice_type ("&[*gdb*]", base_type, usize);
	    }
	}
      else
	new_type = base_type;

      return value::zero (new_type, lhs->lval ());
    }
  else
    {
      LONGEST low_bound;
      struct value *base;

      if (rust_slice_type_p (type))
	{
	  lhs = convert_slice (lhs);
	  type = check_typedef (lhs->type ());
	}

      if (type->code () == TYPE_CODE_ARRAY)
	{
	  base = lhs;
	  if (!get_array_bounds (type, &low_bound, &high_bound))
	    error (_("Can't compute array bounds"));
	  if (low_bound != 0)
	    error (_("Found array with non-zero lower bound"));
	  ++high_bound;
	}
      else if (type->code () == TYPE_CODE_PTR)
	{
	  base = lhs;
	  low_bound = 0;
	  high_bound = LONGEST_MAX;
	}
      else
	error (_("Cannot subscript non-array type"));

      if (want_slice && (kind & RANGE_LOW_BOUND_DEFAULT))
	low = low_bound;
      if (low < 0)
	error (_("Index less than zero"));
      if (low > high_bound)
	error (_("Index greater than length"));

      result = value_subscript (base, low);
    }

  if (for_addr)
    {
      if (want_slice)
	{
	  struct type *usize, *slice;
	  CORE_ADDR addr;
	  struct value *addrval, *tem;

	  if (kind & RANGE_HIGH_BOUND_DEFAULT)
	    high = high_bound;
	  if (high < 0)
	    error (_("High index less than zero"));
	  if (low > high)
	    error (_("Low index greater than high index"));
	  if (high > high_bound)
	    error (_("High index greater than length"));

	  usize = language_lookup_primitive_type (exp->language_defn,
						  exp->gdbarch,
						  "usize");
	  /* Preserve the name for slice-of-slice; this lets
	     string-printing work a bit more nicely.  */
	  const char *new_name = ((orig_type != nullptr
				   && rust_slice_type_p (orig_type))
				  ? orig_type->name () : "&[*gdb*]");

	  slice = rust_slice_type (new_name, result->type (), usize);

	  addrval = value_allocate_space_in_inferior (slice->length ());
	  addr = value_as_long (addrval);
	  tem = value_at_lazy (slice, addr);

	  value_assign (value_field (tem, 0), value_addr (result));
	  value_assign (value_field (tem, 1),
			value_from_longest (usize, high - low));

	  result = value_at_lazy (slice, addr);
	}
      else
	result = value_addr (result);
    }

  return result;
}

struct value *
rust_unop_ind_operation::evaluate (struct type *expect_type,
				   struct expression *exp,
				   enum noside noside)
{
  if (noside != EVAL_NORMAL)
    return unop_ind_operation::evaluate (expect_type, exp, noside);

  struct value *value = std::get<0> (m_storage)->evaluate (nullptr, exp,
							   noside);
  struct value *trait_ptr = rust_get_trait_object_pointer (value);
  if (trait_ptr != NULL)
    value = trait_ptr;

  return value_ind (value);
}

} /* namespace expr */

/* A helper function for UNOP_COMPLEMENT.  */

struct value *
eval_op_rust_complement (struct type *expect_type, struct expression *exp,
			 enum noside noside,
			 enum exp_opcode opcode,
			 struct value *value)
{
  if (value->type ()->code () == TYPE_CODE_BOOL)
    return value_from_longest (value->type (), value_logical_not (value));
  return value_complement (value);
}

/* A helper function for OP_ARRAY.  */

struct value *
eval_op_rust_array (struct type *expect_type, struct expression *exp,
		    enum noside noside,
		    enum exp_opcode opcode,
		    struct value *elt, struct value *ncopies)
{
  int copies = value_as_long (ncopies);
  if (copies < 0)
    error (_("Array with negative number of elements"));

  if (noside == EVAL_NORMAL && copies > 0)
    return value_array (0, std::vector<value *> (copies, elt));
  else
    {
      struct type *arraytype
	= lookup_array_range_type (elt->type (), 0, copies - 1);
      return value::allocate (arraytype);
    }
}

namespace expr
{

struct value *
rust_struct_anon::evaluate (struct type *expect_type,
			    struct expression *exp,
			    enum noside noside)
{
  value *lhs = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
  int field_number = std::get<0> (m_storage);

  struct type *type = check_typedef (lhs->type ());

  if (type->code () == TYPE_CODE_STRUCT)
    {
      struct type *outer_type = NULL;

      if (rust_enum_p (type))
	{
	  type = resolve_dynamic_type (type, lhs->contents (),
				       lhs->address ());

	  if (rust_empty_enum_p (type))
	    error (_("Cannot access field %d of empty enum %s"),
		   field_number, type->name ());

	  int fieldno = rust_enum_variant (type);
	  lhs = lhs->primitive_field (0, fieldno, type);
	  outer_type = type;
	  type = lhs->type ();
	}

      /* Tuples and tuple structs */
      int nfields = type->num_fields ();

      if (field_number >= nfields || field_number < 0)
	{
	  if (outer_type != NULL)
	    error(_("Cannot access field %d of variant %s::%s, "
		    "there are only %d fields"),
		  field_number, outer_type->name (),
		  rust_last_path_segment (type->name ()),
		  nfields);
	  else
	    error(_("Cannot access field %d of %s, "
		    "there are only %d fields"),
		  field_number, type->name (), nfields);
	}

      /* Tuples are tuple structs too.  */
      if (!rust_tuple_struct_type_p (type))
	{
	  if (outer_type != NULL)
	    error(_("Variant %s::%s is not a tuple variant"),
		  outer_type->name (),
		  rust_last_path_segment (type->name ()));
	  else
	    error(_("Attempting to access anonymous field %d "
		    "of %s, which is not a tuple, tuple struct, or "
		    "tuple-like variant"),
		  field_number, type->name ());
	}

      return lhs->primitive_field (0, field_number, type);
    }
  else
    error(_("Anonymous field access is only allowed on tuples, \
tuple structs, and tuple-like enum variants"));
}

struct value *
rust_structop::evaluate (struct type *expect_type,
			 struct expression *exp,
			 enum noside noside)
{
  value *lhs = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
  const char *field_name = std::get<1> (m_storage).c_str ();

  struct value *result;
  struct type *type = lhs->type ();
  if (type->code () == TYPE_CODE_STRUCT && rust_enum_p (type))
    {
      type = resolve_dynamic_type (type, lhs->contents (),
				   lhs->address ());

      if (rust_empty_enum_p (type))
	error (_("Cannot access field %s of empty enum %s"),
	       field_name, type->name ());

      int fieldno = rust_enum_variant (type);
      lhs = lhs->primitive_field (0, fieldno, type);

      struct type *outer_type = type;
      type = lhs->type ();
      if (rust_tuple_type_p (type) || rust_tuple_struct_type_p (type))
	error (_("Attempting to access named field %s of tuple "
		 "variant %s::%s, which has only anonymous fields"),
	       field_name, outer_type->name (),
	       rust_last_path_segment (type->name ()));

      try
	{
	  result = value_struct_elt (&lhs, {}, field_name,
				     NULL, "structure");
	}
      catch (const gdb_exception_error &except)
	{
	  error (_("Could not find field %s of struct variant %s::%s"),
		 field_name, outer_type->name (),
		 rust_last_path_segment (type->name ()));
	}
    }
  else
    {
      if (rust_slice_type_p (type))
	lhs = convert_slice (lhs);
      result = value_struct_elt (&lhs, {}, field_name, NULL, "structure");
    }
  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    result = value::zero (result->type (), result->lval ());
  return result;
}

value *
rust_aggregate_operation::evaluate (struct type *expect_type,
				    struct expression *exp,
				    enum noside noside)
{
  struct type *type = std::get<0> (m_storage);
  CORE_ADDR addr = 0;
  struct value *addrval = NULL;
  value *result;

  if (noside == EVAL_NORMAL)
    {
      addrval = value_allocate_space_in_inferior (type->length ());
      addr = value_as_long (addrval);
      result = value_at_lazy (type, addr);
    }

  if (std::get<1> (m_storage) != nullptr)
    {
      struct value *init = std::get<1> (m_storage)->evaluate (nullptr, exp,
							      noside);

      if (noside == EVAL_NORMAL)
	{
	  /* This isn't quite right but will do for the time
	     being, seeing that we can't implement the Copy
	     trait anyway.  */
	  value_assign (result, init);
	}
    }

  for (const auto &item : std::get<2> (m_storage))
    {
      value *val = item.second->evaluate (nullptr, exp, noside);
      if (noside == EVAL_NORMAL)
	{
	  const char *fieldname = item.first.c_str ();
	  value *field = value_struct_elt (&result, {}, fieldname,
					   nullptr, "structure");
	  value_assign (field, val);
	}
    }

  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    result = value::allocate (type);
  else
    result = value_at_lazy (type, addr);

  return result;
}

value *
rust_structop::evaluate_funcall (struct type *expect_type,
				 struct expression *exp,
				 enum noside noside,
				 const std::vector<operation_up> &ops)
{
  std::vector<struct value *> args (ops.size () + 1);

  /* Evaluate the argument to STRUCTOP_STRUCT, then find its
     type in order to look up the method.  */
  args[0] = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
  /* We don't yet implement real Deref semantics.  */
  while (args[0]->type ()->code () == TYPE_CODE_PTR)
    args[0] = value_ind (args[0]);

  struct type *type = args[0]->type ();
  if ((type->code () != TYPE_CODE_STRUCT
       && type->code () != TYPE_CODE_UNION
       && type->code () != TYPE_CODE_ENUM)
      || rust_tuple_type_p (type))
    error (_("Method calls only supported on struct or enum types"));
  if (type->name () == NULL)
    error (_("Method call on nameless type"));

  std::string name = (std::string (type->name ()) + "::"
		      + std::get<1> (m_storage));

  const struct block *block = get_selected_block (0);
  struct block_symbol sym = lookup_symbol (name.c_str (), block,
					   SEARCH_FUNCTION_DOMAIN,
					   nullptr);
  if (sym.symbol == NULL)
    error (_("Could not find function named '%s'"), name.c_str ());

  struct type *fn_type = sym.symbol->type ();
  if (fn_type->num_fields () == 0)
    error (_("Function '%s' takes no arguments"), name.c_str ());

  if (fn_type->field (0).type ()->code () == TYPE_CODE_PTR)
    args[0] = value_addr (args[0]);

  value *function = address_of_variable (sym.symbol, block);

  for (int i = 0; i < ops.size (); ++i)
    args[i + 1] = ops[i]->evaluate (nullptr, exp, noside);

  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    return value::zero (fn_type->target_type (), not_lval);
  return call_function_by_hand (function, NULL, args);
}

}



/* See language.h.  */

void
rust_language::language_arch_info (struct gdbarch *gdbarch,
				   struct language_arch_info *lai) const
{
  const struct builtin_type *builtin = builtin_type (gdbarch);

  /* Helper function to allow shorter lines below.  */
  auto add  = [&] (struct type * t) -> struct type *
  {
    lai->add_primitive_type (t);
    return t;
  };

  type_allocator alloc (gdbarch);
  struct type *bool_type
    = add (init_boolean_type (alloc, 8, 1, "bool"));
  add (init_character_type (alloc, 32, 1, "char"));
  add (init_integer_type (alloc, 8, 0, "i8"));
  struct type *u8_type
    = add (init_integer_type (alloc, 8, 1, "u8"));
  add (init_integer_type (alloc, 16, 0, "i16"));
  add (init_integer_type (alloc, 16, 1, "u16"));
  add (init_integer_type (alloc, 32, 0, "i32"));
  add (init_integer_type (alloc, 32, 1, "u32"));
  add (init_integer_type (alloc, 64, 0, "i64"));
  add (init_integer_type (alloc, 64, 1, "u64"));
  add (init_integer_type (alloc, 128, 0, "i128"));
  add (init_integer_type (alloc, 128, 1, "u128"));

  unsigned int length = 8 * builtin->builtin_data_ptr->length ();
  add (init_integer_type (alloc, length, 0, "isize"));
  struct type *usize_type
    = add (init_integer_type (alloc, length, 1, "usize"));

  add (init_float_type (alloc, 32, "f32", floatformats_ieee_single));
  add (init_float_type (alloc, 64, "f64", floatformats_ieee_double));
  add (init_integer_type (alloc, 0, 1, "()"));

  struct type *tem = make_cv_type (1, 0, u8_type, NULL);
  add (rust_slice_type ("&str", tem, usize_type));

  lai->set_bool_type (bool_type);
  lai->set_string_char_type (u8_type);
}

/* See language.h.  */

void
rust_language::print_type (struct type *type, const char *varstring,
			   struct ui_file *stream, int show, int level,
			   const struct type_print_options *flags) const
{
  print_offset_data podata (flags);
  rust_internal_print_type (type, varstring, stream, show, level,
			    flags, false, &podata);
}

/* See language.h.  */

void
rust_language::emitchar (int ch, struct type *chtype,
			 struct ui_file *stream, int quoter) const
{
  if (!rust_chartype_p (chtype))
    generic_emit_char (ch, chtype, stream, quoter,
		       target_charset (chtype->arch ()));
  else if (ch == '\\' || ch == quoter)
    gdb_printf (stream, "\\%c", ch);
  else if (ch == '\n')
    gdb_puts ("\\n", stream);
  else if (ch == '\r')
    gdb_puts ("\\r", stream);
  else if (ch == '\t')
    gdb_puts ("\\t", stream);
  else if (ch == '\0')
    gdb_puts ("\\0", stream);
  else if (ch >= 32 && ch <= 127 && c_isprint (ch))
    gdb_putc (ch, stream);
  else if (ch <= 255)
    gdb_printf (stream, "\\x%02x", ch);
  else
    gdb_printf (stream, "\\u{%06x}", ch);
}

/* See language.h.  */

bool
rust_language::is_array_like (struct type *type) const
{
  if (!rust_slice_type_p (type))
    return false;
  return rust_array_like_element_type (type) != nullptr;
}

/* See language.h.  */

bool
rust_language::is_string_type_p (struct type *type) const
{
  LONGEST low_bound, high_bound;

  type = check_typedef (type);
  return ((type->code () == TYPE_CODE_STRING)
	  || (type->code () == TYPE_CODE_PTR
	      && (type->target_type ()->code () == TYPE_CODE_ARRAY
		  && rust_u8_type_p (type->target_type ()->target_type ())
		  && get_array_bounds (type->target_type (), &low_bound,
				       &high_bound)))
	  || (type->code () == TYPE_CODE_STRUCT
	      && !rust_enum_p (type)
	      && rust_slice_type_p (type)
	      && strcmp (type->name (), "&str") == 0));
}

/* See language.h.  */

struct block_symbol
rust_language::lookup_symbol_nonlocal
     (const char *name, const struct block *block,
      const domain_search_flags domain) const
{
  struct block_symbol result = {};

  const char *scope = block == nullptr ? "" : block->scope ();
  symbol_lookup_debug_printf
    ("rust_lookup_symbol_non_local (%s, %s (scope %s), %s)",
     name, host_address_to_string (block), scope,
     domain_name (domain).c_str ());

  /* Look up bare names in the block's scope.  */
  std::string scopedname;
  if (name[cp_find_first_component (name)] == '\0')
    {
      if (scope[0] != '\0')
	{
	  scopedname = std::string (scope) + "::" + name;
	  name = scopedname.c_str ();
	}
      else
	name = NULL;
    }

  if (name != NULL)
    {
      result = lookup_symbol_in_static_block (name, block, domain);
      if (result.symbol == NULL)
	result = lookup_global_symbol (name, block, domain);
    }
  return result;
}

/* Single instance of the Rust language class.  */

static rust_language rust_language_defn;
