Update copyright year range in all GDB files.
[deliverable/binutils-gdb.git] / gdb / rust-lang.c
index 35126da7a65a1e2252e207c762c24cbced292d18..9123bf2146d516dabb72f9d9caff728dced98ef0 100644 (file)
@@ -1,6 +1,6 @@
 /* Rust language support routines for GDB, the GNU debugger.
 
-   Copyright (C) 2016-2018 Free Software Foundation, Inc.
+   Copyright (C) 2016-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "objfiles.h"
 #include "psymtab.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"
 
 /* See rust-lang.h.  */
 
@@ -72,9 +75,22 @@ rust_enum_p (const struct type *type)
          && TYPE_FLAG_DISCRIMINATED_UNION (TYPE_FIELD_TYPE (type, 0)));
 }
 
+/* Return true if TYPE, which must be an enum type, has no
+   variants.  */
+
+static bool
+rust_empty_enum_p (const struct type *type)
+{
+  gdb_assert (rust_enum_p (type));
+  /* In Rust the enum always fills the containing structure.  */
+  gdb_assert (TYPE_FIELD_BITPOS (type, 0) == 0);
+
+  return TYPE_NFIELDS (TYPE_FIELD_TYPE (type, 0)) == 0;
+}
+
 /* Given an enum type and contents, find which variant is active.  */
 
-struct field *
+static struct field *
 rust_enum_variant (struct type *type, const gdb_byte *contents)
 {
   /* In Rust the enum always fills the containing structure.  */
@@ -95,8 +111,8 @@ rust_tuple_type_p (struct type *type)
      nothing else in the debuginfo to distinguish a tuple from a
      struct.  */
   return (TYPE_CODE (type) == TYPE_CODE_STRUCT
-         && TYPE_TAG_NAME (type) != NULL
-         && TYPE_TAG_NAME (type)[0] == '(');
+         && TYPE_NAME (type) != NULL
+         && TYPE_NAME (type)[0] == '(');
 }
 
 /* Return true if all non-static fields of a structlike type are in a
@@ -143,9 +159,9 @@ static bool
 rust_slice_type_p (struct type *type)
 {
   return (TYPE_CODE (type) == TYPE_CODE_STRUCT
-         && TYPE_TAG_NAME (type) != NULL
-         && (strncmp (TYPE_TAG_NAME (type), "&[", 2) == 0
-             || strcmp (TYPE_TAG_NAME (type), "&str") == 0));
+         && TYPE_NAME (type) != NULL
+         && (strncmp (TYPE_NAME (type), "&[", 2) == 0
+             || strcmp (TYPE_NAME (type), "&str") == 0));
 }
 
 /* Return true if TYPE is a range type, otherwise false.  */
@@ -157,8 +173,8 @@ rust_range_type_p (struct type *type)
 
   if (TYPE_CODE (type) != TYPE_CODE_STRUCT
       || TYPE_NFIELDS (type) > 2
-      || TYPE_TAG_NAME (type) == NULL
-      || strstr (TYPE_TAG_NAME (type), "::Range") == NULL)
+      || TYPE_NAME (type) == NULL
+      || strstr (TYPE_NAME (type), "::Range") == NULL)
     return false;
 
   if (TYPE_NFIELDS (type) == 0)
@@ -180,6 +196,17 @@ rust_range_type_p (struct type *type)
   return strcmp (TYPE_FIELD_NAME (type, i), "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 (type), "::RangeInclusive") != NULL
+         || strstr (TYPE_NAME (type), "::RangeToInclusive") != NULL);
+}
+
 /* Return true if TYPE seems to be the type "u8", otherwise false.  */
 
 static bool
@@ -200,6 +227,26 @@ rust_chartype_p (struct type *type)
          && TYPE_UNSIGNED (type));
 }
 
+/* Return true if TYPE is a string type.  */
+
+static bool
+rust_is_string_type_p (struct type *type)
+{
+  LONGEST low_bound, high_bound;
+
+  type = check_typedef (type);
+  return ((TYPE_CODE (type) == TYPE_CODE_STRING)
+         || (TYPE_CODE (type) == TYPE_CODE_PTR
+             && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_ARRAY
+                 && rust_u8_type_p (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (type)))
+                 && get_array_bounds (TYPE_TARGET_TYPE (type), &low_bound,
+                                      &high_bound)))
+         || (TYPE_CODE (type) == TYPE_CODE_STRUCT
+             && !rust_enum_p (type)
+             && rust_slice_type_p (type)
+             && strcmp (TYPE_NAME (type), "&str") == 0));
+}
+
 /* If VALUE represents a trait object pointer, return the underlying
    pointer with the correct (i.e., runtime) type.  Otherwise, return
    NULL.  */
@@ -332,6 +379,14 @@ val_print_struct (struct type *type, int embedded_offset,
 
   if (rust_slice_type_p (type) && strcmp (TYPE_NAME (type), "&str") == 0)
     {
+      /* If what we are printing here is actually a string within a
+        structure then VAL will be the original parent value, while TYPE
+        will be the type of the structure representing the string we want
+        to print.
+        However, RUST_VAL_PRINT_STR looks up the fields of the string
+        inside VAL, assuming that VAL is the string.
+        So, recreate VAL as a value representing just the string.  */
+      val = value_at_lazy (type, value_address (val) + embedded_offset);
       rust_val_print_str (stream, val, options);
       return;
     }
@@ -342,13 +397,13 @@ val_print_struct (struct type *type, int embedded_offset,
 
   if (!is_tuple)
     {
-      if (TYPE_TAG_NAME (type) != NULL)
-        fprintf_filtered (stream, "%s", TYPE_TAG_NAME (type));
+      if (TYPE_NAME (type) != NULL)
+        fprintf_filtered (stream, "%s", TYPE_NAME (type));
 
       if (TYPE_NFIELDS (type) == 0)
         return;
 
-      if (TYPE_TAG_NAME (type) != NULL)
+      if (TYPE_NAME (type) != NULL)
         fputs_filtered (" ", stream);
     }
 
@@ -416,6 +471,15 @@ rust_print_enum (struct type *type, int embedded_offset,
 
   opts.deref_ref = 0;
 
+  if (rust_empty_enum_p (type))
+    {
+      /* Print the enum type name here to be more clear.  */
+      fprintf_filtered (stream, _("%s {%p[<No data fields>%p]}"),
+                       TYPE_NAME (type),
+                       metadata_style.style ().ptr (), nullptr);
+      return;
+    }
+
   const gdb_byte *valaddr = value_contents_for_printing (val);
   struct field *variant_field = rust_enum_variant (type, valaddr);
   embedded_offset += FIELD_BITPOS (*variant_field) / 8;
@@ -605,19 +669,19 @@ 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);
+                         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)
+                      bool for_rust_enum, print_offset_data *podata)
 {
   /* Print a tuple type simply.  */
   if (rust_tuple_type_p (type))
     {
-      fputs_filtered (TYPE_TAG_NAME (type), stream);
+      fputs_filtered (TYPE_NAME (type), stream);
       return;
     }
 
@@ -625,13 +689,19 @@ rust_print_struct_def (struct type *type, const char *varstring,
   if (TYPE_N_BASECLASSES (type) > 0)
     c_print_type (type, varstring, stream, show, level, 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_TAG_NAME (type);
+  const char *tagname = TYPE_NAME (type);
   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);
-  bool is_univariant = false;
 
   int enum_discriminant_index = -1;
 
@@ -645,6 +715,18 @@ rust_print_struct_def (struct type *type, const char *varstring,
       if (is_enum)
        {
          fputs_filtered ("enum ", stream);
+
+         if (rust_empty_enum_p (type))
+           {
+             if (tagname != NULL)
+               {
+                 fputs_filtered (tagname, stream);
+                 fputs_filtered (" ", stream);
+               }
+             fputs_filtered ("{}", stream);
+             return;
+           }
+
          type = TYPE_FIELD_TYPE (type, 0);
 
          struct dynamic_prop *discriminant_prop
@@ -653,12 +735,6 @@ rust_print_struct_def (struct type *type, const char *varstring,
            = (struct discriminant_info *) discriminant_prop->data.baton;
          enum_discriminant_index = info->discriminant_index;
        }
-      else if (TYPE_CODE (type) == TYPE_CODE_UNION && TYPE_NFIELDS (type) == 1)
-       {
-         /* Probably a univariant enum.  */
-         fputs_filtered ("enum ", stream);
-         is_univariant = true;
-       }
       else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
        fputs_filtered ("struct ", stream);
       else
@@ -670,16 +746,41 @@ rust_print_struct_def (struct type *type, const char *varstring,
 
   if (TYPE_NFIELDS (type) == 0 && !is_tuple)
     return;
-  if (for_rust_enum)
+  if (for_rust_enum && !flags->print_offsets)
     fputs_filtered (is_tuple_struct ? "(" : "{", stream);
   else
     fputs_filtered (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_NFIELDS (type); ++i)
     {
-      QUIT;
       if (field_is_static (&TYPE_FIELD (type, i)))
        continue;
+      if (is_enum && i == enum_discriminant_index)
+       continue;
+      fields.push_back (i);
+    }
+  if (flags->print_offsets)
+    std::sort (fields.begin (), fields.end (),
+              [&] (int a, int b)
+              {
+                return (TYPE_FIELD_BITPOS (type, a)
+                        < TYPE_FIELD_BITPOS (type, b));
+              });
+
+  for (int i : fields)
+    {
+      QUIT;
+
+      gdb_assert (!field_is_static (&TYPE_FIELD (type, i)));
+      gdb_assert (! (is_enum && i == enum_discriminant_index));
+
+      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
@@ -687,34 +788,35 @@ rust_print_struct_def (struct type *type, const char *varstring,
 
       /* For a tuple struct we print the type but nothing
         else.  */
-      if (!for_rust_enum)
+      if (!for_rust_enum || flags->print_offsets)
        print_spaces_filtered (level + 2, stream);
       if (is_enum)
-       {
-         if (i == enum_discriminant_index)
-           continue;
-         fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
-       }
-      else if (is_univariant)
-       {
-         const char *name
-           = rust_last_path_segment (TYPE_NAME (TYPE_FIELD_TYPE (type, i)));
-         fputs_filtered (name, stream);
-       }
+       fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
       else if (!is_tuple_struct)
        fprintf_filtered (stream, "%s: ", TYPE_FIELD_NAME (type, i));
 
       rust_internal_print_type (TYPE_FIELD_TYPE (type, i), NULL,
-                               stream,
-                               ((is_enum || is_univariant) ? show : show - 1),
-                               level + 2, flags, is_enum || is_univariant);
-      if (!for_rust_enum)
+                               stream, (is_enum ? show : show - 1),
+                               level + 2, flags, is_enum, podata);
+      if (!for_rust_enum || flags->print_offsets)
        fputs_filtered (",\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_NFIELDS (type))
        fputs_filtered (", ", stream);
     }
 
-  if (!for_rust_enum)
+  if (flags->print_offsets)
+    {
+      /* Undo the temporary level increase we did above.  */
+      level -= 2;
+      podata->finish (type, level, stream);
+      print_spaces_filtered (print_offset_data::indentation, stream);
+      if (level == 0)
+       print_spaces_filtered (2, stream);
+    }
+  if (!for_rust_enum || flags->print_offsets)
     print_spaces_filtered (level, stream);
   fputs_filtered (is_tuple_struct ? ")" : "}", stream);
 }
@@ -727,9 +829,9 @@ rust_print_typedef (struct type *type,
                    struct ui_file *stream)
 {
   type = check_typedef (type);
-  fprintf_filtered (stream, "type %s = ", SYMBOL_PRINT_NAME (new_symbol));
+  fprintf_filtered (stream, "type %s = ", new_symbol->print_name ());
   type_print (type, "", stream, 0);
-  fprintf_filtered (stream, ";\n");
+  fprintf_filtered (stream, ";");
 }
 
 /* la_print_type implementation for Rust.  */
@@ -738,10 +840,8 @@ 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)
+                         bool for_rust_enum, print_offset_data *podata)
 {
-  int i;
-
   QUIT;
   if (show <= 0
       && TYPE_NAME (type) != NULL)
@@ -775,13 +875,13 @@ rust_internal_print_type (struct type *type, const char *varstring,
       if (varstring != NULL)
        fputs_filtered (varstring, stream);
       fputs_filtered ("(", stream);
-      for (i = 0; i < TYPE_NFIELDS (type); ++i)
+      for (int i = 0; i < TYPE_NFIELDS (type); ++i)
        {
          QUIT;
          if (i > 0)
            fputs_filtered (", ", stream);
          rust_internal_print_type (TYPE_FIELD_TYPE (type, i), "", stream,
-                                   -1, 0, flags, false);
+                                   -1, 0, flags, false, podata);
        }
       fputs_filtered (")", stream);
       /* If it returns unit, we can omit the return type.  */
@@ -789,7 +889,7 @@ rust_internal_print_type (struct type *type, const char *varstring,
         {
           fputs_filtered (" -> ", stream);
           rust_internal_print_type (TYPE_TARGET_TYPE (type), "", stream,
-                                   -1, 0, flags, false);
+                                   -1, 0, flags, false, podata);
         }
       break;
 
@@ -799,7 +899,8 @@ rust_internal_print_type (struct type *type, const char *varstring,
 
        fputs_filtered ("[", stream);
        rust_internal_print_type (TYPE_TARGET_TYPE (type), NULL,
-                                 stream, show - 1, level, flags, false);
+                                 stream, show - 1, level, flags, false,
+                                 podata);
 
        if (TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCEXPR
            || TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCLIST)
@@ -814,30 +915,30 @@ rust_internal_print_type (struct type *type, const char *varstring,
     case TYPE_CODE_UNION:
     case TYPE_CODE_STRUCT:
       rust_print_struct_def (type, varstring, stream, show, level, flags,
-                            for_rust_enum);
+                            for_rust_enum, podata);
       break;
 
     case TYPE_CODE_ENUM:
       {
-       int i, len = 0;
+       int len = 0;
 
        fputs_filtered ("enum ", stream);
-       if (TYPE_TAG_NAME (type) != NULL)
+       if (TYPE_NAME (type) != NULL)
          {
-           fputs_filtered (TYPE_TAG_NAME (type), stream);
+           fputs_filtered (TYPE_NAME (type), stream);
            fputs_filtered (" ", stream);
-           len = strlen (TYPE_TAG_NAME (type));
+           len = strlen (TYPE_NAME (type));
          }
        fputs_filtered ("{\n", stream);
 
-       for (i = 0; i < TYPE_NFIELDS (type); ++i)
+       for (int i = 0; i < TYPE_NFIELDS (type); ++i)
          {
            const char *name = TYPE_FIELD_NAME (type, i);
 
            QUIT;
 
            if (len > 0
-               && strncmp (name, TYPE_TAG_NAME (type), len) == 0
+               && strncmp (name, TYPE_NAME (type), len) == 0
                && name[len] == ':'
                && name[len + 1] == ':')
              name += len + 2;
@@ -848,6 +949,20 @@ rust_internal_print_type (struct type *type, const char *varstring,
       }
       break;
 
+    case TYPE_CODE_PTR:
+      {
+       if (TYPE_NAME (type) != nullptr)
+         fputs_filtered (TYPE_NAME (type), stream);
+       else
+         {
+           /* We currently can't distinguish between pointers and
+              references.  */
+           fputs_filtered ("*mut ", stream);
+           type_print (TYPE_TARGET_TYPE (type), "", stream, 0);
+         }
+      }
+      break;
+
     default:
     c_printer:
       c_print_type (type, varstring, stream, show, level, flags);
@@ -859,53 +974,13 @@ rust_print_type (struct type *type, const char *varstring,
                 struct ui_file *stream, int show, int level,
                 const struct type_print_options *flags)
 {
+  print_offset_data podata;
   rust_internal_print_type (type, varstring, stream, show, level,
-                           flags, false);
+                           flags, false, &podata);
 }
 
 \f
 
-/* Compute the alignment of the type T.  */
-
-static int
-rust_type_alignment (struct type *t)
-{
-  t = check_typedef (t);
-  switch (TYPE_CODE (t))
-    {
-    default:
-      error (_("Could not compute alignment of type"));
-
-    case TYPE_CODE_PTR:
-    case TYPE_CODE_ENUM:
-    case TYPE_CODE_INT:
-    case TYPE_CODE_FLT:
-    case TYPE_CODE_REF:
-    case TYPE_CODE_CHAR:
-    case TYPE_CODE_BOOL:
-      return TYPE_LENGTH (t);
-
-    case TYPE_CODE_ARRAY:
-    case TYPE_CODE_COMPLEX:
-      return rust_type_alignment (TYPE_TARGET_TYPE (t));
-
-    case TYPE_CODE_STRUCT:
-    case TYPE_CODE_UNION:
-      {
-       int i;
-       int align = 1;
-
-       for (i = 0; i < TYPE_NFIELDS (t); ++i)
-         {
-           int a = rust_type_alignment (TYPE_FIELD_TYPE (t, i));
-           if (a > align)
-             align = a;
-         }
-       return align;
-      }
-    }
-}
-
 /* Like arch_composite_type, but uses TYPE to decide how to allocate
    -- either on an obstack or on a gdbarch.  */
 
@@ -926,7 +1001,6 @@ rust_composite_type (struct type *original,
 
   TYPE_CODE (result) = TYPE_CODE_STRUCT;
   TYPE_NAME (result) = name;
-  TYPE_TAG_NAME (result) = name;
 
   TYPE_NFIELDS (result) = nfields;
   TYPE_FIELDS (result)
@@ -948,7 +1022,7 @@ rust_composite_type (struct type *original,
   if (field2 != NULL)
     {
       struct field *field = &TYPE_FIELD (result, i);
-      int align = rust_type_alignment (type2);
+      unsigned align = type_align (type2);
 
       if (align != 0)
        {
@@ -1104,10 +1178,10 @@ rust_evaluate_funcall (struct expression *exp, int *pos, enum noside noside)
        && TYPE_CODE (type) != TYPE_CODE_ENUM)
       || rust_tuple_type_p (type))
     error (_("Method calls only supported on struct or enum types"));
-  if (TYPE_TAG_NAME (type) == NULL)
+  if (TYPE_NAME (type) == NULL)
     error (_("Method call on nameless type"));
 
-  std::string name = std::string (TYPE_TAG_NAME (type)) + "::" + method;
+  std::string name = std::string (TYPE_NAME (type)) + "::" + method;
 
   block = get_selected_block (0);
   sym = lookup_symbol (name.c_str (), block, VAR_DOMAIN, NULL);
@@ -1129,7 +1203,7 @@ rust_evaluate_funcall (struct expression *exp, int *pos, enum noside noside)
   if (noside == EVAL_AVOID_SIDE_EFFECTS)
     result = value_zero (TYPE_TARGET_TYPE (fn_type), not_lval);
   else
-    result = call_function_by_hand (function, NULL, num_args + 1, args.data ());
+    result = call_function_by_hand (function, NULL, args);
   return result;
 }
 
@@ -1150,10 +1224,13 @@ rust_range (struct expression *exp, int *pos, enum noside noside)
   kind = (enum range_type) longest_to_int (exp->elts[*pos + 1].longconst);
   *pos += 3;
 
-  if (kind == HIGH_BOUND_DEFAULT || kind == NONE_BOUND_DEFAULT)
+  if (kind == HIGH_BOUND_DEFAULT || kind == NONE_BOUND_DEFAULT
+      || kind == NONE_BOUND_DEFAULT_EXCLUSIVE)
     low = evaluate_subexp (NULL_TYPE, exp, pos, noside);
-  if (kind == LOW_BOUND_DEFAULT || kind == NONE_BOUND_DEFAULT)
+  if (kind == LOW_BOUND_DEFAULT || kind == LOW_BOUND_DEFAULT_EXCLUSIVE
+      || kind == NONE_BOUND_DEFAULT || kind == NONE_BOUND_DEFAULT_EXCLUSIVE)
     high = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+  bool inclusive = (kind == NONE_BOUND_DEFAULT || kind == LOW_BOUND_DEFAULT);
 
   if (noside == EVAL_SKIP)
     return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1);
@@ -1168,7 +1245,8 @@ rust_range (struct expression *exp, int *pos, enum noside noside)
       else
        {
          index_type = value_type (high);
-         name = "std::ops::RangeTo";
+         name = (inclusive
+                 ? "std::ops::RangeToInclusive" : "std::ops::RangeTo");
        }
     }
   else
@@ -1183,7 +1261,7 @@ rust_range (struct expression *exp, int *pos, enum noside noside)
          if (!types_equal (value_type (low), value_type (high)))
            error (_("Range expression with different types"));
          index_type = value_type (low);
-         name = "std::ops::Range";
+         name = inclusive ? "std::ops::RangeInclusive" : "std::ops::Range";
        }
     }
 
@@ -1259,6 +1337,9 @@ rust_compute_range (struct type *type, struct value *range,
       *kind = (*kind == BOTH_BOUND_DEFAULT
               ? LOW_BOUND_DEFAULT : NONE_BOUND_DEFAULT);
       *high = value_as_long (value_field (range, i));
+
+      if (rust_inclusive_range_type_p (type))
+       ++*high;
     }
 }
 
@@ -1549,7 +1630,7 @@ rust_evaluate_subexp (struct type *expect_type, struct expression *exp,
 
     case OP_RUST_ARRAY:
       {
-       int pc = (*pos)++;
+       (*pos)++;
        int copies;
        struct value *elt;
        struct value *ncopies;
@@ -1583,7 +1664,7 @@ rust_evaluate_subexp (struct type *expect_type, struct expression *exp,
         /* Anonymous field access, i.e. foo.1.  */
         struct value *lhs;
         int pc, field_number, nfields;
-        struct type *type, *variant_type;
+        struct type *type;
 
         pc = (*pos)++;
         field_number = longest_to_int (exp->elts[pc + 1].longconst);
@@ -1592,19 +1673,16 @@ rust_evaluate_subexp (struct type *expect_type, struct expression *exp,
 
         type = value_type (lhs);
 
-       /* Treat a univariant union as if it were an enum.  */
-       if (TYPE_CODE (type) == TYPE_CODE_UNION && TYPE_NFIELDS (type) == 1)
-         {
-           lhs = value_primitive_field (lhs, 0, 0, type);
-           type = value_type (lhs);
-         }
-
        if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
          {
            struct type *outer_type = NULL;
 
            if (rust_enum_p (type))
              {
+               if (rust_empty_enum_p (type))
+                 error (_("Cannot access field %d of empty enum %s"),
+                        field_number, TYPE_NAME (type));
+
                const gdb_byte *valaddr = value_contents (lhs);
                struct field *variant_field = rust_enum_variant (type, valaddr);
 
@@ -1627,13 +1705,13 @@ rust_evaluate_subexp (struct type *expect_type, struct expression *exp,
                if (outer_type != NULL)
                  error(_("Cannot access field %d of variant %s::%s, "
                          "there are only %d fields"),
-                       field_number, TYPE_TAG_NAME (outer_type),
-                       rust_last_path_segment (TYPE_TAG_NAME (type)),
+                       field_number, TYPE_NAME (outer_type),
+                       rust_last_path_segment (TYPE_NAME (type)),
                        nfields);
                else
                  error(_("Cannot access field %d of %s, "
                          "there are only %d fields"),
-                       field_number, TYPE_TAG_NAME (type), nfields);
+                       field_number, TYPE_NAME (type), nfields);
              }
 
            /* Tuples are tuple structs too.  */
@@ -1641,13 +1719,13 @@ rust_evaluate_subexp (struct type *expect_type, struct expression *exp,
              {
                if (outer_type != NULL)
                  error(_("Variant %s::%s is not a tuple variant"),
-                       TYPE_TAG_NAME (outer_type),
-                       rust_last_path_segment (TYPE_TAG_NAME (type)));
+                       TYPE_NAME (outer_type),
+                       rust_last_path_segment (TYPE_NAME (type)));
                else
                  error(_("Attempting to access anonymous field %d "
                          "of %s, which is not a tuple, tuple struct, or "
                          "tuple-like variant"),
-                     field_number, TYPE_TAG_NAME (type));
+                     field_number, TYPE_NAME (type));
              }
 
            result = value_primitive_field (lhs, 0, field_number, type);
@@ -1673,6 +1751,10 @@ tuple structs, and tuple-like enum variants"));
         type = value_type (lhs);
         if (TYPE_CODE (type) == TYPE_CODE_STRUCT && rust_enum_p (type))
          {
+           if (rust_empty_enum_p (type))
+             error (_("Cannot access field %s of empty enum %s"),
+                    field_name, TYPE_NAME (type));
+
            const gdb_byte *valaddr = value_contents (lhs);
            struct field *variant_field = rust_enum_variant (type, valaddr);
 
@@ -1687,23 +1769,22 @@ tuple structs, and tuple-like enum variants"));
            struct type *outer_type = type;
            type = value_type (lhs);
            if (rust_tuple_type_p (type) || rust_tuple_struct_type_p (type))
-               error (_("Attempting to access named field foo of tuple "
+               error (_("Attempting to access named field %s of tuple "
                         "variant %s::%s, which has only anonymous fields"),
-                      TYPE_TAG_NAME (outer_type),
+                      field_name, TYPE_NAME (outer_type),
                       rust_last_path_segment (TYPE_NAME (type)));
 
-           TRY
+           try
              {
                result = value_struct_elt (&lhs, NULL, field_name,
                                           NULL, "structure");
              }
-           CATCH (except, RETURN_MASK_ERROR)
+           catch (const gdb_exception_error &except)
              {
                error (_("Could not find field %s of struct variant %s::%s"),
-                      field_name, TYPE_TAG_NAME (outer_type),
+                      field_name, TYPE_NAME (outer_type),
                       rust_last_path_segment (TYPE_NAME (type)));
              }
-           END_CATCH
          }
        else
          result = value_struct_elt (&lhs, NULL, field_name, NULL, "structure");
@@ -1969,7 +2050,7 @@ rust_lookup_symbol_nonlocal (const struct language_defn *langdef,
                             const struct block *block,
                             const domain_enum domain)
 {
-  struct block_symbol result = {NULL, NULL};
+  struct block_symbol result = {};
 
   if (symbol_lookup_debug)
     {
@@ -2058,7 +2139,6 @@ extern const struct language_defn rust_language_defn =
   rust_extensions,
   &exp_descriptor_rust,
   rust_parse,
-  rustyyerror,
   null_post_parser,
   rust_printchar,              /* Print a character constant */
   rust_printstr,               /* Function to print string constant */
@@ -2070,6 +2150,7 @@ extern const struct language_defn rust_language_defn =
   default_read_var_value,      /* la_read_var_value */
   NULL,                                /* Language specific skip_trampoline */
   NULL,                                /* name_of_this */
+  false,                       /* la_store_sym_names_in_linkage_form_p */
   rust_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   gdb_demangle,                        /* Language specific symbol demangler */
@@ -2084,7 +2165,6 @@ extern const struct language_defn rust_language_defn =
   rust_language_arch_info,
   default_print_array_index,
   default_pass_by_reference,
-  c_get_string,
   rust_watch_location_expression,
   NULL,                                /* la_get_symbol_name_matcher */
   iterate_over_symbols,
@@ -2092,5 +2172,6 @@ extern const struct language_defn rust_language_defn =
   &default_varobj_ops,
   NULL,
   NULL,
-  LANG_MAGIC
+  rust_is_string_type_p,
+  "{...}"                      /* la_struct_too_deep_ellipsis */
 };
This page took 0.039885 seconds and 4 git commands to generate.