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

Rollup of 11 pull requests #59538

Closed
wants to merge 40 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
8b37e80
Fix stack overflow when generating debuginfo for 'recursive' type
Aaron1011 Mar 26, 2019
c1b9632
Fix inverted panic check
Aaron1011 Mar 26, 2019
93813cf
Add codegen test
Aaron1011 Mar 27, 2019
4187560
Add comments for new `AdtDef` functions.
davidtwco Mar 22, 2019
4e7ec07
Account for short-hand field syntax when suggesting borrow
estebank Mar 27, 2019
a51ca02
Expand test
estebank Mar 27, 2019
e3918cf
Recover from parse error in tuple syntax
estebank Mar 27, 2019
50ab958
Fix typos
Aaron1011 Mar 28, 2019
8fd3be5
fix broken download link in the armhf-gnu image
pietroalbini Mar 28, 2019
3a88cd7
Implement `#[non_exhaustive]` on variants.
davidtwco Mar 22, 2019
b7dc8e7
fix text after rebase
estebank Mar 29, 2019
9ea6790
Deduplicate parse recovery code
estebank Mar 29, 2019
07857f7
review comments
estebank Mar 28, 2019
e995fa8
implement `AsRawFd` for stdio locks
euclio Mar 29, 2019
1893841
Update documentation.
davidtwco Mar 23, 2019
49a6da2
Support non-exhaustive enum variants in rustdoc.
davidtwco Mar 23, 2019
ff33b27
Whitelist `rustc_on_unimplemented` to avoid erroneous flagging as an …
pnkfelix Mar 29, 2019
3592079
revert change to test file as per review request
estebank Mar 29, 2019
0b96697
Regression test for incremental treatment of rustc_on_unimplemented.
pnkfelix Mar 29, 2019
7642f10
Whitelist rustc_layout_scalar_valid_range_{start,end} so incr comp do…
pnkfelix Mar 29, 2019
cbbd4d5
Regression test for incremental treatment of rustc_scalar_valid_range…
pnkfelix Mar 29, 2019
f10e444
Edited the dbg! docs stating that dbg! works the same way in release …
Mar 29, 2019
9240092
Adjusted the indentation.
Mar 29, 2019
fe210d0
Update src/libstd/macros.rs
Centril Mar 29, 2019
8705de4
Update src/libstd/macros.rs
Centril Mar 29, 2019
ddfa47f
Fix incorrect code
estebank Mar 29, 2019
9e4ec7a
Collapse blanket impls in the same way as normal impls
laurmaedje Mar 29, 2019
b6fb3e3
In doc examples, don't ignore read/write results
mbrubeck Mar 29, 2019
7ce0b67
Fix OnceWith docstring.
goffrie Mar 29, 2019
a7ae8b2
Rollup merge of #59376 - davidtwco:finally-rfc-2008-variants, r=petro…
Centril Mar 29, 2019
76de89e
Rollup merge of #59446 - Aaron1011:fix/debuginfo-overflow, r=oli-obk
Centril Mar 29, 2019
c07b227
Rollup merge of #59453 - estebank:recover-tuple-parse, r=petrochenkov
Centril Mar 29, 2019
22c267d
Rollup merge of #59455 - estebank:borrow-sugg-shorthand-field, r=davi…
Centril Mar 29, 2019
771502e
Rollup merge of #59499 - pietroalbini:fix-arm-broken-link, r=alexcric…
Centril Mar 29, 2019
e4a9b80
Rollup merge of #59512 - euclio:stdio-locks, r=sfackler
Centril Mar 29, 2019
4ce217b
Rollup merge of #59525 - pnkfelix:whitelist-some-rustc-attrs, r=petro…
Centril Mar 29, 2019
abd3db9
Rollup merge of #59528 - DevQps:improve-dbg-macro-docs, r=Centril
Centril Mar 29, 2019
5c57f0a
Rollup merge of #59532 - mbrubeck:docs, r=Centril
Centril Mar 29, 2019
9a53273
Rollup merge of #59534 - laurmaedje:collapse-blanket-impls, r=Guillau…
Centril Mar 29, 2019
dca1e72
Rollup merge of #59537 - goffrie:patch-3, r=Centril
Centril Mar 29, 2019
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
3 changes: 2 additions & 1 deletion src/ci/docker/armhf-gnu/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ COPY scripts/qemu-bare-bones-addentropy.c /tmp/addentropy.c
RUN arm-linux-gnueabihf-gcc addentropy.c -o rootfs/addentropy -static

# TODO: What is this?!
RUN curl -O http://ftp.nl.debian.org/debian/dists/jessie/main/installer-armhf/current/images/device-tree/vexpress-v2p-ca15-tc1.dtb
# Source of the file: https://github.com/vfdev-5/qemu-rpi2-vexpress/raw/master/vexpress-v2p-ca15-tc1.dtb
RUN curl -O https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/vexpress-v2p-ca15-tc1.dtb

COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
Expand Down
11 changes: 6 additions & 5 deletions src/doc/unstable-book/src/language-features/non-exhaustive.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ The tracking issue for this feature is: [#44109]
------------------------

The `non_exhaustive` gate allows you to use the `#[non_exhaustive]` attribute
on structs and enums. When applied within a crate, users of the crate will need
to use the `_` pattern when matching enums and use the `..` pattern when
matching structs. Structs marked as `non_exhaustive` will not be able to be
created normally outside of the defining crate. This is demonstrated below:
on structs, enums and enum variants. When applied within a crate, users of the
crate will need to use the `_` pattern when matching enums and use the `..`
pattern when matching structs. Enum variants cannot be matched against.
Structs and enum variants marked as `non_exhaustive` will not be able to
be created normally outside of the defining crate. This is demonstrated
below:

```rust,ignore (pseudo-Rust)
use std::error::Error as StdError;
Expand Down Expand Up @@ -72,4 +74,3 @@ let config = Config { window_width: 640, window_height: 480 };
// when marked non_exhaustive.
let &Config { window_width, window_height, .. } = config;
```

4 changes: 2 additions & 2 deletions src/libcore/iter/sources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,8 +375,8 @@ pub fn once<T>(value: T) -> Once<T> {
Once { inner: Some(value).into_iter() }
}

/// An iterator that repeats elements of type `A` endlessly by
/// applying the provided closure `F: FnMut() -> A`.
/// An iterator that yields a single element of type `A` by
/// applying the provided closure `F: FnOnce() -> A`.
///
/// This `struct` is created by the [`once_with`] function.
/// See its documentation for more.
Expand Down
14 changes: 12 additions & 2 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1869,6 +1869,11 @@ impl<'a, 'gcx, 'tcx> VariantDef {
if adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, "non_exhaustive") {
debug!("found non-exhaustive field list for {:?}", parent_did);
flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
} else if let Some(variant_did) = variant_did {
if tcx.has_attr(variant_did, "non_exhaustive") {
debug!("found non-exhaustive field list for {:?}", variant_did);
flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
}
}

VariantDef {
Expand Down Expand Up @@ -2146,6 +2151,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
debug!("found non-exhaustive variant list for {:?}", did);
flags = flags | AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE;
}

flags |= match kind {
AdtKind::Enum => AdtFlags::IS_ENUM,
AdtKind::Union => AdtFlags::IS_UNION,
Expand Down Expand Up @@ -2299,21 +2305,25 @@ impl<'a, 'gcx, 'tcx> AdtDef {
self.variants.iter().all(|v| v.fields.is_empty())
}

/// Return a `VariantDef` given a variant id.
pub fn variant_with_id(&self, vid: DefId) -> &VariantDef {
self.variants.iter().find(|v| v.def_id == vid)
.expect("variant_with_id: unknown variant")
}

/// Return a `VariantDef` given a constructor id.
pub fn variant_with_ctor_id(&self, cid: DefId) -> &VariantDef {
self.variants.iter().find(|v| v.ctor_def_id == Some(cid))
.expect("variant_with_ctor_id: unknown variant")
}

/// Return the index of `VariantDef` given a variant id.
pub fn variant_index_with_id(&self, vid: DefId) -> VariantIdx {
self.variants.iter_enumerated().find(|(_, v)| v.def_id == vid)
.expect("variant_index_with_id: unknown variant").0
}

/// Return the index of `VariantDef` given a constructor id.
pub fn variant_index_with_ctor_id(&self, cid: DefId) -> VariantIdx {
self.variants.iter_enumerated().find(|(_, v)| v.ctor_def_id == Some(cid))
.expect("variant_index_with_ctor_id: unknown variant").0
Expand Down Expand Up @@ -2930,8 +2940,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
}

// Returns `ty::VariantDef` if `def` refers to a struct,
// or variant or their constructors, panics otherwise.
/// Returns `ty::VariantDef` if `def` refers to a struct,
/// or variant or their constructors, panics otherwise.
pub fn expect_variant_def(self, def: Def) -> &'tcx VariantDef {
match def {
Def::Variant(did) => {
Expand Down
66 changes: 62 additions & 4 deletions src/librustc_codegen_llvm/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,32 @@ impl TypeMap<'ll, 'tcx> {
}
}

// Removes a Ty to metadata mapping
// This is useful when computing the metadata for a potentially
// recursive type (e.g. a function ptr of the form:
//
// fn foo() -> impl Copy { foo }
//
// This kind of type cannot be properly represented
// via LLVM debuginfo. As a workaround,
// we register a temporary Ty to metadata mapping
// for the function before we compute its actual metadata.
// If the metadata computation ends up recursing back to the
// original function, it will use the temporary mapping
// for the inner self-reference, preventing us from
// recursing forever.
//
// This function is used to remove the temporary metadata
// mapping after we've computed the actual metadata
fn remove_type(
&mut self,
type_: Ty<'tcx>,
) {
if self.type_to_metadata.remove(type_).is_none() {
bug!("Type metadata Ty '{}' is not in the TypeMap!", type_);
}
}

// Adds a UniqueTypeId to metadata mapping to the TypeMap. The method will
// fail if the mapping already exists.
fn register_unique_id_with_metadata(
Expand Down Expand Up @@ -597,17 +623,49 @@ pub fn type_metadata(
}
}
ty::FnDef(..) | ty::FnPtr(_) => {
let fn_metadata = subroutine_type_metadata(cx,
unique_type_id,
t.fn_sig(cx.tcx),
usage_site_span).metadata;

if let Some(metadata) = debug_context(cx).type_map
.borrow()
.find_metadata_for_unique_id(unique_type_id)
{
return metadata;
}

// It's possible to create a self-referential
// type in Rust by using 'impl trait':
//
// fn foo() -> impl Copy { foo }
//
// See TypeMap::remove_type for more detals
// about the workaround

let temp_type = {
unsafe {
// The choice of type here is pretty arbitrary -
// anything reading the debuginfo for a recursive
// type is going to see *somthing* weird - the only
// question is what exactly it will see
let (size, align) = cx.size_and_align_of(t);
llvm::LLVMRustDIBuilderCreateBasicType(
DIB(cx),
SmallCStr::new("<recur_type>").as_ptr(),
size.bits(),
align.bits() as u32,
DW_ATE_unsigned)
}
};

let type_map = &debug_context(cx).type_map;
type_map.borrow_mut().register_type_with_metadata(t, temp_type);

let fn_metadata = subroutine_type_metadata(cx,
unique_type_id,
t.fn_sig(cx.tcx),
usage_site_span).metadata;

type_map.borrow_mut().remove_type(t);


// This is actually a function pointer, so wrap it in pointer DI
MetadataCreationResult::new(pointer_type_metadata(cx, t, fn_metadata), false)

Expand Down
49 changes: 36 additions & 13 deletions src/librustc_codegen_llvm/debuginfo/type_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use rustc::hir::def_id::DefId;
use rustc::ty::subst::SubstsRef;
use rustc::ty::{self, Ty};
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::fx::FxHashSet;

use rustc::hir;

Expand All @@ -17,7 +18,8 @@ pub fn compute_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
qualified: bool)
-> String {
let mut result = String::with_capacity(64);
push_debuginfo_type_name(cx, t, qualified, &mut result);
let mut visited = FxHashSet::default();
push_debuginfo_type_name(cx, t, qualified, &mut result, &mut visited);
result
}

Expand All @@ -26,7 +28,27 @@ pub fn compute_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
t: Ty<'tcx>,
qualified: bool,
output: &mut String) {
output: &mut String,
visited: &mut FxHashSet<Ty<'tcx>>) {

// We've encountered a weird 'recursive type'
// Currently, the only way to generate such a type
// is by using 'impl trait':
//
// fn foo() -> impl Copy { foo }
//
// There's not really a sensible name we can generate,
// since we don't include 'impl trait' types (e.g. ty::Opaque)
// in the output
//
// Since we need to generate *something*, we just
// use a dummy string that should make it clear
// that something unusual is going on
if !visited.insert(t) {
output.push_str("<recursive_type>");
return;
}

// When targeting MSVC, emit C++ style type names for compatibility with
// .natvis visualizers (and perhaps other existing native debuggers?)
let cpp_like_names = cx.sess().target.target.options.is_like_msvc;
Expand All @@ -42,12 +64,12 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
ty::Foreign(def_id) => push_item_name(cx, def_id, qualified, output),
ty::Adt(def, substs) => {
push_item_name(cx, def.did, qualified, output);
push_type_params(cx, substs, output);
push_type_params(cx, substs, output, visited);
},
ty::Tuple(component_types) => {
output.push('(');
for &component_type in component_types {
push_debuginfo_type_name(cx, component_type, true, output);
push_debuginfo_type_name(cx, component_type, true, output, visited);
output.push_str(", ");
}
if !component_types.is_empty() {
Expand All @@ -65,7 +87,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
hir::MutMutable => output.push_str("mut "),
}

push_debuginfo_type_name(cx, inner_type, true, output);
push_debuginfo_type_name(cx, inner_type, true, output, visited);

if cpp_like_names {
output.push('*');
Expand All @@ -79,15 +101,15 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
output.push_str("mut ");
}

push_debuginfo_type_name(cx, inner_type, true, output);
push_debuginfo_type_name(cx, inner_type, true, output, visited);

if cpp_like_names {
output.push('*');
}
},
ty::Array(inner_type, len) => {
output.push('[');
push_debuginfo_type_name(cx, inner_type, true, output);
push_debuginfo_type_name(cx, inner_type, true, output, visited);
output.push_str(&format!("; {}", len.unwrap_usize(cx.tcx)));
output.push(']');
},
Expand All @@ -98,7 +120,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
output.push('[');
}

push_debuginfo_type_name(cx, inner_type, true, output);
push_debuginfo_type_name(cx, inner_type, true, output, visited);

if cpp_like_names {
output.push('>');
Expand All @@ -113,7 +135,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
&principal,
);
push_item_name(cx, principal.def_id, false, output);
push_type_params(cx, principal.substs, output);
push_type_params(cx, principal.substs, output, visited);
} else {
output.push_str("dyn '_");
}
Expand All @@ -136,7 +158,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
if !sig.inputs().is_empty() {
for &parameter_type in sig.inputs() {
push_debuginfo_type_name(cx, parameter_type, true, output);
push_debuginfo_type_name(cx, parameter_type, true, output, visited);
output.push_str(", ");
}
output.pop();
Expand All @@ -155,7 +177,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,

if !sig.output().is_unit() {
output.push_str(" -> ");
push_debuginfo_type_name(cx, sig.output(), true, output);
push_debuginfo_type_name(cx, sig.output(), true, output, visited);
}
},
ty::Closure(..) => {
Expand Down Expand Up @@ -200,15 +222,16 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
// common denominator - otherwise we would run into conflicts.
fn push_type_params<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
substs: SubstsRef<'tcx>,
output: &mut String) {
output: &mut String,
visited: &mut FxHashSet<Ty<'tcx>>) {
if substs.types().next().is_none() {
return;
}

output.push('<');

for type_parameter in substs.types() {
push_debuginfo_type_name(cx, type_parameter, true, output);
push_debuginfo_type_name(cx, type_parameter, true, output, visited);
output.push_str(", ");
}

Expand Down
9 changes: 7 additions & 2 deletions src/librustc_metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -643,13 +643,18 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
}
};

// Variant constructors have the same visibility as the parent enums.
// Variant constructors have the same visibility as the parent enums, unless marked as
// non-exhaustive, in which case they are lowered to `pub(crate)`.
let enum_id = tcx.hir().as_local_hir_id(enum_did).unwrap();
let enum_vis = &tcx.hir().expect_item_by_hir_id(enum_id).vis;
let mut ctor_vis = ty::Visibility::from_hir(enum_vis, enum_id, tcx);
if variant.is_field_list_non_exhaustive() && ctor_vis == ty::Visibility::Public {
ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
}

Entry {
kind: EntryKind::Variant(self.lazy(&data)),
visibility: self.lazy(&ty::Visibility::from_hir(enum_vis, enum_id, tcx)),
visibility: self.lazy(&ctor_vis),
span: self.lazy(&tcx.def_span(def_id)),
attributes: LazySeq::empty(),
children: LazySeq::empty(),
Expand Down
9 changes: 0 additions & 9 deletions src/librustc_passes/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,14 +192,6 @@ impl<'a> AstValidator<'a> {
}
}

fn invalid_non_exhaustive_attribute(&self, variant: &Variant) {
let has_non_exhaustive = attr::contains_name(&variant.node.attrs, "non_exhaustive");
if has_non_exhaustive {
self.err_handler().span_err(variant.span,
"#[non_exhaustive] is not yet supported on variants");
}
}

fn invalid_visibility(&self, vis: &Visibility, note: Option<&str>) {
if let VisibilityKind::Inherited = vis.node {
return
Expand Down Expand Up @@ -608,7 +600,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
ItemKind::Enum(ref def, _) => {
for variant in &def.variants {
self.invalid_non_exhaustive_attribute(variant);
for field in variant.node.data.fields() {
self.invalid_visibility(&field.vis, None);
}
Expand Down
Loading