diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index c53549ab85d6d..571f35a2031d2 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -19,7 +19,6 @@ use core::cmp::Ordering; use core::fmt; -use core::isize; use core::iter::{repeat, FromIterator, FusedIterator}; use core::mem; use core::ops::Bound::{Excluded, Included, Unbounded}; @@ -203,33 +202,6 @@ impl VecDeque { len); } - /// Copies all values from `src` to the back of `self`, wrapping around if needed. - /// - /// # Safety - /// - /// The capacity must be sufficient to hold self.len() + src.len() elements. - /// If so, this function never panics. - #[inline] - unsafe fn copy_slice(&mut self, src: &[T]) { - /// This is guaranteed by `RawVec`. - debug_assert!(self.capacity() <= isize::MAX as usize); - - let expected_new_len = self.len() + src.len(); - debug_assert!(self.capacity() >= expected_new_len); - - let dst_high_ptr = self.ptr().add(self.head); - let dst_high_len = self.cap() - self.head; - - let split = cmp::min(src.len(), dst_high_len); - let (src_high, src_low) = src.split_at(split); - - ptr::copy_nonoverlapping(src_high.as_ptr(), dst_high_ptr, src_high.len()); - ptr::copy_nonoverlapping(src_low.as_ptr(), self.ptr(), src_low.len()); - - self.head = self.wrap_add(self.head, src.len()); - debug_assert!(self.len() == expected_new_len); - } - /// Copies a potentially wrapping block of memory len long from src to dest. /// (abs(dst - src) + len) must be no larger than cap() (There must be at /// most one continuous overlapping region between src and dest). @@ -1052,7 +1024,7 @@ impl VecDeque { iter: Iter { tail: drain_tail, head: drain_head, - ring: unsafe { self.buffer_as_slice() }, + ring: unsafe { self.buffer_as_mut_slice() }, }, } } @@ -1862,22 +1834,8 @@ impl VecDeque { #[inline] #[stable(feature = "append", since = "1.4.0")] pub fn append(&mut self, other: &mut Self) { - unsafe { - // Guarantees there is space in `self` for `other`. - self.reserve(other.len()); - - { - let (src_high, src_low) = other.as_slices(); - - // This is only safe because copy_slice never panics when capacity is sufficient. - self.copy_slice(src_low); - self.copy_slice(src_high); - } - - // Some values now exist in both `other` and `self` but are made inaccessible - // in`other`. - other.tail = other.head; - } + // naive impl + self.extend(other.drain(..)); } /// Retains only the elements specified by the predicate. @@ -2635,8 +2593,8 @@ impl From> for Vec { let mut right_offset = 0; for i in left_edge..right_edge { right_offset = (i - left_edge) % (cap - right_edge); - let src = right_edge + right_offset; - ptr::swap(buf.add(i), buf.add(src)); + let src: isize = (right_edge + right_offset) as isize; + ptr::swap(buf.add(i), buf.offset(src)); } let n_ops = right_edge - left_edge; left_edge += n_ops; diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index c8b7f3aa97b7e..7309358091056 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -4132,16 +4132,16 @@ impl<'a> LoweringContext<'a> { // expand let head = self.lower_expr(head); let head_sp = head.span; + let desugared_span = self.allow_internal_unstable( + CompilerDesugaringKind::ForLoop, + head_sp, + ); let iter = self.str_to_ident("iter"); let next_ident = self.str_to_ident("__next"); - let next_sp = self.allow_internal_unstable( - CompilerDesugaringKind::ForLoop, - head_sp, - ); let next_pat = self.pat_ident_binding_mode( - next_sp, + desugared_span, next_ident, hir::BindingAnnotation::Mutable, ); @@ -4170,8 +4170,11 @@ impl<'a> LoweringContext<'a> { }; // `mut iter` - let iter_pat = - self.pat_ident_binding_mode(head_sp, iter, hir::BindingAnnotation::Mutable); + let iter_pat = self.pat_ident_binding_mode( + desugared_span, + iter, + hir::BindingAnnotation::Mutable + ); // `match ::std::iter::Iterator::next(&mut iter) { ... }` let match_expr = { @@ -4200,8 +4203,12 @@ impl<'a> LoweringContext<'a> { let next_expr = P(self.expr_ident(head_sp, next_ident, next_pat.id)); // `let mut __next` - let next_let = - self.stmt_let_pat(head_sp, None, next_pat, hir::LocalSource::ForLoopDesugar); + let next_let = self.stmt_let_pat( + desugared_span, + None, + next_pat, + hir::LocalSource::ForLoopDesugar, + ); // `let = __next` let pat = self.lower_pat(pat); diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 3b3e38a8bb7ca..da2173fead370 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -46,7 +46,7 @@ use ty::subst::Subst; use ty::SubtypePredicate; use util::nodemap::{FxHashMap, FxHashSet}; -use syntax_pos::{DUMMY_SP, Span}; +use syntax_pos::{DUMMY_SP, Span, ExpnInfo, ExpnFormat}; impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub fn report_fulfillment_errors(&self, @@ -68,18 +68,30 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { }).collect(); for (index, error) in errors.iter().enumerate() { - error_map.entry(error.obligation.cause.span).or_default().push( + // We want to ignore desugarings here: spans are equivalent even + // if one is the result of a desugaring and the other is not. + let mut span = error.obligation.cause.span; + if let Some(ExpnInfo { + format: ExpnFormat::CompilerDesugaring(_), + def_site: Some(def_span), + .. + }) = span.ctxt().outer().expn_info() { + span = def_span; + } + + error_map.entry(span).or_default().push( ErrorDescriptor { predicate: error.obligation.predicate.clone(), index: Some(index) - }); + } + ); self.reported_trait_errors.borrow_mut() - .entry(error.obligation.cause.span).or_default() + .entry(span).or_default() .push(error.obligation.predicate.clone()); } - // We do this in 2 passes because we want to display errors in order, tho + // We do this in 2 passes because we want to display errors in order, though // maybe it *is* better to sort errors by span or something. let mut is_suppressed = vec![false; errors.len()]; for (_, error_set) in error_map.iter() { diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs index ae87d30ec9427..8738f57414823 100644 --- a/src/librustc/ty/codec.rs +++ b/src/librustc/ty/codec.rs @@ -178,19 +178,19 @@ pub fn decode_predicates<'a, 'tcx, D>(decoder: &mut D) Ok(ty::GenericPredicates { parent: Decodable::decode(decoder)?, predicates: (0..decoder.read_usize()?).map(|_| { - // Handle shorthands first, if we have an usize > 0x80. - let predicate = if decoder.positioned_at_shorthand() { - let pos = decoder.read_usize()?; - assert!(pos >= SHORTHAND_OFFSET); - let shorthand = pos - SHORTHAND_OFFSET; - - decoder.with_position(shorthand, ty::Predicate::decode) - } else { - ty::Predicate::decode(decoder) - }?; - Ok((predicate, Decodable::decode(decoder)?)) - }) - .collect::, _>>()?, + // Handle shorthands first, if we have an usize > 0x80. + let predicate = if decoder.positioned_at_shorthand() { + let pos = decoder.read_usize()?; + assert!(pos >= SHORTHAND_OFFSET); + let shorthand = pos - SHORTHAND_OFFSET; + + decoder.with_position(shorthand, ty::Predicate::decode) + } else { + ty::Predicate::decode(decoder) + }?; + Ok((predicate, Decodable::decode(decoder)?)) + }) + .collect::, _>>()?, }) } @@ -267,7 +267,7 @@ pub fn decode_const<'a, 'tcx, D>(decoder: &mut D) #[inline] pub fn decode_allocation<'a, 'tcx, D>(decoder: &mut D) - -> Result<&'tcx Allocation, D::Error> + -> Result<&'tcx Allocation, D::Error> where D: TyDecoder<'a, 'tcx>, 'tcx: 'a, { diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 05b68b34989bf..46ba5f5ef362d 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -190,8 +190,8 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> { // types/regions in the global interner if local as *const _ as usize == global as *const _ as usize { bug!("Attempted to intern `{:?}` which contains \ - inference types/regions in the global type context", - &ty_struct); + inference types/regions in the global type context", + &ty_struct); } // Don't be &mut TyS. @@ -272,9 +272,9 @@ fn validate_hir_id_for_typeck_tables(local_id_root: Option, bug!("node {} with HirId::owner {:?} cannot be placed in \ TypeckTables with local_id_root {:?}", - tcx.hir.node_to_string(node_id), - DefId::local(hir_id.owner), - local_id_root) + tcx.hir.node_to_string(node_id), + DefId::local(hir_id.owner), + local_id_root) }); } } else { @@ -540,16 +540,13 @@ impl<'tcx> TypeckTables<'tcx> { } pub fn node_id_to_type(&self, id: hir::HirId) -> Ty<'tcx> { - match self.node_id_to_type_opt(id) { - Some(ty) => ty, - None => { - bug!("node_id_to_type: no type for node `{}`", - tls::with(|tcx| { - let id = tcx.hir.hir_to_node_id(id); - tcx.hir.node_to_string(id) - })) - } - } + self.node_id_to_type_opt(id).unwrap_or_else(|| + bug!("node_id_to_type: no type for node `{}`", + tls::with(|tcx| { + let id = tcx.hir.hir_to_node_id(id); + tcx.hir.node_to_string(id) + })) + ) } pub fn node_id_to_type_opt(&self, id: hir::HirId) -> Option> { @@ -686,7 +683,7 @@ impl<'tcx> TypeckTables<'tcx> { } pub fn pat_adjustments_mut(&mut self) - -> LocalTableInContextMut<'_, Vec>> { + -> LocalTableInContextMut<'_, Vec>> { LocalTableInContextMut { local_id_root: self.local_id_root, data: &mut self.pat_adjustments, @@ -1199,8 +1196,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let hir_id = hir.node_to_hir_id(k); let map = trait_map.entry(hir_id.owner).or_default(); Lrc::get_mut(map).unwrap() - .insert(hir_id.local_id, - Lrc::new(StableVec::new(v))); + .insert(hir_id.local_id, + Lrc::new(StableVec::new(v))); } let gcx = &GlobalCtxt { @@ -2188,7 +2185,6 @@ macro_rules! sty_debug_print { }; $(let mut $variant = total;)* - for &Interned(t) in tcx.interners.type_.borrow().iter() { let variant = match t.sty { ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) | @@ -2207,7 +2203,7 @@ macro_rules! sty_debug_print { } println!("Ty interner total ty region both"); $(println!(" {:18}: {uses:6} {usespc:4.1}%, \ -{ty:4.1}% {region:5.1}% {both:4.1}%", + {ty:4.1}% {region:5.1}% {both:4.1}%", stringify!($variant), uses = $variant.total, usespc = $variant.total as f64 * 100.0 / total.total as f64, @@ -2216,7 +2212,7 @@ macro_rules! sty_debug_print { both = $variant.both_infer as f64 * 100.0 / total.total as f64); )* println!(" total {uses:6} \ -{ty:4.1}% {region:5.1}% {both:4.1}%", + {ty:4.1}% {region:5.1}% {both:4.1}%", uses = total.total, ty = total.ty_infer as f64 * 100.0 / total.total as f64, region = total.region_infer as f64 * 100.0 / total.total as f64, @@ -2653,7 +2649,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn mk_closure(self, closure_id: DefId, closure_substs: ClosureSubsts<'tcx>) - -> Ty<'tcx> { + -> Ty<'tcx> { self.mk_ty(Closure(closure_id, closure_substs)) } @@ -2686,8 +2682,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn mk_ty_param(self, - index: u32, - name: InternedString) -> Ty<'tcx> { + index: u32, + name: InternedString) -> Ty<'tcx> { self.mk_ty(Param(ParamTy { idx: index, name: name })) } diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index a1edf67e47552..3123f0fbe31de 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -10,6 +10,7 @@ use hir::def_id::DefId; use ty::{self, BoundRegion, Region, Ty, TyCtxt}; +use std::borrow::Cow; use std::fmt; use rustc_target::spec::abi; use syntax::ast; @@ -71,7 +72,7 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use self::TypeError::*; fn report_maybe_different(f: &mut fmt::Formatter<'_>, - expected: String, found: String) -> fmt::Result { + expected: &str, found: &str) -> fmt::Result { // A naive approach to making sure that we're not reporting silly errors such as: // (expected closure, found closure). if expected == found { @@ -126,15 +127,15 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { br) } Sorts(values) => ty::tls::with(|tcx| { - report_maybe_different(f, values.expected.sort_string(tcx), - values.found.sort_string(tcx)) + report_maybe_different(f, &values.expected.sort_string(tcx), + &values.found.sort_string(tcx)) }), Traits(values) => ty::tls::with(|tcx| { report_maybe_different(f, - format!("trait `{}`", - tcx.item_path_str(values.expected)), - format!("trait `{}`", - tcx.item_path_str(values.found))) + &format!("trait `{}`", + tcx.item_path_str(values.expected)), + &format!("trait `{}`", + tcx.item_path_str(values.found))) }), IntMismatch(ref values) => { write!(f, "expected `{:?}`, found `{:?}`", @@ -162,8 +163,8 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { values.found) }, ExistentialMismatch(ref values) => { - report_maybe_different(f, format!("trait `{}`", values.expected), - format!("trait `{}`", values.found)) + report_maybe_different(f, &format!("trait `{}`", values.expected), + &format!("trait `{}`", values.found)) } OldStyleLUB(ref err) => { write!(f, "{}", err) @@ -173,22 +174,22 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { } impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { - pub fn sort_string(&self, tcx: TyCtxt<'a, 'gcx, 'lcx>) -> String { + pub fn sort_string(&self, tcx: TyCtxt<'a, 'gcx, 'lcx>) -> Cow<'static, str> { match self.sty { ty::Bool | ty::Char | ty::Int(_) | - ty::Uint(_) | ty::Float(_) | ty::Str | ty::Never => self.to_string(), - ty::Tuple(ref tys) if tys.is_empty() => self.to_string(), + ty::Uint(_) | ty::Float(_) | ty::Str | ty::Never => self.to_string().into(), + ty::Tuple(ref tys) if tys.is_empty() => self.to_string().into(), - ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.item_path_str(def.did)), - ty::Foreign(def_id) => format!("extern type `{}`", tcx.item_path_str(def_id)), + ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.item_path_str(def.did)).into(), + ty::Foreign(def_id) => format!("extern type `{}`", tcx.item_path_str(def_id)).into(), ty::Array(_, n) => { match n.assert_usize(tcx) { - Some(n) => format!("array of {} elements", n), - None => "array".to_string(), + Some(n) => format!("array of {} elements", n).into(), + None => "array".into(), } } - ty::Slice(_) => "slice".to_string(), - ty::RawPtr(_) => "*-ptr".to_string(), + ty::Slice(_) => "slice".into(), + ty::RawPtr(_) => "*-ptr".into(), ty::Ref(region, ty, mutbl) => { let tymut = ty::TypeAndMut { ty, mutbl }; let tymut_string = tymut.to_string(); @@ -199,39 +200,39 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { format!("{}reference", match mutbl { hir::Mutability::MutMutable => "mutable ", _ => "" - }) + }).into() } else { - format!("&{}", tymut_string) + format!("&{}", tymut_string).into() } } - ty::FnDef(..) => "fn item".to_string(), - ty::FnPtr(_) => "fn pointer".to_string(), + ty::FnDef(..) => "fn item".into(), + ty::FnPtr(_) => "fn pointer".into(), ty::Dynamic(ref inner, ..) => { - inner.principal().map_or_else(|| "trait".to_string(), - |p| format!("trait {}", tcx.item_path_str(p.def_id()))) + inner.principal().map_or_else(|| "trait".into(), + |p| format!("trait {}", tcx.item_path_str(p.def_id())).into()) } - ty::Closure(..) => "closure".to_string(), - ty::Generator(..) => "generator".to_string(), - ty::GeneratorWitness(..) => "generator witness".to_string(), - ty::Tuple(..) => "tuple".to_string(), - ty::Infer(ty::TyVar(_)) => "inferred type".to_string(), - ty::Infer(ty::IntVar(_)) => "integral variable".to_string(), - ty::Infer(ty::FloatVar(_)) => "floating-point variable".to_string(), + ty::Closure(..) => "closure".into(), + ty::Generator(..) => "generator".into(), + ty::GeneratorWitness(..) => "generator witness".into(), + ty::Tuple(..) => "tuple".into(), + ty::Infer(ty::TyVar(_)) => "inferred type".into(), + ty::Infer(ty::IntVar(_)) => "integral variable".into(), + ty::Infer(ty::FloatVar(_)) => "floating-point variable".into(), ty::Infer(ty::CanonicalTy(_)) | - ty::Infer(ty::FreshTy(_)) => "fresh type".to_string(), - ty::Infer(ty::FreshIntTy(_)) => "fresh integral type".to_string(), - ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".to_string(), - ty::Projection(_) => "associated type".to_string(), - ty::UnnormalizedProjection(_) => "non-normalized associated type".to_string(), + ty::Infer(ty::FreshTy(_)) => "fresh type".into(), + ty::Infer(ty::FreshIntTy(_)) => "fresh integral type".into(), + ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(), + ty::Projection(_) => "associated type".into(), + ty::UnnormalizedProjection(_) => "non-normalized associated type".into(), ty::Param(ref p) => { if p.is_self() { - "Self".to_string() + "Self".into() } else { - "type parameter".to_string() + "type parameter".into() } } - ty::Opaque(..) => "opaque type".to_string(), - ty::Error => "type error".to_string(), + ty::Opaque(..) => "opaque type".into(), + ty::Error => "type error".into(), } } } @@ -251,20 +252,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { db.note("no two closures, even if identical, have the same type"); db.help("consider boxing your closure and/or using it as a trait object"); } - match (&values.found.sty, &values.expected.sty) { // Issue #53280 - (ty::Infer(ty::IntVar(_)), ty::Float(_)) => { - if let Ok(snippet) = self.sess.source_map().span_to_snippet(sp) { - if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') { - db.span_suggestion_with_applicability( - sp, - "use a float literal", - format!("{}.0", snippet), - Applicability::MachineApplicable - ); - } + if let (ty::Infer(ty::IntVar(_)), ty::Float(_)) = + (&values.found.sty, &values.expected.sty) // Issue #53280 + { + if let Ok(snippet) = self.sess.source_map().span_to_snippet(sp) { + if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') { + db.span_suggestion_with_applicability( + sp, + "use a float literal", + format!("{}.0", snippet), + Applicability::MachineApplicable + ); } - }, - _ => {} + } } }, OldStyleLUB(err) => { diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index 3ccc24e73a5c9..c3d41873009a7 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -62,9 +62,7 @@ impl FlagComputation { let outer_exclusive_binder = computation.outer_exclusive_binder; if outer_exclusive_binder > ty::INNERMOST { self.add_exclusive_binder(outer_exclusive_binder.shifted_out(1)); - } else { - // otherwise, this binder captures nothing - } + } // otherwise, this binder captures nothing } fn add_sty(&mut self, st: &ty::TyKind<'_>) { diff --git a/src/librustc/ty/inhabitedness/def_id_forest.rs b/src/librustc/ty/inhabitedness/def_id_forest.rs index c152c0fb8e94c..7bc77e1b1a140 100644 --- a/src/librustc/ty/inhabitedness/def_id_forest.rs +++ b/src/librustc/ty/inhabitedness/def_id_forest.rs @@ -66,12 +66,7 @@ impl<'a, 'gcx, 'tcx> DefIdForest { tcx: TyCtxt<'a, 'gcx, 'tcx>, id: DefId) -> bool { - for root_id in self.root_ids.iter() { - if tcx.is_descendant_of(id, *root_id) { - return true; - } - } - false + self.root_ids.iter().any(|root_id| tcx.is_descendant_of(id, *root_id)) } /// Calculate the intersection of a collection of forests. @@ -92,11 +87,7 @@ impl<'a, 'gcx, 'tcx> DefIdForest { } ret.root_ids.extend(old_ret.drain()); - for id in next_forest.root_ids { - if ret.contains(tcx, id) { - next_ret.push(id); - } - } + next_ret.extend(next_forest.root_ids.into_iter().filter(|&id| ret.contains(tcx, id))); mem::swap(&mut next_ret, &mut ret.root_ids); next_ret.drain(); @@ -112,11 +103,7 @@ impl<'a, 'gcx, 'tcx> DefIdForest { let mut ret = DefIdForest::empty(); let mut next_ret = SmallVec::new(); for next_forest in iter { - for id in ret.root_ids.drain() { - if !next_forest.contains(tcx, id) { - next_ret.push(id); - } - } + next_ret.extend(ret.root_ids.drain().filter(|&id| !next_forest.contains(tcx, id))); for id in next_forest.root_ids { if !next_ret.contains(&id) { diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index 66d7541633cde..79eab3c6f34b9 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -23,6 +23,7 @@ use ty::query::Query; use ty::query::QueryCache; use util::profiling::ProfileCategory; +use std::borrow::Cow; use std::hash::Hash; use std::fmt::Debug; use syntax_pos::symbol::InternedString; @@ -55,7 +56,7 @@ pub(super) trait QueryAccessors<'tcx>: QueryConfig<'tcx> { } pub(super) trait QueryDescription<'tcx>: QueryAccessors<'tcx> { - fn describe(tcx: TyCtxt<'_, '_, '_>, key: Self::Key) -> String; + fn describe(tcx: TyCtxt<'_, '_, '_>, key: Self::Key) -> Cow<'static, str>; #[inline] fn cache_on_disk(_: Self::Key) -> bool { @@ -70,12 +71,12 @@ pub(super) trait QueryDescription<'tcx>: QueryAccessors<'tcx> { } impl<'tcx, M: QueryAccessors<'tcx, Key=DefId>> QueryDescription<'tcx> for M { - default fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> String { + default fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { if !tcx.sess.verbose() { - format!("processing `{}`", tcx.item_path_str(def_id)) + format!("processing `{}`", tcx.item_path_str(def_id)).into() } else { let name = unsafe { ::std::intrinsics::type_name::() }; - format!("processing `{}` applied to `{:?}`", name, def_id) + format!("processing `{}` applied to `{:?}`", name, def_id).into() } } } @@ -84,57 +85,59 @@ impl<'tcx> QueryDescription<'tcx> for queries::normalize_projection_ty<'tcx> { fn describe( _tcx: TyCtxt<'_, '_, '_>, goal: CanonicalProjectionGoal<'tcx>, - ) -> String { - format!("normalizing `{:?}`", goal) + ) -> Cow<'static, str> { + format!("normalizing `{:?}`", goal).into() } } impl<'tcx> QueryDescription<'tcx> for queries::implied_outlives_bounds<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTyGoal<'tcx>) -> String { - format!("computing implied outlives bounds for `{:?}`", goal) + fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTyGoal<'tcx>) -> Cow<'static, str> { + format!("computing implied outlives bounds for `{:?}`", goal).into() } } impl<'tcx> QueryDescription<'tcx> for queries::dropck_outlives<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTyGoal<'tcx>) -> String { - format!("computing dropck types for `{:?}`", goal) + fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTyGoal<'tcx>) -> Cow<'static, str> { + format!("computing dropck types for `{:?}`", goal).into() } } impl<'tcx> QueryDescription<'tcx> for queries::normalize_ty_after_erasing_regions<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: ParamEnvAnd<'tcx, Ty<'tcx>>) -> String { - format!("normalizing `{:?}`", goal) + fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: ParamEnvAnd<'tcx, Ty<'tcx>>) -> Cow<'static, str> { + format!("normalizing `{:?}`", goal).into() } } impl<'tcx> QueryDescription<'tcx> for queries::evaluate_obligation<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalPredicateGoal<'tcx>) -> String { - format!("evaluating trait selection obligation `{}`", goal.value.value) + fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalPredicateGoal<'tcx>) -> Cow<'static, str> { + format!("evaluating trait selection obligation `{}`", goal.value.value).into() } } impl<'tcx> QueryDescription<'tcx> for queries::type_op_eq<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTypeOpEqGoal<'tcx>) -> String { - format!("evaluating `type_op_eq` `{:?}`", goal) + fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTypeOpEqGoal<'tcx>) -> Cow<'static, str> { + format!("evaluating `type_op_eq` `{:?}`", goal).into() } } impl<'tcx> QueryDescription<'tcx> for queries::type_op_subtype<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTypeOpSubtypeGoal<'tcx>) -> String { - format!("evaluating `type_op_subtype` `{:?}`", goal) + fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTypeOpSubtypeGoal<'tcx>) + -> Cow<'static, str> { + format!("evaluating `type_op_subtype` `{:?}`", goal).into() } } impl<'tcx> QueryDescription<'tcx> for queries::type_op_prove_predicate<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTypeOpProvePredicateGoal<'tcx>) -> String { - format!("evaluating `type_op_prove_predicate` `{:?}`", goal) + fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTypeOpProvePredicateGoal<'tcx>) + -> Cow<'static, str> { + format!("evaluating `type_op_prove_predicate` `{:?}`", goal).into() } } impl<'tcx> QueryDescription<'tcx> for queries::type_op_normalize_ty<'tcx> { fn describe(_tcx: TyCtxt<'_, '_, '_>, - goal: CanonicalTypeOpNormalizeGoal<'tcx, Ty<'tcx>>) -> String { - format!("normalizing `{:?}`", goal) + goal: CanonicalTypeOpNormalizeGoal<'tcx, Ty<'tcx>>) -> Cow<'static, str> { + format!("normalizing `{:?}`", goal).into() } } @@ -142,8 +145,8 @@ impl<'tcx> QueryDescription<'tcx> for queries::type_op_normalize_predicate<'tcx> fn describe( _tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::Predicate<'tcx>>, - ) -> String { - format!("normalizing `{:?}`", goal) + ) -> Cow<'static, str> { + format!("normalizing `{:?}`", goal).into() } } @@ -151,134 +154,141 @@ impl<'tcx> QueryDescription<'tcx> for queries::type_op_normalize_poly_fn_sig<'tc fn describe( _tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::PolyFnSig<'tcx>>, - ) -> String { - format!("normalizing `{:?}`", goal) + ) -> Cow<'static, str> { + format!("normalizing `{:?}`", goal).into() } } impl<'tcx> QueryDescription<'tcx> for queries::type_op_normalize_fn_sig<'tcx> { fn describe(_tcx: TyCtxt<'_, '_, '_>, - goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::FnSig<'tcx>>) -> String { - format!("normalizing `{:?}`", goal) + goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::FnSig<'tcx>>) -> Cow<'static, str> { + format!("normalizing `{:?}`", goal).into() } } impl<'tcx> QueryDescription<'tcx> for queries::is_copy_raw<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String { - format!("computing whether `{}` is `Copy`", env.value) + fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) + -> Cow<'static, str> { + format!("computing whether `{}` is `Copy`", env.value).into() } } impl<'tcx> QueryDescription<'tcx> for queries::is_sized_raw<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String { - format!("computing whether `{}` is `Sized`", env.value) + fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) + -> Cow<'static, str> { + format!("computing whether `{}` is `Sized`", env.value).into() } } impl<'tcx> QueryDescription<'tcx> for queries::is_freeze_raw<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String { - format!("computing whether `{}` is freeze", env.value) + fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) + -> Cow<'static, str> { + format!("computing whether `{}` is freeze", env.value).into() } } impl<'tcx> QueryDescription<'tcx> for queries::needs_drop_raw<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String { - format!("computing whether `{}` needs drop", env.value) + fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) + -> Cow<'static, str> { + format!("computing whether `{}` needs drop", env.value).into() } } impl<'tcx> QueryDescription<'tcx> for queries::layout_raw<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String { - format!("computing layout of `{}`", env.value) + fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) + -> Cow<'static, str> { + format!("computing layout of `{}`", env.value).into() } } impl<'tcx> QueryDescription<'tcx> for queries::super_predicates_of<'tcx> { - fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> String { + fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { format!("computing the supertraits of `{}`", - tcx.item_path_str(def_id)) + tcx.item_path_str(def_id)).into() } } impl<'tcx> QueryDescription<'tcx> for queries::erase_regions_ty<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, ty: Ty<'tcx>) -> String { - format!("erasing regions from `{:?}`", ty) + fn describe(_tcx: TyCtxt<'_, '_, '_>, ty: Ty<'tcx>) -> Cow<'static, str> { + format!("erasing regions from `{:?}`", ty).into() } } impl<'tcx> QueryDescription<'tcx> for queries::type_param_predicates<'tcx> { - fn describe(tcx: TyCtxt<'_, '_, '_>, (_, def_id): (DefId, DefId)) -> String { + fn describe(tcx: TyCtxt<'_, '_, '_>, (_, def_id): (DefId, DefId)) -> Cow<'static, str> { let id = tcx.hir.as_local_node_id(def_id).unwrap(); format!("computing the bounds for type parameter `{}`", - tcx.hir.ty_param_name(id)) + tcx.hir.ty_param_name(id)).into() } } impl<'tcx> QueryDescription<'tcx> for queries::coherent_trait<'tcx> { - fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> String { + fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { format!("coherence checking all impls of trait `{}`", - tcx.item_path_str(def_id)) + tcx.item_path_str(def_id)).into() } } impl<'tcx> QueryDescription<'tcx> for queries::upstream_monomorphizations<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, k: CrateNum) -> String { - format!("collecting available upstream monomorphizations `{:?}`", k) + fn describe(_: TyCtxt<'_, '_, '_>, k: CrateNum) -> Cow<'static, str> { + format!("collecting available upstream monomorphizations `{:?}`", k).into() } } impl<'tcx> QueryDescription<'tcx> for queries::crate_inherent_impls<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, k: CrateNum) -> String { - format!("all inherent impls defined in crate `{:?}`", k) + fn describe(_: TyCtxt<'_, '_, '_>, k: CrateNum) -> Cow<'static, str> { + format!("all inherent impls defined in crate `{:?}`", k).into() } } impl<'tcx> QueryDescription<'tcx> for queries::crate_inherent_impls_overlap_check<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "check for overlap between inherent impls defined in this crate".to_string() + fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "check for overlap between inherent impls defined in this crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::crate_variances<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "computing the variances for items in this crate".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "computing the variances for items in this crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::inferred_outlives_crate<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "computing the inferred outlives predicates for items in this crate".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "computing the inferred outlives predicates for items in this crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::mir_shims<'tcx> { - fn describe(tcx: TyCtxt<'_, '_, '_>, def: ty::InstanceDef<'tcx>) -> String { + fn describe(tcx: TyCtxt<'_, '_, '_>, def: ty::InstanceDef<'tcx>) -> Cow<'static, str> { format!("generating MIR shim for `{}`", - tcx.item_path_str(def.def_id())) + tcx.item_path_str(def.def_id())).into() } } impl<'tcx> QueryDescription<'tcx> for queries::privacy_access_levels<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "privacy access levels".to_string() + fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "privacy access levels".into() } } impl<'tcx> QueryDescription<'tcx> for queries::typeck_item_bodies<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "type-checking all item bodies".to_string() + fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "type-checking all item bodies".into() } } impl<'tcx> QueryDescription<'tcx> for queries::reachable_set<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "reachability".to_string() + fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "reachability".into() } } impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'tcx> { - fn describe(tcx: TyCtxt<'_, '_, '_>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> String { - format!("const-evaluating `{}`", tcx.item_path_str(key.value.instance.def.def_id())) + fn describe(tcx: TyCtxt<'_, '_, '_>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) + -> Cow<'static, str> + { + format!("const-evaluating `{}`", tcx.item_path_str(key.value.instance.def.def_id())).into() } #[inline] @@ -295,14 +305,14 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'tcx> { } impl<'tcx> QueryDescription<'tcx> for queries::mir_keys<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "getting a list of all mir_keys".to_string() + fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "getting a list of all mir_keys".into() } } impl<'tcx> QueryDescription<'tcx> for queries::symbol_name<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, instance: ty::Instance<'tcx>) -> String { - format!("computing the symbol for `{}`", instance) + fn describe(_tcx: TyCtxt<'_, '_, '_>, instance: ty::Instance<'tcx>) -> Cow<'static, str> { + format!("computing the symbol for `{}`", instance).into() } #[inline] @@ -319,64 +329,64 @@ impl<'tcx> QueryDescription<'tcx> for queries::symbol_name<'tcx> { } impl<'tcx> QueryDescription<'tcx> for queries::describe_def<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> String { + fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> { bug!("describe_def") } } impl<'tcx> QueryDescription<'tcx> for queries::def_span<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> String { + fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> { bug!("def_span") } } impl<'tcx> QueryDescription<'tcx> for queries::lookup_stability<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> String { + fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> { bug!("stability") } } impl<'tcx> QueryDescription<'tcx> for queries::lookup_deprecation_entry<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> String { + fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> { bug!("deprecation") } } impl<'tcx> QueryDescription<'tcx> for queries::item_attrs<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> String { + fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> { bug!("item_attrs") } } impl<'tcx> QueryDescription<'tcx> for queries::is_reachable_non_generic<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> String { + fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> { bug!("is_reachable_non_generic") } } impl<'tcx> QueryDescription<'tcx> for queries::fn_arg_names<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> String { + fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> { bug!("fn_arg_names") } } impl<'tcx> QueryDescription<'tcx> for queries::impl_parent<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> String { + fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> { bug!("impl_parent") } } impl<'tcx> QueryDescription<'tcx> for queries::trait_of_item<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> String { + fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> { bug!("trait_of_item") } } impl<'tcx> QueryDescription<'tcx> for queries::const_is_rvalue_promotable_to_static<'tcx> { - fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> String { + fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { format!("const checking if rvalue is promotable to static `{}`", - tcx.item_path_str(def_id)) + tcx.item_path_str(def_id)).into() } #[inline] @@ -386,30 +396,31 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_is_rvalue_promotable_to_sta #[inline] fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - id: SerializedDepNodeIndex) - -> Option { + id: SerializedDepNodeIndex) + -> Option { tcx.queries.on_disk_cache.try_load_query_result(tcx, id) } } impl<'tcx> QueryDescription<'tcx> for queries::rvalue_promotable_map<'tcx> { - fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> String { + fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { format!("checking which parts of `{}` are promotable to static", - tcx.item_path_str(def_id)) + tcx.item_path_str(def_id)).into() } } impl<'tcx> QueryDescription<'tcx> for queries::is_mir_available<'tcx> { - fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> String { + fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { format!("checking if item is mir available: `{}`", - tcx.item_path_str(def_id)) + tcx.item_path_str(def_id)).into() } } impl<'tcx> QueryDescription<'tcx> for queries::codegen_fulfill_obligation<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, - key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)) -> String { + key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)) -> Cow<'static, str> { format!("checking if `{}` fulfills its obligations", tcx.item_path_str(key.1.def_id())) + .into() } #[inline] @@ -426,320 +437,320 @@ impl<'tcx> QueryDescription<'tcx> for queries::codegen_fulfill_obligation<'tcx> } impl<'tcx> QueryDescription<'tcx> for queries::trait_impls_of<'tcx> { - fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> String { - format!("trait impls of `{}`", tcx.item_path_str(def_id)) + fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { + format!("trait impls of `{}`", tcx.item_path_str(def_id)).into() } } impl<'tcx> QueryDescription<'tcx> for queries::is_object_safe<'tcx> { - fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> String { - format!("determine object safety of trait `{}`", tcx.item_path_str(def_id)) + fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { + format!("determine object safety of trait `{}`", tcx.item_path_str(def_id)).into() } } impl<'tcx> QueryDescription<'tcx> for queries::is_const_fn_raw<'tcx> { - fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> String { - format!("checking if item is const fn: `{}`", tcx.item_path_str(def_id)) + fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { + format!("checking if item is const fn: `{}`", tcx.item_path_str(def_id)).into() } } impl<'tcx> QueryDescription<'tcx> for queries::dylib_dependency_formats<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "dylib dependency formats of crate".to_string() + fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "dylib dependency formats of crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::is_panic_runtime<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "checking if the crate is_panic_runtime".to_string() + fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "checking if the crate is_panic_runtime".into() } } impl<'tcx> QueryDescription<'tcx> for queries::is_compiler_builtins<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "checking if the crate is_compiler_builtins".to_string() + fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "checking if the crate is_compiler_builtins".into() } } impl<'tcx> QueryDescription<'tcx> for queries::has_global_allocator<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "checking if the crate has_global_allocator".to_string() + fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "checking if the crate has_global_allocator".into() } } impl<'tcx> QueryDescription<'tcx> for queries::has_panic_handler<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "checking if the crate has_panic_handler".to_string() + fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "checking if the crate has_panic_handler".into() } } impl<'tcx> QueryDescription<'tcx> for queries::extern_crate<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> String { - "getting crate's ExternCrateData".to_string() + fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> { + "getting crate's ExternCrateData".into() } } impl<'tcx> QueryDescription<'tcx> for queries::lint_levels<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "computing the lint levels for items in this crate".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "computing the lint levels for items in this crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::specializes<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: (DefId, DefId)) -> String { - "computing whether impls specialize one another".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: (DefId, DefId)) -> Cow<'static, str> { + "computing whether impls specialize one another".into() } } impl<'tcx> QueryDescription<'tcx> for queries::in_scope_traits_map<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefIndex) -> String { - "traits in scope at a block".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefIndex) -> Cow<'static, str> { + "traits in scope at a block".into() } } impl<'tcx> QueryDescription<'tcx> for queries::is_no_builtins<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "test whether a crate has #![no_builtins]".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "test whether a crate has #![no_builtins]".into() } } impl<'tcx> QueryDescription<'tcx> for queries::panic_strategy<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "query a crate's configured panic strategy".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "query a crate's configured panic strategy".into() } } impl<'tcx> QueryDescription<'tcx> for queries::is_profiler_runtime<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "query a crate is #![profiler_runtime]".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "query a crate is #![profiler_runtime]".into() } } impl<'tcx> QueryDescription<'tcx> for queries::is_sanitizer_runtime<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "query a crate is #![sanitizer_runtime]".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "query a crate is #![sanitizer_runtime]".into() } } impl<'tcx> QueryDescription<'tcx> for queries::reachable_non_generics<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "looking up the exported symbols of a crate".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "looking up the exported symbols of a crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::native_libraries<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "looking up the native libraries of a linked crate".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "looking up the native libraries of a linked crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::foreign_modules<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "looking up the foreign modules of a linked crate".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "looking up the foreign modules of a linked crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::plugin_registrar_fn<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "looking up the plugin registrar for a crate".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "looking up the plugin registrar for a crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::derive_registrar_fn<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "looking up the derive registrar for a crate".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "looking up the derive registrar for a crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::crate_disambiguator<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "looking up the disambiguator a crate".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "looking up the disambiguator a crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::crate_hash<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "looking up the hash a crate".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "looking up the hash a crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::original_crate_name<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "looking up the original name a crate".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "looking up the original name a crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::extra_filename<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "looking up the extra filename for a crate".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "looking up the extra filename for a crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::implementations_of_trait<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: (CrateNum, DefId)) -> String { - "looking up implementations of a trait in a crate".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: (CrateNum, DefId)) -> Cow<'static, str> { + "looking up implementations of a trait in a crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::all_trait_implementations<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "looking up all (?) trait implementations".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "looking up all (?) trait implementations".into() } } impl<'tcx> QueryDescription<'tcx> for queries::link_args<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "looking up link arguments for a crate".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "looking up link arguments for a crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::resolve_lifetimes<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "resolving lifetimes".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "resolving lifetimes".into() } } impl<'tcx> QueryDescription<'tcx> for queries::named_region_map<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefIndex) -> String { - "looking up a named region".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefIndex) -> Cow<'static, str> { + "looking up a named region".into() } } impl<'tcx> QueryDescription<'tcx> for queries::is_late_bound_map<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefIndex) -> String { - "testing if a region is late bound".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefIndex) -> Cow<'static, str> { + "testing if a region is late bound".into() } } impl<'tcx> QueryDescription<'tcx> for queries::object_lifetime_defaults_map<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefIndex) -> String { - "looking up lifetime defaults for a region".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefIndex) -> Cow<'static, str> { + "looking up lifetime defaults for a region".into() } } impl<'tcx> QueryDescription<'tcx> for queries::dep_kind<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "fetching what a dependency looks like".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "fetching what a dependency looks like".into() } } impl<'tcx> QueryDescription<'tcx> for queries::crate_name<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "fetching what a crate is named".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "fetching what a crate is named".into() } } impl<'tcx> QueryDescription<'tcx> for queries::get_lib_features<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - format!("calculating the lib features map") + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "calculating the lib features map".into() } } impl<'tcx> QueryDescription<'tcx> for queries::defined_lib_features<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - format!("calculating the lib features defined in a crate") + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "calculating the lib features defined in a crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::get_lang_items<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "calculating the lang items map".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "calculating the lang items map".into() } } impl<'tcx> QueryDescription<'tcx> for queries::defined_lang_items<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "calculating the lang items defined in a crate".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "calculating the lang items defined in a crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::missing_lang_items<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "calculating the missing lang items in a crate".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "calculating the missing lang items in a crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::visible_parent_map<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "calculating the visible parent map".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "calculating the visible parent map".into() } } impl<'tcx> QueryDescription<'tcx> for queries::missing_extern_crate_item<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "seeing if we're missing an `extern crate` item for this crate".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "seeing if we're missing an `extern crate` item for this crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::used_crate_source<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "looking at the source for a crate".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "looking at the source for a crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::postorder_cnums<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "generating a postorder list of CrateNums".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "generating a postorder list of CrateNums".into() } } impl<'tcx> QueryDescription<'tcx> for queries::maybe_unused_extern_crates<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "looking up all possibly unused extern crates".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "looking up all possibly unused extern crates".into() } } impl<'tcx> QueryDescription<'tcx> for queries::stability_index<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "calculating the stability index for the local crate".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "calculating the stability index for the local crate".into() } } impl<'tcx> QueryDescription<'tcx> for queries::all_traits<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "fetching all foreign and local traits".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "fetching all foreign and local traits".into() } } impl<'tcx> QueryDescription<'tcx> for queries::all_crate_nums<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "fetching all foreign CrateNum instances".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "fetching all foreign CrateNum instances".into() } } impl<'tcx> QueryDescription<'tcx> for queries::exported_symbols<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "exported_symbols".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "exported_symbols".into() } } impl<'tcx> QueryDescription<'tcx> for queries::collect_and_partition_mono_items<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "collect_and_partition_mono_items".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "collect_and_partition_mono_items".into() } } impl<'tcx> QueryDescription<'tcx> for queries::codegen_unit<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: InternedString) -> String { - "codegen_unit".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: InternedString) -> Cow<'static, str> { + "codegen_unit".into() } } impl<'tcx> QueryDescription<'tcx> for queries::output_filenames<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "output_filenames".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "output_filenames".into() } } impl<'tcx> QueryDescription<'tcx> for queries::vtable_methods<'tcx> { - fn describe(tcx: TyCtxt<'_, '_, '_>, key: ty::PolyTraitRef<'tcx> ) -> String { - format!("finding all methods for trait {}", tcx.item_path_str(key.def_id())) + fn describe(tcx: TyCtxt<'_, '_, '_>, key: ty::PolyTraitRef<'tcx> ) -> Cow<'static, str> { + format!("finding all methods for trait {}", tcx.item_path_str(key.def_id())).into() } } impl<'tcx> QueryDescription<'tcx> for queries::features_query<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "looking up enabled feature gates".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "looking up enabled feature gates".into() } } @@ -776,20 +787,20 @@ impl<'tcx> QueryDescription<'tcx> for queries::optimized_mir<'tcx> { } impl<'tcx> QueryDescription<'tcx> for queries::substitute_normalize_and_test_predicates<'tcx> { - fn describe(tcx: TyCtxt<'_, '_, '_>, key: (DefId, &'tcx Substs<'tcx>)) -> String { - format!("testing substituted normalized predicates:`{}`", tcx.item_path_str(key.0)) + fn describe(tcx: TyCtxt<'_, '_, '_>, key: (DefId, &'tcx Substs<'tcx>)) -> Cow<'static, str> { + format!("testing substituted normalized predicates:`{}`", tcx.item_path_str(key.0)).into() } } impl<'tcx> QueryDescription<'tcx> for queries::target_features_whitelist<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "looking up the whitelist of target features".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "looking up the whitelist of target features".into() } } impl<'tcx> QueryDescription<'tcx> for queries::instance_def_size_estimate<'tcx> { - fn describe(tcx: TyCtxt<'_, '_, '_>, def: ty::InstanceDef<'tcx>) -> String { - format!("estimating size for `{}`", tcx.item_path_str(def.def_id())) + fn describe(tcx: TyCtxt<'_, '_, '_>, def: ty::InstanceDef<'tcx>) -> Cow<'static, str> { + format!("estimating size for `{}`", tcx.item_path_str(def.def_id())).into() } } @@ -809,26 +820,26 @@ impl<'tcx> QueryDescription<'tcx> for queries::generics_of<'tcx> { } impl<'tcx> QueryDescription<'tcx> for queries::program_clauses_for<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefId) -> String { - "generating chalk-style clauses".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> { + "generating chalk-style clauses".into() } } impl<'tcx> QueryDescription<'tcx> for queries::program_clauses_for_env<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: ty::ParamEnv<'tcx>) -> String { - "generating chalk-style clauses for param env".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: ty::ParamEnv<'tcx>) -> Cow<'static, str> { + "generating chalk-style clauses for param env".into() } } impl<'tcx> QueryDescription<'tcx> for queries::wasm_import_module_map<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "wasm import module map".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "wasm import module map".into() } } impl<'tcx> QueryDescription<'tcx> for queries::dllimport_foreign_items<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String { - "wasm import module map".to_string() + fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { + "wasm import module map".into() } } diff --git a/src/librustc/ty/query/job.rs b/src/librustc/ty/query/job.rs index d07891fca12ae..d588bc8c0cb5c 100644 --- a/src/librustc/ty/query/job.rs +++ b/src/librustc/ty/query/job.rs @@ -123,9 +123,11 @@ impl<'tcx> QueryJob<'tcx> { let mut cycle = Vec::new(); while let Some(job) = current_job { - cycle.insert(0, job.info.clone()); + cycle.push(job.info.clone()); if ptr::eq(&*job, self) { + cycle.reverse(); + // This is the end of the cycle // The span entry we included was for the usage // of the cycle itself, and not part of the cycle @@ -324,16 +326,16 @@ fn connected_to_root<'tcx>( query: Lrc>, visited: &mut FxHashSet<*const QueryJob<'tcx>> ) -> bool { - // We already visited this or we're deliberately ignoring it - if visited.contains(&query.as_ptr()) { - return false; - } - // This query is connected to the root (it has no query parent), return true if query.parent.is_none() { return true; } + // We already visited this or we're deliberately ignoring it + if visited.contains(&query.as_ptr()) { + return false; + } + visited.insert(query.as_ptr()); let mut connected = false; @@ -368,13 +370,11 @@ fn remove_cycle<'tcx>( // Reverse the stack so earlier entries require later entries stack.reverse(); - // Extract the spans and queries into separate arrays - let mut spans: Vec<_> = stack.iter().map(|e| e.0).collect(); - let queries = stack.into_iter().map(|e| e.1); + // The stack is a vector of pairs of spans and queries + let (mut spans, queries): (Vec<_>, Vec<_>) = stack.into_iter().unzip(); // Shift the spans so that queries are matched with the span for their waitee - let last = spans.pop().unwrap(); - spans.insert(0, last); + spans.rotate_right(1); // Zip them back together let mut stack: Vec<_> = spans.into_iter().zip(queries).collect(); @@ -388,7 +388,7 @@ fn remove_cycle<'tcx>( // Find the queries in the cycle which are // connected to queries outside the cycle - let entry_points: Vec>> = stack.iter().filter_map(|query| { + let entry_points = stack.iter().filter_map(|query| { // Mark all the other queries in the cycle as already visited let mut visited = FxHashSet::from_iter(stack.iter().filter_map(|q| { if q.1.as_ptr() != query.1.as_ptr() { @@ -403,21 +403,21 @@ fn remove_cycle<'tcx>( } else { None } - }).collect(); + }); // Deterministically pick an entry point // FIXME: Sort this instead let mut hcx = tcx.create_stable_hashing_context(); - let entry_point = entry_points.iter().min_by_key(|q| { + let entry_point = entry_points.min_by_key(|q| { let mut stable_hasher = StableHasher::::new(); q.info.query.hash_stable(&mut hcx, &mut stable_hasher); stable_hasher.finish() }).unwrap().as_ptr(); - // Shift the stack until our entry point is first - while stack[0].1.as_ptr() != entry_point { - let last = stack.pop().unwrap(); - stack.insert(0, last); + // Shift the stack so that our entry point is first + let entry_point_pos = stack.iter().position(|(_, query)| query.as_ptr() == entry_point); + if let Some(pos) = entry_point_pos { + stack.rotate_right(pos); } // Create the cycle error diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 44c9c55b8a4eb..7f5bc35f91f9b 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -56,6 +56,7 @@ use rustc_data_structures::stable_hasher::StableVec; use rustc_data_structures::sync::Lrc; use rustc_target::spec::PanicStrategy; +use std::borrow::Cow; use std::ops::Deref; use std::sync::Arc; use syntax_pos::{Span, DUMMY_SP}; diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index bb87786463223..ce580c7803355 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -254,23 +254,19 @@ impl<'sess> OnDiskCache<'sess> { })?; // Encode diagnostics - let diagnostics_index = { - let mut diagnostics_index = EncodedDiagnosticsIndex::new(); - - for (dep_node_index, diagnostics) in self.current_diagnostics - .borrow() - .iter() { - let pos = AbsoluteBytePos::new(encoder.position()); - // Let's make sure we get the expected type here: - let diagnostics: &EncodedDiagnostics = diagnostics; - let dep_node_index = - SerializedDepNodeIndex::new(dep_node_index.index()); - encoder.encode_tagged(dep_node_index, diagnostics)?; - diagnostics_index.push((dep_node_index, pos)); - } - - diagnostics_index - }; + let diagnostics_index: EncodedDiagnosticsIndex = self.current_diagnostics.borrow() + .iter() + .map(|(dep_node_index, diagnostics)| + { + let pos = AbsoluteBytePos::new(encoder.position()); + // Let's make sure we get the expected type here: + let diagnostics: &EncodedDiagnostics = diagnostics; + let dep_node_index = SerializedDepNodeIndex::new(dep_node_index.index()); + encoder.encode_tagged(dep_node_index, diagnostics)?; + + Ok((dep_node_index, pos)) + }) + .collect::>()?; let interpret_alloc_index = { let mut interpret_alloc_index = Vec::new(); @@ -282,6 +278,7 @@ impl<'sess> OnDiskCache<'sess> { // otherwise, abort break; } + interpret_alloc_index.reserve(new_n); for idx in n..new_n { let id = encoder.interpret_allocs_inverse[idx]; let pos = encoder.position() as u32; @@ -441,16 +438,15 @@ impl<'sess> OnDiskCache<'sess> { tcx.dep_graph.with_ignore(|| { let current_cnums = tcx.all_crate_nums(LOCAL_CRATE).iter().map(|&cnum| { let crate_name = tcx.original_crate_name(cnum) - .as_str() .to_string(); let crate_disambiguator = tcx.crate_disambiguator(cnum); ((crate_name, crate_disambiguator), cnum) }).collect::>(); let map_size = prev_cnums.iter() - .map(|&(cnum, ..)| cnum) - .max() - .unwrap_or(0) + 1; + .map(|&(cnum, ..)| cnum) + .max() + .unwrap_or(0) + 1; let mut map = IndexVec::new(); map.resize(map_size as usize, None); @@ -465,7 +461,6 @@ impl<'sess> OnDiskCache<'sess> { } } - //- DECODING ------------------------------------------------------------------- /// A decoder that can read the incr. comp. cache. It is similar to the one @@ -494,7 +489,7 @@ impl<'a, 'tcx, 'x> CacheDecoder<'a, 'tcx, 'x> { file_index_to_file.borrow_mut().entry(index).or_insert_with(|| { let stable_id = file_index_to_stable_id[&index]; source_map.source_file_by_stable_id(stable_id) - .expect("Failed to lookup SourceFile in new context.") + .expect("Failed to lookup SourceFile in new context.") }).clone() } } @@ -761,7 +756,7 @@ for CacheDecoder<'a, 'tcx, 'x> { struct CacheEncoder<'enc, 'a, 'tcx, E> where E: 'enc + ty_codec::TyEncoder, - 'tcx: 'a, + 'tcx: 'a, { tcx: TyCtxt<'a, 'tcx, 'tcx>, encoder: &'enc mut E, @@ -839,9 +834,7 @@ impl<'enc, 'a, 'tcx, E> SpecializedEncoder for CacheEncoder<'enc, 'a, 'tcx let (file_lo, line_lo, col_lo) = match self.source_map .byte_pos_to_line_and_col(span_data.lo) { Some(pos) => pos, - None => { - return TAG_INVALID_SPAN.encode(self); - } + None => return TAG_INVALID_SPAN.encode(self) }; if !file_lo.contains(span_data.hi) { diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index fbd3a8f69bc45..39a59cf090ea8 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -449,14 +449,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let prev_dep_node_index = self.dep_graph.prev_dep_node_index_of(dep_node); let result = Q::try_load_from_disk(self.global_tcx(), - prev_dep_node_index); + prev_dep_node_index); // We always expect to find a cached result for things that // can be forced from DepNode. debug_assert!(!dep_node.kind.can_reconstruct_query_key() || - result.is_some(), - "Missing on-disk cache entry for {:?}", - dep_node); + result.is_some(), + "Missing on-disk cache entry for {:?}", + dep_node); result } else { // Some things are never cached on disk. @@ -491,7 +491,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { assert!(Some(self.dep_graph.fingerprint_of(dep_node_index)) == self.dep_graph.prev_fingerprint_of(dep_node), "Fingerprint for green query instance not loaded \ - from cache: {:?}", dep_node); + from cache: {:?}", dep_node); debug!("BEGIN verify_ich({:?})", dep_node); let mut hcx = self.create_stable_hashing_context(); @@ -530,8 +530,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // (see for example #48923) assert!(!self.dep_graph.dep_node_exists(&dep_node), "Forcing query with already existing DepNode.\n\ - - query-key: {:?}\n\ - - dep-node: {:?}", + - query-key: {:?}\n\ + - dep-node: {:?}", key, dep_node); profq_msg!(self, ProfileQueriesMsg::ProviderBegin); @@ -709,14 +709,19 @@ macro_rules! define_queries_inner { // We use try_lock here since we are only called from the // deadlock handler, and this shouldn't be locked - $(for v in self.$name.try_lock().unwrap().active.values() { - match *v { - QueryResult::Started(ref job) => jobs.push(job.clone()), - _ => (), - } - })* - - return jobs; + $( + jobs.extend( + self.$name.try_lock().unwrap().active.values().filter_map(|v| + if let QueryResult::Started(ref job) = *v { + Some(job.clone()) + } else { + None + } + ) + ); + )* + + jobs } } @@ -733,14 +738,14 @@ macro_rules! define_queries_inner { } } - pub fn describe(&self, tcx: TyCtxt<'_, '_, '_>) -> String { + pub fn describe(&self, tcx: TyCtxt<'_, '_, '_>) -> Cow<'static, str> { let (r, name) = match *self { $(Query::$name(key) => { (queries::$name::describe(tcx, key), stringify!($name)) })* }; if tcx.sess.verbose() { - format!("{} [{}]", r, name) + format!("{} [{}]", r, name).into() } else { r } @@ -753,9 +758,8 @@ macro_rules! define_queries_inner { } // The def_span query is used to calculate default_span, // so exit to avoid infinite recursion - match *self { - Query::def_span(..) => return span, - _ => () + if let Query::def_span(..) = *self { + return span } match *self { $(Query::$name(key) => key.default_span(tcx),)* @@ -1028,13 +1032,10 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, ) ); - match tcx.force_query::<::ty::query::queries::$query<'_>>( + if let Err(e) = tcx.force_query::<::ty::query::queries::$query<'_>>( $key, DUMMY_SP, *dep_node ) { - Ok(_) => {}, - Err(e) => { - tcx.report_cycle(e).emit(); - } + tcx.report_cycle(e).emit(); } } } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index bc8efa23ebb33..71940196a64c6 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -126,10 +126,25 @@ pub enum TyKind<'tcx> { Ref(Region<'tcx>, Ty<'tcx>, hir::Mutability), /// The anonymous type of a function declaration/definition. Each - /// function has a unique type. + /// function has a unique type, which is output (for a function + /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`. + /// + /// For example the type of `bar` here: + /// + /// ```rust + /// fn foo() -> i32 { 1 } + /// let bar = foo; // bar: fn() -> i32 {foo} + /// ``` FnDef(DefId, &'tcx Substs<'tcx>), /// A pointer to a function. Written as `fn() -> i32`. + /// + /// For example the type of `bar` here: + /// + /// ```rust + /// fn foo() -> i32 { 1 } + /// let bar: fn() -> i32 = foo; + /// ``` FnPtr(PolyFnSig<'tcx>), /// A trait, defined with `trait`. diff --git a/src/librustc_borrowck/borrowck/unused.rs b/src/librustc_borrowck/borrowck/unused.rs index f10361cb076bd..b1f89ce33fcfa 100644 --- a/src/librustc_borrowck/borrowck/unused.rs +++ b/src/librustc_borrowck/borrowck/unused.rs @@ -76,10 +76,14 @@ impl<'a, 'tcx> UnusedMutCx<'a, 'tcx> { } let (hir_id, span) = ids[0]; - let mut_span = tcx.sess.source_map().span_until_non_whitespace(span); + if span.compiler_desugaring_kind().is_some() { + // If the `mut` arises as part of a desugaring, we should ignore it. + continue; + } // Ok, every name wasn't used mutably, so issue a warning that this // didn't need to be mutable. + let mut_span = tcx.sess.source_map().span_until_non_whitespace(span); tcx.struct_span_lint_hir(UNUSED_MUT, hir_id, span, diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 103cb3b2a3182..0943b36440aa6 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -316,7 +316,10 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>( } let span = local_decl.source_info.span; - let mut_span = tcx.sess.source_map().span_until_non_whitespace(span); + if span.compiler_desugaring_kind().is_some() { + // If the `mut` arises as part of a desugaring, we should ignore it. + continue; + } let mut err = tcx.struct_span_lint_node( UNUSED_MUT, @@ -324,6 +327,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>( span, "variable does not need to be mutable", ); + let mut_span = tcx.sess.source_map().span_until_non_whitespace(span); err.span_suggestion_short_with_applicability( mut_span, "remove this `mut`", diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 6c3dd0ea3cc37..7ee45d7078739 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -140,7 +140,8 @@ enum CallKind { fn temp_decl(mutability: Mutability, ty: Ty, span: Span) -> LocalDecl { let source_info = SourceInfo { scope: OUTERMOST_SOURCE_SCOPE, span }; LocalDecl { - mutability, ty, + mutability, + ty, user_ty: None, name: None, source_info, diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index ee811f3379239..58ac46d22717b 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -97,7 +97,6 @@ h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod):not(.important), h4 h1.fqn { border-bottom: 1px dashed; margin-top: 0; - overflow: auto; } h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant) { border-bottom: 1px solid; diff --git a/src/libstd/sync/mod.rs b/src/libstd/sync/mod.rs index e12ef8d9eda2d..d69ebc1762272 100644 --- a/src/libstd/sync/mod.rs +++ b/src/libstd/sync/mod.rs @@ -10,10 +10,154 @@ //! Useful synchronization primitives. //! -//! This module contains useful safe and unsafe synchronization primitives. -//! Most of the primitives in this module do not provide any sort of locking -//! and/or blocking at all, but rather provide the necessary tools to build -//! other types of concurrent primitives. +//! ## The need for synchronization +//! +//! Conceptually, a Rust program is a series of operations which will +//! be executed on a computer. The timeline of events happening in the +//! program is consistent with the order of the operations in the code. +//! +//! Consider the following code, operating on some global static variables: +//! +//! ```rust +//! static mut A: u32 = 0; +//! static mut B: u32 = 0; +//! static mut C: u32 = 0; +//! +//! fn main() { +//! unsafe { +//! A = 3; +//! B = 4; +//! A = A + B; +//! C = B; +//! println!("{} {} {}", A, B, C); +//! C = A; +//! } +//! } +//! ``` +//! +//! It appears as if some variables stored in memory are changed, an addition +//! is performed, result is stored in `A` and the variable `C` is +//! modified twice. +//! +//! When only a single thread is involved, the results are as expected: +//! the line `7 4 4` gets printed. +//! +//! As for what happens behind the scenes, when optimizations are enabled the +//! final generated machine code might look very different from the code: +//! +//! - The first store to `C` might be moved before the store to `A` or `B`, +//! _as if_ we had written `C = 4; A = 3; B = 4`. +//! +//! - Assignment of `A + B` to `A` might be removed, since the sum can be stored +//! in a temporary location until it gets printed, with the global variable +//! never getting updated. +//! +//! - The final result could be determined just by looking at the code +//! at compile time, so [constant folding] might turn the whole +//! block into a simple `println!("7 4 4")`. +//! +//! The compiler is allowed to perform any combination of these +//! optimizations, as long as the final optimized code, when executed, +//! produces the same results as the one without optimizations. +//! +//! Due to the [concurrency] involved in modern computers, assumptions +//! about the program's execution order are often wrong. Access to +//! global variables can lead to nondeterministic results, **even if** +//! compiler optimizations are disabled, and it is **still possible** +//! to introduce synchronization bugs. +//! +//! Note that thanks to Rust's safety guarantees, accessing global (static) +//! variables requires `unsafe` code, assuming we don't use any of the +//! synchronization primitives in this module. +//! +//! [constant folding]: https://en.wikipedia.org/wiki/Constant_folding +//! [concurrency]: https://en.wikipedia.org/wiki/Concurrency_(computer_science) +//! +//! ## Out-of-order execution +//! +//! Instructions can execute in a different order from the one we define, due to +//! various reasons: +//! +//! - The **compiler** reordering instructions: If the compiler can issue an +//! instruction at an earlier point, it will try to do so. For example, it +//! might hoist memory loads at the top of a code block, so that the CPU can +//! start [prefetching] the values from memory. +//! +//! In single-threaded scenarios, this can cause issues when writing +//! signal handlers or certain kinds of low-level code. +//! Use [compiler fences] to prevent this reordering. +//! +//! - A **single processor** executing instructions [out-of-order]: +//! Modern CPUs are capable of [superscalar] execution, +//! i.e. multiple instructions might be executing at the same time, +//! even though the machine code describes a sequential process. +//! +//! This kind of reordering is handled transparently by the CPU. +//! +//! - A **multiprocessor** system executing multiple hardware threads +//! at the same time: In multi-threaded scenarios, you can use two +//! kinds of primitives to deal with synchronization: +//! - [memory fences] to ensure memory accesses are made visibile to +//! other CPUs in the right order. +//! - [atomic operations] to ensure simultaneous access to the same +//! memory location doesn't lead to undefined behavior. +//! +//! [prefetching]: https://en.wikipedia.org/wiki/Cache_prefetching +//! [compiler fences]: crate::sync::atomic::compiler_fence +//! [out-of-order]: https://en.wikipedia.org/wiki/Out-of-order_execution +//! [superscalar]: https://en.wikipedia.org/wiki/Superscalar_processor +//! [memory fences]: crate::sync::atomic::fence +//! [atomic operations]: crate::sync::atomic +//! +//! ## Higher-level synchronization objects +//! +//! Most of the low-level synchronization primitives are quite error-prone and +//! inconvenient to use, which is why the standard library also exposes some +//! higher-level synchronization objects. +//! +//! These abstractions can be built out of lower-level primitives. +//! For efficiency, the sync objects in the standard library are usually +//! implemented with help from the operating system's kernel, which is +//! able to reschedule the threads while they are blocked on acquiring +//! a lock. +//! +//! The following is an overview of the available synchronization +//! objects: +//! +//! - [`Arc`]: Atomically Reference-Counted pointer, which can be used +//! in multithreaded environments to prolong the lifetime of some +//! data until all the threads have finished using it. +//! +//! - [`Barrier`]: Ensures multiple threads will wait for each other +//! to reach a point in the program, before continuing execution all +//! together. +//! +//! - [`Condvar`]: Condition Variable, providing the ability to block +//! a thread while waiting for an event to occur. +//! +//! - [`mpsc`]: Multi-producer, single-consumer queues, used for +//! message-based communication. Can provide a lightweight +//! inter-thread synchronisation mechanism, at the cost of some +//! extra memory. +//! +//! - [`Mutex`]: Mutual Exclusion mechanism, which ensures that at +//! most one thread at a time is able to access some data. +//! +//! - [`Once`]: Used for thread-safe, one-time initialization of a +//! global variable. +//! +//! - [`RwLock`]: Provides a mutual exclusion mechanism which allows +//! multiple readers at the same time, while allowing only one +//! writer at a time. In some cases, this can be more efficient than +//! a mutex. +//! +//! [`Arc`]: crate::sync::Arc +//! [`Barrier`]: crate::sync::Barrier +//! [`Condvar`]: crate::sync::Condvar +//! [`mpsc`]: crate::sync::mpsc +//! [`Mutex`]: crate::sync::Mutex +//! [`Once`]: crate::sync::Once +//! [`RwLock`]: crate::sync::RwLock #![stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 9c9419c734722..9e06384f5a804 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1001,9 +1001,7 @@ impl<'a> Parser<'a> { AstFragmentKind::ForeignItems => { let mut items = SmallVec::new(); while self.token != token::Eof { - if let Some(item) = self.parse_foreign_item()? { - items.push(item); - } + items.push(self.parse_foreign_item()?); } AstFragment::ForeignItems(items) } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 5571a18b59625..d653ed819fddd 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1777,7 +1777,26 @@ impl<'a> Parser<'a> { require_name); let pat = self.parse_pat()?; - self.expect(&token::Colon)?; + if let Err(mut err) = self.expect(&token::Colon) { + // If we find a pattern followed by an identifier, it could be an (incorrect) + // C-style parameter declaration. + if self.check_ident() && self.look_ahead(1, |t| { + *t == token::Comma || *t == token::CloseDelim(token::Paren) + }) { + let ident = self.parse_ident().unwrap(); + let span = pat.span.with_hi(ident.span.hi()); + + err.span_suggestion_with_applicability( + span, + "declare the type after the parameter binding", + String::from(": "), + Applicability::HasPlaceholders, + ); + } + + return Err(err); + } + (pat, self.parse_ty()?) } else { debug!("parse_arg_general ident_to_pat"); @@ -6718,10 +6737,9 @@ impl<'a> Parser<'a> { attrs.extend(self.parse_inner_attributes()?); let mut foreign_items = vec![]; - while let Some(item) = self.parse_foreign_item()? { - foreign_items.push(item); + while !self.eat(&token::CloseDelim(token::Brace)) { + foreign_items.push(self.parse_foreign_item()?); } - self.expect(&token::CloseDelim(token::Brace))?; let prev_span = self.prev_span; let m = ast::ForeignMod { @@ -7305,8 +7323,8 @@ impl<'a> Parser<'a> { } /// Parse a foreign item. - crate fn parse_foreign_item(&mut self) -> PResult<'a, Option> { - maybe_whole!(self, NtForeignItem, |ni| Some(ni)); + crate fn parse_foreign_item(&mut self) -> PResult<'a, ForeignItem> { + maybe_whole!(self, NtForeignItem, |ni| ni); let attrs = self.parse_outer_attributes()?; let lo = self.span; @@ -7326,20 +7344,20 @@ impl<'a> Parser<'a> { ).emit(); } self.bump(); // `static` or `const` - return Ok(Some(self.parse_item_foreign_static(visibility, lo, attrs)?)); + return Ok(self.parse_item_foreign_static(visibility, lo, attrs)?); } // FOREIGN FUNCTION ITEM if self.check_keyword(keywords::Fn) { - return Ok(Some(self.parse_item_foreign_fn(visibility, lo, attrs)?)); + return Ok(self.parse_item_foreign_fn(visibility, lo, attrs)?); } // FOREIGN TYPE ITEM if self.check_keyword(keywords::Type) { - return Ok(Some(self.parse_item_foreign_type(visibility, lo, attrs)?)); + return Ok(self.parse_item_foreign_type(visibility, lo, attrs)?); } match self.parse_assoc_macro_invoc("extern", Some(&visibility), &mut false)? { Some(mac) => { - Ok(Some( + Ok( ForeignItem { ident: keywords::Invalid.ident(), span: lo.to(self.prev_span), @@ -7348,14 +7366,14 @@ impl<'a> Parser<'a> { vis: visibility, node: ForeignItemKind::Macro(mac), } - )) + ) } None => { - if !attrs.is_empty() { + if !attrs.is_empty() { self.expected_item_err(&attrs); } - Ok(None) + self.unexpected() } } } diff --git a/src/test/parse-fail/duplicate-visibility.rs b/src/test/parse-fail/duplicate-visibility.rs index 6899caa7153bb..cc3286fe70512 100644 --- a/src/test/parse-fail/duplicate-visibility.rs +++ b/src/test/parse-fail/duplicate-visibility.rs @@ -10,7 +10,7 @@ // compile-flags: -Z parse-only -// error-pattern:expected one of `(`, `fn`, `static`, `type`, or `}` here +// error-pattern:expected one of `(`, `fn`, `static`, or `type` extern { pub pub fn foo(); } diff --git a/src/test/ui/issues/issue-13058.nll.stderr b/src/test/ui/issues/issue-13058.nll.stderr index 33c0eefbfaa28..0d641ec8e891a 100644 --- a/src/test/ui/issues/issue-13058.nll.stderr +++ b/src/test/ui/issues/issue-13058.nll.stderr @@ -1,15 +1,12 @@ -error[E0308]: mismatched types - --> $DIR/issue-13058.rs:36:11 +error[E0621]: explicit lifetime required in the type of `cont` + --> $DIR/issue-13058.rs:24:21 | -LL | check((3, 5)); - | ^^^^^^ - | | - | expected reference, found tuple - | help: consider borrowing here: `&(3, 5)` - | - = note: expected type `&_` - found type `({integer}, {integer})` +LL | fn check<'r, I: Iterator, T: Itble<'r, usize, I>>(cont: &T) -> bool + | -- help: add explicit lifetime `'r` to the type of `cont`: `&'r T` +LL | { +LL | let cont_iter = cont.iter(); + | ^^^^^^^^^^^ lifetime `'r` required error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/issues/issue-13058.rs b/src/test/ui/issues/issue-13058.rs index dbcf9998ad937..cabf02194776a 100644 --- a/src/test/ui/issues/issue-13058.rs +++ b/src/test/ui/issues/issue-13058.rs @@ -33,6 +33,5 @@ fn check<'r, I: Iterator, T: Itble<'r, usize, I>>(cont: &T) -> bool } fn main() { - check((3, 5)); -//~^ ERROR mismatched types + check(&(3, 5)); } diff --git a/src/test/ui/issues/issue-13058.stderr b/src/test/ui/issues/issue-13058.stderr index 5e8319d26ad3c..ee39678736cdd 100644 --- a/src/test/ui/issues/issue-13058.stderr +++ b/src/test/ui/issues/issue-13058.stderr @@ -7,19 +7,6 @@ LL | { LL | let cont_iter = cont.iter(); | ^^^^ lifetime `'r` required -error[E0308]: mismatched types - --> $DIR/issue-13058.rs:36:11 - | -LL | check((3, 5)); - | ^^^^^^ - | | - | expected reference, found tuple - | help: consider borrowing here: `&(3, 5)` - | - = note: expected type `&_` - found type `({integer}, {integer})` - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0308, E0621. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/macros/issue-54441.rs b/src/test/ui/macros/issue-54441.rs new file mode 100644 index 0000000000000..b45aedb549ecd --- /dev/null +++ b/src/test/ui/macros/issue-54441.rs @@ -0,0 +1,13 @@ +#![feature(macros_in_extern)] + +macro_rules! m { + () => { + let //~ ERROR expected + }; +} + +extern "C" { + m!(); +} + +fn main() {} diff --git a/src/test/ui/macros/issue-54441.stderr b/src/test/ui/macros/issue-54441.stderr new file mode 100644 index 0000000000000..aa1edb2cf893f --- /dev/null +++ b/src/test/ui/macros/issue-54441.stderr @@ -0,0 +1,14 @@ +error: expected one of `crate`, `fn`, `pub`, `static`, or `type`, found `let` + --> $DIR/issue-54441.rs:5:9 + | +LL | #![feature(macros_in_extern)] + | - expected one of `crate`, `fn`, `pub`, `static`, or `type` here +... +LL | let //~ ERROR expected + | ^^^ unexpected token +... +LL | m!(); + | ----- in this macro invocation + +error: aborting due to previous error + diff --git a/src/test/ui/mut/no-mut-lint-for-desugared-mut.rs b/src/test/ui/mut/no-mut-lint-for-desugared-mut.rs new file mode 100644 index 0000000000000..419d580419f42 --- /dev/null +++ b/src/test/ui/mut/no-mut-lint-for-desugared-mut.rs @@ -0,0 +1,8 @@ +// run-pass + +#![deny(unused_mut)] +#![allow(unreachable_code)] + +fn main() { + for _ in { return (); 0..3 } {} // ok +} diff --git a/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs b/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs new file mode 100644 index 0000000000000..a114d7092ecf9 --- /dev/null +++ b/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs @@ -0,0 +1,42 @@ +#![feature(nll)] +// compile-pass + +// rust-lang/rust#32382: Borrow checker used to complain about +// `foobar_3` in the `impl` below, presumably due to some interaction +// between the use of a lifetime in the associated type and the use of +// the overloaded operator[]. This regression test ensures that we do +// not resume complaining about it in the future. + + +use std::marker::PhantomData; +use std::ops::Index; + +pub trait Context: Clone { + type Container: ?Sized; + fn foobar_1( container: &Self::Container ) -> &str; + fn foobar_2( container: &Self::Container ) -> &str; + fn foobar_3( container: &Self::Container ) -> &str; +} + +#[derive(Clone)] +struct Foobar<'a> { + phantom: PhantomData<&'a ()> +} + +impl<'a> Context for Foobar<'a> { + type Container = [&'a str]; + + fn foobar_1<'r>( container: &'r [&'a str] ) -> &'r str { + container[0] + } + + fn foobar_2<'r>( container: &'r Self::Container ) -> &'r str { + container.index( 0 ) + } + + fn foobar_3<'r>( container: &'r Self::Container ) -> &'r str { + container[0] + } +} + +fn main() { } diff --git a/src/test/ui/parser/inverted-parameters.rs b/src/test/ui/parser/inverted-parameters.rs new file mode 100644 index 0000000000000..a100debbf1242 --- /dev/null +++ b/src/test/ui/parser/inverted-parameters.rs @@ -0,0 +1,39 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct S; + +impl S { + fn foo(&self, &str bar) {} + //~^ ERROR expected one of `:` or `@` + //~| HELP declare the type after the parameter binding + //~| SUGGESTION : +} + +fn baz(S quux, xyzzy: i32) {} +//~^ ERROR expected one of `:` or `@` +//~| HELP declare the type after the parameter binding +//~| SUGGESTION : + +fn one(i32 a b) {} +//~^ ERROR expected one of `:` or `@` + +fn pattern((i32, i32) (a, b)) {} +//~^ ERROR expected `:` + +fn fizz(i32) {} +//~^ ERROR expected one of `:` or `@` + +fn missing_colon(quux S) {} +//~^ ERROR expected one of `:` or `@` +//~| HELP declare the type after the parameter binding +//~| SUGGESTION : + +fn main() {} diff --git a/src/test/ui/parser/inverted-parameters.stderr b/src/test/ui/parser/inverted-parameters.stderr new file mode 100644 index 0000000000000..3f4f0615bc8f7 --- /dev/null +++ b/src/test/ui/parser/inverted-parameters.stderr @@ -0,0 +1,47 @@ +error: expected one of `:` or `@`, found `bar` + --> $DIR/inverted-parameters.rs:14:24 + | +LL | fn foo(&self, &str bar) {} + | -----^^^ + | | | + | | expected one of `:` or `@` here + | help: declare the type after the parameter binding: `: ` + +error: expected one of `:` or `@`, found `quux` + --> $DIR/inverted-parameters.rs:20:10 + | +LL | fn baz(S quux, xyzzy: i32) {} + | --^^^^ + | | | + | | expected one of `:` or `@` here + | help: declare the type after the parameter binding: `: ` + +error: expected one of `:` or `@`, found `a` + --> $DIR/inverted-parameters.rs:25:12 + | +LL | fn one(i32 a b) {} + | ^ expected one of `:` or `@` here + +error: expected `:`, found `(` + --> $DIR/inverted-parameters.rs:28:23 + | +LL | fn pattern((i32, i32) (a, b)) {} + | ^ expected `:` + +error: expected one of `:` or `@`, found `)` + --> $DIR/inverted-parameters.rs:31:12 + | +LL | fn fizz(i32) {} + | ^ expected one of `:` or `@` here + +error: expected one of `:` or `@`, found `S` + --> $DIR/inverted-parameters.rs:34:23 + | +LL | fn missing_colon(quux S) {} + | -----^ + | | | + | | expected one of `:` or `@` here + | help: declare the type after the parameter binding: `: ` + +error: aborting due to 6 previous errors +