Skip to content

Commit a2491ee

Browse files
committed
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
2 parents 5e380b7 + d145d1e commit a2491ee

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+430
-237
lines changed

src/liballoc/vec.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,7 @@ impl<T> Vec<T> {
861861
///
862862
/// [`truncate`]: #method.truncate
863863
/// [`resize`]: #method.resize
864-
/// [`extend`]: #method.extend-1
864+
/// [`extend`]: ../../std/iter/trait.Extend.html#tymethod.extend
865865
/// [`clear`]: #method.clear
866866
///
867867
/// # Safety

src/librustc/traits/coherence.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ pub fn trait_ref_is_local_or_fundamental<'tcx>(
238238

239239
pub enum OrphanCheckErr<'tcx> {
240240
NonLocalInputType(Vec<(Ty<'tcx>, bool /* Is this the first input type? */)>),
241-
UncoveredTy(Ty<'tcx>),
241+
UncoveredTy(Ty<'tcx>, Option<Ty<'tcx>>),
242242
}
243243

244244
/// Checks the coherence orphan rules. `impl_def_id` should be the
@@ -402,7 +402,15 @@ fn orphan_check_trait_ref<'tcx>(
402402
return Ok(());
403403
} else if let ty::Param(_) = input_ty.kind {
404404
debug!("orphan_check_trait_ref: uncovered ty: `{:?}`", input_ty);
405-
return Err(OrphanCheckErr::UncoveredTy(input_ty))
405+
let local_type = trait_ref
406+
.input_types()
407+
.flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate))
408+
.filter(|ty| ty_is_non_local_constructor(tcx, ty, in_crate).is_none())
409+
.next();
410+
411+
debug!("orphan_check_trait_ref: uncovered ty local_type: `{:?}`", local_type);
412+
413+
return Err(OrphanCheckErr::UncoveredTy(input_ty, local_type))
406414
}
407415
if let Some(non_local_tys) = non_local_tys {
408416
for input_ty in non_local_tys {

src/librustc_parse/parser/item.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -1742,14 +1742,25 @@ impl<'a> Parser<'a> {
17421742
}
17431743

17441744
fn report_invalid_macro_expansion_item(&self) {
1745+
let has_close_delim = self.sess.source_map()
1746+
.span_to_snippet(self.prev_span)
1747+
.map(|s| s.ends_with(")") || s.ends_with("]"))
1748+
.unwrap_or(false);
1749+
let right_brace_span = if has_close_delim {
1750+
// it's safe to peel off one character only when it has the close delim
1751+
self.prev_span.with_lo(self.prev_span.hi() - BytePos(1))
1752+
} else {
1753+
self.sess.source_map().next_point(self.prev_span)
1754+
};
1755+
17451756
self.struct_span_err(
17461757
self.prev_span,
17471758
"macros that expand to items must be delimited with braces or followed by a semicolon",
17481759
).multipart_suggestion(
17491760
"change the delimiters to curly braces",
17501761
vec![
1751-
(self.prev_span.with_hi(self.prev_span.lo() + BytePos(1)), String::from(" {")),
1752-
(self.prev_span.with_lo(self.prev_span.hi() - BytePos(1)), '}'.to_string()),
1762+
(self.prev_span.with_hi(self.prev_span.lo() + BytePos(1)), "{".to_string()),
1763+
(right_brace_span, '}'.to_string()),
17531764
],
17541765
Applicability::MaybeIncorrect,
17551766
).span_suggestion(

src/librustc_parse/parser/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,9 @@ impl<'a> Parser<'a> {
443443
crate fn unexpected<T>(&mut self) -> PResult<'a, T> {
444444
match self.expect_one_of(&[], &[]) {
445445
Err(e) => Err(e),
446-
Ok(_) => unreachable!(),
446+
// We can get `Ok(true)` from `recover_closing_delimiter`
447+
// which is called in `expected_one_of_not_found`.
448+
Ok(_) => FatalError.raise(),
447449
}
448450
}
449451

src/librustc_typeck/check/pat.rs

+61-29
Original file line numberDiff line numberDiff line change
@@ -362,37 +362,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
362362
|| ty.is_char()
363363
|| ty.references_error()
364364
};
365-
let lhs_compat = numeric_or_char(lhs_ty);
366-
let rhs_compat = numeric_or_char(rhs_ty);
367-
368-
if !lhs_compat || !rhs_compat {
369-
let span = if !lhs_compat && !rhs_compat {
370-
span
371-
} else if !lhs_compat {
372-
begin.span
373-
} else {
374-
end.span
375-
};
365+
let lhs_fail = !numeric_or_char(lhs_ty);
366+
let rhs_fail = !numeric_or_char(rhs_ty);
376367

377-
let mut err = struct_span_err!(
378-
self.tcx.sess,
379-
span,
380-
E0029,
381-
"only char and numeric types are allowed in range patterns"
368+
if lhs_fail || rhs_fail {
369+
self.emit_err_pat_range(
370+
span, begin.span, end.span, lhs_fail, rhs_fail, lhs_ty, rhs_ty
382371
);
383-
err.span_label(span, "ranges require char or numeric types");
384-
err.note(&format!("start type: {}", self.ty_to_string(lhs_ty)));
385-
err.note(&format!("end type: {}", self.ty_to_string(rhs_ty)));
386-
if self.tcx.sess.teach(&err.get_code().unwrap()) {
387-
err.note(
388-
"In a match expression, only numbers and characters can be matched \
389-
against a range. This is because the compiler checks that the range \
390-
is non-empty at compile-time, and is unable to evaluate arbitrary \
391-
comparison functions. If you want to capture values of an orderable \
392-
type between two end-points, you can use a guard."
393-
);
394-
}
395-
err.emit();
396372
return None;
397373
}
398374

@@ -406,6 +382,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
406382
Some(common_type)
407383
}
408384

385+
fn emit_err_pat_range(
386+
&self,
387+
span: Span,
388+
begin_span: Span,
389+
end_span: Span,
390+
lhs_fail: bool,
391+
rhs_fail: bool,
392+
lhs_ty: Ty<'tcx>,
393+
rhs_ty: Ty<'tcx>,
394+
) {
395+
let span = if lhs_fail && rhs_fail {
396+
span
397+
} else if lhs_fail {
398+
begin_span
399+
} else {
400+
end_span
401+
};
402+
403+
let mut err = struct_span_err!(
404+
self.tcx.sess,
405+
span,
406+
E0029,
407+
"only char and numeric types are allowed in range patterns"
408+
);
409+
let msg = |ty| {
410+
format!("this is of type `{}` but it should be `char` or numeric", ty)
411+
};
412+
let mut one_side_err = |first_span, first_ty, second_span, second_ty: Ty<'_>| {
413+
err.span_label(first_span, &msg(first_ty));
414+
if !second_ty.references_error() {
415+
err.span_label(
416+
second_span,
417+
&format!("this is of type `{}`", second_ty)
418+
);
419+
}
420+
};
421+
if lhs_fail && rhs_fail {
422+
err.span_label(begin_span, &msg(lhs_ty));
423+
err.span_label(end_span, &msg(rhs_ty));
424+
} else if lhs_fail {
425+
one_side_err(begin_span, lhs_ty, end_span, rhs_ty);
426+
} else {
427+
one_side_err(end_span, rhs_ty, begin_span, lhs_ty);
428+
}
429+
if self.tcx.sess.teach(&err.get_code().unwrap()) {
430+
err.note(
431+
"In a match expression, only numbers and characters can be matched \
432+
against a range. This is because the compiler checks that the range \
433+
is non-empty at compile-time, and is unable to evaluate arbitrary \
434+
comparison functions. If you want to capture values of an orderable \
435+
type between two end-points, you can use a guard."
436+
);
437+
}
438+
err.emit();
439+
}
440+
409441
fn check_pat_ident(
410442
&self,
411443
pat: &Pat,

src/librustc_typeck/coherence/orphan.rs

+46-18
Original file line numberDiff line numberDiff line change
@@ -77,30 +77,58 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> {
7777
err.emit();
7878
return;
7979
}
80-
Err(traits::OrphanCheckErr::UncoveredTy(param_ty)) => {
80+
Err(traits::OrphanCheckErr::UncoveredTy(param_ty, local_type)) => {
8181
let mut sp = sp;
8282
for param in &generics.params {
8383
if param.name.ident().to_string() == param_ty.to_string() {
8484
sp = param.span;
8585
}
8686
}
87-
let mut err = struct_span_err!(
88-
self.tcx.sess,
89-
sp,
90-
E0210,
91-
"type parameter `{}` must be used as the type parameter for some local \
92-
type (e.g., `MyStruct<{}>`)",
93-
param_ty,
94-
param_ty
95-
);
96-
err.span_label(sp, format!(
97-
"type parameter `{}` must be used as the type parameter for some local \
98-
type",
99-
param_ty,
100-
));
101-
err.note("only traits defined in the current crate can be implemented for a \
102-
type parameter");
103-
err.emit();
87+
88+
match local_type {
89+
Some(local_type) => {
90+
struct_span_err!(
91+
self.tcx.sess,
92+
sp,
93+
E0210,
94+
"type parameter `{}` must be covered by another type \
95+
when it appears before the first local type (`{}`)",
96+
param_ty,
97+
local_type
98+
).span_label(sp, format!(
99+
"type parameter `{}` must be covered by another type \
100+
when it appears before the first local type (`{}`)",
101+
param_ty,
102+
local_type
103+
)).note("implementing a foreign trait is only possible if at \
104+
least one of the types for which is it implemented is local, \
105+
and no uncovered type parameters appear before that first \
106+
local type"
107+
).note("in this case, 'before' refers to the following order: \
108+
`impl<..> ForeignTrait<T1, ..., Tn> for T0`, \
109+
where `T0` is the first and `Tn` is the last"
110+
).emit();
111+
}
112+
None => {
113+
struct_span_err!(
114+
self.tcx.sess,
115+
sp,
116+
E0210,
117+
"type parameter `{}` must be used as the type parameter for some \
118+
local type (e.g., `MyStruct<{}>`)",
119+
param_ty,
120+
param_ty
121+
).span_label(sp, format!(
122+
"type parameter `{}` must be used as the type parameter for some \
123+
local type",
124+
param_ty,
125+
)).note("implementing a foreign trait is only possible if at \
126+
least one of the types for which is it implemented is local"
127+
).note("only traits defined in the current crate can be \
128+
implemented for a type parameter"
129+
).emit();
130+
}
131+
};
104132
return;
105133
}
106134
}

src/librustc_typeck/error_codes.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -2114,8 +2114,13 @@ E0210: r##"
21142114
This error indicates a violation of one of Rust's orphan rules for trait
21152115
implementations. The rule concerns the use of type parameters in an
21162116
implementation of a foreign trait (a trait defined in another crate), and
2117-
states that type parameters must be "covered" by a local type. To understand
2118-
what this means, it is perhaps easiest to consider a few examples.
2117+
states that type parameters must be "covered" by a local type.
2118+
2119+
When implementing a foreign trait for a foreign type,
2120+
the trait must have one or more type parameters.
2121+
A type local to your crate must appear before any use of any type parameters.
2122+
2123+
To understand what this means, it is perhaps easier to consider a few examples.
21192124
21202125
If `ForeignTrait` is a trait defined in some external crate `foo`, then the
21212126
following trait `impl` is an error:
@@ -2173,12 +2178,18 @@ impl<P1, ..., Pm> ForeignTrait<T1, ..., Tn> for T0 { ... }
21732178
21742179
where `P1, ..., Pm` are the type parameters of the `impl` and `T0, ..., Tn`
21752180
are types. One of the types `T0, ..., Tn` must be a local type (this is another
2176-
orphan rule, see the explanation for E0117). Let `i` be the smallest integer
2177-
such that `Ti` is a local type. Then no type parameter can appear in any of the
2178-
`Tj` for `j < i`.
2181+
orphan rule, see the explanation for E0117).
21792182
2180-
For information on the design of the orphan rules, see [RFC 1023].
2183+
Both of the following must be true:
2184+
1. At least one of the types `T0..=Tn` must be a local type.
2185+
Let `Ti` be the first such type.
2186+
2. No uncovered type parameters `P1..=Pm` may appear in `T0..Ti`
2187+
(excluding `Ti`).
2188+
2189+
For information on the design of the orphan rules,
2190+
see [RFC 2451] and [RFC 1023].
21812191
2192+
[RFC 2451]: https://rust-lang.github.io/rfcs/2451-re-rebalancing-coherence.html
21822193
[RFC 1023]: https://github.com/rust-lang/rfcs/blob/master/text/1023-rebalancing-coherence.md
21832194
"##,
21842195

src/libstd/net/ip.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -633,8 +633,8 @@ impl Ipv4Addr {
633633
/// network devices benchmarking. This range is defined in [IETF RFC 2544] as `192.18.0.0`
634634
/// through `198.19.255.255` but [errata 423] corrects it to `198.18.0.0/15`.
635635
///
636-
/// [IETF RFC 1112]: https://tools.ietf.org/html/rfc1112
637-
/// [errate 423]: https://www.rfc-editor.org/errata/eid423
636+
/// [IETF RFC 2544]: https://tools.ietf.org/html/rfc2544
637+
/// [errata 423]: https://www.rfc-editor.org/errata/eid423
638638
/// [`true`]: ../../std/primitive.bool.html
639639
///
640640
/// # Examples

src/libsyntax_ext/source_util.rs

+8
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use rustc_data_structures::sync::Lrc;
2121
/// line!(): expands to the current line number
2222
pub fn expand_line(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
2323
-> Box<dyn base::MacResult+'static> {
24+
let sp = cx.with_def_site_ctxt(sp);
2425
base::check_zero_tts(cx, sp, tts, "line!");
2526

2627
let topmost = cx.expansion_cause().unwrap_or(sp);
@@ -32,6 +33,7 @@ pub fn expand_line(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
3233
/* column!(): expands to the current column number */
3334
pub fn expand_column(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
3435
-> Box<dyn base::MacResult+'static> {
36+
let sp = cx.with_def_site_ctxt(sp);
3537
base::check_zero_tts(cx, sp, tts, "column!");
3638

3739
let topmost = cx.expansion_cause().unwrap_or(sp);
@@ -45,6 +47,7 @@ pub fn expand_column(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
4547
/// out if we wanted.
4648
pub fn expand_file(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
4749
-> Box<dyn base::MacResult+'static> {
50+
let sp = cx.with_def_site_ctxt(sp);
4851
base::check_zero_tts(cx, sp, tts, "file!");
4952

5053
let topmost = cx.expansion_cause().unwrap_or(sp);
@@ -54,12 +57,14 @@ pub fn expand_file(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
5457

5558
pub fn expand_stringify(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
5659
-> Box<dyn base::MacResult+'static> {
60+
let sp = cx.with_def_site_ctxt(sp);
5761
let s = pprust::tts_to_string(tts);
5862
base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&s)))
5963
}
6064

6165
pub fn expand_mod(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
6266
-> Box<dyn base::MacResult+'static> {
67+
let sp = cx.with_def_site_ctxt(sp);
6368
base::check_zero_tts(cx, sp, tts, "module_path!");
6469
let mod_path = &cx.current_expansion.module.mod_path;
6570
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)
7277
/// unhygienically.
7378
pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
7479
-> Box<dyn base::MacResult+'cx> {
80+
let sp = cx.with_def_site_ctxt(sp);
7581
let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
7682
Some(f) => f,
7783
None => return DummyResult::any(sp),
@@ -125,6 +131,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
125131
// include_str! : read the given file, insert it as a literal string expr
126132
pub fn expand_include_str(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
127133
-> Box<dyn base::MacResult+'static> {
134+
let sp = cx.with_def_site_ctxt(sp);
128135
let file = match get_single_str_from_tts(cx, sp, tts, "include_str!") {
129136
Some(f) => f,
130137
None => return DummyResult::any(sp)
@@ -156,6 +163,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
156163

157164
pub fn expand_include_bytes(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
158165
-> Box<dyn base::MacResult+'static> {
166+
let sp = cx.with_def_site_ctxt(sp);
159167
let file = match get_single_str_from_tts(cx, sp, tts, "include_bytes!") {
160168
Some(f) => f,
161169
None => return DummyResult::any(sp)

src/test/ui/coherence/coherence-all-remote.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ error[E0210]: type parameter `T` must be used as the type parameter for some loc
44
LL | impl<T> Remote1<T> for isize { }
55
| ^ type parameter `T` must be used as the type parameter for some local type
66
|
7+
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local
78
= note: only traits defined in the current crate can be implemented for a type parameter
89

910
error: aborting due to previous error

src/test/ui/coherence/coherence-bigint-param.stderr

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
1+
error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`BigInt`)
22
--> $DIR/coherence-bigint-param.rs:8:6
33
|
44
LL | impl<T> Remote1<BigInt> for T { }
5-
| ^ type parameter `T` must be used as the type parameter for some local type
5+
| ^ type parameter `T` must be covered by another type when it appears before the first local type (`BigInt`)
66
|
7-
= note: only traits defined in the current crate can be implemented for a type parameter
7+
= 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
8+
= 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
89

910
error: aborting due to previous error
1011

0 commit comments

Comments
 (0)