Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

debuginfo: Fix type description generic enum discriminants. #27070

Merged
merged 1 commit into from
Jul 17, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions src/librustc_trans/trans/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand Down Expand Up @@ -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
}
Expand Down
7 changes: 4 additions & 3 deletions src/librustc_trans/trans/debuginfo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -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;
Expand Down Expand Up @@ -73,7 +74,7 @@ pub struct CrateDebugContext<'tcx> {
builder: DIBuilderRef,
current_debug_location: Cell<InternalDebugLocation>,
created_files: RefCell<FnvHashMap<String, DIFile>>,
created_enum_disr_types: RefCell<DefIdMap<DIType>>,
created_enum_disr_types: RefCell<FnvHashMap<(ast::DefId, IntType), DIType>>,

type_map: RefCell<TypeMap<'tcx>>,
namespace_map: RefCell<FnvHashMap<Vec<ast::Name>, Rc<NamespaceTreeNode>>>,
Expand All @@ -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()),
Expand Down
91 changes: 91 additions & 0 deletions src/test/debuginfo/generic-enum-with-different-disr-sizes.rs
Original file line number Diff line number Diff line change
@@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<T> {
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() { () }