From f9a20bb2060105d369cae41f448dc6bb6915d5ac Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 16 Jul 2015 01:34:13 -0700 Subject: [PATCH] debuginfo: Fix type description generic enum discriminants. --- .../trans/debuginfo/metadata.rs | 9 +- src/librustc_trans/trans/debuginfo/mod.rs | 7 +- .../generic-enum-with-different-disr-sizes.rs | 91 +++++++++++++++++++ 3 files changed, 98 insertions(+), 9 deletions(-) create mode 100644 src/test/debuginfo/generic-enum-with-different-disr-sizes.rs diff --git a/src/librustc_trans/trans/debuginfo/metadata.rs b/src/librustc_trans/trans/debuginfo/metadata.rs index ed494d0765bb0..599a255ef8b6c 100644 --- a/src/librustc_trans/trans/debuginfo/metadata.rs +++ b/src/librustc_trans/trans/debuginfo/metadata.rs @@ -1606,13 +1606,10 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, .collect(); let discriminant_type_metadata = |inttype| { - // We can reuse the type of the discriminant for all monomorphized - // instances of an enum because it doesn't depend on any type - // parameters. The def_id, uniquely identifying the enum's polytype acts - // as key in this cache. + let disr_type_key = (enum_def_id, inttype); let cached_discriminant_type_metadata = debug_context(cx).created_enum_disr_types .borrow() - .get(&enum_def_id).cloned(); + .get(&disr_type_key).cloned(); match cached_discriminant_type_metadata { Some(discriminant_type_metadata) => discriminant_type_metadata, None => { @@ -1641,7 +1638,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, debug_context(cx).created_enum_disr_types .borrow_mut() - .insert(enum_def_id, discriminant_type_metadata); + .insert(disr_type_key, discriminant_type_metadata); discriminant_type_metadata } diff --git a/src/librustc_trans/trans/debuginfo/mod.rs b/src/librustc_trans/trans/debuginfo/mod.rs index 3d1b384c2d915..a873529891731 100644 --- a/src/librustc_trans/trans/debuginfo/mod.rs +++ b/src/librustc_trans/trans/debuginfo/mod.rs @@ -32,7 +32,7 @@ use trans; use trans::monomorphize; use middle::ty::Ty; use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo}; -use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet}; +use util::nodemap::{NodeMap, FnvHashMap, FnvHashSet}; use libc::c_uint; use std::cell::{Cell, RefCell}; @@ -41,6 +41,7 @@ use std::ptr; use std::rc::Rc; use syntax::codemap::{Span, Pos}; use syntax::{ast, codemap, ast_util}; +use syntax::attr::IntType; use syntax::parse::token::{self, special_idents}; pub mod gdb; @@ -73,7 +74,7 @@ pub struct CrateDebugContext<'tcx> { builder: DIBuilderRef, current_debug_location: Cell, created_files: RefCell>, - created_enum_disr_types: RefCell>, + created_enum_disr_types: RefCell>, type_map: RefCell>, namespace_map: RefCell, Rc>>, @@ -94,7 +95,7 @@ impl<'tcx> CrateDebugContext<'tcx> { builder: builder, current_debug_location: Cell::new(InternalDebugLocation::UnknownLocation), created_files: RefCell::new(FnvHashMap()), - created_enum_disr_types: RefCell::new(DefIdMap()), + created_enum_disr_types: RefCell::new(FnvHashMap()), type_map: RefCell::new(TypeMap::new()), namespace_map: RefCell::new(FnvHashMap()), composite_types_completed: RefCell::new(FnvHashSet()), diff --git a/src/test/debuginfo/generic-enum-with-different-disr-sizes.rs b/src/test/debuginfo/generic-enum-with-different-disr-sizes.rs new file mode 100644 index 0000000000000..ab8f150a145c6 --- /dev/null +++ b/src/test/debuginfo/generic-enum-with-different-disr-sizes.rs @@ -0,0 +1,91 @@ +// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-tidy-linelength +// min-lldb-version: 310 + +// compile-flags:-g + +// === GDB TESTS =================================================================================== +// gdb-command:run + +// gdb-command:print eight_bytes1 +// gdb-check:$1 = {{RUST$ENUM$DISR = Variant1, __0 = 100}, {RUST$ENUM$DISR = Variant1, __0 = 100}} +// gdb-command:print four_bytes1 +// gdb-check:$2 = {{RUST$ENUM$DISR = Variant1, __0 = 101}, {RUST$ENUM$DISR = Variant1, __0 = 101}} +// gdb-command:print two_bytes1 +// gdb-check:$3 = {{RUST$ENUM$DISR = Variant1, __0 = 102}, {RUST$ENUM$DISR = Variant1, __0 = 102}} +// gdb-command:print one_byte1 +// gdb-check:$4 = {{RUST$ENUM$DISR = Variant1, __0 = 65 'A'}, {RUST$ENUM$DISR = Variant1, __0 = 65 'A'}} + +// gdb-command:print eight_bytes2 +// gdb-check:$5 = {{RUST$ENUM$DISR = Variant2, __0 = 100}, {RUST$ENUM$DISR = Variant2, __0 = 100}} +// gdb-command:print four_bytes2 +// gdb-check:$6 = {{RUST$ENUM$DISR = Variant2, __0 = 101}, {RUST$ENUM$DISR = Variant2, __0 = 101}} +// gdb-command:print two_bytes2 +// gdb-check:$7 = {{RUST$ENUM$DISR = Variant2, __0 = 102}, {RUST$ENUM$DISR = Variant2, __0 = 102}} +// gdb-command:print one_byte2 +// gdb-check:$8 = {{RUST$ENUM$DISR = Variant2, __0 = 65 'A'}, {RUST$ENUM$DISR = Variant2, __0 = 65 'A'}} + +// gdb-command:continue + +// === LLDB TESTS ================================================================================== +// lldb-command:run + +// lldb-command:print eight_bytes1 +// lldb-check:[...]$0 = Variant1(100) +// lldb-command:print four_bytes1 +// lldb-check:[...]$1 = Variant1(101) +// lldb-command:print two_bytes1 +// lldb-check:[...]$2 = Variant1(102) +// lldb-command:print one_byte1 +// lldb-check:[...]$3 = Variant1('A') + +// lldb-command:print eight_bytes2 +// lldb-check:[...]$4 = Variant2(100) +// lldb-command:print four_bytes2 +// lldb-check:[...]$5 = Variant2(101) +// lldb-command:print two_bytes2 +// lldb-check:[...]$6 = Variant2(102) +// lldb-command:print one_byte2 +// lldb-check:[...]$7 = Variant2('A') + +// lldb-command:continue + +#![allow(unused_variables)] +#![allow(dead_code)] +#![omit_gdb_pretty_printer_section] + +// This test case makes sure that we get correct type descriptions for the enum +// discriminant of different instantiations of the same generic enum type where, +// dependending on the generic type parameter(s), the discriminant has a +// different size in memory. + +enum Enum { + Variant1(T), + Variant2(T) +} + +fn main() { + // These are ordered for descending size on purpose + let eight_bytes1 = Enum::Variant1(100.0f64); + let four_bytes1 = Enum::Variant1(101i32); + let two_bytes1 = Enum::Variant1(102i16); + let one_byte1 = Enum::Variant1(65u8); + + let eight_bytes2 = Enum::Variant2(100.0f64); + let four_bytes2 = Enum::Variant2(101i32); + let two_bytes2 = Enum::Variant2(102i16); + let one_byte2 = Enum::Variant2(65u8); + + zzz(); // #break +} + +fn zzz() { () }