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 4de84e5ba399c..f87406c2ce469 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,9 +6,10 @@ 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, 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,14 +570,26 @@ 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 { + 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 + }; + 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"); + 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 2580ac6bebd86..a60a17befeffd 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/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index d32a7a4062e27..29daf7e9309aa 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> { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index aacf61e5b425a..56746666e2f1f 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(()); diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index bc51c8b6cd41c..715319747e390 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 because 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 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, + 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/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 825221c22a8c1..d4c8ba082751e 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 diff --git a/compiler/rustc_mir/src/monomorphize/partitioning/default.rs b/compiler/rustc_mir/src/monomorphize/partitioning/default.rs index b48bae8378779..827d037f31988 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 d92f1367e7d67..5107e6972632c 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 @@ -84,7 +83,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 0f6f078d9686f..b60beca688068 100644 --- a/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs +++ b/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs @@ -108,31 +108,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>, ); } @@ -157,12 +161,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)); @@ -172,7 +177,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()); } @@ -182,7 +187,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)); @@ -193,7 +198,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. diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index d40a380286762..1192b9e164a14 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) : "memory" : "volatile"); } dummy diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index 4202e52448dcf..ddb1aaebc1f3e 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -7,11 +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. -/// -/// [`flat_map`]: trait.Iterator.html#method.flat_map -/// [`Iterator`]: trait.Iterator.html +/// This `struct` is created by [`Iterator::flat_map`]. See its documentation +/// for more. #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] pub struct FlatMap { diff --git a/library/core/src/num/dec2flt/algorithm.rs b/library/core/src/num/dec2flt/algorithm.rs index aaeb4d8a22c29..a5fbdc6ee2d48 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. diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 34756af21e4fc..140507eab66e6 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -683,7 +683,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. @@ -691,7 +691,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. @@ -1488,6 +1488,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 98a0119e4df12..f90e76a4f4ea6 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 045dda2d4cb4c..ba5f75c49ac77 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()); } 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 38fea2a8094b9..0000000000000 --- 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 b623e53583b5e..0000000000000 --- 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 a678d353d52f5..0000000000000 --- 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 diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md index 28a5fe31fc4b5..df113f0f1613c 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. 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 da01d9228f14e..a2f029db29165 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)] 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 78% 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 index 053139787edf9..84e75cc376416 100644 --- 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 @@ -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/cannot-infer-const-args.min.stderr b/src/test/ui/const-generics/infer/cannot-infer-const-args.min.stderr similarity index 78% 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 index 053139787edf9..84e75cc376416 100644 --- 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 @@ -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/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 0000000000000..e65bc3f109681 --- /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: cannot infer the value of the const parameter `N` + +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 0000000000000..e65bc3f109681 --- /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: cannot infer the value of the const parameter `N` + +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 0000000000000..9389ca20d106f --- /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 +} 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 60% rename from src/test/ui/const-generics/uninferred-consts.full.stderr rename to src/test/ui/const-generics/infer/uninferred-consts.full.stderr index 2c5af9e65f827..e47b6bd5dc691 100644 --- a/src/test/ui/const-generics/uninferred-consts.full.stderr +++ b/src/test/ui/const-generics/infer/uninferred-consts.full.stderr @@ -1,10 +1,10 @@ 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 + = note: cannot infer the value of the const parameter `N` error: aborting due to previous error 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 60% rename from src/test/ui/const-generics/uninferred-consts.min.stderr rename to src/test/ui/const-generics/infer/uninferred-consts.min.stderr index 2c5af9e65f827..e47b6bd5dc691 100644 --- a/src/test/ui/const-generics/uninferred-consts.min.stderr +++ b/src/test/ui/const-generics/infer/uninferred-consts.min.stderr @@ -1,10 +1,10 @@ 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 + = note: cannot infer the value of the const parameter `N` error: aborting due to previous error 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 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 0000000000000..db3a95f5c4f61 --- /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 0000000000000..bf75175179efd --- /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 0000000000000..3a21e9c6b2ad4 --- /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 fa6f342241025..d8c7f595e62ef 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 diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs index 5323bc357c09d..92b3d186fa141 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()) diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer index 0275b08d15216..0d03fe6ef57d3 160000 --- a/src/tools/rust-analyzer +++ b/src/tools/rust-analyzer @@ -1 +1 @@ -Subproject commit 0275b08d1521606fa733f76fe5d5707717456fb4 +Subproject commit 0d03fe6ef57d3956e92382e0e1f1a916015191cb