diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 0ab4c79e3b236..707aceebb1eda 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -294,7 +294,7 @@ def default_build_triple(): raise ValueError('unknown byteorder: {}'.format(sys.byteorder)) # only the n64 ABI is supported, indicate it ostype += 'abi64' - elif cputype == 'sparcv9': + elif cputype == 'sparcv9' or cputype == 'sparc64': pass else: err = "unknown cpu type: {}".format(cputype) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index fb15f767f9e34..19409ef779ecc 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -451,6 +451,7 @@ impl Step for Openssl { "x86_64-apple-darwin" => "darwin64-x86_64-cc", "x86_64-linux-android" => "linux-x86_64", "x86_64-unknown-freebsd" => "BSD-x86_64", + "x86_64-unknown-dragonfly" => "BSD-x86_64", "x86_64-unknown-linux-gnu" => "linux-x86_64", "x86_64-unknown-linux-musl" => "linux-x86_64", "x86_64-unknown-netbsd" => "BSD-x86_64", diff --git a/src/liblibc b/src/liblibc index 7e33065ce4975..68f9959e53da6 160000 --- a/src/liblibc +++ b/src/liblibc @@ -1 +1 @@ -Subproject commit 7e33065ce49759958c0d1c04fcadef961032a943 +Subproject commit 68f9959e53da6c70bed7119cd09342859d431266 diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 58f1b1f9a41e7..e23e2acefb732 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1054,7 +1054,9 @@ pub enum Expr_ { /// A function call /// /// The first field resolves to the function itself (usually an `ExprPath`), - /// and the second field is the list of arguments + /// and the second field is the list of arguments. + /// This also represents calling the constructor of + /// tuple-like ADTs such as tuple structs and enum variants. ExprCall(P, HirVec), /// A method call (`x.foo::<'static, Bar, Baz>(a, b, c, d)`) /// diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index f46540114f750..d24344e4e2166 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -371,17 +371,18 @@ impl<'gcx> HashStable> for Span { // If this is not an empty or invalid span, we want to hash the last // position that belongs to it, as opposed to hashing the first // position past it. - let span_hi = if self.hi() > self.lo() { + let span = self.data(); + let span_hi = if span.hi > span.lo { // We might end up in the middle of a multibyte character here, // but that's OK, since we are not trying to decode anything at // this position. - self.hi() - ::syntax_pos::BytePos(1) + span.hi - ::syntax_pos::BytePos(1) } else { - self.hi() + span.hi }; { - let loc1 = hcx.codemap().byte_pos_to_line_and_col(self.lo()); + let loc1 = hcx.codemap().byte_pos_to_line_and_col(span.lo); let loc1 = loc1.as_ref() .map(|&(ref fm, line, col)| (&fm.name[..], line, col.to_usize())) .unwrap_or(("???", 0, 0)); @@ -414,7 +415,7 @@ impl<'gcx> HashStable> for Span { } } - if self.ctxt() == SyntaxContext::empty() { + if span.ctxt == SyntaxContext::empty() { 0u8.hash_stable(hcx, hasher); } else { 1u8.hash_stable(hcx, hasher); diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index a9d9f6f28ec0d..259794e9d0ee4 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -51,7 +51,7 @@ struct MarkSymbolVisitor<'a, 'tcx: 'a> { tables: &'a ty::TypeckTables<'tcx>, live_symbols: Box>, struct_has_extern_repr: bool, - ignore_non_const_paths: bool, + in_pat: bool, inherited_pub_visibility: bool, ignore_variant_stack: Vec, } @@ -75,10 +75,10 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { fn handle_definition(&mut self, def: Def) { match def { - Def::Const(_) | Def::AssociatedConst(..) => { + Def::Const(_) | Def::AssociatedConst(..) | Def::TyAlias(_) => { self.check_def_id(def.def_id()); } - _ if self.ignore_non_const_paths => (), + _ if self.in_pat => (), Def::PrimTy(..) | Def::SelfTy(..) | Def::Local(..) | Def::Upvar(..) => {} Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => { @@ -289,9 +289,9 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> { _ => () } - self.ignore_non_const_paths = true; + self.in_pat = true; intravisit::walk_pat(self, pat); - self.ignore_non_const_paths = false; + self.in_pat = false; } fn visit_path(&mut self, path: &'tcx hir::Path, _: ast::NodeId) { @@ -429,7 +429,7 @@ fn find_live<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tables: &ty::TypeckTables::empty(None), live_symbols: box FxHashSet(), struct_has_extern_repr: false, - ignore_non_const_paths: false, + in_pat: false, inherited_pub_visibility: false, ignore_variant_stack: vec![], }; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 83eeaf551c56c..3b27890013a22 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3606,12 +3606,12 @@ impl<'a> Resolver<'a> { } } - fn report_conflict(&mut self, + fn report_conflict<'b>(&mut self, parent: Module, ident: Ident, ns: Namespace, - new_binding: &NameBinding, - old_binding: &NameBinding) { + new_binding: &NameBinding<'b>, + old_binding: &NameBinding<'b>) { // Error on the second of two conflicting names if old_binding.span.lo() > new_binding.span.lo() { return self.report_conflict(parent, ident, ns, old_binding, new_binding); @@ -3683,6 +3683,26 @@ impl<'a> Resolver<'a> { old_noun, old_kind, name)); } + // See https://github.com/rust-lang/rust/issues/32354 + if old_binding.is_import() || new_binding.is_import() { + let binding = if new_binding.is_import() { + new_binding + } else { + old_binding + }; + + let cm = self.session.codemap(); + let rename_msg = "You can use `as` to change the binding name of the import"; + + if let Ok(snippet) = cm.span_to_snippet(binding.span) { + err.span_suggestion(binding.span, + rename_msg, + format!("{} as Other{}", snippet, name)); + } else { + err.span_label(binding.span, rename_msg); + } + } + err.emit(); self.name_already_seen.insert(name, span); } diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs index 99422bf8c90af..51f89110eb4ae 100644 --- a/src/librustc_trans/back/linker.rs +++ b/src/librustc_trans/back/linker.rs @@ -747,7 +747,7 @@ impl<'a> Linker for EmLinker<'a> { fn exported_symbols(tcx: TyCtxt, crate_type: CrateType) -> Vec { let mut symbols = Vec::new(); - let export_threshold = symbol_export::threshold(tcx); + let export_threshold = symbol_export::crates_export_threshold(&[crate_type]); for &(ref name, _, level) in tcx.exported_symbols(LOCAL_CRATE).iter() { if level.is_below_threshold(export_threshold) { symbols.push(name.clone()); diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index dcb0de3bb92de..398a692f8df5e 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -545,7 +545,8 @@ a { .content .search-results td:first-child { padding-right: 0; } .content .search-results td:first-child a { padding-right: 10px; } -tr.result span.primitive::after { content: ' (primitive type)'; font-style: italic; color: black; +tr.result span.primitive::after { + content: ' (primitive type)'; font-style: italic; color: black; } body.blur > :not(#help) { @@ -761,6 +762,15 @@ span.since { margin-top: 5px; } +.docblock > .section-header:first-child { + margin-left: 15px; + margin-top: 0; +} + +.docblock > .section-header:first-child:hover > a:before { + left: -10px; +} + .enum > .collapsed, .struct > .collapsed { margin-bottom: 25px; } diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 074ab3ebd8fdc..dec281212a514 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -736,10 +736,10 @@ pub trait Read { /// Transforms this `Read` instance to an [`Iterator`] over its bytes. /// - /// The returned type implements [`Iterator`] where the `Item` is [`Result`]`<`[`u8`]`, - /// R::Err>`. The yielded item is [`Ok`] if a byte was successfully read and - /// [`Err`] otherwise for I/O errors. EOF is mapped to returning [`None`] from - /// this iterator. + /// The returned type implements [`Iterator`] where the `Item` is + /// [`Result`]`<`[`u8`]`, `[`io::Error`]>`. + /// The yielded item is [`Ok`] if a byte was successfully read and [`Err`] + /// otherwise. EOF is mapped to returning [`None`] from this iterator. /// /// # Examples /// @@ -748,6 +748,7 @@ pub trait Read { /// [file]: ../fs/struct.File.html /// [`Iterator`]: ../../std/iter/trait.Iterator.html /// [`Result`]: ../../std/result/enum.Result.html + /// [`io::Error``]: ../../std/io/struct.Error.html /// [`u8`]: ../../std/primitive.u8.html /// [`Ok`]: ../../std/result/enum.Result.html#variant.Ok /// [`Err`]: ../../std/result/enum.Result.html#variant.Err @@ -1410,6 +1411,8 @@ pub trait BufRead: Read { /// /// If successful, this function will return the total number of bytes read. /// + /// An empty buffer returned indicates that the stream has reached EOF. + /// /// # Errors /// /// This function will ignore all instances of [`ErrorKind::Interrupted`] and @@ -1470,6 +1473,8 @@ pub trait BufRead: Read { /// /// If successful, this function will return the total number of bytes read. /// + /// An empty buffer returned indicates that the stream has reached EOF. + /// /// # Errors /// /// This function has the same error semantics as [`read_until`] and will diff --git a/src/libstd/sys/unix/ext/mod.rs b/src/libstd/sys/unix/ext/mod.rs index 98bc90dd4e132..c221f7c8cfe24 100644 --- a/src/libstd/sys/unix/ext/mod.rs +++ b/src/libstd/sys/unix/ext/mod.rs @@ -10,8 +10,14 @@ //! Experimental extensions to `std` for Unix platforms. //! -//! For now, this module is limited to extracting file descriptors, -//! but its functionality will grow over time. +//! Provides access to platform-level information on Unix platforms, and +//! exposes Unix-specific functions that would otherwise be inappropriate as +//! part of the core `std` library. +//! +//! It exposes more ways to deal with platform-specific strings (`OsStr`, +//! `OsString`), allows to set permissions more granularly, extract low-level +//! file descriptors from files and sockets, and has platform-specific helpers +//! for spawning processes. //! //! # Examples //! diff --git a/src/libstd/sys/unix/rand.rs b/src/libstd/sys/unix/rand.rs index fd066c9cdbeef..e2d40742c7136 100644 --- a/src/libstd/sys/unix/rand.rs +++ b/src/libstd/sys/unix/rand.rs @@ -49,7 +49,9 @@ mod imp { target_arch = "powerpc64", target_arch = "s390x")))] fn getrandom(buf: &mut [u8]) -> libc::c_long { - #[cfg(target_arch = "x86_64")] + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + const NR_GETRANDOM: libc::c_long = 0x40000000 + 318; + #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] const NR_GETRANDOM: libc::c_long = 318; #[cfg(target_arch = "x86")] const NR_GETRANDOM: libc::c_long = 355; diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index d3995d957928e..be0af8052eb13 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -901,7 +901,9 @@ pub enum ExprKind { /// A function call /// /// The first field resolves to the function itself, - /// and the second field is the list of arguments + /// and the second field is the list of arguments. + /// This also represents calling the constructor of + /// tuple-like ADTs such as tuple structs and enum variants. Call(P, Vec>), /// A method call (`x.foo::<'static, Bar, Baz>(a, b, c, d)`) /// diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index 48c92873e146d..053746b579dcb 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -105,11 +105,10 @@ impl<'a> Parser<'a> { let span = self.span; self.diagnostic() .struct_span_err(span, reason) - .note("inner attributes and doc comments, like `#![no_std]` or \ - `//! My crate`, annotate the item enclosing them, and are \ - usually found at the beginning of source files. Outer \ - attributes and doc comments, like `#[test]` and - `/// My function`, annotate the item following them.") + .note("inner attributes, like `#![no_std]`, annotate the item \ + enclosing them, and are usually found at the beginning of \ + source files. Outer attributes, like `#[test]`, annotate the \ + item following them.") .emit() } ast::AttrStyle::Inner diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index d30d79ece15c7..44e73d876e85a 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -75,6 +75,21 @@ pub struct SpanData { pub ctxt: SyntaxContext, } +impl SpanData { + #[inline] + pub fn with_lo(&self, lo: BytePos) -> Span { + Span::new(lo, self.hi, self.ctxt) + } + #[inline] + pub fn with_hi(&self, hi: BytePos) -> Span { + Span::new(self.lo, hi, self.ctxt) + } + #[inline] + pub fn with_ctxt(&self, ctxt: SyntaxContext) -> Span { + Span::new(self.lo, self.hi, ctxt) + } +} + // The interner in thread-local, so `Span` shouldn't move between threads. impl !Send for Span {} impl !Sync for Span {} @@ -109,8 +124,7 @@ impl Span { } #[inline] pub fn with_lo(self, lo: BytePos) -> Span { - let base = self.data(); - Span::new(lo, base.hi, base.ctxt) + self.data().with_lo(lo) } #[inline] pub fn hi(self) -> BytePos { @@ -118,8 +132,7 @@ impl Span { } #[inline] pub fn with_hi(self, hi: BytePos) -> Span { - let base = self.data(); - Span::new(base.lo, hi, base.ctxt) + self.data().with_hi(hi) } #[inline] pub fn ctxt(self) -> SyntaxContext { @@ -127,20 +140,21 @@ impl Span { } #[inline] pub fn with_ctxt(self, ctxt: SyntaxContext) -> Span { - let base = self.data(); - Span::new(base.lo, base.hi, ctxt) + self.data().with_ctxt(ctxt) } /// Returns a new span representing just the end-point of this span pub fn end_point(self) -> Span { - let lo = cmp::max(self.hi().0 - 1, self.lo().0); - self.with_lo(BytePos(lo)) + let span = self.data(); + let lo = cmp::max(span.hi.0 - 1, span.lo.0); + span.with_lo(BytePos(lo)) } /// Returns a new span representing the next character after the end-point of this span pub fn next_point(self) -> Span { - let lo = cmp::max(self.hi().0, self.lo().0 + 1); - Span::new(BytePos(lo), BytePos(lo), self.ctxt()) + let span = self.data(); + let lo = cmp::max(span.hi.0, span.lo.0 + 1); + Span::new(BytePos(lo), BytePos(lo), span.ctxt) } /// Returns `self` if `self` is not the dummy span, and `other` otherwise. @@ -150,7 +164,9 @@ impl Span { /// Return true if `self` fully encloses `other`. pub fn contains(self, other: Span) -> bool { - self.lo() <= other.lo() && other.hi() <= self.hi() + let span = self.data(); + let other = other.data(); + span.lo <= other.lo && other.hi <= span.hi } /// Return true if the spans are equal with regards to the source text. @@ -158,13 +174,17 @@ impl Span { /// Use this instead of `==` when either span could be generated code, /// and you only care that they point to the same bytes of source text. pub fn source_equal(&self, other: &Span) -> bool { - self.lo() == other.lo() && self.hi() == other.hi() + let span = self.data(); + let other = other.data(); + span.lo == other.lo && span.hi == other.hi } /// Returns `Some(span)`, where the start is trimmed by the end of `other` pub fn trim_start(self, other: Span) -> Option { - if self.hi() > other.hi() { - Some(self.with_lo(cmp::max(self.lo(), other.hi()))) + let span = self.data(); + let other = other.data(); + if span.hi > other.hi { + Some(span.with_lo(cmp::max(span.lo, other.hi))) } else { None } @@ -268,29 +288,35 @@ impl Span { /// Return a `Span` that would enclose both `self` and `end`. pub fn to(self, end: Span) -> Span { + let span = self.data(); + let end = end.data(); Span::new( - cmp::min(self.lo(), end.lo()), - cmp::max(self.hi(), end.hi()), + cmp::min(span.lo, end.lo), + cmp::max(span.hi, end.hi), // FIXME(jseyfried): self.ctxt should always equal end.ctxt here (c.f. issue #23480) - if self.ctxt() == SyntaxContext::empty() { end.ctxt() } else { self.ctxt() }, + if span.ctxt == SyntaxContext::empty() { end.ctxt } else { span.ctxt }, ) } /// Return a `Span` between the end of `self` to the beginning of `end`. pub fn between(self, end: Span) -> Span { + let span = self.data(); + let end = end.data(); Span::new( - self.hi(), - end.lo(), - if end.ctxt() == SyntaxContext::empty() { end.ctxt() } else { self.ctxt() }, + span.hi, + end.lo, + if end.ctxt == SyntaxContext::empty() { end.ctxt } else { span.ctxt }, ) } /// Return a `Span` between the beginning of `self` to the beginning of `end`. pub fn until(self, end: Span) -> Span { + let span = self.data(); + let end = end.data(); Span::new( - self.lo(), - end.lo(), - if end.ctxt() == SyntaxContext::empty() { end.ctxt() } else { self.ctxt() }, + span.lo, + end.lo, + if end.ctxt == SyntaxContext::empty() { end.ctxt } else { span.ctxt }, ) } } @@ -316,13 +342,14 @@ impl Default for Span { impl serialize::UseSpecializedEncodable for Span { fn default_encode(&self, s: &mut S) -> Result<(), S::Error> { + let span = self.data(); s.emit_struct("Span", 2, |s| { s.emit_struct_field("lo", 0, |s| { - self.lo().encode(s) + span.lo.encode(s) })?; s.emit_struct_field("hi", 1, |s| { - self.hi().encode(s) + span.hi.encode(s) }) }) } diff --git a/src/test/run-make/symbol-visibility/Makefile b/src/test/run-make/symbol-visibility/Makefile index 988c9473f6a7e..f1ada814bdb80 100644 --- a/src/test/run-make/symbol-visibility/Makefile +++ b/src/test/run-make/symbol-visibility/Makefile @@ -9,17 +9,17 @@ all: else NM=nm -D -DYLIB_EXT=so CDYLIB_NAME=liba_cdylib.so RDYLIB_NAME=liba_rust_dylib.so EXE_NAME=an_executable +COMBINED_CDYLIB_NAME=libcombined_rlib_dylib.so ifeq ($(UNAME),Darwin) NM=nm -gU -DYLIB_EXT=dylib CDYLIB_NAME=liba_cdylib.dylib RDYLIB_NAME=liba_rust_dylib.dylib EXE_NAME=an_executable +COMBINED_CDYLIB_NAME=libcombined_rlib_dylib.dylib endif all: @@ -27,6 +27,7 @@ all: $(RUSTC) a_cdylib.rs $(RUSTC) a_rust_dylib.rs $(RUSTC) an_executable.rs + $(RUSTC) a_cdylib.rs --crate-name combined_rlib_dylib --crate-type=rlib,cdylib # Check that a cdylib exports its public #[no_mangle] functions [ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -c public_c_function_from_cdylib)" -eq "1" ] @@ -47,4 +48,13 @@ all: [ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -c public_c_function_from_rlib)" -eq "0" ] [ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -c public_rust_function_from_exe)" -eq "0" ] + + # Check the combined case, where we generate a cdylib and an rlib in the same + # compilation session: + # Check that a cdylib exports its public #[no_mangle] functions + [ "$$($(NM) $(TMPDIR)/$(COMBINED_CDYLIB_NAME) | grep -c public_c_function_from_cdylib)" -eq "1" ] + # Check that a cdylib exports the public #[no_mangle] functions of dependencies + [ "$$($(NM) $(TMPDIR)/$(COMBINED_CDYLIB_NAME) | grep -c public_c_function_from_rlib)" -eq "1" ] + # Check that a cdylib DOES NOT export any public Rust functions + [ "$$($(NM) $(TMPDIR)/$(COMBINED_CDYLIB_NAME) | grep -c _ZN.*h.*E)" -eq "0" ] endif diff --git a/src/test/run-pass/dead-code-alias-in-pat.rs b/src/test/run-pass/dead-code-alias-in-pat.rs new file mode 100644 index 0000000000000..a37d671e5c171 --- /dev/null +++ b/src/test/run-pass/dead-code-alias-in-pat.rs @@ -0,0 +1,18 @@ +// Copyright 2017 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. + +#![deny(dead_code)] + +fn main() { + struct Foo { x: T } + type Bar = Foo; + let spam = |Bar { x }| x != 0; + println!("{}", spam(Foo { x: 10 })); +} diff --git a/src/test/ui/issue-45296.stderr b/src/test/ui/issue-45296.stderr index 7bfcac974c53e..1a660e4c6784e 100644 --- a/src/test/ui/issue-45296.stderr +++ b/src/test/ui/issue-45296.stderr @@ -4,8 +4,7 @@ error: an inner attribute is not permitted in this context 14 | #![allow(unused_variables)] | ^ | - = note: inner attributes and doc comments, like `#![no_std]` or `//! My crate`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes and doc comments, like `#[test]` and - `/// My function`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. error: aborting due to previous error diff --git a/src/test/ui/suggestions/issue-32354-suggest-import-rename.rs b/src/test/ui/suggestions/issue-32354-suggest-import-rename.rs new file mode 100644 index 0000000000000..51aba27498f88 --- /dev/null +++ b/src/test/ui/suggestions/issue-32354-suggest-import-rename.rs @@ -0,0 +1,22 @@ +// Copyright 2017 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. + +pub mod extension1 { + pub trait ConstructorExtension {} +} + +pub mod extension2 { + pub trait ConstructorExtension {} +} + +use extension1::ConstructorExtension; +use extension2::ConstructorExtension; + +fn main() {} diff --git a/src/test/ui/suggestions/issue-32354-suggest-import-rename.stderr b/src/test/ui/suggestions/issue-32354-suggest-import-rename.stderr new file mode 100644 index 0000000000000..0798519128474 --- /dev/null +++ b/src/test/ui/suggestions/issue-32354-suggest-import-rename.stderr @@ -0,0 +1,16 @@ +error[E0252]: the name `ConstructorExtension` is defined multiple times + --> $DIR/issue-32354-suggest-import-rename.rs:20:5 + | +19 | use extension1::ConstructorExtension; + | -------------------------------- previous import of the trait `ConstructorExtension` here +20 | use extension2::ConstructorExtension; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ConstructorExtension` reimported here + | + = note: `ConstructorExtension` must be defined only once in the type namespace of this module +help: You can use `as` to change the binding name of the import + | +20 | use extension2::ConstructorExtension as OtherConstructorExtension; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index a2a264490a141..9736c03993081 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -351,6 +351,26 @@ fn map_lib_features(base_src_path: &Path, } } becoming_feature = None; + if line.contains("rustc_const_unstable(") { + // const fn features are handled specially + let feature_name = match find_attr_val(line, "feature") { + Some(name) => name, + None => err!("malformed stability attribute"), + }; + let feature = Feature { + level: Status::Unstable, + since: "None".to_owned(), + has_gate_test: false, + // Whether there is a common tracking issue + // for these feature gates remains an open question + // https://github.com/rust-lang/rust/issues/24111#issuecomment-340283184 + // But we take 24111 otherwise they will be shown as + // "internal to the compiler" which they are not. + tracking_issue: Some(24111), + }; + mf(Ok((feature_name, feature)), file, i + 1); + continue; + } let level = if line.contains("[unstable(") { Status::Unstable } else if line.contains("[stable(") {