Auto merge of #54859 - pietroalbini:rollup, r=pietroalbini
Rollup of 11 pull requests Successful merges: - #54078 (Expand the documentation for the `std::sync` module) - #54717 (Cleanup rustc/ty part 1) - #54781 (Add examples to `TyKind::FnDef` and `TyKind::FnPtr` docs) - #54787 (Only warn about unused `mut` in user-written code) - #54804 (add suggestion for inverted function parameters) - #54812 (Regression test for #32382.) - #54833 (make `Parser::parse_foreign_item()` return a foreign item or error) - #54834 (rustdoc: overflow:auto doesn't work nicely on small screens) - #54838 (Fix typo in src/libsyntax/parse/parser.rs) - #54851 (Fix a regression in 1.30 by reverting #53564) - #54853 (Remove unneccessary error from test, revealing NLL error.) Failed merges: r? @ghost
This commit is contained in:
commit
ac841e7450
31 changed files with 793 additions and 500 deletions
|
@ -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<T> VecDeque<T> {
|
|||
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<T> VecDeque<T> {
|
|||
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<T> VecDeque<T> {
|
|||
#[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<T> From<VecDeque<T>> for Vec<T> {
|
|||
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;
|
||||
|
|
|
@ -4132,16 +4132,16 @@ impl<'a> LoweringContext<'a> {
|
|||
// expand <head>
|
||||
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 <pat> = __next`
|
||||
let pat = self.lower_pat(pat);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
// 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::<Result<Vec<_>, _>>()?,
|
||||
decoder.with_position(shorthand, ty::Predicate::decode)
|
||||
} else {
|
||||
ty::Predicate::decode(decoder)
|
||||
}?;
|
||||
Ok((predicate, Decodable::decode(decoder)?))
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
{
|
||||
|
|
|
@ -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<DefId>,
|
|||
|
||||
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<Ty<'tcx>> {
|
||||
|
@ -686,7 +683,7 @@ impl<'tcx> TypeckTables<'tcx> {
|
|||
}
|
||||
|
||||
pub fn pat_adjustments_mut(&mut self)
|
||||
-> LocalTableInContextMut<'_, Vec<Ty<'tcx>>> {
|
||||
-> LocalTableInContextMut<'_, Vec<Ty<'tcx>>> {
|
||||
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 }))
|
||||
}
|
||||
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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<'_>) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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::<M>() };
|
||||
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<Self::Value> {
|
||||
id: SerializedDepNodeIndex)
|
||||
-> Option<Self::Value> {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<QueryJob<'tcx>>,
|
||||
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<Lrc<QueryJob<'tcx>>> = 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::<u64>::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
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -254,23 +254,19 @@ impl<'sess> OnDiskCache<'sess> {
|
|||
})?;
|
||||
|
||||
// Encode diagnostics
|
||||
let diagnostics_index = {
|
||||
let mut diagnostics_index = EncodedDiagnosticsIndex::new();
|
||||
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)?;
|
||||
|
||||
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
|
||||
};
|
||||
Ok((dep_node_index, pos))
|
||||
})
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
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::<FxHashMap<_,_>>();
|
||||
|
||||
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<Span> 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) {
|
||||
|
|
|
@ -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()),
|
||||
_ => (),
|
||||
}
|
||||
})*
|
||||
$(
|
||||
jobs.extend(
|
||||
self.$name.try_lock().unwrap().active.values().filter_map(|v|
|
||||
if let QueryResult::Started(ref job) = *v {
|
||||
Some(job.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
)
|
||||
);
|
||||
)*
|
||||
|
||||
return jobs;
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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`",
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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")]
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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("<identifier>: <type>"),
|
||||
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<ForeignItem>> {
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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<Item=usize>, 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`.
|
||||
|
|
|
@ -33,6 +33,5 @@ fn check<'r, I: Iterator<Item=usize>, T: Itble<'r, usize, I>>(cont: &T) -> bool
|
|||
}
|
||||
|
||||
fn main() {
|
||||
check((3, 5));
|
||||
//~^ ERROR mismatched types
|
||||
check(&(3, 5));
|
||||
}
|
||||
|
|
|
@ -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 previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
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`.
|
||||
|
|
13
src/test/ui/macros/issue-54441.rs
Normal file
13
src/test/ui/macros/issue-54441.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
#![feature(macros_in_extern)]
|
||||
|
||||
macro_rules! m {
|
||||
() => {
|
||||
let //~ ERROR expected
|
||||
};
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
m!();
|
||||
}
|
||||
|
||||
fn main() {}
|
14
src/test/ui/macros/issue-54441.stderr
Normal file
14
src/test/ui/macros/issue-54441.stderr
Normal file
|
@ -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
|
||||
|
8
src/test/ui/mut/no-mut-lint-for-desugared-mut.rs
Normal file
8
src/test/ui/mut/no-mut-lint-for-desugared-mut.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
// run-pass
|
||||
|
||||
#![deny(unused_mut)]
|
||||
#![allow(unreachable_code)]
|
||||
|
||||
fn main() {
|
||||
for _ in { return (); 0..3 } {} // ok
|
||||
}
|
|
@ -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() { }
|
39
src/test/ui/parser/inverted-parameters.rs
Normal file
39
src/test/ui/parser/inverted-parameters.rs
Normal file
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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 <identifier>: <type>
|
||||
}
|
||||
|
||||
fn baz(S quux, xyzzy: i32) {}
|
||||
//~^ ERROR expected one of `:` or `@`
|
||||
//~| HELP declare the type after the parameter binding
|
||||
//~| SUGGESTION <identifier>: <type>
|
||||
|
||||
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 <identifier>: <type>
|
||||
|
||||
fn main() {}
|
47
src/test/ui/parser/inverted-parameters.stderr
Normal file
47
src/test/ui/parser/inverted-parameters.stderr
Normal file
|
@ -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: `<identifier>: <type>`
|
||||
|
||||
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: `<identifier>: <type>`
|
||||
|
||||
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: `<identifier>: <type>`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue