Skip to content

Commit

Permalink
Auto merge of #70246 - Dylan-DPC:rollup-vt9wex2, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 10 pull requests

Successful merges:

 - #70003 (symbol_names: treat ReifyShim like VtableShim.)
 - #70051 (Allow `hir().find` to return `None`)
 - #70126 (Fix ICE caused by truncating a negative ZST enum discriminant)
 - #70197 (For issue 53957: revise unit test to focus on underlying bug of 23076.)
 - #70215 (ast: Compress `AttrId` from `usize` to `u32`)
 - #70218 (Fix deprecated Error.description() usage in docs)
 - #70228 (Remove CARGO_BUILD_TARGET from bootstrap.py)
 - #70231 (Add explanation message for E0224)
 - #70232 (Tweak wording for std::io::Read::read function)
 - #70238 (Add a test for out-of-line module passed through a proc macro)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Mar 21, 2020
2 parents 38114ff + 17e6ed1 commit c6b172f
Show file tree
Hide file tree
Showing 27 changed files with 208 additions and 58 deletions.
4 changes: 4 additions & 0 deletions src/bootstrap/bootstrap.py
Expand Up @@ -664,6 +664,10 @@ def build_bootstrap(self):
if self.clean and os.path.exists(build_dir):
shutil.rmtree(build_dir)
env = os.environ.copy()
# `CARGO_BUILD_TARGET` breaks bootstrap build.
# See also: <https://github.com/rust-lang/rust/issues/70208>.
if "CARGO_BUILD_TARGET" in env:
del env["CARGO_BUILD_TARGET"]
env["RUSTC_BOOTSTRAP"] = '1'
env["CARGO_TARGET_DIR"] = build_dir
env["RUSTC"] = self.rustc()
Expand Down
32 changes: 19 additions & 13 deletions src/librustc/hir/map/mod.rs
Expand Up @@ -337,23 +337,28 @@ impl<'hir> Map<'hir> {
}

fn find_entry(&self, id: HirId) -> Option<Entry<'hir>> {
Some(self.get_entry(id))
}

fn get_entry(&self, id: HirId) -> Entry<'hir> {
if id.local_id == ItemLocalId::from_u32(0) {
let owner = self.tcx.hir_owner(id.owner);
Entry { parent: owner.parent, node: owner.node }
owner.map(|owner| Entry { parent: owner.parent, node: owner.node })
} else {
let owner = self.tcx.hir_owner_nodes(id.owner);
let node = owner.nodes[id.local_id].as_ref().unwrap();
// FIXME(eddyb) use a single generic type insted of having both
// `Entry` and `ParentedNode`, which are effectively the same.
// Alternatively, rewrite code using `Entry` to use `ParentedNode`.
Entry { parent: HirId { owner: id.owner, local_id: node.parent }, node: node.node }
owner.and_then(|owner| {
let node = owner.nodes[id.local_id].as_ref();
// FIXME(eddyb) use a single generic type insted of having both
// `Entry` and `ParentedNode`, which are effectively the same.
// Alternatively, rewrite code using `Entry` to use `ParentedNode`.
node.map(|node| Entry {
parent: HirId { owner: id.owner, local_id: node.parent },
node: node.node,
})
})
}
}

fn get_entry(&self, id: HirId) -> Entry<'hir> {
self.find_entry(id).unwrap()
}

pub fn item(&self, id: HirId) -> &'hir Item<'hir> {
match self.find(id).unwrap() {
Node::Item(item) => item,
Expand All @@ -376,7 +381,7 @@ impl<'hir> Map<'hir> {
}

pub fn body(&self, id: BodyId) -> &'hir Body<'hir> {
self.tcx.hir_owner_nodes(id.hir_id.owner).bodies.get(&id.hir_id.local_id).unwrap()
self.tcx.hir_owner_nodes(id.hir_id.owner).unwrap().bodies.get(&id.hir_id.local_id).unwrap()
}

pub fn fn_decl_by_hir_id(&self, hir_id: HirId) -> Option<&'hir FnDecl<'hir>> {
Expand Down Expand Up @@ -536,8 +541,9 @@ impl<'hir> Map<'hir> {

/// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
pub fn find(&self, hir_id: HirId) -> Option<Node<'hir>> {
let node = self.get_entry(hir_id).node;
if let Node::Crate(..) = node { None } else { Some(node) }
self.find_entry(hir_id).and_then(|entry| {
if let Node::Crate(..) = entry.node { None } else { Some(entry.node) }
})
}

/// Similar to `get_parent`; returns the parent HIR Id, or just `hir_id` if there
Expand Down
7 changes: 3 additions & 4 deletions src/librustc/hir/mod.rs
Expand Up @@ -78,9 +78,8 @@ pub fn provide(providers: &mut Providers<'_>) {
let module = hir.as_local_hir_id(id.to_def_id()).unwrap();
&tcx.untracked_crate.modules[&module]
};
providers.hir_owner = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].signature.unwrap();
providers.hir_owner_nodes = |tcx, id| {
tcx.index_hir(LOCAL_CRATE).map[id].with_bodies.as_ref().map(|nodes| &**nodes).unwrap()
};
providers.hir_owner = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].signature;
providers.hir_owner_nodes =
|tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].with_bodies.as_ref().map(|nodes| &**nodes);
map::provide(providers);
}
4 changes: 2 additions & 2 deletions src/librustc/query/mod.rs
Expand Up @@ -76,7 +76,7 @@ rustc_queries! {
//
// This can be conveniently accessed by methods on `tcx.hir()`.
// Avoid calling this query directly.
query hir_owner(key: LocalDefId) -> &'tcx crate::hir::Owner<'tcx> {
query hir_owner(key: LocalDefId) -> Option<&'tcx crate::hir::Owner<'tcx>> {
eval_always
desc { |tcx| "HIR owner of `{}`", tcx.def_path_str(key.to_def_id()) }
}
Expand All @@ -85,7 +85,7 @@ rustc_queries! {
//
// This can be conveniently accessed by methods on `tcx.hir()`.
// Avoid calling this query directly.
query hir_owner_nodes(key: LocalDefId) -> &'tcx crate::hir::OwnerNodes<'tcx> {
query hir_owner_nodes(key: LocalDefId) -> Option<&'tcx crate::hir::OwnerNodes<'tcx>> {
eval_always
desc { |tcx| "HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) }
}
Expand Down
4 changes: 0 additions & 4 deletions src/librustc/ty/instance.rs
Expand Up @@ -406,10 +406,6 @@ impl<'tcx> Instance<'tcx> {
| InstanceDef::VtableShim(..) => Some(self.substs),
}
}

pub fn is_vtable_shim(&self) -> bool {
if let InstanceDef::VtableShim(..) = self.def { true } else { false }
}
}

fn needs_fn_once_adapter_shim(
Expand Down
22 changes: 8 additions & 14 deletions src/librustc_ast/ast.rs
Expand Up @@ -31,7 +31,6 @@ use crate::tokenstream::{DelimSpan, TokenStream, TokenTree};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_index::vec::Idx;
use rustc_macros::HashStable_Generic;
use rustc_serialize::{self, Decoder, Encoder};
use rustc_span::source_map::{respan, Spanned};
Expand Down Expand Up @@ -2251,27 +2250,22 @@ pub enum AttrStyle {
Inner,
}

#[derive(Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, Copy)]
pub struct AttrId(pub usize);

impl Idx for AttrId {
fn new(idx: usize) -> Self {
AttrId(idx)
}
fn index(self) -> usize {
self.0
rustc_index::newtype_index! {
pub struct AttrId {
ENCODABLE = custom
DEBUG_FORMAT = "AttrId({})"
}
}

impl rustc_serialize::Encodable for AttrId {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_unit()
fn encode<S: Encoder>(&self, _: &mut S) -> Result<(), S::Error> {
Ok(())
}
}

impl rustc_serialize::Decodable for AttrId {
fn decode<D: Decoder>(d: &mut D) -> Result<AttrId, D::Error> {
d.read_nil().map(|_| crate::attr::mk_attr_id())
fn decode<D: Decoder>(_: &mut D) -> Result<AttrId, D::Error> {
Ok(crate::attr::mk_attr_id())
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/librustc_ast/attr/mod.rs
Expand Up @@ -366,14 +366,14 @@ pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem {
}

crate fn mk_attr_id() -> AttrId {
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::AtomicU32;
use std::sync::atomic::Ordering;

static NEXT_ATTR_ID: AtomicUsize = AtomicUsize::new(0);
static NEXT_ATTR_ID: AtomicU32 = AtomicU32::new(0);

let id = NEXT_ATTR_ID.fetch_add(1, Ordering::SeqCst);
assert!(id != ::std::usize::MAX);
AttrId(id)
assert!(id != u32::MAX);
AttrId::from_u32(id)
}

pub fn mk_attr(style: AttrStyle, path: Path, args: MacArgs, span: Span) -> Attribute {
Expand Down
7 changes: 6 additions & 1 deletion src/librustc_codegen_ssa/mir/rvalue.rs
Expand Up @@ -293,7 +293,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
if let Some(discr) =
operand.layout.ty.discriminant_for_variant(bx.tcx(), index)
{
let discr_val = bx.cx().const_uint_big(ll_t_out, discr.val);
let discr_layout = bx.cx().layout_of(discr.ty);
let discr_t = bx.cx().immediate_backend_type(discr_layout);
let discr_val = bx.cx().const_uint_big(discr_t, discr.val);
let discr_val =
bx.intcast(discr_val, ll_t_out, discr.ty.is_signed());

return (
bx,
OperandRef {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_error_codes/error_codes.rs
Expand Up @@ -118,6 +118,7 @@ E0220: include_str!("./error_codes/E0220.md"),
E0221: include_str!("./error_codes/E0221.md"),
E0222: include_str!("./error_codes/E0222.md"),
E0223: include_str!("./error_codes/E0223.md"),
E0224: include_str!("./error_codes/E0224.md"),
E0225: include_str!("./error_codes/E0225.md"),
E0229: include_str!("./error_codes/E0229.md"),
E0230: include_str!("./error_codes/E0230.md"),
Expand Down Expand Up @@ -469,7 +470,6 @@ E0748: include_str!("./error_codes/E0748.md"),
// E0217, // ambiguous associated type, defined in multiple supertraits
// E0218, // no associated type defined
// E0219, // associated type defined in higher-ranked supertrait
E0224, // at least one non-builtin train is required for an object type
E0226, // only a single explicit lifetime bound is permitted
E0227, // ambiguous lifetime bound, explicit lifetime bound required
E0228, // explicit lifetime bound required
Expand Down
15 changes: 15 additions & 0 deletions src/librustc_error_codes/error_codes/E0224.md
@@ -0,0 +1,15 @@
A trait object was declaired with no traits.

Erroneous code example:

```compile_fail,E0224
type Foo = dyn 'static +;
```

Rust does not currently support this.

To solve ensure the the trait object has at least one trait:

```
type Foo = dyn 'static + Copy;
```
10 changes: 7 additions & 3 deletions src/librustc_mir/interpret/cast.rs
Expand Up @@ -3,6 +3,7 @@ use rustc::ty::layout::{self, Size, TyLayout};
use rustc::ty::{self, Ty, TypeAndMut, TypeFoldable};
use rustc_ast::ast::FloatTy;
use rustc_span::symbol::sym;
use rustc_target::abi::LayoutOf;

use rustc::mir::interpret::{InterpResult, PointerArithmetic, Scalar};
use rustc::mir::CastKind;
Expand Down Expand Up @@ -134,7 +135,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
layout::Variants::Single { index } => {
if let Some(discr) = src.layout.ty.discriminant_for_variant(*self.tcx, index) {
assert!(src.layout.is_zst());
return Ok(Scalar::from_uint(discr.val, dest_layout.size).into());
let discr_layout = self.layout_of(discr.ty)?;
return Ok(self
.cast_from_int_like(discr.val, discr_layout, dest_layout)?
.into());
}
}
layout::Variants::Multiple { .. } => {}
Expand Down Expand Up @@ -171,10 +175,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// (b) cast from an integer-like (including bool, char, enums).
// In both cases we want the bits.
let bits = self.force_bits(src.to_scalar()?, src.layout.size)?;
Ok(self.cast_from_int(bits, src.layout, dest_layout)?.into())
Ok(self.cast_from_int_like(bits, src.layout, dest_layout)?.into())
}

fn cast_from_int(
fn cast_from_int_like(
&self,
v: u128, // raw bits
src_layout: TyLayout<'tcx>,
Expand Down
9 changes: 7 additions & 2 deletions src/librustc_symbol_mangling/legacy.rs
Expand Up @@ -59,10 +59,14 @@ pub(super) fn mangle(
.print_def_path(def_id, &[])
.unwrap();

if instance.is_vtable_shim() {
if let ty::InstanceDef::VtableShim(..) = instance.def {
let _ = printer.write_str("{{vtable-shim}}");
}

if let ty::InstanceDef::ReifyShim(..) = instance.def {
let _ = printer.write_str("{{reify-shim}}");
}

printer.path.finish(hash)
}

Expand Down Expand Up @@ -123,7 +127,8 @@ fn get_symbol_hash<'tcx>(
}

// We want to avoid accidental collision between different types of instances.
// Especially, VtableShim may overlap with its original instance without this.
// Especially, `VtableShim`s and `ReifyShim`s may overlap with their original
// instances without this.
discriminant(&instance.def).hash_stable(&mut hcx, &mut hasher);
});

Expand Down
13 changes: 11 additions & 2 deletions src/librustc_symbol_mangling/v0.rs
Expand Up @@ -34,8 +34,17 @@ pub(super) fn mangle(
binders: vec![],
out: String::from(prefix),
};
cx = if instance.is_vtable_shim() {
cx.path_append_ns(|cx| cx.print_def_path(def_id, substs), 'S', 0, "").unwrap()

// Append `::{shim:...#0}` to shims that can coexist with a non-shim instance.
let shim_kind = match instance.def {
ty::InstanceDef::VtableShim(_) => Some("vtable"),
ty::InstanceDef::ReifyShim(_) => Some("reify"),

_ => None,
};

cx = if let Some(shim_kind) = shim_kind {
cx.path_append_ns(|cx| cx.print_def_path(def_id, substs), 'S', 0, shim_kind).unwrap()
} else {
cx.print_def_path(def_id, substs).unwrap()
};
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/error.rs
Expand Up @@ -88,7 +88,7 @@ pub trait Error: Debug + Display {
/// fn main() {
/// match get_super_error() {
/// Err(e) => {
/// println!("Error: {}", e.description());
/// println!("Error: {}", e);
/// println!("Caused by: {}", e.source().unwrap());
/// }
/// _ => println!("No error"),
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/io/mod.rs
Expand Up @@ -502,7 +502,7 @@ pub trait Read {
/// how many bytes were read.
///
/// This function does not provide any guarantees about whether it blocks
/// waiting for data, but if an object needs to block for a read but cannot
/// waiting for data, but if an object needs to block for a read and cannot,
/// it will typically signal this via an [`Err`] return value.
///
/// If the return value of this method is [`Ok(n)`], then it must be
Expand Down
23 changes: 19 additions & 4 deletions src/libstd/net/addr.rs
Expand Up @@ -989,11 +989,26 @@ mod tests {
// s has been moved into the tsa call
}

// FIXME: figure out why this fails on openbsd and fix it
#[test]
#[cfg(not(any(windows, target_os = "openbsd")))]
fn to_socket_addr_str_bad() {
assert!(tsa("1200::AB00:1234::2552:7777:1313:34300").is_err());
fn bind_udp_socket_bad() {
// rust-lang/rust#53957: This is a regression test for a parsing problem
// discovered as part of issue rust-lang/rust#23076, where we were
// incorrectly parsing invalid input and then that would result in a
// successful `UdpSocket` binding when we would expect failure.
//
// At one time, this test was written as a call to `tsa` with
// INPUT_23076. However, that structure yields an unreliable test,
// because it ends up passing junk input to the DNS server, and some DNS
// servers will respond with `Ok` to such input, with the ip address of
// the DNS server itself.
//
// This form of the test is more robust: even when the DNS server
// returns its own address, it is still an error to bind a UDP socket to
// a non-local address, and so we still get an error here in that case.

const INPUT_23076: &'static str = "1200::AB00:1234::2552:7777:1313:34300";

assert!(crate::net::UdpSocket::bind(INPUT_23076).is_err())
}

#[test]
Expand Down
47 changes: 47 additions & 0 deletions src/test/ui/consts/cast-discriminant-zst-enum.rs
@@ -0,0 +1,47 @@
// run-pass
// Test a ZST enum whose dicriminant is ~0i128. This caused an ICE when casting to a i32.

#[derive(Copy, Clone)]
enum Nums {
NegOne = -1,
}

const NEG_ONE_I8: i8 = Nums::NegOne as i8;
const NEG_ONE_I16: i16 = Nums::NegOne as i16;
const NEG_ONE_I32: i32 = Nums::NegOne as i32;
const NEG_ONE_I64: i64 = Nums::NegOne as i64;
const NEG_ONE_I128: i128 = Nums::NegOne as i128;

#[inline(never)]
fn identity<T>(t: T) -> T { t }

fn test_as_arg(n: Nums) {
assert_eq!(-1i8, n as i8);
assert_eq!(-1i16, n as i16);
assert_eq!(-1i32, n as i32);
assert_eq!(-1i64, n as i64);
assert_eq!(-1i128, n as i128);
}

fn main() {
let kind = Nums::NegOne;
assert_eq!(-1i8, kind as i8);
assert_eq!(-1i16, kind as i16);
assert_eq!(-1i32, kind as i32);
assert_eq!(-1i64, kind as i64);
assert_eq!(-1i128, kind as i128);

assert_eq!(-1i8, identity(kind) as i8);
assert_eq!(-1i16, identity(kind) as i16);
assert_eq!(-1i32, identity(kind) as i32);
assert_eq!(-1i64, identity(kind) as i64);
assert_eq!(-1i128, identity(kind) as i128);

test_as_arg(Nums::NegOne);

assert_eq!(-1i8, NEG_ONE_I8);
assert_eq!(-1i16, NEG_ONE_I16);
assert_eq!(-1i32, NEG_ONE_I32);
assert_eq!(-1i64, NEG_ONE_I64);
assert_eq!(-1i128, NEG_ONE_I128);
}

0 comments on commit c6b172f

Please sign in to comment.