diff --git a/src/etc/gdb_rust_pretty_printing.py b/src/etc/gdb_rust_pretty_printing.py index b9413563fd9ff..a6b09722e1c94 100755 --- a/src/etc/gdb_rust_pretty_printing.py +++ b/src/etc/gdb_rust_pretty_printing.py @@ -330,19 +330,20 @@ def children_of_node(boxed_node, height, want_values): leaf = node_ptr['data'] else: leaf = node_ptr.dereference() - keys = leaf['keys']['value']['value'] + keys = leaf['keys'] if want_values: - values = leaf['vals']['value']['value'] + values = leaf['vals'] length = int(leaf['len']) for i in xrange(0, length + 1): if height > 0: - for child in children_of_node(node_ptr['edges'][i], height - 1, want_values): + child_ptr = node_ptr['edges'][i]['value']['value'] + for child in children_of_node(child_ptr, height - 1, want_values): yield child if i < length: if want_values: - yield (keys[i], values[i]) + yield (keys[i]['value']['value'], values[i]['value']['value']) else: - yield keys[i] + yield keys[i]['value']['value'] class RustStdBTreeSetPrinter(object): def __init__(self, val): diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs index 603d73100a8b4..b47337e44b2fe 100644 --- a/src/liballoc/borrow.rs +++ b/src/liballoc/borrow.rs @@ -380,7 +380,6 @@ impl<'a, B: ?Sized> Hash for Cow<'a, B> } #[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated)] impl<'a, T: ?Sized + ToOwned> AsRef for Cow<'a, T> { fn as_ref(&self) -> &T { self diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index f9a21aa95db71..e969e119dbe88 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -95,8 +95,8 @@ struct LeafNode { /// The arrays storing the actual data of the node. Only the first `len` elements of each /// array are initialized and valid. - keys: MaybeUninit<[K; CAPACITY]>, - vals: MaybeUninit<[V; CAPACITY]>, + keys: [MaybeUninit; CAPACITY], + vals: [MaybeUninit; CAPACITY], } impl LeafNode { @@ -106,8 +106,8 @@ impl LeafNode { LeafNode { // As a general policy, we leave fields uninitialized if they can be, as this should // be both slightly faster and easier to track in Valgrind. - keys: MaybeUninit::uninitialized(), - vals: MaybeUninit::uninitialized(), + keys: uninitialized_array![_; CAPACITY], + vals: uninitialized_array![_; CAPACITY], parent: ptr::null(), parent_idx: MaybeUninit::uninitialized(), len: 0 @@ -145,7 +145,7 @@ struct InternalNode { /// The pointers to the children of this node. `len + 1` of these are considered /// initialized and valid. - edges: [BoxedNode; 2 * B], + edges: [MaybeUninit>; 2 * B], } impl InternalNode { @@ -159,7 +159,7 @@ impl InternalNode { unsafe fn new() -> Self { InternalNode { data: LeafNode::new(), - edges: mem::uninitialized() + edges: uninitialized_array![_; 2*B], } } } @@ -261,7 +261,7 @@ impl Root { -> NodeRef { debug_assert!(!self.is_shared_root()); let mut new_node = Box::new(unsafe { InternalNode::new() }); - new_node.edges[0] = unsafe { BoxedNode::from_ptr(self.node.as_ptr()) }; + new_node.edges[0].set(unsafe { BoxedNode::from_ptr(self.node.as_ptr()) }); self.node = BoxedNode::from_internal(new_node); self.height += 1; @@ -623,7 +623,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { // We cannot be the root, so `as_leaf` is okay unsafe { slice::from_raw_parts( - self.as_leaf().vals.as_ptr() as *const V, + MaybeUninit::first_ptr(&self.as_leaf().vals), self.len() ) } @@ -650,7 +650,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { } else { unsafe { slice::from_raw_parts_mut( - (*self.as_leaf_mut()).keys.as_mut_ptr() as *mut K, + MaybeUninit::first_ptr_mut(&mut (*self.as_leaf_mut()).keys), self.len() ) } @@ -661,7 +661,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { debug_assert!(!self.is_shared_root()); unsafe { slice::from_raw_parts_mut( - (*self.as_leaf_mut()).vals.as_mut_ptr() as *mut V, + MaybeUninit::first_ptr_mut(&mut (*self.as_leaf_mut()).vals), self.len() ) } @@ -718,7 +718,7 @@ impl<'a, K, V> NodeRef, K, V, marker::Internal> { unsafe { ptr::write(self.keys_mut().get_unchecked_mut(idx), key); ptr::write(self.vals_mut().get_unchecked_mut(idx), val); - ptr::write(self.as_internal_mut().edges.get_unchecked_mut(idx + 1), edge.node); + self.as_internal_mut().edges.get_unchecked_mut(idx + 1).set(edge.node); (*self.as_leaf_mut()).len += 1; @@ -749,7 +749,7 @@ impl<'a, K, V> NodeRef, K, V, marker::Internal> { slice_insert(self.vals_mut(), 0, val); slice_insert( slice::from_raw_parts_mut( - self.as_internal_mut().edges.as_mut_ptr(), + MaybeUninit::first_ptr_mut(&mut self.as_internal_mut().edges), self.len()+1 ), 0, @@ -778,7 +778,9 @@ impl<'a, K, V> NodeRef, K, V, marker::LeafOrInternal> { let edge = match self.reborrow_mut().force() { ForceResult::Leaf(_) => None, ForceResult::Internal(internal) => { - let edge = ptr::read(internal.as_internal().edges.get_unchecked(idx + 1)); + let edge = ptr::read( + internal.as_internal().edges.get_unchecked(idx + 1).as_ptr() + ); let mut new_root = Root { node: edge, height: internal.height - 1 }; (*new_root.as_mut().as_leaf_mut()).parent = ptr::null(); Some(new_root) @@ -806,7 +808,7 @@ impl<'a, K, V> NodeRef, K, V, marker::LeafOrInternal> { ForceResult::Internal(mut internal) => { let edge = slice_remove( slice::from_raw_parts_mut( - internal.as_internal_mut().edges.as_mut_ptr(), + MaybeUninit::first_ptr_mut(&mut internal.as_internal_mut().edges), old_len+1 ), 0 @@ -1085,7 +1087,7 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: slice_insert( slice::from_raw_parts_mut( - self.node.as_internal_mut().edges.as_mut_ptr(), + MaybeUninit::first_ptr_mut(&mut self.node.as_internal_mut().edges), self.node.len() ), self.idx + 1, @@ -1140,7 +1142,9 @@ impl pub fn descend(self) -> NodeRef { NodeRef { height: self.node.height - 1, - node: unsafe { self.node.as_internal().edges.get_unchecked(self.idx).as_ptr() }, + node: unsafe { + self.node.as_internal().edges.get_unchecked(self.idx).get_ref().as_ptr() + }, root: self.node.root, _marker: PhantomData } diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 3050a93ef39a0..d2ff1bae63561 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -63,8 +63,9 @@ #![no_std] #![needs_allocator] -#![deny(intra_doc_link_resolution_failure)] -#![deny(missing_debug_implementations)] +#![warn(deprecated_in_future)] +#![warn(intra_doc_link_resolution_failure)] +#![warn(missing_debug_implementations)] #![cfg_attr(not(test), feature(fn_traits))] #![cfg_attr(not(test), feature(generator_trait))] diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index d3a55c59ff69c..c0dc010fe59a5 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - //! Single-threaded reference-counting pointers. 'Rc' stands for 'Reference //! Counted'. //! diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 935579f4943b6..530b2f52c0df2 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -2048,7 +2048,7 @@ macro_rules! tuple { ( $($name:ident,)+ ) => ( #[stable(feature = "rust1", since = "1.0.0")] impl<$($name:Debug),*> Debug for ($($name,)*) where last_type!($($name,)+): ?Sized { - #[allow(non_snake_case, unused_assignments, deprecated)] + #[allow(non_snake_case, unused_assignments)] fn fmt(&self, f: &mut Formatter) -> Result { let mut builder = f.debug_tuple(""); let ($(ref $name,)*) = *self; diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index c7c8fc50efaae..3a812337bb111 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -1,14 +1,12 @@ //! Integer and floating-point number formatting -#![allow(deprecated)] - use fmt; use ops::{Div, Rem, Sub}; use str; use slice; use ptr; -use mem; +use mem::MaybeUninit; #[doc(hidden)] trait Int: PartialEq + PartialOrd + Div + Rem + @@ -53,7 +51,7 @@ trait GenericRadix { // characters for a base 2 number. let zero = T::zero(); let is_nonnegative = x >= zero; - let mut buf: [u8; 128] = unsafe { mem::uninitialized() }; + let mut buf = uninitialized_array![u8; 128]; let mut curr = buf.len(); let base = T::from_u8(Self::BASE); if is_nonnegative { @@ -62,7 +60,7 @@ trait GenericRadix { for byte in buf.iter_mut().rev() { let n = x % base; // Get the current place value. x = x / base; // Deaccumulate the number. - *byte = Self::digit(n.to_u8()); // Store the digit in the buffer. + byte.set(Self::digit(n.to_u8())); // Store the digit in the buffer. curr -= 1; if x == zero { // No more digits left to accumulate. @@ -74,7 +72,7 @@ trait GenericRadix { for byte in buf.iter_mut().rev() { let n = zero - (x % base); // Get the current place value. x = x / base; // Deaccumulate the number. - *byte = Self::digit(n.to_u8()); // Store the digit in the buffer. + byte.set(Self::digit(n.to_u8())); // Store the digit in the buffer. curr -= 1; if x == zero { // No more digits left to accumulate. @@ -82,7 +80,11 @@ trait GenericRadix { }; } } - let buf = unsafe { str::from_utf8_unchecked(&buf[curr..]) }; + let buf = &buf[curr..]; + let buf = unsafe { str::from_utf8_unchecked(slice::from_raw_parts( + MaybeUninit::first_ptr(buf), + buf.len() + )) }; f.pad_integral(is_nonnegative, Self::PREFIX, buf) } } @@ -196,9 +198,9 @@ macro_rules! impl_Display { // convert the negative num to positive by summing 1 to it's 2 complement (!self.$conv_fn()).wrapping_add(1) }; - let mut buf: [u8; 39] = unsafe { mem::uninitialized() }; + let mut buf = uninitialized_array![u8; 39]; let mut curr = buf.len() as isize; - let buf_ptr = buf.as_mut_ptr(); + let buf_ptr = MaybeUninit::first_ptr_mut(&mut buf); let lut_ptr = DEC_DIGITS_LUT.as_ptr(); unsafe { diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs index 3377b831a9daa..18f09f4c5dda4 100644 --- a/src/libcore/hash/sip.rs +++ b/src/libcore/hash/sip.rs @@ -1,6 +1,6 @@ //! An implementation of SipHash. -#![allow(deprecated)] +#![allow(deprecated)] // the types in this module are deprecated use marker::PhantomData; use ptr; diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 825e5148fd503..1ef21832592ca 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -58,11 +58,12 @@ issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/", test(no_crate_inject, attr(deny(warnings))), test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))] - #![no_core] -#![deny(missing_docs)] -#![deny(intra_doc_link_resolution_failure)] -#![deny(missing_debug_implementations)] + +#![warn(deprecated_in_future)] +#![warn(missing_docs)] +#![warn(intra_doc_link_resolution_failure)] +#![warn(missing_debug_implementations)] #![feature(allow_internal_unstable)] #![feature(arbitrary_self_types)] @@ -122,6 +123,7 @@ #![feature(structural_match)] #![feature(abi_unadjusted)] #![feature(adx_target_feature)] +#![feature(maybe_uninit)] #[prelude_import] #[allow(unused)] diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 2f350df2f5c18..12b7adb8a9d26 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -547,6 +547,23 @@ macro_rules! unimplemented { ($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*))); } +/// A macro to create an array of [`MaybeUninit`] +/// +/// This macro constructs and uninitialized array of the type `[MaybeUninit; N]`. +/// +/// [`MaybeUninit`]: mem/union.MaybeUninit.html +#[macro_export] +#[unstable(feature = "maybe_uninit", issue = "53491")] +macro_rules! uninitialized_array { + // This `into_inner` is safe because an array of `MaybeUninit` does not + // require initialization. + // FIXME(#49147): Could be replaced by an array initializer, once those can + // be any const expression. + ($t:ty; $size:expr) => (unsafe { + MaybeUninit::<[MaybeUninit<$t>; $size]>::uninitialized().into_inner() + }); +} + /// Built-in macros to the compiler itself. /// /// These macros do not have any corresponding definition with a `macro_rules!` diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 0eeac5e1ea940..8b6d9d882b5ad 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1148,4 +1148,18 @@ impl MaybeUninit { pub fn as_mut_ptr(&mut self) -> *mut T { unsafe { &mut *self.value as *mut T } } + + /// Get a pointer to the first element of the array. + #[unstable(feature = "maybe_uninit", issue = "53491")] + #[inline(always)] + pub fn first_ptr(this: &[MaybeUninit]) -> *const T { + this as *const [MaybeUninit] as *const T + } + + /// Get a mutable pointer to the first element of the array. + #[unstable(feature = "maybe_uninit", issue = "53491")] + #[inline(always)] + pub fn first_ptr_mut(this: &mut [MaybeUninit]) -> *mut T { + this as *mut [MaybeUninit] as *mut T + } } diff --git a/src/libcore/slice/sort.rs b/src/libcore/slice/sort.rs index dd9b49fb7a002..3f84faa049939 100644 --- a/src/libcore/slice/sort.rs +++ b/src/libcore/slice/sort.rs @@ -216,14 +216,14 @@ fn partition_in_blocks(v: &mut [T], pivot: &T, is_less: &mut F) -> usize let mut block_l = BLOCK; let mut start_l = ptr::null_mut(); let mut end_l = ptr::null_mut(); - let mut offsets_l = MaybeUninit::<[u8; BLOCK]>::uninitialized(); + let mut offsets_l: [MaybeUninit; BLOCK] = uninitialized_array![u8; BLOCK]; // The current block on the right side (from `r.sub(block_r)` to `r`). let mut r = unsafe { l.add(v.len()) }; let mut block_r = BLOCK; let mut start_r = ptr::null_mut(); let mut end_r = ptr::null_mut(); - let mut offsets_r = MaybeUninit::<[u8; BLOCK]>::uninitialized(); + let mut offsets_r: [MaybeUninit; BLOCK] = uninitialized_array![u8; BLOCK]; // FIXME: When we get VLAs, try creating one array of length `min(v.len(), 2 * BLOCK)` rather // than two fixed-size arrays of length `BLOCK`. VLAs might be more cache-efficient. @@ -262,8 +262,8 @@ fn partition_in_blocks(v: &mut [T], pivot: &T, is_less: &mut F) -> usize if start_l == end_l { // Trace `block_l` elements from the left side. - start_l = offsets_l.as_mut_ptr() as *mut u8; - end_l = offsets_l.as_mut_ptr() as *mut u8; + start_l = MaybeUninit::first_ptr_mut(&mut offsets_l); + end_l = MaybeUninit::first_ptr_mut(&mut offsets_l); let mut elem = l; for i in 0..block_l { @@ -278,8 +278,8 @@ fn partition_in_blocks(v: &mut [T], pivot: &T, is_less: &mut F) -> usize if start_r == end_r { // Trace `block_r` elements from the right side. - start_r = offsets_r.as_mut_ptr() as *mut u8; - end_r = offsets_r.as_mut_ptr() as *mut u8; + start_r = MaybeUninit::first_ptr_mut(&mut offsets_r); + end_r = MaybeUninit::first_ptr_mut(&mut offsets_r); let mut elem = r; for i in 0..block_r { diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 287a45a21eadf..1e10329bb55ce 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -362,6 +362,10 @@ struct Foo1 { x: &bool } // ^ expected lifetime parameter struct Foo2<'a> { x: &'a bool } // correct +impl Foo2 {} + // ^^^^ expected lifetime parameter +impl<'a> Foo2<'a> {} // correct + struct Bar1 { x: Foo2 } // ^^^^ expected lifetime parameter struct Bar2<'a> { x: Foo2<'a> } // correct @@ -766,11 +770,40 @@ struct Foo { These can be fixed by declaring lifetime parameters: ``` +struct Foo<'a> { + x: &'a str, +} + fn foo<'a>(x: &'a str) {} +``` +Impl blocks declare lifetime parameters separately. You need to add lifetime +parameters to an impl block if you're implementing a type that has a lifetime +parameter of its own. +For example: + +```compile_fail,E0261 struct Foo<'a> { x: &'a str, } + +// error, use of undeclared lifetime name `'a` +impl Foo<'a> { + fn foo<'a>(x: &'a str) {} +} +``` + +This is fixed by declaring the impl block like this: + +``` +struct Foo<'a> { + x: &'a str, +} + +// correct +impl<'a> Foo<'a> { + fn foo(x: &'a str) {} +} ``` "##, diff --git a/src/librustc/ty/erase_regions.rs b/src/librustc/ty/erase_regions.rs index bbf71c62ca69d..da7e021b2d54b 100644 --- a/src/librustc/ty/erase_regions.rs +++ b/src/librustc/ty/erase_regions.rs @@ -1,4 +1,4 @@ -use ty::{self, Ty, TyCtxt}; +use ty::{self, Ty, TyCtxt, TypeFlags}; use ty::fold::{TypeFolder, TypeFoldable}; pub(super) fn provide(providers: &mut ty::query::Providers<'_>) { @@ -21,6 +21,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn erase_regions(self, value: &T) -> T where T : TypeFoldable<'tcx> { + // If there's nothing to erase avoid performing the query at all + if !value.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND | TypeFlags::HAS_FREE_REGIONS) { + return value.clone(); + } + let value1 = value.fold_with(&mut RegionEraserVisitor { tcx: self }); debug!("erase_regions({:?}) = {:?}", value, value1); value1 diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index fb5b6c97689d0..abf575aed6725 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -15,11 +15,13 @@ use syntax::ast::{self, Ident}; use syntax::attr; use syntax::errors::DiagnosticBuilder; use syntax::ext::base::{self, Determinacy}; -use syntax::ext::base::{Annotatable, MacroKind, SyntaxExtension}; +use syntax::ext::base::{MacroKind, SyntaxExtension}; use syntax::ext::expand::{AstFragment, Invocation, InvocationKind}; use syntax::ext::hygiene::{self, Mark}; use syntax::ext::tt::macro_rules; -use syntax::feature_gate::{feature_err, is_builtin_attr_name, GateIssue}; +use syntax::feature_gate::{ + feature_err, is_builtin_attr_name, AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES, +}; use syntax::symbol::{Symbol, keywords}; use syntax::visit::Visitor; use syntax::util::lev_distance::find_best_match_for_name; @@ -127,9 +129,9 @@ impl<'a> base::Resolver for Resolver<'a> { mark } - fn resolve_dollar_crates(&mut self, annotatable: &Annotatable) { - pub struct ResolveDollarCrates<'a, 'b: 'a> { - pub resolver: &'a mut Resolver<'b>, + fn resolve_dollar_crates(&mut self, fragment: &AstFragment) { + struct ResolveDollarCrates<'a, 'b: 'a> { + resolver: &'a mut Resolver<'b> } impl<'a> Visitor<'a> for ResolveDollarCrates<'a, '_> { fn visit_ident(&mut self, ident: Ident) { @@ -144,7 +146,7 @@ impl<'a> base::Resolver for Resolver<'a> { fn visit_mac(&mut self, _: &ast::Mac) {} } - annotatable.visit_with(&mut ResolveDollarCrates { resolver: self }); + fragment.visit_with(&mut ResolveDollarCrates { resolver: self }); } fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment, @@ -310,15 +312,18 @@ impl<'a> Resolver<'a> { if !features.rustc_attrs { let msg = "unless otherwise specified, attributes with the prefix \ `rustc_` are reserved for internal compiler diagnostics"; - feature_err(&self.session.parse_sess, "rustc_attrs", path.span, - GateIssue::Language, &msg).emit(); + self.report_unknown_attribute(path.span, &name, msg, "rustc_attrs"); } } else if !features.custom_attribute { let msg = format!("The attribute `{}` is currently unknown to the \ compiler and may have meaning added to it in the \ future", path); - feature_err(&self.session.parse_sess, "custom_attribute", path.span, - GateIssue::Language, &msg).emit(); + self.report_unknown_attribute( + path.span, + &name, + &msg, + "custom_attribute", + ); } } } else { @@ -339,6 +344,61 @@ impl<'a> Resolver<'a> { Ok((def, self.get_macro(def))) } + fn report_unknown_attribute(&self, span: Span, name: &str, msg: &str, feature: &str) { + let mut err = feature_err( + &self.session.parse_sess, + feature, + span, + GateIssue::Language, + &msg, + ); + + let features = self.session.features_untracked(); + + let attr_candidates = BUILTIN_ATTRIBUTES + .iter() + .filter_map(|(name, _, _, gate)| { + if name.starts_with("rustc_") && !features.rustc_attrs { + return None; + } + + match gate { + AttributeGate::Gated(Stability::Unstable, ..) + if self.session.opts.unstable_features.is_nightly_build() => + { + Some(name) + } + AttributeGate::Gated(Stability::Deprecated(..), ..) => Some(name), + AttributeGate::Ungated => Some(name), + _ => None, + } + }) + .map(|name| Symbol::intern(name)) + .chain( + // Add built-in macro attributes as well. + self.builtin_macros.iter().filter_map(|(name, binding)| { + match binding.macro_kind() { + Some(MacroKind::Attr) => Some(*name), + _ => None, + } + }), + ) + .collect::>(); + + let lev_suggestion = find_best_match_for_name(attr_candidates.iter(), &name, None); + + if let Some(suggestion) = lev_suggestion { + err.span_suggestion( + span, + "a built-in attribute with a similar name exists", + suggestion.to_string(), + Applicability::MaybeIncorrect, + ); + } + + err.emit(); + } + pub fn resolve_macro_to_def_inner( &mut self, path: &ast::Path, diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index fd55897522bf7..9a04c9d60b868 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -537,11 +537,8 @@ impl<'a> Resolver<'a> { primary_binding: &'a NameBinding<'a>, secondary_binding: &'a NameBinding<'a>) -> &'a NameBinding<'a> { self.arenas.alloc_name_binding(NameBinding { - kind: primary_binding.kind.clone(), ambiguity: Some((secondary_binding, kind)), - vis: primary_binding.vis, - span: primary_binding.span, - expansion: primary_binding.expansion, + ..primary_binding.clone() }) } diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index 52a30967a2310..6935ecde791f8 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -410,10 +410,6 @@ kbd { color: #ccc; } -.impl-items code { - background-color: rgba(0, 0, 0, 0); -} - #sidebar-toggle { background-color: #565656; } diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index d20fea666e61d..306e8dc15d893 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -405,10 +405,6 @@ kbd { color: #999; } -.impl-items code { - background-color: rgba(0, 0, 0, 0); -} - #sidebar-toggle { background-color: #F1F1F1; } diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index a55b32c08a303..eb8e0c1c8ac66 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -607,7 +607,7 @@ impl Builder { pub fn spawn(f: F) -> JoinHandle where F: FnOnce() -> T, F: Send + 'static, T: Send + 'static { - Builder::new().spawn(f).unwrap() + Builder::new().spawn(f).expect("failed to spawn thread") } /// Gets a handle to the thread that invokes it. diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 2793754e1033a..09e7e57f78cfa 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -14,7 +14,6 @@ use parse::token; use ptr::P; use smallvec::SmallVec; use symbol::{keywords, Ident, Symbol}; -use visit::Visitor; use ThinVec; use rustc_data_structures::fx::FxHashMap; @@ -136,17 +135,6 @@ impl Annotatable { _ => false, } } - - pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) { - match self { - Annotatable::Item(item) => visitor.visit_item(item), - Annotatable::TraitItem(trait_item) => visitor.visit_trait_item(trait_item), - Annotatable::ImplItem(impl_item) => visitor.visit_impl_item(impl_item), - Annotatable::ForeignItem(foreign_item) => visitor.visit_foreign_item(foreign_item), - Annotatable::Stmt(stmt) => visitor.visit_stmt(stmt), - Annotatable::Expr(expr) => visitor.visit_expr(expr), - } - } } // A more flexible ItemDecorator. @@ -742,7 +730,7 @@ pub trait Resolver { fn next_node_id(&mut self) -> ast::NodeId; fn get_module_scope(&mut self, id: ast::NodeId) -> Mark; - fn resolve_dollar_crates(&mut self, annotatable: &Annotatable); + fn resolve_dollar_crates(&mut self, fragment: &AstFragment); fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment, derives: &[Mark]); fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc); @@ -776,7 +764,7 @@ impl Resolver for DummyResolver { fn next_node_id(&mut self) -> ast::NodeId { ast::DUMMY_NODE_ID } fn get_module_scope(&mut self, _id: ast::NodeId) -> Mark { Mark::root() } - fn resolve_dollar_crates(&mut self, _annotatable: &Annotatable) {} + fn resolve_dollar_crates(&mut self, _fragment: &AstFragment) {} fn visit_ast_fragment_with_placeholders(&mut self, _invoc: Mark, _fragment: &AstFragment, _derives: &[Mark]) {} fn add_builtin(&mut self, _ident: ast::Ident, _ext: Lrc) {} diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index d1f7b4df9bea4..1b4b44270ad06 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -443,6 +443,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> { /// prepares data for resolving paths of macro invocations. fn collect_invocations(&mut self, fragment: AstFragment, derives: &[Mark]) -> (AstFragment, Vec) { + // Resolve `$crate`s in the fragment for pretty-printing. + self.cx.resolver.resolve_dollar_crates(&fragment); + let (fragment_with_placeholders, invocations) = { let mut collector = InvocationCollector { cfg: StripUnconfigured { @@ -574,8 +577,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { Some(invoc.fragment_kind.expect_from_annotatables(items)) } AttrProcMacro(ref mac, ..) => { - // Resolve `$crate`s in case we have to go though stringification. - self.cx.resolver.resolve_dollar_crates(&item); self.gate_proc_macro_attr_item(attr.span, &item); let item_tok = TokenTree::Token(DUMMY_SP, Token::interpolated(match item { Annotatable::Item(item) => token::NtItem(item), @@ -917,8 +918,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { match *ext { ProcMacroDerive(ref ext, ..) => { - // Resolve `$crate`s in case we have to go though stringification. - self.cx.resolver.resolve_dollar_crates(&item); invoc.expansion_data.mark.set_expn_info(expn_info); let span = span.with_ctxt(self.cx.backtrace()); let dummy = ast::MetaItem { // FIXME(jseyfried) avoid this diff --git a/src/test/pretty/dollar-crate.pp b/src/test/pretty/dollar-crate.pp new file mode 100644 index 0000000000000..3d2d949be2b2e --- /dev/null +++ b/src/test/pretty/dollar-crate.pp @@ -0,0 +1,18 @@ +#![feature(prelude_import)] +#![no_std] +#[prelude_import] +use ::std::prelude::v1::*; +#[macro_use] +extern crate std; +// pretty-compare-only +// pretty-mode:expanded +// pp-exact:dollar-crate.pp + +fn main() { + { + ::std::io::_print(::std::fmt::Arguments::new_v1(&["rust\n"], + &match () { + () => [], + })); + }; +} diff --git a/src/test/pretty/dollar-crate.rs b/src/test/pretty/dollar-crate.rs new file mode 100644 index 0000000000000..e46bc7f4859a7 --- /dev/null +++ b/src/test/pretty/dollar-crate.rs @@ -0,0 +1,7 @@ +// pretty-compare-only +// pretty-mode:expanded +// pp-exact:dollar-crate.pp + +fn main() { + println!("rust"); +} diff --git a/src/test/ui/issues/issue-49074.stderr b/src/test/ui/issues/issue-49074.stderr index d4648270f2d30..a25d8ee352686 100644 --- a/src/test/ui/issues/issue-49074.stderr +++ b/src/test/ui/issues/issue-49074.stderr @@ -2,7 +2,7 @@ error[E0658]: The attribute `marco_use` is currently unknown to the compiler and --> $DIR/issue-49074.rs:3:3 | LL | #[marco_use] // typo - | ^^^^^^^^^ + | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_use` | = help: add #![feature(custom_attribute)] to the crate attributes to enable diff --git a/src/test/ui/macros/macro-reexport-removed.stderr b/src/test/ui/macros/macro-reexport-removed.stderr index 7c3555a92ed8b..6cfec3ee762dd 100644 --- a/src/test/ui/macros/macro-reexport-removed.stderr +++ b/src/test/ui/macros/macro-reexport-removed.stderr @@ -14,7 +14,7 @@ error[E0658]: The attribute `macro_reexport` is currently unknown to the compile --> $DIR/macro-reexport-removed.rs:5:3 | LL | #[macro_reexport(macro_one)] //~ ERROR attribute `macro_reexport` is currently unknown - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_export` | = help: add #![feature(custom_attribute)] to the crate attributes to enable diff --git a/src/test/ui/proc-macro/derive-still-gated.stderr b/src/test/ui/proc-macro/derive-still-gated.stderr index d54a593f78311..ece1b6212914d 100644 --- a/src/test/ui/proc-macro/derive-still-gated.stderr +++ b/src/test/ui/proc-macro/derive-still-gated.stderr @@ -2,7 +2,7 @@ error[E0658]: The attribute `derive_A` is currently unknown to the compiler and --> $DIR/derive-still-gated.rs:8:3 | LL | #[derive_A] //~ ERROR attribute `derive_A` is currently unknown - | ^^^^^^^^ + | ^^^^^^^^ help: a built-in attribute with a similar name exists: `derive` | = help: add #![feature(custom_attribute)] to the crate attributes to enable diff --git a/src/test/ui/suggestions/attribute-typos.rs b/src/test/ui/suggestions/attribute-typos.rs new file mode 100644 index 0000000000000..13c6308b97e85 --- /dev/null +++ b/src/test/ui/suggestions/attribute-typos.rs @@ -0,0 +1,13 @@ +#[deprcated] //~ ERROR E0658 +fn foo() {} //~| HELP a built-in attribute with a similar name exists + //~| SUGGESTION deprecated + //~| HELP add #![feature(custom_attribute)] to the crate attributes to enable + +#[tests] //~ ERROR E0658 +fn bar() {} //~| HELP a built-in attribute with a similar name exists + //~| SUGGESTION test + //~| HELP add #![feature(custom_attribute)] to the crate attributes to enable + +#[rustc_err] //~ ERROR E0658 +fn main() {} //~| HELP add #![feature(rustc_attrs)] to the crate attributes to enable + // don't suggest rustc attributes diff --git a/src/test/ui/suggestions/attribute-typos.stderr b/src/test/ui/suggestions/attribute-typos.stderr new file mode 100644 index 0000000000000..e40da787e96ca --- /dev/null +++ b/src/test/ui/suggestions/attribute-typos.stderr @@ -0,0 +1,27 @@ +error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics (see issue #29642) + --> $DIR/attribute-typos.rs:11:3 + | +LL | #[rustc_err] //~ ERROR E0658 + | ^^^^^^^^^ + | + = help: add #![feature(rustc_attrs)] to the crate attributes to enable + +error[E0658]: The attribute `tests` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) + --> $DIR/attribute-typos.rs:6:3 + | +LL | #[tests] //~ ERROR E0658 + | ^^^^^ help: a built-in attribute with a similar name exists: `test` + | + = help: add #![feature(custom_attribute)] to the crate attributes to enable + +error[E0658]: The attribute `deprcated` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) + --> $DIR/attribute-typos.rs:1:3 + | +LL | #[deprcated] //~ ERROR E0658 + | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `deprecated` + | + = help: add #![feature(custom_attribute)] to the crate attributes to enable + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0658`.