Auto merge of #66403 - JohnTitor:rollup-7obuivl, r=JohnTitor

Rollup of 9 pull requests

Successful merges:

 - #66253 (Improve errors after re rebalance coherence)
 - #66264 (fix an ICE in macro's diagnostic message)
 - #66349 (expand source_util macros with def-site context)
 - #66351 (Tweak non-char/numeric in range pattern diagnostic)
 - #66360 (Fix link to Exten in Vec::set_len)
 - #66361 (parser: don't use `unreachable!()` in `fn unexpected`.)
 - #66363 (Improve error message in make_tests)
 - #66369 (compiletest: Obtain timestamps for common inputs only once)
 - #66372 (Fix broken links in Ipv4Addr::is_benchmarking docs)

Failed merges:

r? @ghost
This commit is contained in:
bors 2019-11-14 08:03:01 +00:00
commit a2491ee4e6
44 changed files with 431 additions and 238 deletions

View File

@ -861,7 +861,7 @@ pub fn as_mut_ptr(&mut self) -> *mut T {
///
/// [`truncate`]: #method.truncate
/// [`resize`]: #method.resize
/// [`extend`]: #method.extend-1
/// [`extend`]: ../../std/iter/trait.Extend.html#tymethod.extend
/// [`clear`]: #method.clear
///
/// # Safety

View File

@ -238,7 +238,7 @@ pub fn trait_ref_is_local_or_fundamental<'tcx>(
pub enum OrphanCheckErr<'tcx> {
NonLocalInputType(Vec<(Ty<'tcx>, bool /* Is this the first input type? */)>),
UncoveredTy(Ty<'tcx>),
UncoveredTy(Ty<'tcx>, Option<Ty<'tcx>>),
}
/// Checks the coherence orphan rules. `impl_def_id` should be the
@ -402,7 +402,15 @@ fn uncover_fundamental_ty<'tcx>(
return Ok(());
} else if let ty::Param(_) = input_ty.kind {
debug!("orphan_check_trait_ref: uncovered ty: `{:?}`", input_ty);
return Err(OrphanCheckErr::UncoveredTy(input_ty))
let local_type = trait_ref
.input_types()
.flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate))
.filter(|ty| ty_is_non_local_constructor(tcx, ty, in_crate).is_none())
.next();
debug!("orphan_check_trait_ref: uncovered ty local_type: `{:?}`", local_type);
return Err(OrphanCheckErr::UncoveredTy(input_ty, local_type))
}
if let Some(non_local_tys) = non_local_tys {
for input_ty in non_local_tys {

View File

@ -1742,14 +1742,25 @@ fn complain_if_pub_macro(&self, vis: &VisibilityKind, sp: Span) {
}
fn report_invalid_macro_expansion_item(&self) {
let has_close_delim = self.sess.source_map()
.span_to_snippet(self.prev_span)
.map(|s| s.ends_with(")") || s.ends_with("]"))
.unwrap_or(false);
let right_brace_span = if has_close_delim {
// it's safe to peel off one character only when it has the close delim
self.prev_span.with_lo(self.prev_span.hi() - BytePos(1))
} else {
self.sess.source_map().next_point(self.prev_span)
};
self.struct_span_err(
self.prev_span,
"macros that expand to items must be delimited with braces or followed by a semicolon",
).multipart_suggestion(
"change the delimiters to curly braces",
vec![
(self.prev_span.with_hi(self.prev_span.lo() + BytePos(1)), String::from(" {")),
(self.prev_span.with_lo(self.prev_span.hi() - BytePos(1)), '}'.to_string()),
(self.prev_span.with_hi(self.prev_span.lo() + BytePos(1)), "{".to_string()),
(right_brace_span, '}'.to_string()),
],
Applicability::MaybeIncorrect,
).span_suggestion(

View File

@ -443,7 +443,9 @@ pub(super) fn this_token_descr(&self) -> String {
crate fn unexpected<T>(&mut self) -> PResult<'a, T> {
match self.expect_one_of(&[], &[]) {
Err(e) => Err(e),
Ok(_) => unreachable!(),
// We can get `Ok(true)` from `recover_closing_delimiter`
// which is called in `expected_one_of_not_found`.
Ok(_) => FatalError.raise(),
}
}

View File

@ -362,37 +362,13 @@ fn check_pat_range(
|| ty.is_char()
|| ty.references_error()
};
let lhs_compat = numeric_or_char(lhs_ty);
let rhs_compat = numeric_or_char(rhs_ty);
let lhs_fail = !numeric_or_char(lhs_ty);
let rhs_fail = !numeric_or_char(rhs_ty);
if !lhs_compat || !rhs_compat {
let span = if !lhs_compat && !rhs_compat {
span
} else if !lhs_compat {
begin.span
} else {
end.span
};
let mut err = struct_span_err!(
self.tcx.sess,
span,
E0029,
"only char and numeric types are allowed in range patterns"
if lhs_fail || rhs_fail {
self.emit_err_pat_range(
span, begin.span, end.span, lhs_fail, rhs_fail, lhs_ty, rhs_ty
);
err.span_label(span, "ranges require char or numeric types");
err.note(&format!("start type: {}", self.ty_to_string(lhs_ty)));
err.note(&format!("end type: {}", self.ty_to_string(rhs_ty)));
if self.tcx.sess.teach(&err.get_code().unwrap()) {
err.note(
"In a match expression, only numbers and characters can be matched \
against a range. This is because the compiler checks that the range \
is non-empty at compile-time, and is unable to evaluate arbitrary \
comparison functions. If you want to capture values of an orderable \
type between two end-points, you can use a guard."
);
}
err.emit();
return None;
}
@ -406,6 +382,62 @@ fn check_pat_range(
Some(common_type)
}
fn emit_err_pat_range(
&self,
span: Span,
begin_span: Span,
end_span: Span,
lhs_fail: bool,
rhs_fail: bool,
lhs_ty: Ty<'tcx>,
rhs_ty: Ty<'tcx>,
) {
let span = if lhs_fail && rhs_fail {
span
} else if lhs_fail {
begin_span
} else {
end_span
};
let mut err = struct_span_err!(
self.tcx.sess,
span,
E0029,
"only char and numeric types are allowed in range patterns"
);
let msg = |ty| {
format!("this is of type `{}` but it should be `char` or numeric", ty)
};
let mut one_side_err = |first_span, first_ty, second_span, second_ty: Ty<'_>| {
err.span_label(first_span, &msg(first_ty));
if !second_ty.references_error() {
err.span_label(
second_span,
&format!("this is of type `{}`", second_ty)
);
}
};
if lhs_fail && rhs_fail {
err.span_label(begin_span, &msg(lhs_ty));
err.span_label(end_span, &msg(rhs_ty));
} else if lhs_fail {
one_side_err(begin_span, lhs_ty, end_span, rhs_ty);
} else {
one_side_err(end_span, rhs_ty, begin_span, lhs_ty);
}
if self.tcx.sess.teach(&err.get_code().unwrap()) {
err.note(
"In a match expression, only numbers and characters can be matched \
against a range. This is because the compiler checks that the range \
is non-empty at compile-time, and is unable to evaluate arbitrary \
comparison functions. If you want to capture values of an orderable \
type between two end-points, you can use a guard."
);
}
err.emit();
}
fn check_pat_ident(
&self,
pat: &Pat,

View File

@ -77,30 +77,58 @@ fn visit_item(&mut self, item: &hir::Item) {
err.emit();
return;
}
Err(traits::OrphanCheckErr::UncoveredTy(param_ty)) => {
Err(traits::OrphanCheckErr::UncoveredTy(param_ty, local_type)) => {
let mut sp = sp;
for param in &generics.params {
if param.name.ident().to_string() == param_ty.to_string() {
sp = param.span;
}
}
let mut err = struct_span_err!(
self.tcx.sess,
sp,
E0210,
"type parameter `{}` must be used as the type parameter for some local \
type (e.g., `MyStruct<{}>`)",
param_ty,
param_ty
);
err.span_label(sp, format!(
"type parameter `{}` must be used as the type parameter for some local \
type",
param_ty,
));
err.note("only traits defined in the current crate can be implemented for a \
type parameter");
err.emit();
match local_type {
Some(local_type) => {
struct_span_err!(
self.tcx.sess,
sp,
E0210,
"type parameter `{}` must be covered by another type \
when it appears before the first local type (`{}`)",
param_ty,
local_type
).span_label(sp, format!(
"type parameter `{}` must be covered by another type \
when it appears before the first local type (`{}`)",
param_ty,
local_type
)).note("implementing a foreign trait is only possible if at \
least one of the types for which is it implemented is local, \
and no uncovered type parameters appear before that first \
local type"
).note("in this case, 'before' refers to the following order: \
`impl<..> ForeignTrait<T1, ..., Tn> for T0`, \
where `T0` is the first and `Tn` is the last"
).emit();
}
None => {
struct_span_err!(
self.tcx.sess,
sp,
E0210,
"type parameter `{}` must be used as the type parameter for some \
local type (e.g., `MyStruct<{}>`)",
param_ty,
param_ty
).span_label(sp, format!(
"type parameter `{}` must be used as the type parameter for some \
local type",
param_ty,
)).note("implementing a foreign trait is only possible if at \
least one of the types for which is it implemented is local"
).note("only traits defined in the current crate can be \
implemented for a type parameter"
).emit();
}
};
return;
}
}

View File

@ -2114,8 +2114,13 @@ fn make(&mut self) -> Foo<T> {
This error indicates a violation of one of Rust's orphan rules for trait
implementations. The rule concerns the use of type parameters in an
implementation of a foreign trait (a trait defined in another crate), and
states that type parameters must be "covered" by a local type. To understand
what this means, it is perhaps easiest to consider a few examples.
states that type parameters must be "covered" by a local type.
When implementing a foreign trait for a foreign type,
the trait must have one or more type parameters.
A type local to your crate must appear before any use of any type parameters.
To understand what this means, it is perhaps easier to consider a few examples.
If `ForeignTrait` is a trait defined in some external crate `foo`, then the
following trait `impl` is an error:
@ -2173,12 +2178,18 @@ impl<P1, ..., Pm> ForeignTrait<T1, ..., Tn> for T0 { ... }
where `P1, ..., Pm` are the type parameters of the `impl` and `T0, ..., Tn`
are types. One of the types `T0, ..., Tn` must be a local type (this is another
orphan rule, see the explanation for E0117). Let `i` be the smallest integer
such that `Ti` is a local type. Then no type parameter can appear in any of the
`Tj` for `j < i`.
orphan rule, see the explanation for E0117).
For information on the design of the orphan rules, see [RFC 1023].
Both of the following must be true:
1. At least one of the types `T0..=Tn` must be a local type.
Let `Ti` be the first such type.
2. No uncovered type parameters `P1..=Pm` may appear in `T0..Ti`
(excluding `Ti`).
For information on the design of the orphan rules,
see [RFC 2451] and [RFC 1023].
[RFC 2451]: https://rust-lang.github.io/rfcs/2451-re-rebalancing-coherence.html
[RFC 1023]: https://github.com/rust-lang/rfcs/blob/master/text/1023-rebalancing-coherence.md
"##,

View File

@ -633,8 +633,8 @@ pub fn is_ietf_protocol_assignment(&self) -> bool {
/// network devices benchmarking. This range is defined in [IETF RFC 2544] as `192.18.0.0`
/// through `198.19.255.255` but [errata 423] corrects it to `198.18.0.0/15`.
///
/// [IETF RFC 1112]: https://tools.ietf.org/html/rfc1112
/// [errate 423]: https://www.rfc-editor.org/errata/eid423
/// [IETF RFC 2544]: https://tools.ietf.org/html/rfc2544
/// [errata 423]: https://www.rfc-editor.org/errata/eid423
/// [`true`]: ../../std/primitive.bool.html
///
/// # Examples

View File

@ -21,6 +21,7 @@
/// line!(): expands to the current line number
pub fn expand_line(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
-> Box<dyn base::MacResult+'static> {
let sp = cx.with_def_site_ctxt(sp);
base::check_zero_tts(cx, sp, tts, "line!");
let topmost = cx.expansion_cause().unwrap_or(sp);
@ -32,6 +33,7 @@ pub fn expand_line(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
/* column!(): expands to the current column number */
pub fn expand_column(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
-> Box<dyn base::MacResult+'static> {
let sp = cx.with_def_site_ctxt(sp);
base::check_zero_tts(cx, sp, tts, "column!");
let topmost = cx.expansion_cause().unwrap_or(sp);
@ -45,6 +47,7 @@ pub fn expand_column(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
/// out if we wanted.
pub fn expand_file(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
-> Box<dyn base::MacResult+'static> {
let sp = cx.with_def_site_ctxt(sp);
base::check_zero_tts(cx, sp, tts, "file!");
let topmost = cx.expansion_cause().unwrap_or(sp);
@ -54,12 +57,14 @@ pub fn expand_file(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
pub fn expand_stringify(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
-> Box<dyn base::MacResult+'static> {
let sp = cx.with_def_site_ctxt(sp);
let s = pprust::tts_to_string(tts);
base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&s)))
}
pub fn expand_mod(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
-> Box<dyn base::MacResult+'static> {
let sp = cx.with_def_site_ctxt(sp);
base::check_zero_tts(cx, sp, tts, "module_path!");
let mod_path = &cx.current_expansion.module.mod_path;
let string = mod_path.iter().map(|x| x.to_string()).collect::<Vec<String>>().join("::");
@ -72,6 +77,7 @@ pub fn expand_mod(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
/// unhygienically.
pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
-> Box<dyn base::MacResult+'cx> {
let sp = cx.with_def_site_ctxt(sp);
let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
Some(f) => f,
None => return DummyResult::any(sp),
@ -125,6 +131,7 @@ fn make_expr(mut self: Box<ExpandResult<'a>>) -> Option<P<ast::Expr>> {
// include_str! : read the given file, insert it as a literal string expr
pub fn expand_include_str(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
-> Box<dyn base::MacResult+'static> {
let sp = cx.with_def_site_ctxt(sp);
let file = match get_single_str_from_tts(cx, sp, tts, "include_str!") {
Some(f) => f,
None => return DummyResult::any(sp)
@ -156,6 +163,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
pub fn expand_include_bytes(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
-> Box<dyn base::MacResult+'static> {
let sp = cx.with_def_site_ctxt(sp);
let file = match get_single_str_from_tts(cx, sp, tts, "include_bytes!") {
Some(f) => f,
None => return DummyResult::any(sp)

View File

@ -4,6 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc
LL | impl<T> Remote1<T> for isize { }
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error: aborting due to previous error

View File

@ -1,10 +1,11 @@
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`BigInt`)
--> $DIR/coherence-bigint-param.rs:8:6
|
LL | impl<T> Remote1<BigInt> for T { }
| ^ type parameter `T` must be used as the type parameter for some local type
| ^ type parameter `T` must be covered by another type when it appears before the first local type (`BigInt`)
|
= note: only traits defined in the current crate can be implemented for a type parameter
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local, and no uncovered type parameters appear before that first local type
= note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
error: aborting due to previous error

View File

@ -13,6 +13,7 @@ error[E0210]: type parameter `A` must be used as the type parameter for some loc
LL | impl<A> Foo for A {
| ^ type parameter `A` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error: aborting due to 2 previous errors

View File

@ -4,6 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc
LL | impl<T> Remote for T { }
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error: aborting due to previous error

View File

@ -4,6 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc
LL | impl<T> Remote for Box<T> {
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error: aborting due to previous error

View File

@ -4,6 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc
LL | impl<T> Remote1<u32> for Box<T> {
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
@ -12,6 +13,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc
LL | impl<'a, T> Remote1<u32> for &'a T {
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error: aborting due to 2 previous errors

View File

@ -4,6 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc
LL | impl<T> Remote1<u32> for T {
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error: aborting due to previous error

View File

@ -4,6 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc
LL | impl<T> Remote1<Box<T>> for u32 {
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
@ -12,6 +13,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc
LL | impl<'a, T> Remote1<&'a T> for u32 {
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error: aborting due to 2 previous errors

View File

@ -4,6 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc
LL | impl<'a, T> Remote1<Box<T>> for &'a T {
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
@ -12,6 +13,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc
LL | impl<'a, T> Remote1<&'a T> for Box<T> {
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error: aborting due to 2 previous errors

View File

@ -4,6 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc
LL | impl<T> Remote1<Box<T>> for T {
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
@ -12,6 +13,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc
LL | impl<'a, T> Remote1<&'a T> for T {
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error: aborting due to 2 previous errors

View File

@ -8,11 +8,11 @@
struct Local;
impl<T> Remote2<Box<T>, Local> for u32 {
//~^ ERROR type parameter `T` must be used as the type parameter for some local type
//~^ ERROR type parameter `T` must be covered by another type
}
impl<'a, T> Remote2<&'a T, Local> for u32 {
//~^ ERROR type parameter `T` must be used as the type parameter for some local type
//~^ ERROR type parameter `T` must be covered by another type
}
fn main() {}

View File

@ -1,18 +1,20 @@
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
--> $DIR/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs:10:6
|
LL | impl<T> Remote2<Box<T>, Local> for u32 {
| ^ type parameter `T` must be used as the type parameter for some local type
| ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
|
= note: only traits defined in the current crate can be implemented for a type parameter
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local, and no uncovered type parameters appear before that first local type
= note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
--> $DIR/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs:14:10
|
LL | impl<'a, T> Remote2<&'a T, Local> for u32 {
| ^ type parameter `T` must be used as the type parameter for some local type
| ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
|
= note: only traits defined in the current crate can be implemented for a type parameter
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local, and no uncovered type parameters appear before that first local type
= note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
error: aborting due to 2 previous errors

View File

@ -8,11 +8,11 @@
struct Local;
impl<T> Remote1<Local> for Box<T> {
//~^ ERROR type parameter `T` must be used as the type parameter for some local type
//~^ ERROR type parameter `T` must be covered by another type
}
impl<T> Remote1<Local> for &T {
//~^ ERROR type parameter `T` must be used as the type parameter for some local type
//~^ ERROR type parameter `T` must be covered by another type
}
fn main() {}

View File

@ -1,18 +1,20 @@
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
--> $DIR/impl[t]-foreign[local]-for-fundamental[t].rs:10:6
|
LL | impl<T> Remote1<Local> for Box<T> {
| ^ type parameter `T` must be used as the type parameter for some local type
| ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
|
= note: only traits defined in the current crate can be implemented for a type parameter
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local, and no uncovered type parameters appear before that first local type
= note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
--> $DIR/impl[t]-foreign[local]-for-fundamental[t].rs:14:6
|
LL | impl<T> Remote1<Local> for &T {
| ^ type parameter `T` must be used as the type parameter for some local type
| ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
|
= note: only traits defined in the current crate can be implemented for a type parameter
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local, and no uncovered type parameters appear before that first local type
= note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
error: aborting due to 2 previous errors

View File

@ -8,7 +8,7 @@
struct Local;
impl<T> Remote1<Local> for T {
//~^ ERROR type parameter `T` must be used as the type parameter for some local type
//~^ ERROR type parameter `T` must be covered by another type
}
fn main() {}

View File

@ -1,10 +1,11 @@
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
--> $DIR/impl[t]-foreign[local]-for-t.rs:10:6
|
LL | impl<T> Remote1<Local> for T {
| ^ type parameter `T` must be used as the type parameter for some local type
| ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
|
= note: only traits defined in the current crate can be implemented for a type parameter
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local, and no uncovered type parameters appear before that first local type
= note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
error: aborting due to previous error

View File

@ -4,6 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc
LL | impl<T> Remote1<T> for u32 {
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error: aborting due to previous error

View File

@ -4,6 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc
LL | impl<T> Remote1<T> for Box<T> {
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error[E0210]: type parameter `B` must be used as the type parameter for some local type (e.g., `MyStruct<B>`)
@ -12,6 +13,7 @@ error[E0210]: type parameter `B` must be used as the type parameter for some loc
LL | impl<'a, A, B> Remote1<A> for &'a B {
| ^ type parameter `B` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error: aborting due to 2 previous errors

View File

@ -4,6 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc
LL | impl<T> Remote1<T> for T {
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error: aborting due to previous error

View File

@ -2,10 +2,11 @@ error[E0029]: only char and numeric types are allowed in range patterns
--> $DIR/E0029-teach.rs:7:9
|
LL | "hello" ..= "world" => {}
| ^^^^^^^^^^^^^^^^^^^ ranges require char or numeric types
| -------^^^^^-------
| | |
| | this is of type `&'static str` but it should be `char` or numeric
| this is of type `&'static str` but it should be `char` or numeric
|
= note: start type: &'static str
= note: end type: &'static str
= note: In a match expression, only numbers and characters can be matched against a range. This is because the compiler checks that the range is non-empty at compile-time, and is unable to evaluate arbitrary comparison functions. If you want to capture values of an orderable type between two end-points, you can use a guard.
error: aborting due to previous error

View File

@ -2,10 +2,10 @@ error[E0029]: only char and numeric types are allowed in range patterns
--> $DIR/E0029.rs:5:9
|
LL | "hello" ..= "world" => {}
| ^^^^^^^^^^^^^^^^^^^ ranges require char or numeric types
|
= note: start type: &'static str
= note: end type: &'static str
| -------^^^^^-------
| | |
| | this is of type `&'static str` but it should be `char` or numeric
| this is of type `&'static str` but it should be `char` or numeric
error: aborting due to previous error

View File

@ -14,6 +14,7 @@ error[E0210]: type parameter `Foo` must be used as the type parameter for some l
LL | impl<Foo> Deref for Foo { }
| ^^^ type parameter `Foo` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error: aborting due to 2 previous errors

View File

@ -21,6 +21,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc
LL | impl<T> Drop for T where T: A {
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error: aborting due to 3 previous errors

View File

@ -3,15 +3,16 @@ fn main() {
"bar" ..= "foo" => { }
};
//~^^ ERROR only char and numeric types are allowed in range
//~| start type: &'static str
//~| end type: &'static str
match "wow" {
10 ..= "what" => ()
};
//~^^ ERROR only char and numeric types are allowed in range
//~| start type: {integer}
//~| end type: &'static str
match "wow" {
true ..= "what" => {}
};
//~^^ ERROR only char and numeric types are allowed in range
match 5 {
'c' ..= 100 => { }

View File

@ -2,22 +2,30 @@ error[E0029]: only char and numeric types are allowed in range patterns
--> $DIR/match-range-fail.rs:3:9
|
LL | "bar" ..= "foo" => { }
| ^^^^^^^^^^^^^^^ ranges require char or numeric types
|
= note: start type: &'static str
= note: end type: &'static str
| -----^^^^^-----
| | |
| | this is of type `&'static str` but it should be `char` or numeric
| this is of type `&'static str` but it should be `char` or numeric
error[E0029]: only char and numeric types are allowed in range patterns
--> $DIR/match-range-fail.rs:10:16
--> $DIR/match-range-fail.rs:8:16
|
LL | 10 ..= "what" => ()
| ^^^^^^ ranges require char or numeric types
| -- ^^^^^^ this is of type `&'static str` but it should be `char` or numeric
| |
| this is of type `{integer}`
error[E0029]: only char and numeric types are allowed in range patterns
--> $DIR/match-range-fail.rs:13:9
|
= note: start type: {integer}
= note: end type: &'static str
LL | true ..= "what" => {}
| ----^^^^^------
| | |
| | this is of type `&'static str` but it should be `char` or numeric
| this is of type `bool` but it should be `char` or numeric
error[E0308]: mismatched types
--> $DIR/match-range-fail.rs:17:9
--> $DIR/match-range-fail.rs:18:9
|
LL | 'c' ..= 100 => { }
| ^^^^^^^^^^^ expected integer, found char
@ -25,7 +33,7 @@ LL | 'c' ..= 100 => { }
= note: expected type `{integer}`
found type `char`
error: aborting due to 3 previous errors
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0029, E0308.
For more information about an error, try `rustc --explain E0029`.

View File

@ -4,6 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc
LL | impl<T> RemoteTrait for T where T: LocalTrait {}
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error: aborting due to previous error

View File

@ -0,0 +1,14 @@
// The problem in #66357 was that the call trace:
//
// - parse_fn_block_decl
// - expect_or
// - unexpected
// - expect_one_of
// - expected_one_of_not_found
// - recover_closing_delimiter
//
// ended up bubbling up `Ok(true)` to `unexpected` which then used `unreachable!()`.
fn f() { |[](* }
//~^ ERROR expected one of `,` or `:`, found `(`
//~| ERROR expected one of `)`, `-`, `_`, `box`, `mut`, `ref`, `|`, identifier, or path, found `*`

View File

@ -0,0 +1,16 @@
error: expected one of `,` or `:`, found `(`
--> $DIR/issue-66357-unexpected-unreachable.rs:12:13
|
LL | fn f() { |[](* }
| ^ expected one of `,` or `:`
error: expected one of `)`, `-`, `_`, `box`, `mut`, `ref`, `|`, identifier, or path, found `*`
--> $DIR/issue-66357-unexpected-unreachable.rs:12:14
|
LL | fn f() { |[](* }
| -^ help: `)` may belong here
| |
| unclosed delimiter
error: aborting due to 2 previous errors

View File

@ -6,8 +6,8 @@ LL | macro_rules! foo()
|
help: change the delimiters to curly braces
|
LL | macro_rules! foo {}
| ^^
LL | macro_rules! foo{}
| ^^
help: add a semicolon
|
LL | macro_rules! foo();
@ -26,7 +26,7 @@ LL | | )
|
help: change the delimiters to curly braces
|
LL | bar! {
LL | bar!{
LL | blah
LL | blah
LL | blah

View File

@ -0,0 +1,3 @@
// ignore-tidy-trailing-newlines
// error-pattern: aborting due to 3 previous errors
macro_rules! abc(ؼ

View File

@ -0,0 +1,31 @@
error: this file contains an un-closed delimiter
--> $DIR/mbe_missing_right_paren.rs:3:19
|
LL | macro_rules! abc(ؼ
| - ^
| |
| un-closed delimiter
error: macros that expand to items must be delimited with braces or followed by a semicolon
--> $DIR/mbe_missing_right_paren.rs:3:17
|
LL | macro_rules! abc(ؼ
| ^^
|
help: change the delimiters to curly braces
|
LL | macro_rules! abc{ؼ}
| ^ ^
help: add a semicolon
|
LL | macro_rules! abc(ؼ;
| ^
error: unexpected end of macro invocation
--> $DIR/mbe_missing_right_paren.rs:3:1
|
LL | macro_rules! abc(ؼ
| ^^^^^^^^^^^^^^^^^^ missing tokens in macro arguments
error: aborting due to 3 previous errors

View File

@ -401,19 +401,17 @@ error[E0029]: only char and numeric types are allowed in range patterns
--> $DIR/recover-range-pats.rs:19:12
|
LL | if let true..Y = 0 {}
| ^^^^ ranges require char or numeric types
|
= note: start type: bool
= note: end type: u8
| ^^^^ - this is of type `u8`
| |
| this is of type `bool` but it should be `char` or numeric
error[E0029]: only char and numeric types are allowed in range patterns
--> $DIR/recover-range-pats.rs:20:15
|
LL | if let X..true = 0 {}
| ^^^^ ranges require char or numeric types
|
= note: start type: u8
= note: end type: bool
| - ^^^^ this is of type `bool` but it should be `char` or numeric
| |
| this is of type `u8`
error[E0308]: mismatched types
--> $DIR/recover-range-pats.rs:21:12
@ -437,19 +435,17 @@ error[E0029]: only char and numeric types are allowed in range patterns
--> $DIR/recover-range-pats.rs:32:12
|
LL | if let true..=Y = 0 {}
| ^^^^ ranges require char or numeric types
|
= note: start type: bool
= note: end type: u8
| ^^^^ - this is of type `u8`
| |
| this is of type `bool` but it should be `char` or numeric
error[E0029]: only char and numeric types are allowed in range patterns
--> $DIR/recover-range-pats.rs:33:16
|
LL | if let X..=true = 0 {}
| ^^^^ ranges require char or numeric types
|
= note: start type: u8
= note: end type: bool
| - ^^^^ this is of type `bool` but it should be `char` or numeric
| |
| this is of type `u8`
error[E0308]: mismatched types
--> $DIR/recover-range-pats.rs:34:12
@ -473,19 +469,17 @@ error[E0029]: only char and numeric types are allowed in range patterns
--> $DIR/recover-range-pats.rs:45:12
|
LL | if let true...Y = 0 {}
| ^^^^ ranges require char or numeric types
|
= note: start type: bool
= note: end type: u8
| ^^^^ - this is of type `u8`
| |
| this is of type `bool` but it should be `char` or numeric
error[E0029]: only char and numeric types are allowed in range patterns
--> $DIR/recover-range-pats.rs:47:16
|
LL | if let X...true = 0 {}
| ^^^^ ranges require char or numeric types
|
= note: start type: u8
= note: end type: bool
| - ^^^^ this is of type `bool` but it should be `char` or numeric
| |
| this is of type `u8`
error[E0308]: mismatched types
--> $DIR/recover-range-pats.rs:49:12
@ -509,10 +503,7 @@ error[E0029]: only char and numeric types are allowed in range patterns
--> $DIR/recover-range-pats.rs:60:12
|
LL | if let true.. = 0 {}
| ^^^^ ranges require char or numeric types
|
= note: start type: bool
= note: end type: [type error]
| ^^^^ this is of type `bool` but it should be `char` or numeric
error[E0308]: mismatched types
--> $DIR/recover-range-pats.rs:62:12
@ -527,10 +518,7 @@ error[E0029]: only char and numeric types are allowed in range patterns
--> $DIR/recover-range-pats.rs:70:12
|
LL | if let true..= = 0 {}
| ^^^^ ranges require char or numeric types
|
= note: start type: bool
= note: end type: [type error]
| ^^^^ this is of type `bool` but it should be `char` or numeric
error[E0308]: mismatched types
--> $DIR/recover-range-pats.rs:72:12
@ -545,10 +533,7 @@ error[E0029]: only char and numeric types are allowed in range patterns
--> $DIR/recover-range-pats.rs:82:12
|
LL | if let true... = 0 {}
| ^^^^ ranges require char or numeric types
|
= note: start type: bool
= note: end type: [type error]
| ^^^^ this is of type `bool` but it should be `char` or numeric
error[E0308]: mismatched types
--> $DIR/recover-range-pats.rs:85:12
@ -563,10 +548,7 @@ error[E0029]: only char and numeric types are allowed in range patterns
--> $DIR/recover-range-pats.rs:94:14
|
LL | if let ..true = 0 {}
| ^^^^ ranges require char or numeric types
|
= note: start type: [type error]
= note: end type: bool
| ^^^^ this is of type `bool` but it should be `char` or numeric
error[E0308]: mismatched types
--> $DIR/recover-range-pats.rs:96:12
@ -581,10 +563,7 @@ error[E0029]: only char and numeric types are allowed in range patterns
--> $DIR/recover-range-pats.rs:104:15
|
LL | if let ..=true = 0 {}
| ^^^^ ranges require char or numeric types
|
= note: start type: [type error]
= note: end type: bool
| ^^^^ this is of type `bool` but it should be `char` or numeric
error[E0308]: mismatched types
--> $DIR/recover-range-pats.rs:106:12
@ -599,10 +578,7 @@ error[E0029]: only char and numeric types are allowed in range patterns
--> $DIR/recover-range-pats.rs:116:15
|
LL | if let ...true = 0 {}
| ^^^^ ranges require char or numeric types
|
= note: start type: [type error]
= note: end type: bool
| ^^^^ this is of type `bool` but it should be `char` or numeric
error[E0308]: mismatched types
--> $DIR/recover-range-pats.rs:119:12

View File

@ -7,11 +7,11 @@ LL | Arith = 1 + 1,
error[E0029]: only char and numeric types are allowed in range patterns
--> $DIR/patkind-litrange-no-expr.rs:20:13
|
LL | $( $value ..= 42 => Some($name::$variant), )* // PatKind::Range
| -- this is of type `{integer}`
...
LL | Arith = 1 + 1,
| ^^^^^ ranges require char or numeric types
|
= note: start type: {integer}
= note: end type: {integer}
| ^^^^^ this is of type `_` but it should be `char` or numeric
error: aborting due to 2 previous errors

View File

@ -8,10 +8,9 @@ error[E0029]: only char and numeric types are allowed in range patterns
--> $DIR/qualified-path-params.rs:22:15
|
LL | 0 ..= <S as Tr>::A::f::<u8> => {}
| ^^^^^^^^^^^^^^^^^^^^^ ranges require char or numeric types
|
= note: start type: {integer}
= note: end type: fn() {S::f::<u8>}
| - ^^^^^^^^^^^^^^^^^^^^^ this is of type `fn() {S::f::<u8>}` but it should be `char` or numeric
| |
| this is of type `{integer}`
error: aborting due to 2 previous errors

View File

@ -574,22 +574,59 @@ pub fn test_opts(config: &Config) -> test::TestOpts {
pub fn make_tests(config: &Config) -> Vec<test::TestDescAndFn> {
debug!("making tests from {:?}", config.src_base.display());
let inputs = common_inputs_stamp(config);
let mut tests = Vec::new();
collect_tests_from_dir(
config,
&config.src_base,
&config.src_base,
&PathBuf::new(),
&inputs,
&mut tests,
).unwrap();
).expect(&format!("Could not read tests from {}", config.src_base.display()));
tests
}
/// Returns a stamp constructed from input files common to all test cases.
fn common_inputs_stamp(config: &Config) -> Stamp {
let rust_src_dir = config
.find_rust_src_root()
.expect("Could not find Rust source root");
let mut stamp = Stamp::from_path(&config.rustc_path);
// Relevant pretty printer files
let pretty_printer_files = [
"src/etc/debugger_pretty_printers_common.py",
"src/etc/gdb_load_rust_pretty_printers.py",
"src/etc/gdb_rust_pretty_printing.py",
"src/etc/lldb_batchmode.py",
"src/etc/lldb_rust_formatters.py",
];
for file in &pretty_printer_files {
let path = rust_src_dir.join(file);
stamp.add_path(&path);
}
stamp.add_dir(&config.run_lib_path);
if let Some(ref rustdoc_path) = config.rustdoc_path {
stamp.add_path(&rustdoc_path);
stamp.add_path(&rust_src_dir.join("src/etc/htmldocck.py"));
}
// Compiletest itself.
stamp.add_dir(&rust_src_dir.join("src/tools/compiletest/"));
stamp
}
fn collect_tests_from_dir(
config: &Config,
base: &Path,
dir: &Path,
relative_dir_path: &Path,
inputs: &Stamp,
tests: &mut Vec<test::TestDescAndFn>,
) -> io::Result<()> {
// Ignore directories that contain a file named `compiletest-ignore-dir`.
@ -602,7 +639,7 @@ fn collect_tests_from_dir(
file: dir.to_path_buf(),
relative_dir: relative_dir_path.parent().unwrap().to_path_buf(),
};
tests.extend(make_test(config, &paths));
tests.extend(make_test(config, &paths, inputs));
return Ok(());
}
@ -627,12 +664,14 @@ fn collect_tests_from_dir(
file: file_path,
relative_dir: relative_dir_path.to_path_buf(),
};
tests.extend(make_test(config, &paths))
tests.extend(make_test(config, &paths, inputs))
} else if file_path.is_dir() {
let relative_file_path = relative_dir_path.join(file.file_name());
if &file_name != "auxiliary" {
debug!("found directory: {:?}", file_path.display());
collect_tests_from_dir(config, base, &file_path, &relative_file_path, tests)?;
collect_tests_from_dir(
config, base, &file_path, &relative_file_path,
inputs, tests)?;
}
} else {
debug!("found other file/directory: {:?}", file_path.display());
@ -655,7 +694,7 @@ pub fn is_test(file_name: &OsString) -> bool {
!invalid_prefixes.iter().any(|p| file_name.starts_with(p))
}
pub fn make_test(config: &Config, testpaths: &TestPaths) -> Vec<test::TestDescAndFn> {
fn make_test(config: &Config, testpaths: &TestPaths, inputs: &Stamp) -> Vec<test::TestDescAndFn> {
let early_props = if config.mode == Mode::RunMake {
// Allow `ignore` directives to be in the Makefile.
EarlyProps::from_file(config, &testpaths.file.join("Makefile"))
@ -685,19 +724,21 @@ pub fn make_test(config: &Config, testpaths: &TestPaths) -> Vec<test::TestDescAn
revisions
.into_iter()
.map(|revision| {
// Debugging emscripten code doesn't make sense today
let ignore = early_props.ignore == Ignore::Ignore
|| !up_to_date(
config,
testpaths,
&early_props,
revision.map(|s| s.as_str()),
)
// Debugging emscripten code doesn't make sense today
|| ((config.mode == DebugInfoGdbLldb || config.mode == DebugInfoCdb ||
config.mode == DebugInfoGdb || config.mode == DebugInfoLldb)
&& config.target.contains("emscripten"))
|| (config.mode == DebugInfoGdb && !early_props.ignore.can_run_gdb())
|| (config.mode == DebugInfoLldb && !early_props.ignore.can_run_lldb());
|| (config.mode == DebugInfoLldb && !early_props.ignore.can_run_lldb())
// Ignore tests that already run and are up to date with respect to inputs.
|| is_up_to_date(
config,
testpaths,
&early_props,
revision.map(|s| s.as_str()),
inputs,
);
test::TestDescAndFn {
desc: test::TestDesc {
name: make_test_name(config, testpaths, revision),
@ -716,98 +757,75 @@ fn stamp(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> Path
output_base_dir(config, testpaths, revision).join("stamp")
}
fn up_to_date(
fn is_up_to_date(
config: &Config,
testpaths: &TestPaths,
props: &EarlyProps,
revision: Option<&str>,
inputs: &Stamp,
) -> bool {
let stamp_name = stamp(config, testpaths, revision);
// Check hash.
let contents = match fs::read_to_string(&stamp_name) {
Ok(f) => f,
Err(ref e) if e.kind() == ErrorKind::InvalidData => panic!("Can't read stamp contents"),
Err(_) => return true,
Err(_) => return false,
};
let expected_hash = runtest::compute_stamp_hash(config);
if contents != expected_hash {
return true;
return false;
}
// Check timestamps.
let rust_src_dir = config
.find_rust_src_root()
.expect("Could not find Rust source root");
let stamp = Stamp::from_path(&stamp_name);
let mut inputs = vec![Stamp::from_path(&testpaths.file), Stamp::from_path(&config.rustc_path)];
inputs.extend(
props
.aux
.iter()
.map(|aux| {
Stamp::from_path(&testpaths.file.parent().unwrap().join("auxiliary").join(aux))
}),
);
// Relevant pretty printer files
let pretty_printer_files = [
"src/etc/debugger_pretty_printers_common.py",
"src/etc/gdb_load_rust_pretty_printers.py",
"src/etc/gdb_rust_pretty_printing.py",
"src/etc/lldb_batchmode.py",
"src/etc/lldb_rust_formatters.py",
];
inputs.extend(pretty_printer_files.iter().map(|pretty_printer_file| {
Stamp::from_path(&rust_src_dir.join(pretty_printer_file))
}));
inputs.extend(Stamp::from_dir(&config.run_lib_path));
if let Some(ref rustdoc_path) = config.rustdoc_path {
inputs.push(Stamp::from_path(&rustdoc_path));
inputs.push(Stamp::from_path(&rust_src_dir.join("src/etc/htmldocck.py")));
let mut inputs = inputs.clone();
inputs.add_path(&testpaths.file);
for aux in &props.aux {
let path = testpaths.file.parent()
.unwrap()
.join("auxiliary")
.join(aux);
inputs.add_path(&path);
}
// UI test files.
inputs.extend(UI_EXTENSIONS.iter().map(|extension| {
for extension in UI_EXTENSIONS {
let path = &expected_output_path(testpaths, revision, &config.compare_mode, extension);
Stamp::from_path(path)
}));
inputs.add_path(path);
}
// Compiletest itself.
inputs.extend(Stamp::from_dir(&rust_src_dir.join("src/tools/compiletest/")));
inputs.iter().any(|input| input > &stamp)
inputs < Stamp::from_path(&stamp_name)
}
#[derive(Debug, PartialEq, PartialOrd, Ord, Eq)]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Stamp {
time: SystemTime,
file: PathBuf,
}
impl Stamp {
fn from_path(p: &Path) -> Self {
let time = fs::metadata(p)
.and_then(|metadata| metadata.modified())
.unwrap_or(SystemTime::UNIX_EPOCH);
Stamp {
time,
file: p.into(),
}
fn from_path(path: &Path) -> Self {
let mut stamp = Stamp { time: SystemTime::UNIX_EPOCH };
stamp.add_path(path);
stamp
}
fn from_dir(path: &Path) -> impl Iterator<Item = Stamp> {
WalkDir::new(path)
.into_iter()
.map(|entry| entry.unwrap())
.filter(|entry| entry.file_type().is_file())
.map(|entry| {
let time = (|| -> io::Result<_> { entry.metadata()?.modified() })();
fn add_path(&mut self, path: &Path) {
let modified = fs::metadata(path)
.and_then(|metadata| metadata.modified())
.unwrap_or(SystemTime::UNIX_EPOCH);
self.time = self.time.max(modified);
}
Stamp {
time: time.unwrap_or(SystemTime::UNIX_EPOCH),
file: entry.path().into(),
}
})
fn add_dir(&mut self, path: &Path) {
for entry in WalkDir::new(path) {
let entry = entry.unwrap();
if entry.file_type().is_file() {
let modified = entry.metadata().ok()
.and_then(|metadata| metadata.modified().ok())
.unwrap_or(SystemTime::UNIX_EPOCH);
self.time = self.time.max(modified);
}
}
}
}