From 8d96cc238e571ef7d83dcf87239d525d644bbb69 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Sun, 13 Sep 2020 14:39:55 +0000 Subject: [PATCH 01/18] make llvm_asm options more intense --- src/doc/unstable-book/src/library-features/llvm-asm.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/unstable-book/src/library-features/llvm-asm.md b/src/doc/unstable-book/src/library-features/llvm-asm.md index da01d9228f14..a2f029db2916 100644 --- a/src/doc/unstable-book/src/library-features/llvm-asm.md +++ b/src/doc/unstable-book/src/library-features/llvm-asm.md @@ -159,12 +159,12 @@ specify some extra info about the inline assembly: Current valid options are: -1. *volatile* - specifying this is analogous to +1. `volatile` - specifying this is analogous to `__asm__ __volatile__ (...)` in gcc/clang. -2. *alignstack* - certain instructions expect the stack to be +2. `alignstack` - certain instructions expect the stack to be aligned a certain way (i.e. SSE) and specifying this indicates to the compiler to insert its usual stack alignment code -3. *intel* - use intel syntax instead of the default AT&T. +3. `intel` - use intel syntax instead of the default AT&T. ```rust # #![feature(llvm_asm)] From b7ce5b44dd2e0fa8d6f7131a246ecad77328921e Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sun, 13 Sep 2020 22:06:06 +0200 Subject: [PATCH 02/18] remove orphaned files Should been part of https://github.com/rust-lang/rust/pull/74163 --- .../dist-x86_64-linux/build-git.sh | 15 ------------- .../dist-x86_64-linux/build-headers.sh | 16 -------------- .../dist-x86_64-linux/build-perl.sh | 21 ------------------- 3 files changed, 52 deletions(-) delete mode 100755 src/ci/docker/host-x86_64/dist-x86_64-linux/build-git.sh delete mode 100755 src/ci/docker/host-x86_64/dist-x86_64-linux/build-headers.sh delete mode 100755 src/ci/docker/host-x86_64/dist-x86_64-linux/build-perl.sh diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-git.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-git.sh deleted file mode 100755 index 38fea2a8094b..000000000000 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-git.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash - -set -ex -source shared.sh - -curl -L https://www.kernel.org/pub/software/scm/git/git-2.10.0.tar.gz | tar xzf - - -cd git-2.10.0 -make configure -hide_output ./configure --prefix=/rustroot -hide_output make -j10 -hide_output make install - -cd .. -rm -rf git-2.10.0 diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-headers.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-headers.sh deleted file mode 100755 index b623e53583b5..000000000000 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-headers.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash - -set -ex -source shared.sh - -curl https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-3.2.84.tar.xz | unxz | tar x - -cd linux-3.2.84 -hide_output make mrproper -hide_output make INSTALL_HDR_PATH=dest headers_install - -find dest/include \( -name .install -o -name ..install.cmd \) -delete -yes | cp -fr dest/include/* /usr/include - -cd .. -rm -rf linux-3.2.84 diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-perl.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-perl.sh deleted file mode 100755 index a678d353d52f..000000000000 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-perl.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash - -set -ex -source shared.sh - -curl https://www.cpan.org/src/5.0/perl-5.28.0.tar.gz | \ - tar xzf - - -cd perl-5.28.0 - -# Gotta do some hackery to tell python about our custom OpenSSL build, but other -# than that fairly normal. -CC=gcc \ -CFLAGS='-I /rustroot/include -fgnu89-inline' \ -LDFLAGS='-L /rustroot/lib -L /rustroot/lib64' \ - hide_output ./configure.gnu -hide_output make -j10 -hide_output make install - -cd .. -rm -rf perl-5.28.0 From c9686cb31ad9dd9428825dbb3b362f5df72ab719 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Sun, 26 Jul 2020 08:53:39 -0400 Subject: [PATCH 03/18] Introduce a PartitioningCx struct --- .../src/monomorphize/partitioning/default.rs | 32 +++++++++---------- .../src/monomorphize/partitioning/merging.rs | 15 ++++----- .../src/monomorphize/partitioning/mod.rs | 25 +++++++++------ 3 files changed, 38 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_mir/src/monomorphize/partitioning/default.rs b/compiler/rustc_mir/src/monomorphize/partitioning/default.rs index b48bae837877..827d037f3198 100644 --- a/compiler/rustc_mir/src/monomorphize/partitioning/default.rs +++ b/compiler/rustc_mir/src/monomorphize/partitioning/default.rs @@ -11,6 +11,7 @@ use rustc_middle::ty::print::characteristic_def_id_of_type; use rustc_middle::ty::{self, DefIdTree, InstanceDef, TyCtxt}; use rustc_span::symbol::Symbol; +use super::PartitioningCx; use crate::monomorphize::collector::InliningMap; use crate::monomorphize::partitioning::merging; use crate::monomorphize::partitioning::{ @@ -22,35 +23,36 @@ pub struct DefaultPartitioning; impl<'tcx> Partitioner<'tcx> for DefaultPartitioning { fn place_root_mono_items( &mut self, - tcx: TyCtxt<'tcx>, + cx: &PartitioningCx<'_, 'tcx>, mono_items: &mut dyn Iterator>, ) -> PreInliningPartitioning<'tcx> { let mut roots = FxHashSet::default(); let mut codegen_units = FxHashMap::default(); - let is_incremental_build = tcx.sess.opts.incremental.is_some(); + let is_incremental_build = cx.tcx.sess.opts.incremental.is_some(); let mut internalization_candidates = FxHashSet::default(); // Determine if monomorphizations instantiated in this crate will be made // available to downstream crates. This depends on whether we are in // share-generics mode and whether the current crate can even have // downstream crates. - let export_generics = tcx.sess.opts.share_generics() && tcx.local_crate_exports_generics(); + let export_generics = + cx.tcx.sess.opts.share_generics() && cx.tcx.local_crate_exports_generics(); - let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx); + let cgu_name_builder = &mut CodegenUnitNameBuilder::new(cx.tcx); let cgu_name_cache = &mut FxHashMap::default(); for mono_item in mono_items { - match mono_item.instantiation_mode(tcx) { + match mono_item.instantiation_mode(cx.tcx) { InstantiationMode::GloballyShared { .. } => {} InstantiationMode::LocalCopy => continue, } - let characteristic_def_id = characteristic_def_id_of_mono_item(tcx, mono_item); + let characteristic_def_id = characteristic_def_id_of_mono_item(cx.tcx, mono_item); let is_volatile = is_incremental_build && mono_item.is_generic_fn(); let codegen_unit_name = match characteristic_def_id { Some(def_id) => compute_codegen_unit_name( - tcx, + cx.tcx, cgu_name_builder, def_id, is_volatile, @@ -65,7 +67,7 @@ impl<'tcx> Partitioner<'tcx> for DefaultPartitioning { let mut can_be_internalized = true; let (linkage, visibility) = mono_item_linkage_and_visibility( - tcx, + cx.tcx, &mono_item, &mut can_be_internalized, export_generics, @@ -97,17 +99,16 @@ impl<'tcx> Partitioner<'tcx> for DefaultPartitioning { fn merge_codegen_units( &mut self, - tcx: TyCtxt<'tcx>, + cx: &PartitioningCx<'_, 'tcx>, initial_partitioning: &mut PreInliningPartitioning<'tcx>, - target_cgu_count: usize, ) { - merging::merge_codegen_units(tcx, initial_partitioning, target_cgu_count); + merging::merge_codegen_units(cx, initial_partitioning); } fn place_inlined_mono_items( &mut self, + cx: &PartitioningCx<'_, 'tcx>, initial_partitioning: PreInliningPartitioning<'tcx>, - inlining_map: &InliningMap<'tcx>, ) -> PostInliningPartitioning<'tcx> { let mut new_partitioning = Vec::new(); let mut mono_item_placements = FxHashMap::default(); @@ -124,7 +125,7 @@ impl<'tcx> Partitioner<'tcx> for DefaultPartitioning { // Collect all items that need to be available in this codegen unit. let mut reachable = FxHashSet::default(); for root in old_codegen_unit.items().keys() { - follow_inlining(*root, inlining_map, &mut reachable); + follow_inlining(*root, cx.inlining_map, &mut reachable); } let mut new_codegen_unit = CodegenUnit::new(old_codegen_unit.name()); @@ -198,9 +199,8 @@ impl<'tcx> Partitioner<'tcx> for DefaultPartitioning { fn internalize_symbols( &mut self, - _tcx: TyCtxt<'tcx>, + cx: &PartitioningCx<'_, 'tcx>, partitioning: &mut PostInliningPartitioning<'tcx>, - inlining_map: &InliningMap<'tcx>, ) { if partitioning.codegen_units.len() == 1 { // Fast path for when there is only one codegen unit. In this case we @@ -218,7 +218,7 @@ impl<'tcx> Partitioner<'tcx> for DefaultPartitioning { // Build a map from every monomorphization to all the monomorphizations that // reference it. let mut accessor_map: FxHashMap, Vec>> = Default::default(); - inlining_map.iter_accesses(|accessor, accessees| { + cx.inlining_map.iter_accesses(|accessor, accessees| { for accessee in accessees { accessor_map.entry(*accessee).or_default().push(accessor); } diff --git a/compiler/rustc_mir/src/monomorphize/partitioning/merging.rs b/compiler/rustc_mir/src/monomorphize/partitioning/merging.rs index 1787e6df1b9c..3f3aaa2f63ca 100644 --- a/compiler/rustc_mir/src/monomorphize/partitioning/merging.rs +++ b/compiler/rustc_mir/src/monomorphize/partitioning/merging.rs @@ -3,17 +3,16 @@ use std::cmp; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder}; -use rustc_middle::ty::TyCtxt; use rustc_span::symbol::{Symbol, SymbolStr}; +use super::PartitioningCx; use crate::monomorphize::partitioning::PreInliningPartitioning; pub fn merge_codegen_units<'tcx>( - tcx: TyCtxt<'tcx>, + cx: &PartitioningCx<'_, 'tcx>, initial_partitioning: &mut PreInliningPartitioning<'tcx>, - target_cgu_count: usize, ) { - assert!(target_cgu_count >= 1); + assert!(cx.target_cgu_count >= 1); let codegen_units = &mut initial_partitioning.codegen_units; // Note that at this point in time the `codegen_units` here may not be in a @@ -32,7 +31,7 @@ pub fn merge_codegen_units<'tcx>( codegen_units.iter().map(|cgu| (cgu.name(), vec![cgu.name().as_str()])).collect(); // Merge the two smallest codegen units until the target size is reached. - while codegen_units.len() > target_cgu_count { + while codegen_units.len() > cx.target_cgu_count { // Sort small cgus to the back codegen_units.sort_by_cached_key(|cgu| cmp::Reverse(cgu.size_estimate())); let mut smallest = codegen_units.pop().unwrap(); @@ -56,9 +55,9 @@ pub fn merge_codegen_units<'tcx>( ); } - let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx); + let cgu_name_builder = &mut CodegenUnitNameBuilder::new(cx.tcx); - if tcx.sess.opts.incremental.is_some() { + if cx.tcx.sess.opts.incremental.is_some() { // If we are doing incremental compilation, we want CGU names to // reflect the path of the source level module they correspond to. // For CGUs that contain the code of multiple modules because of the @@ -82,7 +81,7 @@ pub fn merge_codegen_units<'tcx>( for cgu in codegen_units.iter_mut() { if let Some(new_cgu_name) = new_cgu_names.get(&cgu.name()) { - if tcx.sess.opts.debugging_opts.human_readable_cgu_names { + if cx.tcx.sess.opts.debugging_opts.human_readable_cgu_names { cgu.set_name(Symbol::intern(&new_cgu_name)); } else { // If we don't require CGU names to be human-readable, we diff --git a/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs b/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs index b45fe0ee010f..f66fec37b25d 100644 --- a/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs +++ b/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs @@ -107,31 +107,35 @@ use rustc_span::symbol::Symbol; use crate::monomorphize::collector::InliningMap; use crate::monomorphize::collector::{self, MonoItemCollectionMode}; +pub struct PartitioningCx<'a, 'tcx> { + tcx: TyCtxt<'tcx>, + target_cgu_count: usize, + inlining_map: &'a InliningMap<'tcx>, +} + trait Partitioner<'tcx> { fn place_root_mono_items( &mut self, - tcx: TyCtxt<'tcx>, + cx: &PartitioningCx<'_, 'tcx>, mono_items: &mut dyn Iterator>, ) -> PreInliningPartitioning<'tcx>; fn merge_codegen_units( &mut self, - tcx: TyCtxt<'tcx>, + cx: &PartitioningCx<'_, 'tcx>, initial_partitioning: &mut PreInliningPartitioning<'tcx>, - target_cgu_count: usize, ); fn place_inlined_mono_items( &mut self, + cx: &PartitioningCx<'_, 'tcx>, initial_partitioning: PreInliningPartitioning<'tcx>, - inlining_map: &InliningMap<'tcx>, ) -> PostInliningPartitioning<'tcx>; fn internalize_symbols( &mut self, - tcx: TyCtxt<'tcx>, + cx: &PartitioningCx<'_, 'tcx>, partitioning: &mut PostInliningPartitioning<'tcx>, - inlining_map: &InliningMap<'tcx>, ); } @@ -156,12 +160,13 @@ pub fn partition<'tcx>( let _prof_timer = tcx.prof.generic_activity("cgu_partitioning"); let mut partitioner = get_partitioner(tcx); + let cx = &PartitioningCx { tcx, target_cgu_count: max_cgu_count, inlining_map }; // In the first step, we place all regular monomorphizations into their // respective 'home' codegen unit. Regular monomorphizations are all // functions and statics defined in the local crate. let mut initial_partitioning = { let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_roots"); - partitioner.place_root_mono_items(tcx, mono_items) + partitioner.place_root_mono_items(cx, mono_items) }; initial_partitioning.codegen_units.iter_mut().for_each(|cgu| cgu.estimate_size(tcx)); @@ -171,7 +176,7 @@ pub fn partition<'tcx>( // Merge until we have at most `max_cgu_count` codegen units. { let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_merge_cgus"); - partitioner.merge_codegen_units(tcx, &mut initial_partitioning, max_cgu_count); + partitioner.merge_codegen_units(cx, &mut initial_partitioning); debug_dump(tcx, "POST MERGING:", initial_partitioning.codegen_units.iter()); } @@ -181,7 +186,7 @@ pub fn partition<'tcx>( // local functions the definition of which is marked with `#[inline]`. let mut post_inlining = { let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_inline_items"); - partitioner.place_inlined_mono_items(initial_partitioning, inlining_map) + partitioner.place_inlined_mono_items(cx, initial_partitioning) }; post_inlining.codegen_units.iter_mut().for_each(|cgu| cgu.estimate_size(tcx)); @@ -192,7 +197,7 @@ pub fn partition<'tcx>( // more freedom to optimize. if !tcx.sess.link_dead_code() { let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_internalize_symbols"); - partitioner.internalize_symbols(tcx, &mut post_inlining, inlining_map); + partitioner.internalize_symbols(cx, &mut post_inlining); } // Finally, sort by codegen unit name, so that we get deterministic results. From 0eac38b7a65c29734f4b2d34f35ee0aa9cb00a74 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 13 Sep 2020 20:55:06 -0700 Subject: [PATCH 04/18] fix syntax error in suggesting generic constraint in trait parameter suggest `where T: Foo` for the first bound on a trait, then suggest `, T: Foo` when the suggested bound would add to an existing set of `where` clauses. `where T: Foo` may be the first bound if `T` has a default, because we'd rather suggest ``` trait A where T: Copy ``` than ``` trait A ``` for legibility reasons. --- compiler/rustc_middle/src/ty/diagnostics.rs | 66 +++++++++++++------ .../ui/trait-impl-bound-suggestions.fixed | 20 ++++++ src/test/ui/trait-impl-bound-suggestions.rs | 20 ++++++ .../ui/trait-impl-bound-suggestions.stderr | 17 +++++ src/test/ui/type/type-check-defaults.stderr | 4 +- 5 files changed, 105 insertions(+), 22 deletions(-) create mode 100644 src/test/ui/trait-impl-bound-suggestions.fixed create mode 100644 src/test/ui/trait-impl-bound-suggestions.rs create mode 100644 src/test/ui/trait-impl-bound-suggestions.stderr diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index bc51c8b6cd41..0416ef9e6438 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -202,33 +202,59 @@ pub fn suggest_constraining_type_param( // Suggestion: // fn foo(t: T) where T: Foo, T: Bar {... } // - insert: `, T: Zar` + // + // Additionally, there may be no `where` clause whatsoever in the case that this was + // reached becauase the generic parameter has a default: + // + // Message: + // trait Foo {... } + // - help: consider further restricting this type parameter with `where T: Zar` + // + // Suggestion: + // trait Foo where T: Zar {... } + // - insert: `where T: Zar` - let mut param_spans = Vec::new(); + if matches!(param.kind, hir::GenericParamKind::Type { default: Some(_), .. }) + && generics.where_clause.predicates.len() == 0 + { + // Suggest a bound, but there are no existing where clauses for this ``, so + // suggest adding one. + err.span_suggestion_verbose( + generics.where_clause.tail_span_for_suggestion(), + &msg_restrict_type_further, + format!(" where {}: {}", param_name, constraint), + Applicability::MachineApplicable, + ); + } else { + let mut param_spans = Vec::new(); - for predicate in generics.where_clause.predicates { - if let WherePredicate::BoundPredicate(WhereBoundPredicate { - span, bounded_ty, .. - }) = predicate - { - if let TyKind::Path(QPath::Resolved(_, path)) = &bounded_ty.kind { - if let Some(segment) = path.segments.first() { - if segment.ident.to_string() == param_name { - param_spans.push(span); + for predicate in generics.where_clause.predicates { + if let WherePredicate::BoundPredicate(WhereBoundPredicate { + span, + bounded_ty, + .. + }) = predicate + { + if let TyKind::Path(QPath::Resolved(_, path)) = &bounded_ty.kind { + if let Some(segment) = path.segments.first() { + if segment.ident.to_string() == param_name { + param_spans.push(span); + } } } } } - } - match ¶m_spans[..] { - &[¶m_span] => suggest_restrict(param_span.shrink_to_hi()), - _ => { - err.span_suggestion_verbose( - generics.where_clause.tail_span_for_suggestion(), - &msg_restrict_type_further, - format!(", {}: {}", param_name, constraint), - Applicability::MachineApplicable, - ); + match ¶m_spans[..] { + &[¶m_span] => suggest_restrict(param_span.shrink_to_hi()), + _ => { + err.span_suggestion_verbose( + generics.where_clause.tail_span_for_suggestion(), + &msg_restrict_type_further, + format!(", {}: {}", param_name, constraint), + Applicability::MachineApplicable, + ); + } } } diff --git a/src/test/ui/trait-impl-bound-suggestions.fixed b/src/test/ui/trait-impl-bound-suggestions.fixed new file mode 100644 index 000000000000..db3a95f5c4f6 --- /dev/null +++ b/src/test/ui/trait-impl-bound-suggestions.fixed @@ -0,0 +1,20 @@ +// run-rustfix + +#[allow(unused)] +use std::fmt::Debug; +// Rustfix should add this, or use `std::fmt::Debug` instead. + +#[allow(dead_code)] +struct ConstrainedStruct { + x: X +} + +#[allow(dead_code)] +trait InsufficientlyConstrainedGeneric where X: Copy { + fn return_the_constrained_type(&self, x: X) -> ConstrainedStruct { + //~^ ERROR the trait bound `X: Copy` is not satisfied + ConstrainedStruct { x } + } +} + +pub fn main() { } diff --git a/src/test/ui/trait-impl-bound-suggestions.rs b/src/test/ui/trait-impl-bound-suggestions.rs new file mode 100644 index 000000000000..bf75175179ef --- /dev/null +++ b/src/test/ui/trait-impl-bound-suggestions.rs @@ -0,0 +1,20 @@ +// run-rustfix + +#[allow(unused)] +use std::fmt::Debug; +// Rustfix should add this, or use `std::fmt::Debug` instead. + +#[allow(dead_code)] +struct ConstrainedStruct { + x: X +} + +#[allow(dead_code)] +trait InsufficientlyConstrainedGeneric { + fn return_the_constrained_type(&self, x: X) -> ConstrainedStruct { + //~^ ERROR the trait bound `X: Copy` is not satisfied + ConstrainedStruct { x } + } +} + +pub fn main() { } diff --git a/src/test/ui/trait-impl-bound-suggestions.stderr b/src/test/ui/trait-impl-bound-suggestions.stderr new file mode 100644 index 000000000000..3a21e9c6b2ad --- /dev/null +++ b/src/test/ui/trait-impl-bound-suggestions.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `X: Copy` is not satisfied + --> $DIR/trait-impl-bound-suggestions.rs:14:52 + | +LL | struct ConstrainedStruct { + | ---- required by this bound in `ConstrainedStruct` +... +LL | fn return_the_constrained_type(&self, x: X) -> ConstrainedStruct { + | ^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `X` + | +help: consider further restricting type parameter `X` + | +LL | trait InsufficientlyConstrainedGeneric where X: Copy { + | ^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type/type-check-defaults.stderr b/src/test/ui/type/type-check-defaults.stderr index fa6f34224102..d8c7f595e62e 100644 --- a/src/test/ui/type/type-check-defaults.stderr +++ b/src/test/ui/type/type-check-defaults.stderr @@ -56,8 +56,8 @@ LL | trait Base: Super { } | help: consider further restricting type parameter `T` | -LL | trait Base: Super, T: Copy { } - | ^^^^^^^^^ +LL | trait Base: Super where T: Copy { } + | ^^^^^^^^^^^^^ error[E0277]: cannot add `u8` to `i32` --> $DIR/type-check-defaults.rs:24:66 From dd57275c3e4d52b443090d0d75a9a3443bc5ce5c Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Mon, 14 Sep 2020 09:45:02 +0200 Subject: [PATCH 05/18] shrink const infer error --- .../infer/error_reporting/need_type_info.rs | 15 ++++++++----- .../cannot-infer-const-args.full.stderr | 0 .../cannot-infer-const-args.min.stderr | 0 .../{ => infer}/cannot-infer-const-args.rs | 0 .../infer/method-chain.full.stderr | 11 ++++++++++ .../infer/method-chain.min.stderr | 11 ++++++++++ .../ui/const-generics/infer/method-chain.rs | 22 +++++++++++++++++++ .../{ => infer}/uninferred-consts.full.stderr | 4 ++-- .../{ => infer}/uninferred-consts.min.stderr | 4 ++-- .../{ => infer}/uninferred-consts.rs | 0 10 files changed, 57 insertions(+), 10 deletions(-) rename src/test/ui/const-generics/{ => infer}/cannot-infer-const-args.full.stderr (100%) rename src/test/ui/const-generics/{ => infer}/cannot-infer-const-args.min.stderr (100%) rename src/test/ui/const-generics/{ => infer}/cannot-infer-const-args.rs (100%) create mode 100644 src/test/ui/const-generics/infer/method-chain.full.stderr create mode 100644 src/test/ui/const-generics/infer/method-chain.min.stderr create mode 100644 src/test/ui/const-generics/infer/method-chain.rs rename src/test/ui/const-generics/{ => infer}/uninferred-consts.full.stderr (80%) rename src/test/ui/const-generics/{ => infer}/uninferred-consts.min.stderr (80%) rename src/test/ui/const-generics/{ => infer}/uninferred-consts.rs (100%) diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 4de84e5ba399..9be234a7bb8b 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -8,7 +8,7 @@ use rustc_hir::{Body, Expr, ExprKind, FnRetTy, HirId, Local, Pat}; use rustc_middle::hir::map::Map; use rustc_middle::ty::print::Print; use rustc_middle::ty::subst::{GenericArg, GenericArgKind}; -use rustc_middle::ty::{self, DefIdTree, Ty}; +use rustc_middle::ty::{self, DefIdTree, InferConst, Ty}; use rustc_span::source_map::DesugaringKind; use rustc_span::symbol::kw; use rustc_span::Span; @@ -569,12 +569,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { local_visitor.visit_expr(expr); } + let span = if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.val { + self.inner.borrow_mut().const_unification_table().probe_value(vid).origin.span + } else { + local_visitor.target_span + }; + let error_code = error_code.into(); - let mut err = self.tcx.sess.struct_span_err_with_code( - local_visitor.target_span, - "type annotations needed", - error_code, - ); + let mut err = + self.tcx.sess.struct_span_err_with_code(span, "type annotations needed", error_code); err.note("unable to infer the value of a const parameter"); diff --git a/src/test/ui/const-generics/cannot-infer-const-args.full.stderr b/src/test/ui/const-generics/infer/cannot-infer-const-args.full.stderr similarity index 100% rename from src/test/ui/const-generics/cannot-infer-const-args.full.stderr rename to src/test/ui/const-generics/infer/cannot-infer-const-args.full.stderr diff --git a/src/test/ui/const-generics/cannot-infer-const-args.min.stderr b/src/test/ui/const-generics/infer/cannot-infer-const-args.min.stderr similarity index 100% rename from src/test/ui/const-generics/cannot-infer-const-args.min.stderr rename to src/test/ui/const-generics/infer/cannot-infer-const-args.min.stderr diff --git a/src/test/ui/const-generics/cannot-infer-const-args.rs b/src/test/ui/const-generics/infer/cannot-infer-const-args.rs similarity index 100% rename from src/test/ui/const-generics/cannot-infer-const-args.rs rename to src/test/ui/const-generics/infer/cannot-infer-const-args.rs diff --git a/src/test/ui/const-generics/infer/method-chain.full.stderr b/src/test/ui/const-generics/infer/method-chain.full.stderr new file mode 100644 index 000000000000..06e4c2e7bc6b --- /dev/null +++ b/src/test/ui/const-generics/infer/method-chain.full.stderr @@ -0,0 +1,11 @@ +error[E0282]: type annotations needed + --> $DIR/method-chain.rs:21:33 + | +LL | Foo.bar().bar().bar().bar().baz(); + | ^^^ + | + = note: unable to infer the value of a const parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/const-generics/infer/method-chain.min.stderr b/src/test/ui/const-generics/infer/method-chain.min.stderr new file mode 100644 index 000000000000..06e4c2e7bc6b --- /dev/null +++ b/src/test/ui/const-generics/infer/method-chain.min.stderr @@ -0,0 +1,11 @@ +error[E0282]: type annotations needed + --> $DIR/method-chain.rs:21:33 + | +LL | Foo.bar().bar().bar().bar().baz(); + | ^^^ + | + = note: unable to infer the value of a const parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/const-generics/infer/method-chain.rs b/src/test/ui/const-generics/infer/method-chain.rs new file mode 100644 index 000000000000..b3184642f36b --- /dev/null +++ b/src/test/ui/const-generics/infer/method-chain.rs @@ -0,0 +1,22 @@ +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Foo; + +impl Foo { + fn bar(self) -> Foo { + Foo + } + + fn baz(self) -> Foo { + println!("baz: {}", N); + Foo + } +} + +fn main() { + Foo.bar().bar().bar().bar().baz(); //~ ERROR type annotations needed +} \ No newline at end of file diff --git a/src/test/ui/const-generics/uninferred-consts.full.stderr b/src/test/ui/const-generics/infer/uninferred-consts.full.stderr similarity index 80% rename from src/test/ui/const-generics/uninferred-consts.full.stderr rename to src/test/ui/const-generics/infer/uninferred-consts.full.stderr index 2c5af9e65f82..6af49ba64523 100644 --- a/src/test/ui/const-generics/uninferred-consts.full.stderr +++ b/src/test/ui/const-generics/infer/uninferred-consts.full.stderr @@ -1,8 +1,8 @@ error[E0282]: type annotations needed - --> $DIR/uninferred-consts.rs:14:5 + --> $DIR/uninferred-consts.rs:14:9 | LL | Foo.foo(); - | ^^^^^^^^^ + | ^^^ | = note: unable to infer the value of a const parameter diff --git a/src/test/ui/const-generics/uninferred-consts.min.stderr b/src/test/ui/const-generics/infer/uninferred-consts.min.stderr similarity index 80% rename from src/test/ui/const-generics/uninferred-consts.min.stderr rename to src/test/ui/const-generics/infer/uninferred-consts.min.stderr index 2c5af9e65f82..6af49ba64523 100644 --- a/src/test/ui/const-generics/uninferred-consts.min.stderr +++ b/src/test/ui/const-generics/infer/uninferred-consts.min.stderr @@ -1,8 +1,8 @@ error[E0282]: type annotations needed - --> $DIR/uninferred-consts.rs:14:5 + --> $DIR/uninferred-consts.rs:14:9 | LL | Foo.foo(); - | ^^^^^^^^^ + | ^^^ | = note: unable to infer the value of a const parameter diff --git a/src/test/ui/const-generics/uninferred-consts.rs b/src/test/ui/const-generics/infer/uninferred-consts.rs similarity index 100% rename from src/test/ui/const-generics/uninferred-consts.rs rename to src/test/ui/const-generics/infer/uninferred-consts.rs From 035f8791668406bc49fc315253835cbdec247549 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Mon, 14 Sep 2020 10:08:32 +0200 Subject: [PATCH 06/18] improve const infer err --- .../src/infer/error_reporting/need_type_info.rs | 14 ++++++++++++-- compiler/rustc_middle/src/infer/unify_key.rs | 1 + .../infer/cannot-infer-const-args.full.stderr | 2 +- .../infer/cannot-infer-const-args.min.stderr | 2 +- .../const-generics/infer/method-chain.full.stderr | 2 +- .../const-generics/infer/method-chain.min.stderr | 2 +- src/test/ui/const-generics/infer/method-chain.rs | 2 +- .../infer/uninferred-consts.full.stderr | 2 +- .../infer/uninferred-consts.min.stderr | 2 +- 9 files changed, 20 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 9be234a7bb8b..f87406c2ce46 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -6,6 +6,7 @@ use rustc_hir::def::{DefKind, Namespace}; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::{Body, Expr, ExprKind, FnRetTy, HirId, Local, Pat}; use rustc_middle::hir::map::Map; +use rustc_middle::infer::unify_key::ConstVariableOriginKind; use rustc_middle::ty::print::Print; use rustc_middle::ty::subst::{GenericArg, GenericArgKind}; use rustc_middle::ty::{self, DefIdTree, InferConst, Ty}; @@ -569,8 +570,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { local_visitor.visit_expr(expr); } + let mut param_name = None; let span = if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.val { - self.inner.borrow_mut().const_unification_table().probe_value(vid).origin.span + let origin = self.inner.borrow_mut().const_unification_table().probe_value(vid).origin; + if let ConstVariableOriginKind::ConstParameterDefinition(param) = origin.kind { + param_name = Some(param); + } + origin.span } else { local_visitor.target_span }; @@ -579,7 +585,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let mut err = self.tcx.sess.struct_span_err_with_code(span, "type annotations needed", error_code); - err.note("unable to infer the value of a const parameter"); + if let Some(param_name) = param_name { + err.note(&format!("cannot infer the value of the const parameter `{}`", param_name)); + } else { + err.note("unable to infer the value of a const parameter"); + } err } diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs index 2580ac6bebd8..a60a17befeff 100644 --- a/compiler/rustc_middle/src/infer/unify_key.rs +++ b/compiler/rustc_middle/src/infer/unify_key.rs @@ -124,6 +124,7 @@ pub struct ConstVariableOrigin { pub enum ConstVariableOriginKind { MiscVariable, ConstInference, + // FIXME(const_generics): Consider storing the `DefId` of the param here. ConstParameterDefinition(Symbol), SubstitutionPlaceholder, } diff --git a/src/test/ui/const-generics/infer/cannot-infer-const-args.full.stderr b/src/test/ui/const-generics/infer/cannot-infer-const-args.full.stderr index 053139787edf..84e75cc37641 100644 --- a/src/test/ui/const-generics/infer/cannot-infer-const-args.full.stderr +++ b/src/test/ui/const-generics/infer/cannot-infer-const-args.full.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed LL | foo(); | ^^^ | - = note: unable to infer the value of a const parameter + = note: cannot infer the value of the const parameter `X` error: aborting due to previous error diff --git a/src/test/ui/const-generics/infer/cannot-infer-const-args.min.stderr b/src/test/ui/const-generics/infer/cannot-infer-const-args.min.stderr index 053139787edf..84e75cc37641 100644 --- a/src/test/ui/const-generics/infer/cannot-infer-const-args.min.stderr +++ b/src/test/ui/const-generics/infer/cannot-infer-const-args.min.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed LL | foo(); | ^^^ | - = note: unable to infer the value of a const parameter + = note: cannot infer the value of the const parameter `X` error: aborting due to previous error diff --git a/src/test/ui/const-generics/infer/method-chain.full.stderr b/src/test/ui/const-generics/infer/method-chain.full.stderr index 06e4c2e7bc6b..e65bc3f10968 100644 --- a/src/test/ui/const-generics/infer/method-chain.full.stderr +++ b/src/test/ui/const-generics/infer/method-chain.full.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed LL | Foo.bar().bar().bar().bar().baz(); | ^^^ | - = note: unable to infer the value of a const parameter + = note: cannot infer the value of the const parameter `N` error: aborting due to previous error diff --git a/src/test/ui/const-generics/infer/method-chain.min.stderr b/src/test/ui/const-generics/infer/method-chain.min.stderr index 06e4c2e7bc6b..e65bc3f10968 100644 --- a/src/test/ui/const-generics/infer/method-chain.min.stderr +++ b/src/test/ui/const-generics/infer/method-chain.min.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed LL | Foo.bar().bar().bar().bar().baz(); | ^^^ | - = note: unable to infer the value of a const parameter + = note: cannot infer the value of the const parameter `N` error: aborting due to previous error diff --git a/src/test/ui/const-generics/infer/method-chain.rs b/src/test/ui/const-generics/infer/method-chain.rs index b3184642f36b..9389ca20d106 100644 --- a/src/test/ui/const-generics/infer/method-chain.rs +++ b/src/test/ui/const-generics/infer/method-chain.rs @@ -19,4 +19,4 @@ impl Foo { fn main() { Foo.bar().bar().bar().bar().baz(); //~ ERROR type annotations needed -} \ No newline at end of file +} diff --git a/src/test/ui/const-generics/infer/uninferred-consts.full.stderr b/src/test/ui/const-generics/infer/uninferred-consts.full.stderr index 6af49ba64523..e47b6bd5dc69 100644 --- a/src/test/ui/const-generics/infer/uninferred-consts.full.stderr +++ b/src/test/ui/const-generics/infer/uninferred-consts.full.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed LL | Foo.foo(); | ^^^ | - = note: unable to infer the value of a const parameter + = note: cannot infer the value of the const parameter `N` error: aborting due to previous error diff --git a/src/test/ui/const-generics/infer/uninferred-consts.min.stderr b/src/test/ui/const-generics/infer/uninferred-consts.min.stderr index 6af49ba64523..e47b6bd5dc69 100644 --- a/src/test/ui/const-generics/infer/uninferred-consts.min.stderr +++ b/src/test/ui/const-generics/infer/uninferred-consts.min.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed LL | Foo.foo(); | ^^^ | - = note: unable to infer the value of a const parameter + = note: cannot infer the value of the const parameter `N` error: aborting due to previous error From b88155160cf4abc07a5b8da98385ac343a5eeca0 Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Mon, 14 Sep 2020 21:08:08 +0800 Subject: [PATCH 07/18] Simplify iter flatten struct doc --- library/core/src/iter/adapters/flatten.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index 4202e52448dc..4b19c451a993 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -7,8 +7,8 @@ use super::Map; /// An iterator that maps each element to an iterator, and yields the elements /// of the produced iterators. /// -/// This `struct` is created by the [`flat_map`] method on [`Iterator`]. See its -/// documentation for more. +/// This `struct` is created by [`Iterator::flat_map`]. See its documentation +/// for more. /// /// [`flat_map`]: trait.Iterator.html#method.flat_map /// [`Iterator`]: trait.Iterator.html From 43709f7111b37a473dc779b12c755ed4df5beaf5 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 14 Sep 2020 16:11:06 +0200 Subject: [PATCH 08/18] :arrow_up: rust-analyzer --- src/tools/rust-analyzer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer index 0275b08d1521..0d03fe6ef57d 160000 --- a/src/tools/rust-analyzer +++ b/src/tools/rust-analyzer @@ -1 +1 @@ -Subproject commit 0275b08d1521606fa733f76fe5d5707717456fb4 +Subproject commit 0d03fe6ef57d3956e92382e0e1f1a916015191cb From 5112f879ff3c106dadc9d5699f471b06473cf7e0 Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Tue, 15 Sep 2020 00:35:48 +0800 Subject: [PATCH 09/18] Remove flatten doc intra-doc links --- library/core/src/iter/adapters/flatten.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index 4b19c451a993..ddb1aaebc1f3 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -9,9 +9,6 @@ use super::Map; /// /// This `struct` is created by [`Iterator::flat_map`]. See its documentation /// for more. -/// -/// [`flat_map`]: trait.Iterator.html#method.flat_map -/// [`Iterator`]: trait.Iterator.html #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] pub struct FlatMap { From 1f26a189551ea037e769d27c433b4eaf8c3091b2 Mon Sep 17 00:00:00 2001 From: Camelid <37223377+camelid@users.noreply.github.com> Date: Mon, 14 Sep 2020 10:32:42 -0700 Subject: [PATCH 10/18] Use intra-doc links for `DelaySpanBugEmitted` Also improve the docs for it a bit. --- compiler/rustc_middle/src/ty/context.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index aacf61e5b425..56746666e2f1 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -66,8 +66,8 @@ use std::mem; use std::ops::{Bound, Deref}; use std::sync::Arc; -/// A type that is not publicly constructable. This prevents people from making `TyKind::Error` -/// except through `tcx.err*()`, which are in this module. +/// A type that is not publicly constructable. This prevents people from making [`TyKind::Error`]s +/// except through the error-reporting functions on a [`tcx`][TyCtxt]. #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] #[derive(TyEncodable, TyDecodable, HashStable)] pub struct DelaySpanBugEmitted(()); From 15349ef5fad7778c872ce0f7d887e581819183f4 Mon Sep 17 00:00:00 2001 From: Camelid <37223377+camelid@users.noreply.github.com> Date: Mon, 14 Sep 2020 10:39:07 -0700 Subject: [PATCH 11/18] Minor improvements to `mir::Constant` docs --- compiler/rustc_middle/src/mir/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index d32a7a4062e2..29daf7e9309a 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2285,8 +2285,8 @@ impl<'tcx> Debug for Rvalue<'tcx> { /// Constants /// /// Two constants are equal if they are the same constant. Note that -/// this does not necessarily mean that they are "==" in Rust -- in -/// particular one must be wary of `NaN`! +/// this does not necessarily mean that they are `==` in Rust -- in +/// particular, one must be wary of `NaN`! #[derive(Clone, Copy, PartialEq, TyEncodable, TyDecodable, HashStable)] pub struct Constant<'tcx> { From 5c1043a7507245098d9ba1a90e034487654dd961 Mon Sep 17 00:00:00 2001 From: Camelid <37223377+camelid@users.noreply.github.com> Date: Mon, 14 Sep 2020 10:42:06 -0700 Subject: [PATCH 12/18] Fix diagram for `DebruijnIndex` --- compiler/rustc_middle/src/ty/sty.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 9f5fc5a2d3fb..1f6c0121ae2e 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1233,13 +1233,13 @@ rustc_index::newtype_index! { /// particular, imagine a type like this: /// /// for<'a> fn(for<'b> fn(&'b isize, &'a isize), &'a char) - /// ^ ^ | | | - /// | | | | | - /// | +------------+ 0 | | - /// | | | - /// +--------------------------------+ 1 | - /// | | - /// +------------------------------------------+ 0 + /// ^ ^ | | | + /// | | | | | + /// | +------------+ 0 | | + /// | | | + /// +----------------------------------+ 1 | + /// | | + /// +----------------------------------------------+ 0 /// /// In this type, there are two binders (the outer fn and the inner /// fn). We need to be able to determine, for any given region, which From e1607c87f0bb96c1c59d84a2789b7f7d2b69e182 Mon Sep 17 00:00:00 2001 From: iximeow Date: Mon, 14 Sep 2020 13:13:02 -0700 Subject: [PATCH 13/18] clean up comment text a bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Esteban Küber --- compiler/rustc_middle/src/ty/diagnostics.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 0416ef9e6438..715319747e39 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -204,7 +204,7 @@ pub fn suggest_constraining_type_param( // - insert: `, T: Zar` // // Additionally, there may be no `where` clause whatsoever in the case that this was - // reached becauase the generic parameter has a default: + // reached because the generic parameter has a default: // // Message: // trait Foo {... } @@ -217,8 +217,8 @@ pub fn suggest_constraining_type_param( if matches!(param.kind, hir::GenericParamKind::Type { default: Some(_), .. }) && generics.where_clause.predicates.len() == 0 { - // Suggest a bound, but there are no existing where clauses for this ``, so - // suggest adding one. + // Suggest a bound, but there is no existing `where` clause *and* the type param has a + // default (``), so we suggest adding `where T: Bar`. err.span_suggestion_verbose( generics.where_clause.tail_span_for_suggestion(), &msg_restrict_type_further, From 32efcfca2fece73a69efcedd1c78f45b0bbcb39c Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 14 Sep 2020 14:42:37 -0700 Subject: [PATCH 14/18] Include non-JSON output in error display for lint-doc failure. Some errors, like if rustc is broken, or dylib search path is wrong, will only display non-JSON errors. Show those, too, to make it easier to debug a problem. --- src/tools/lint-docs/src/lib.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs index 5323bc357c09..92b3d186fa14 100644 --- a/src/tools/lint-docs/src/lib.rs +++ b/src/tools/lint-docs/src/lib.rs @@ -402,9 +402,12 @@ fn generate_lint_output( None => { let rendered: Vec<&str> = msgs.iter().filter_map(|msg| msg["rendered"].as_str()).collect(); + let non_json: Vec<&str> = + stderr.lines().filter(|line| !line.starts_with('{')).collect(); Err(format!( - "did not find lint `{}` in output of example, got:\n{}", + "did not find lint `{}` in output of example, got:\n{}\n{}", name, + non_json.join("\n"), rendered.join("\n") ) .into()) From 9dad90814543bdd10b1989020edad70939b0e869 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 14 Sep 2020 14:42:56 -0700 Subject: [PATCH 15/18] Fix generating rustc docs with non-default lib directory. --- src/bootstrap/builder.rs | 8 ++++++-- src/bootstrap/doc.rs | 4 ++++ src/bootstrap/test.rs | 8 ++++---- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 0f18660c0e10..53560c9deb6c 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -710,7 +710,7 @@ impl<'a> Builder<'a> { /// Adds the compiler's directory of dynamic libraries to `cmd`'s dynamic /// library lookup path. - pub fn add_rustc_lib_path(&self, compiler: Compiler, cmd: &mut Cargo) { + pub fn add_rustc_lib_path(&self, compiler: Compiler, cmd: &mut Command) { // Windows doesn't need dylib path munging because the dlls for the // compiler live next to the compiler and the system will find them // automatically. @@ -718,7 +718,7 @@ impl<'a> Builder<'a> { return; } - add_dylib_path(vec![self.rustc_libdir(compiler)], &mut cmd.command); + add_dylib_path(vec![self.rustc_libdir(compiler)], cmd); } /// Gets a path to the compiler specified. @@ -1515,6 +1515,10 @@ impl Cargo { self.command.env(key.as_ref(), value.as_ref()); self } + + pub fn add_rustc_lib_path(&mut self, builder: &Builder<'_>, compiler: Compiler) { + builder.add_rustc_lib_path(compiler, &mut self.command); + } } impl From for Command { diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 98a0119e4df1..f90e76a4f4ea 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -766,6 +766,10 @@ impl Step for RustcBook { if builder.config.verbose() { cmd.arg("--verbose"); } + // If the lib directories are in an unusual location (changed in + // config.toml), then this needs to explicitly update the dylib search + // path. + builder.add_rustc_lib_path(self.compiler, &mut cmd); builder.run(&mut cmd); // Run rustbook/mdbook to generate the HTML pages. builder.ensure(RustbookSrc { diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 045dda2d4cb4..ba5f75c49ac7 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -270,7 +270,7 @@ impl Step for Rls { &[], ); - builder.add_rustc_lib_path(compiler, &mut cargo); + cargo.add_rustc_lib_path(builder, compiler); cargo.arg("--").args(builder.config.cmd.test_args()); if try_run(builder, &mut cargo.into()) { @@ -328,7 +328,7 @@ impl Step for Rustfmt { t!(fs::create_dir_all(&dir)); cargo.env("RUSTFMT_TEST_DIR", dir); - builder.add_rustc_lib_path(compiler, &mut cargo); + cargo.add_rustc_lib_path(builder, compiler); if try_run(builder, &mut cargo.into()) { builder.save_toolstate("rustfmt", ToolState::TestPass); @@ -449,7 +449,7 @@ impl Step for Miri { cargo.arg("--").args(builder.config.cmd.test_args()); - builder.add_rustc_lib_path(compiler, &mut cargo); + cargo.add_rustc_lib_path(builder, compiler); if !try_run(builder, &mut cargo.into()) { return; @@ -554,7 +554,7 @@ impl Step for Clippy { cargo.arg("--").args(builder.config.cmd.test_args()); - builder.add_rustc_lib_path(compiler, &mut cargo); + cargo.add_rustc_lib_path(builder, compiler); builder.run(&mut cargo.into()); } From e82be710e47a38dc303ae8f2df02d9a8c682b1b6 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Mon, 14 Sep 2020 04:59:55 +0000 Subject: [PATCH 16/18] document how to use memory addresses as operands Co-authored-by: Amanieu --- .../unstable-book/src/library-features/asm.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md index 28a5fe31fc4b..df113f0f1613 100644 --- a/src/doc/unstable-book/src/library-features/asm.md +++ b/src/doc/unstable-book/src/library-features/asm.md @@ -345,6 +345,25 @@ The `h` modifier will emit the register name for the high byte of that register If you use a smaller data type (e.g. `u16`) with an operand and forget the use template modifiers, the compiler will emit a warning and suggest the correct modifier to use. +## Memory address operands + +Sometimes assembly instructions require operands passed via memory addresses/memory locations. +You have to manually use the memory address syntax specified by the respectively architectures. +For example, in x86/x86_64 and intel assembly syntax, you should wrap inputs/outputs in `[]` +to indicate they are memory operands: + +```rust,allow_fail +# #![feature(asm, llvm_asm)] +# fn load_fpu_control_word(control: u16) { +unsafe { + asm!("fldcw [{}]", in(reg) &control, options(nostack)); + + // Previously this would have been written with the deprecated `llvm_asm!` like this + llvm_asm!("fldcw $0" :: "m" (control) :: "volatile"); +} +# } +``` + ## Options By default, an inline assembly block is treated the same way as an external FFI function call with a custom calling convention: it may read/write memory, have observable side effects, etc. However in many cases, it is desirable to give the compiler more information about what the assembly code is actually doing so that it can optimize better. From 87666e5bce23c8ef420dfb0e5d86668ddf1acbf2 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Wed, 16 Sep 2020 04:46:23 +0000 Subject: [PATCH 17/18] Prefer asm! over llvm_asm! in core --- library/core/src/hint.rs | 5 +++-- library/core/src/num/dec2flt/algorithm.rs | 20 +++++++++++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index d40a38028676..929c22e4538f 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -111,7 +111,7 @@ pub fn spin_loop() { #[inline] #[unstable(feature = "test", issue = "50297")] #[allow(unreachable_code)] // this makes #[cfg] a bit easier below. -pub fn black_box(dummy: T) -> T { +pub fn black_box(mut dummy: T) -> T { // We need to "use" the argument in some way LLVM can't introspect, and on // targets that support it we can typically leverage inline assembly to do // this. LLVM's interpretation of inline assembly is that it's, well, a black @@ -121,7 +121,8 @@ pub fn black_box(dummy: T) -> T { #[cfg(not(miri))] // This is just a hint, so it is fine to skip in Miri. // SAFETY: the inline assembly is a no-op. unsafe { - llvm_asm!("" : : "r"(&dummy)); + // FIXME: Cannot use `asm!` because it doesn't support MIPS and other architectures. + llvm_asm!("" : : "r"(&mut dummy)); } dummy diff --git a/library/core/src/num/dec2flt/algorithm.rs b/library/core/src/num/dec2flt/algorithm.rs index aaeb4d8a22c2..a5fbdc6ee2d4 100644 --- a/library/core/src/num/dec2flt/algorithm.rs +++ b/library/core/src/num/dec2flt/algorithm.rs @@ -60,12 +60,19 @@ mod fpu_precision { fn set_cw(cw: u16) { // SAFETY: the `fldcw` instruction has been audited to be able to work correctly with // any `u16` - unsafe { llvm_asm!("fldcw $0" :: "m" (cw) :: "volatile") } + unsafe { + asm!( + "fldcw ({})", + in(reg) &cw, + // FIXME: We are using ATT syntax to support LLVM 8 and LLVM 9. + options(att_syntax, nostack), + ) + } } /// Sets the precision field of the FPU to `T` and returns a `FPUControlWord`. pub fn set_precision() -> FPUControlWord { - let cw = 0u16; + let mut cw = 0_u16; // Compute the value for the Precision Control field that is appropriate for `T`. let cw_precision = match size_of::() { @@ -78,7 +85,14 @@ mod fpu_precision { // `FPUControlWord` structure is dropped // SAFETY: the `fnstcw` instruction has been audited to be able to work correctly with // any `u16` - unsafe { llvm_asm!("fnstcw $0" : "=*m" (&cw) ::: "volatile") } + unsafe { + asm!( + "fnstcw ({})", + in(reg) &mut cw, + // FIXME: We are using ATT syntax to support LLVM 8 and LLVM 9. + options(att_syntax, nostack), + ) + } // Set the control word to the desired precision. This is achieved by masking away the old // precision (bits 8 and 9, 0x300) and replacing it with the precision flag computed above. From 4dc4e9f671a36026cf59894622fdf4f6b979bf76 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Wed, 16 Sep 2020 09:25:54 +0000 Subject: [PATCH 18/18] Fix black_box bug detected by Amanieu Co-authored-by: Amanieu --- library/core/src/hint.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 929c22e4538f..1192b9e164a1 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -122,7 +122,7 @@ pub fn black_box(mut dummy: T) -> T { // SAFETY: the inline assembly is a no-op. unsafe { // FIXME: Cannot use `asm!` because it doesn't support MIPS and other architectures. - llvm_asm!("" : : "r"(&mut dummy)); + llvm_asm!("" : : "r"(&mut dummy) : "memory" : "volatile"); } dummy