diff options
27 files changed, 251 insertions, 92 deletions
diff --git a/.mailmap b/.mailmap index b8a9fc27eb7..92be3174750 100644 --- a/.mailmap +++ b/.mailmap @@ -102,6 +102,7 @@ Carol Willing <carolcode@willingconsulting.com> Chandler Deng <chandde@microsoft.com> Charles Lew <crlf0710@gmail.com> CrLF0710 <crlf0710@gmail.com> Chris C Cerami <chrisccerami@users.noreply.github.com> Chris C Cerami <chrisccerami@gmail.com> +Chris Denton <chris@chrisdenton.dev> Chris Denton <ChrisDenton@users.noreply.github.com> Chris Gregory <czipperz@gmail.com> Chris Pardy <chrispardy36@gmail.com> Chris Pressey <cpressey@gmail.com> diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d732075fb2d..dfaa70bb9db 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,7 +33,6 @@ find a mentor! You can learn more about asking questions and getting help in the Did a compiler error message tell you to come here? If you want to create an ICE report, refer to [this section][contributing-bug-reports] and [open an issue][issue template]. -[Contributing to Rust]: https://rustc-dev-guide.rust-lang.org/contributing.html#contributing-to-rust [rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/ [std-dev-guide]: https://std-dev-guide.rust-lang.org/ [contributing-bug-reports]: https://rustc-dev-guide.rust-lang.org/contributing.html#bug-reports diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 06206efb9ab..7ff440e49aa 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -869,17 +869,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let resolution = self.resolution(module, key).try_borrow_mut().map_err(|_| (Determined, Weak::No))?; // This happens when there is a cycle of imports. - if let Some(Finalize { path_span, report_private, .. }) = finalize { - // If the primary binding is unusable, search further and return the shadowed glob - // binding if it exists. What we really want here is having two separate scopes in - // a module - one for non-globs and one for globs, but until that's done use this - // hack to avoid inconsistent resolution ICEs during import validation. - let binding = [resolution.binding, resolution.shadowed_glob].into_iter().find_map( - |binding| match (binding, ignore_binding) { + // If the primary binding is unusable, search further and return the shadowed glob + // binding if it exists. What we really want here is having two separate scopes in + // a module - one for non-globs and one for globs, but until that's done use this + // hack to avoid inconsistent resolution ICEs during import validation. + let binding = + [resolution.binding, resolution.shadowed_glob].into_iter().find_map(|binding| { + match (binding, ignore_binding) { (Some(binding), Some(ignored)) if ptr::eq(binding, ignored) => None, _ => binding, - }, - ); + } + }); + + if let Some(Finalize { path_span, report_private, .. }) = finalize { let Some(binding) = binding else { return Err((Determined, Weak::No)); }; @@ -927,15 +929,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } let check_usable = |this: &mut Self, binding: &'a NameBinding<'a>| { - if let Some(ignored) = ignore_binding && ptr::eq(binding, ignored) { - return Err((Determined, Weak::No)); - } let usable = this.is_accessible_from(binding.vis, parent_scope.module); if usable { Ok(binding) } else { Err((Determined, Weak::No)) } }; // Items and single imports are not shadowable, if we have one, then it's determined. - if let Some(binding) = resolution.binding { + if let Some(binding) = binding { if !binding.is_glob_import() { return check_usable(self, binding); } @@ -952,6 +951,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if !self.is_accessible_from(import_vis, parent_scope.module) { continue; } + if let Some(ignored) = ignore_binding && + let NameBindingKind::Import { import, .. } = ignored.kind && + ptr::eq(import, &**single_import) { + // Ignore not just the binding itself, but if it has a shadowed_glob, + // ignore that, too, because this loop is supposed to only process + // named imports. + continue; + } let Some(module) = single_import.imported_module.get() else { return Err((Undetermined, Weak::No)); }; @@ -989,7 +996,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // and prohibit access to macro-expanded `macro_export` macros instead (unless restricted // shadowing is enabled, see `macro_expanded_macro_export_errors`). let unexpanded_macros = !module.unexpanded_invocations.borrow().is_empty(); - if let Some(binding) = resolution.binding { + if let Some(binding) = binding { if !unexpanded_macros || ns == MacroNS || restricted_shadowing { return check_usable(self, binding); } else { diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 47a351590b1..090312338e0 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -998,8 +998,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Alias(..) | ty::Param(..) | ty::Bound(..) - | ty::Error(_) => {} - ty::Infer(_) => { + | ty::Error(_) + | ty::Infer( + ty::InferTy::IntVar(_) + | ty::InferTy::FloatVar(_) + | ty::InferTy::FreshIntTy(_) + | ty::InferTy::FreshFloatTy(_), + ) => {} + ty::Infer(ty::InferTy::TyVar(_) | ty::InferTy::FreshTy(_)) => { candidates.ambiguous = true; } } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 3ed3dd2d20d..b58e62536d6 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -177,14 +177,14 @@ struct TraitObligationStack<'prev, 'tcx> { } struct SelectionCandidateSet<'tcx> { - // A list of candidates that definitely apply to the current - // obligation (meaning: types unify). + /// A list of candidates that definitely apply to the current + /// obligation (meaning: types unify). vec: Vec<SelectionCandidate<'tcx>>, - // If `true`, then there were candidates that might or might - // not have applied, but we couldn't tell. This occurs when some - // of the input types are type variables, in which case there are - // various "builtin" rules that might or might not trigger. + /// If `true`, then there were candidates that might or might + /// not have applied, but we couldn't tell. This occurs when some + /// of the input types are type variables, in which case there are + /// various "builtin" rules that might or might not trigger. ambiguous: bool, } diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 63bce5d0ccd..d728dc03817 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -1816,7 +1816,7 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> { /// `UnsafeCell<T>` opts-out of the immutability guarantee for `&T`: a shared reference /// `&UnsafeCell<T>` may point to data that is being mutated. This is called "interior mutability". /// -/// All other types that allow internal mutability, such as `Cell<T>` and `RefCell<T>`, internally +/// All other types that allow internal mutability, such as [`Cell<T>`] and [`RefCell<T>`], internally /// use `UnsafeCell` to wrap their data. /// /// Note that only the immutability guarantee for shared references is affected by `UnsafeCell`. The diff --git a/src/ci/run.sh b/src/ci/run.sh index 5f4e4a8e1b4..3056d9fc054 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -58,7 +58,12 @@ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-manage-submodules" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-locked-deps" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-cargo-native-static" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.codegen-units-std=1" -RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set dist.compression-profile=best" +# rust-lang/promote-release will recompress CI artifacts, and while we care +# about the per-commit artifact sizes, it's not as important that they're +# highly compressed as it is that the process is fast. Best compression +# generally implies single-threaded compression which results in wasting most +# of our CPU resources. +RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set dist.compression-profile=balanced" # When building for mingw, limit the number of parallel linker jobs during # the LLVM build, as not to run out of memory. diff --git a/src/doc/book b/src/doc/book -Subproject 21a2ed14f4480dab62438dcc1130291bebc6537 +Subproject 0510ca84c2ce6bf93c4ccf9248756e9e4fd00b1 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example -Subproject cfbfd648ce33926c3490f24de9a5b56cce404b8 +Subproject ba84bf35d0f17d404003349309201654d25f61a diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide -Subproject d08baa166b463537229eeb737c4ccadabd83cf7 +Subproject fca8af6c154c6cde2512f1331cf2704f214a818 diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index ffa13ebb77c..a37d4f31643 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -452,10 +452,12 @@ impl Item { pub(crate) fn links(&self, cx: &Context<'_>) -> Vec<RenderedLink> { use crate::html::format::{href, link_tooltip}; - cx.cache() + let Some(links) = cx.cache() .intra_doc_links - .get(&self.item_id) - .map_or(&[][..], |v| v.as_slice()) + .get(&self.item_id) else { + return vec![] + }; + links .iter() .filter_map(|ItemLink { link: s, link_text, page_id: id, ref fragment }| { debug!(?id); @@ -483,10 +485,12 @@ impl Item { /// the link text, but does need to know which `[]`-bracketed names /// are actually links. pub(crate) fn link_names(&self, cache: &Cache) -> Vec<RenderedLink> { - cache + let Some(links) = cache .intra_doc_links - .get(&self.item_id) - .map_or(&[][..], |v| v.as_slice()) + .get(&self.item_id) else { + return vec![]; + }; + links .iter() .map(|ItemLink { link: s, link_text, .. }| RenderedLink { original_text: s.clone(), @@ -1006,7 +1010,7 @@ pub(crate) fn collapse_doc_fragments(doc_strings: &[DocFragment]) -> String { /// A link that has not yet been rendered. /// /// This link will be turned into a rendered link by [`Item::links`]. -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq, Hash)] pub(crate) struct ItemLink { /// The original link written in the markdown pub(crate) link: Box<str>, diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 0295de8437e..c0329182032 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -1,6 +1,6 @@ use std::mem; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet}; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::Symbol; @@ -118,7 +118,7 @@ pub(crate) struct Cache { /// All intra-doc links resolved so far. /// /// Links are indexed by the DefId of the item they document. - pub(crate) intra_doc_links: FxHashMap<ItemId, Vec<clean::ItemLink>>, + pub(crate) intra_doc_links: FxHashMap<ItemId, FxIndexSet<clean::ItemLink>>, /// Cfg that have been hidden via #![doc(cfg_hide(...))] pub(crate) hidden_cfg: FxHashSet<clean::cfg::Cfg>, } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 1c6ab44a4c7..2cd9c8a8781 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -978,7 +978,7 @@ impl LinkCollector<'_, '_> { for md_link in preprocessed_markdown_links(&doc) { let link = self.resolve_link(item, item_id, module_id, &doc, &md_link); if let Some(link) = link { - self.cx.cache.intra_doc_links.entry(item.item_id).or_default().push(link); + self.cx.cache.intra_doc_links.entry(item.item_id).or_default().insert(link); } } } diff --git a/src/tools/rust-installer/src/compression.rs b/src/tools/rust-installer/src/compression.rs index 510c914163c..7c9c946e0b5 100644 --- a/src/tools/rust-installer/src/compression.rs +++ b/src/tools/rust-installer/src/compression.rs @@ -89,43 +89,11 @@ impl CompressionFormat { xz2::stream::MtStreamBuilder::new().threads(6).preset(6).encoder().unwrap() } CompressionProfile::Best => { - let mut filters = xz2::stream::Filters::new(); - // the preset is overridden by the other options so it doesn't matter - let mut lzma_ops = xz2::stream::LzmaOptions::new_preset(9).unwrap(); - // This sets the overall dictionary size, which is also how much memory (baseline) - // is needed for decompression. - lzma_ops.dict_size(64 * 1024 * 1024); - // Use the best match finder for compression ratio. - lzma_ops.match_finder(xz2::stream::MatchFinder::BinaryTree4); - lzma_ops.mode(xz2::stream::Mode::Normal); - // Set nice len to the maximum for best compression ratio - lzma_ops.nice_len(273); - // Set depth to a reasonable value, 0 means auto, 1000 is somwhat high but gives - // good results. - lzma_ops.depth(1000); - // 2 is the default and does well for most files - lzma_ops.position_bits(2); - // 0 is the default and does well for most files - lzma_ops.literal_position_bits(0); - // 3 is the default and does well for most files - lzma_ops.literal_context_bits(3); - - filters.lzma2(&lzma_ops); - - let mut builder = xz2::stream::MtStreamBuilder::new(); - builder.filters(filters); - - // On 32-bit platforms limit ourselves to 3 threads, otherwise we exceed memory - // usage this process can take. In the future we'll likely only do super-fast - // compression in CI and move this heavyweight processing to promote-release (which - // is always 64-bit and can run on big-memory machines) but for now this lets us - // move forward. - if std::mem::size_of::<usize>() == 4 { - builder.threads(3); - } else { - builder.threads(6); - } - builder.encoder().unwrap() + // Note that this isn't actually the best compression settings for the + // produced artifacts, the production artifacts on static.rust-lang.org are + // produced by rust-lang/promote-release which hosts recompression logic + // and is tuned for optimal compression. + xz2::stream::MtStreamBuilder::new().threads(6).preset(9).encoder().unwrap() } }; @@ -245,20 +213,14 @@ impl Write for CombinedEncoder { } fn flush(&mut self) -> std::io::Result<()> { - self.encoders - .par_iter_mut() - .map(|w| w.flush()) - .collect::<std::io::Result<Vec<()>>>()?; + self.encoders.par_iter_mut().map(|w| w.flush()).collect::<std::io::Result<Vec<()>>>()?; Ok(()) } } impl Encoder for CombinedEncoder { fn finish(self: Box<Self>) -> Result<(), Error> { - self.encoders - .into_par_iter() - .map(|e| e.finish()) - .collect::<Result<Vec<()>, Error>>()?; + self.encoders.into_par_iter().map(|e| e.finish()).collect::<Result<Vec<()>, Error>>()?; Ok(()) } } diff --git a/tests/codegen/vec-in-place.rs b/tests/codegen/vec-in-place.rs index 9992604221b..d68067ceb19 100644 --- a/tests/codegen/vec-in-place.rs +++ b/tests/codegen/vec-in-place.rs @@ -1,11 +1,13 @@ // ignore-debug: the debug assertions get in the way // compile-flags: -O -Z merge-functions=disabled +// min-llvm-version: 16 #![crate_type = "lib"] // Ensure that trivial casts of vec elements are O(1) pub struct Wrapper<T>(T); +// previously repr(C) caused the optimization to fail #[repr(C)] pub struct Foo { a: u64, @@ -14,9 +16,8 @@ pub struct Foo { d: u64, } -// Going from an aggregate struct to another type currently requires Copy to -// enable the TrustedRandomAccess specialization. Without it optimizations do not yet -// reliably recognize the loops as noop for repr(C) or non-Copy structs. +// implementing Copy exercises the TrustedRandomAccess specialization inside the in-place +// specialization #[derive(Copy, Clone)] pub struct Bar { a: u64, @@ -25,6 +26,14 @@ pub struct Bar { d: u64, } +// this exercises the try-fold codepath +pub struct Baz { + a: u64, + b: u64, + c: u64, + d: u64, +} + // CHECK-LABEL: @vec_iterator_cast_primitive #[no_mangle] pub fn vec_iterator_cast_primitive(vec: Vec<i8>) -> Vec<u8> { @@ -52,18 +61,29 @@ pub fn vec_iterator_cast_unwrap(vec: Vec<Wrapper<u8>>) -> Vec<u8> { // CHECK-LABEL: @vec_iterator_cast_aggregate #[no_mangle] pub fn vec_iterator_cast_aggregate(vec: Vec<[u64; 4]>) -> Vec<Foo> { - // FIXME These checks should be the same as other functions. - // CHECK-NOT: @__rust_alloc - // CHECK-NOT: @__rust_alloc + // CHECK-NOT: loop + // CHECK-NOT: call vec.into_iter().map(|e| unsafe { std::mem::transmute(e) }).collect() } -// CHECK-LABEL: @vec_iterator_cast_deaggregate +// CHECK-LABEL: @vec_iterator_cast_deaggregate_tra #[no_mangle] -pub fn vec_iterator_cast_deaggregate(vec: Vec<Bar>) -> Vec<[u64; 4]> { - // FIXME These checks should be the same as other functions. - // CHECK-NOT: @__rust_alloc - // CHECK-NOT: @__rust_alloc +pub fn vec_iterator_cast_deaggregate_tra(vec: Vec<Bar>) -> Vec<[u64; 4]> { + // CHECK-NOT: loop + // CHECK-NOT: call + + // Safety: For the purpose of this test we assume that Bar layout matches [u64; 4]. + // This currently is not guaranteed for repr(Rust) types, but it happens to work here and + // the UCG may add additional guarantees for homogenous types in the future that would make this + // correct. + vec.into_iter().map(|e| unsafe { std::mem::transmute(e) }).collect() +} + +// CHECK-LABEL: @vec_iterator_cast_deaggregate_fold +#[no_mangle] +pub fn vec_iterator_cast_deaggregate_fold(vec: Vec<Baz>) -> Vec<[u64; 4]> { + // CHECK-NOT: loop + // CHECK-NOT: call // Safety: For the purpose of this test we assume that Bar layout matches [u64; 4]. // This currently is not guaranteed for repr(Rust) types, but it happens to work here and diff --git a/tests/ui/async-await/missed-capture-issue-107414.rs b/tests/ui/async-await/missed-capture-issue-107414.rs new file mode 100644 index 00000000000..0ab4f5ade98 --- /dev/null +++ b/tests/ui/async-await/missed-capture-issue-107414.rs @@ -0,0 +1,24 @@ +// check-pass +// edition:2018 + +fn main() {} + +struct StructA {} +struct StructB {} + +impl StructA { + fn fn_taking_struct_b(&self, struct_b: &StructB) -> bool { + true + } +} + +async fn get_struct_a_async() -> StructA { + StructA {} +} + +async fn ice() { + match Some(StructB {}) { + Some(struct_b) if get_struct_a_async().await.fn_taking_struct_b(&struct_b) => {} + _ => {} + } +} diff --git a/tests/ui/fn/fn-ptr-trait-int-float-infer-var.rs b/tests/ui/fn/fn-ptr-trait-int-float-infer-var.rs new file mode 100644 index 00000000000..eec7da044c0 --- /dev/null +++ b/tests/ui/fn/fn-ptr-trait-int-float-infer-var.rs @@ -0,0 +1,10 @@ +// check-pass +trait MyCmp { + fn cmp(&self) {} +} +impl MyCmp for f32 {} + +fn main() { + // Ensure that `impl<F: FnPtr> Ord for F` is never considered for int and float infer vars. + 0.0.cmp(); +} diff --git a/tests/ui/lint/use-redundant/issue-92904.rs b/tests/ui/lint/use-redundant/issue-92904.rs new file mode 100644 index 00000000000..511d9d263cf --- /dev/null +++ b/tests/ui/lint/use-redundant/issue-92904.rs @@ -0,0 +1,17 @@ +// check-pass + +pub struct Foo(bar::Bar); + +pub mod bar { + pub struct Foo(pub Bar); + pub struct Bar(pub char); +} + +pub fn warning() -> Foo { + use bar::*; + #[deny(unused_imports)] + use self::Foo; // no error + Foo(Bar('a')) +} + +fn main() {} diff --git a/tests/ui/lint/use-redundant/use-redundant-glob-parent.rs b/tests/ui/lint/use-redundant/use-redundant-glob-parent.rs new file mode 100644 index 00000000000..6b1e018d2dc --- /dev/null +++ b/tests/ui/lint/use-redundant/use-redundant-glob-parent.rs @@ -0,0 +1,16 @@ +// check-pass +#![warn(unused_imports)] + +pub mod bar { + pub struct Foo(pub Bar); + pub struct Bar(pub char); +} + +use bar::*; + +pub fn warning() -> Foo { + use bar::Foo; //~ WARNING imported redundantly + Foo(Bar('a')) +} + +fn main() {} diff --git a/tests/ui/lint/use-redundant/use-redundant-glob-parent.stderr b/tests/ui/lint/use-redundant/use-redundant-glob-parent.stderr new file mode 100644 index 00000000000..2c3b3345270 --- /dev/null +++ b/tests/ui/lint/use-redundant/use-redundant-glob-parent.stderr @@ -0,0 +1,17 @@ +warning: the item `Foo` is imported redundantly + --> $DIR/use-redundant-glob-parent.rs:12:9 + | +LL | use bar::*; + | ------ the item `Foo` is already imported here +... +LL | use bar::Foo; + | ^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/use-redundant-glob-parent.rs:2:9 + | +LL | #![warn(unused_imports)] + | ^^^^^^^^^^^^^^ + +warning: 1 warning emitted + diff --git a/tests/ui/lint/use-redundant/use-redundant-glob.rs b/tests/ui/lint/use-redundant/use-redundant-glob.rs new file mode 100644 index 00000000000..bd9e51b6f59 --- /dev/null +++ b/tests/ui/lint/use-redundant/use-redundant-glob.rs @@ -0,0 +1,15 @@ +// check-pass +#![warn(unused_imports)] + +pub mod bar { + pub struct Foo(pub Bar); + pub struct Bar(pub char); +} + +pub fn warning() -> bar::Foo { + use bar::*; + use bar::Foo; //~ WARNING imported redundantly + Foo(Bar('a')) +} + +fn main() {} diff --git a/tests/ui/lint/use-redundant/use-redundant-glob.stderr b/tests/ui/lint/use-redundant/use-redundant-glob.stderr new file mode 100644 index 00000000000..d3b406d82b6 --- /dev/null +++ b/tests/ui/lint/use-redundant/use-redundant-glob.stderr @@ -0,0 +1,16 @@ +warning: the item `Foo` is imported redundantly + --> $DIR/use-redundant-glob.rs:11:9 + | +LL | use bar::*; + | ------ the item `Foo` is already imported here +LL | use bar::Foo; + | ^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/use-redundant-glob.rs:2:9 + | +LL | #![warn(unused_imports)] + | ^^^^^^^^^^^^^^ + +warning: 1 warning emitted + diff --git a/tests/ui/lint/use-redundant/use-redundant-multiple-namespaces.rs b/tests/ui/lint/use-redundant/use-redundant-multiple-namespaces.rs new file mode 100644 index 00000000000..0fb60840f8a --- /dev/null +++ b/tests/ui/lint/use-redundant/use-redundant-multiple-namespaces.rs @@ -0,0 +1,21 @@ +// check-pass +#![allow(nonstandard_style)] + +pub mod bar { + pub struct Foo { pub bar: Bar } + pub struct Bar(pub char); +} + +pub mod x { + use crate::bar; + pub const Foo: bar::Bar = bar::Bar('a'); +} + +pub fn warning() -> bar::Foo { + #![deny(unused_imports)] // no error + use bar::*; + use x::Foo; + Foo { bar: Foo } +} + +fn main() {} diff --git a/tests/ui/lint/use-redundant/use-redundant-not-parent.rs b/tests/ui/lint/use-redundant/use-redundant-not-parent.rs new file mode 100644 index 00000000000..c97a3d34163 --- /dev/null +++ b/tests/ui/lint/use-redundant/use-redundant-not-parent.rs @@ -0,0 +1,19 @@ +// check-pass + +pub mod bar { + pub struct Foo(pub Bar); + pub struct Bar(pub char); +} + +pub mod x { + pub struct Foo(pub crate::bar::Bar); +} + +pub fn warning() -> x::Foo { + use bar::*; + #[deny(unused_imports)] + use x::Foo; // no error + Foo(Bar('a')) +} + +fn main() {} diff --git a/tests/ui/lint/use-redundant.rs b/tests/ui/lint/use-redundant/use-redundant.rs index 53315dcf638..53315dcf638 100644 --- a/tests/ui/lint/use-redundant.rs +++ b/tests/ui/lint/use-redundant/use-redundant.rs diff --git a/tests/ui/lint/use-redundant.stderr b/tests/ui/lint/use-redundant/use-redundant.stderr index c861a1956e1..c861a1956e1 100644 --- a/tests/ui/lint/use-redundant.stderr +++ b/tests/ui/lint/use-redundant/use-redundant.stderr diff --git a/triagebot.toml b/triagebot.toml index c86c1613fa9..20a8be283b9 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -482,7 +482,7 @@ message = "This PR changes src/bootstrap/defaults/config.codegen.toml. If approp [assign] warn_non_default_branch = true -contributing_url = "https://rustc-dev-guide.rust-lang.org/contributing.html" +contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html" [assign.adhoc_groups] compiler-team = [ |
