Skip to content

Commit f8f1751

Browse files
committedFeb 12, 2022
Auto merge of rust-lang#93933 - matthiaskrgr:rollup-1hjae6g, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#91908 (Add 2 tests) - rust-lang#93595 (fix ICE when parsing lifetime as function argument) - rust-lang#93757 (Add some known GAT bugs as tests) - rust-lang#93759 (Pretty print ItemKind::Use in rustfmt style) - rust-lang#93897 (linkchecker: fix panic on directory symlinks) - rust-lang#93898 (tidy: Extend error code check) - rust-lang#93928 (Add missing release notes for rust-lang#85200) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 9cdefd7 + 0e3ecd2 commit f8f1751

36 files changed

+644
-31
lines changed
 

‎RELEASES.md

+5
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ Language
156156
- [Macro attributes may follow `#[derive]` and will see the original (pre-`cfg`) input.][87220]
157157
- [Accept curly-brace macros in expressions, like `m!{ .. }.method()` and `m!{ .. }?`.][88690]
158158
- [Allow panicking in constant evaluation.][89508]
159+
- [Ignore derived `Clone` and `Debug` implementations during dead code analysis.][85200]
159160

160161
Compiler
161162
--------
@@ -216,6 +217,9 @@ Cargo
216217
Compatibility notes
217218
-------------------
218219

220+
- [Ignore derived `Clone` and `Debug` implementations during dead code analysis.][85200]
221+
This will break some builds that set `#![deny(dead_code)]`.
222+
219223
Internal changes
220224
----------------
221225
These changes provide no direct user facing benefits, but represent significant
@@ -224,6 +228,7 @@ and related tools.
224228

225229
- [Added an experimental backend for codegen with `libgccjit`.][87260]
226230

231+
[85200]: https://github.com/rust-lang/rust/pull/85200/
227232
[86191]: https://github.com/rust-lang/rust/pull/86191/
228233
[87220]: https://github.com/rust-lang/rust/pull/87220/
229234
[87260]: https://github.com/rust-lang/rust/pull/87260/

‎compiler/rustc_ast_pretty/src/pp/convenience.rs

+4
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ impl Printer {
7575
}
7676

7777
pub fn trailing_comma(&mut self) {
78+
self.scan_break(BreakToken { pre_break: Some(','), ..BreakToken::default() });
79+
}
80+
81+
pub fn trailing_comma_or_space(&mut self) {
7882
self.scan_break(BreakToken {
7983
blank_space: 1,
8084
pre_break: Some(','),

‎compiler/rustc_ast_pretty/src/pprust/state/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ impl<'a> State<'a> {
142142
if !field.is_last || has_rest {
143143
self.word_space(",");
144144
} else {
145-
self.trailing_comma();
145+
self.trailing_comma_or_space();
146146
}
147147
}
148148
if has_rest {

‎compiler/rustc_ast_pretty/src/pprust/state/item.rs

+34-14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::pp::Breaks::Inconsistent;
2-
use crate::pprust::state::{AnnNode, PrintState, State};
2+
use crate::pprust::state::delimited::IterDelimited;
3+
use crate::pprust::state::{AnnNode, PrintState, State, INDENT_UNIT};
34

45
use rustc_ast as ast;
56
use rustc_ast::GenericBound;
@@ -138,11 +139,10 @@ impl<'a> State<'a> {
138139
self.end(); // end outer head-block
139140
}
140141
ast::ItemKind::Use(ref tree) => {
141-
self.head(visibility_qualified(&item.vis, "use"));
142+
self.print_visibility(&item.vis);
143+
self.word_nbsp("use");
142144
self.print_use_tree(tree);
143145
self.word(";");
144-
self.end(); // end inner head-block
145-
self.end(); // end outer head-block
146146
}
147147
ast::ItemKind::Static(ref ty, mutbl, ref body) => {
148148
let def = ast::Defaultness::Final;
@@ -615,8 +615,8 @@ impl<'a> State<'a> {
615615
ast::UseTreeKind::Simple(rename, ..) => {
616616
self.print_path(&tree.prefix, false, 0);
617617
if let Some(rename) = rename {
618-
self.space();
619-
self.word_space("as");
618+
self.nbsp();
619+
self.word_nbsp("as");
620620
self.print_ident(rename);
621621
}
622622
}
@@ -628,16 +628,36 @@ impl<'a> State<'a> {
628628
self.word("*");
629629
}
630630
ast::UseTreeKind::Nested(ref items) => {
631-
if tree.prefix.segments.is_empty() {
632-
self.word("{");
633-
} else {
631+
if !tree.prefix.segments.is_empty() {
634632
self.print_path(&tree.prefix, false, 0);
635-
self.word("::{");
633+
self.word("::");
634+
}
635+
if items.is_empty() {
636+
self.word("{}");
637+
} else if items.len() == 1 {
638+
self.print_use_tree(&items[0].0);
639+
} else {
640+
self.cbox(INDENT_UNIT);
641+
self.word("{");
642+
self.zerobreak();
643+
self.ibox(0);
644+
for use_tree in items.iter().delimited() {
645+
self.print_use_tree(&use_tree.0);
646+
if !use_tree.is_last {
647+
self.word(",");
648+
if let ast::UseTreeKind::Nested(_) = use_tree.0.kind {
649+
self.hardbreak();
650+
} else {
651+
self.space();
652+
}
653+
}
654+
}
655+
self.end();
656+
self.trailing_comma();
657+
self.offset(-INDENT_UNIT);
658+
self.word("}");
659+
self.end();
636660
}
637-
self.commasep(Inconsistent, &items, |this, &(ref tree, _)| {
638-
this.print_use_tree(tree)
639-
});
640-
self.word("}");
641661
}
642662
}
643663
}

‎compiler/rustc_error_codes/src/error_codes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ E0184: include_str!("./error_codes/E0184.md"),
9797
E0185: include_str!("./error_codes/E0185.md"),
9898
E0186: include_str!("./error_codes/E0186.md"),
9999
E0191: include_str!("./error_codes/E0191.md"),
100+
E0192: include_str!("./error_codes/E0192.md"),
100101
E0193: include_str!("./error_codes/E0193.md"),
101102
E0195: include_str!("./error_codes/E0195.md"),
102103
E0197: include_str!("./error_codes/E0197.md"),
@@ -522,7 +523,6 @@ E0787: include_str!("./error_codes/E0787.md"),
522523
// E0188, // can not cast an immutable reference to a mutable pointer
523524
// E0189, // deprecated: can only cast a boxed pointer to a boxed object
524525
// E0190, // deprecated: can only cast a &-pointer to an &-object
525-
// E0192, // negative impl only applicable to auto traits
526526
// E0194, // merged into E0403
527527
// E0196, // cannot determine a type for this closure
528528
E0208,

‎compiler/rustc_error_codes/src/error_codes/E0192.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
1+
#### Note: this error code is no longer emitted by the compiler.
2+
13
A negative impl was added on a trait implementation.
24

35
Erroneous code example:
46

5-
```compile_fail,E0192
7+
```compile_fail
68
trait Trait {
79
type Bar;
810
}
911
1012
struct Foo;
1113
12-
impl !Trait for Foo { } //~ ERROR E0192
14+
impl !Trait for Foo { } //~ ERROR
1315
1416
fn main() {}
1517
```

‎compiler/rustc_parse/src/parser/expr.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1457,9 +1457,9 @@ impl<'a> Parser<'a> {
14571457
} else if self.check(&token::OpenDelim(token::Brace)) || self.token.is_whole_block() {
14581458
self.parse_block_expr(label, lo, BlockCheckMode::Default, attrs)
14591459
} else if !ate_colon && (self.check(&TokenKind::Comma) || self.check(&TokenKind::Gt)) {
1460-
// We're probably inside of a `Path<'a>` that needs a turbofish, so suppress the
1461-
// "must be followed by a colon" error, and the "expected one of" error.
1462-
self.diagnostic().delay_span_bug(lo, "this label wasn't parsed correctly");
1460+
// We're probably inside of a `Path<'a>` that needs a turbofish
1461+
let msg = "expected `while`, `for`, `loop` or `{` after a label";
1462+
self.struct_span_err(self.token.span, msg).span_label(self.token.span, msg).emit();
14631463
consume_colon = false;
14641464
Ok(self.mk_expr_err(lo))
14651465
} else {

‎src/test/pretty/use-tree.rs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// pp-exact
2+
// edition:2021
3+
4+
#![allow(unused_imports)]
5+
6+
use ::std::fmt::{self, Debug, Display, Write as _};
7+
8+
use core::option::Option::*;
9+
10+
use core::{
11+
cmp::{Eq, Ord, PartialEq, PartialOrd},
12+
convert::{AsMut, AsRef, From, Into},
13+
iter::{
14+
DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator,
15+
IntoIterator, Iterator,
16+
},
17+
marker::{
18+
Copy as Copy, Send as Send, Sized as Sized, Sync as Sync, Unpin as U,
19+
},
20+
ops::{*, Drop, Fn, FnMut, FnOnce},
21+
};
22+
23+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// check-pass
2+
3+
pub trait Associate {
4+
type Associated;
5+
}
6+
7+
pub struct Wrap<'a> {
8+
pub field: &'a i32,
9+
}
10+
11+
pub trait Create<T> {
12+
fn create() -> Self;
13+
}
14+
15+
pub fn oh_no<'a, T>()
16+
where
17+
Wrap<'a>: Associate,
18+
<Wrap<'a> as Associate>::Associated: Create<T>,
19+
{
20+
<Wrap<'a> as Associate>::Associated::create();
21+
}
22+
23+
24+
pub fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// check-fail
2+
3+
// This should pass, but it requires `Sized` to be coinductive.
4+
5+
#![feature(generic_associated_types)]
6+
7+
trait Allocator {
8+
type Allocated<T>;
9+
}
10+
11+
enum LinkedList<A: Allocator> {
12+
Head,
13+
Next(A::Allocated<Self>)
14+
//~^ overflow
15+
}
16+
17+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0275]: overflow evaluating the requirement `LinkedList<A>: Sized`
2+
--> $DIR/issue-80626.rs:13:10
3+
|
4+
LL | Next(A::Allocated<Self>)
5+
| ^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: no field of an enum variant may have a dynamically sized type
8+
= help: change the field's type to have a statically known size
9+
help: borrowed types always have a statically known size
10+
|
11+
LL | Next(&A::Allocated<Self>)
12+
| +
13+
help: the `Box` type always has a statically known size and allocates its contents in the heap
14+
|
15+
LL | Next(Box<A::Allocated<Self>>)
16+
| ++++ +
17+
18+
error: aborting due to previous error
19+
20+
For more information about this error, try `rustc --explain E0275`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// check-fail
2+
3+
// This should pass, but seems to run into a TAIT issue.
4+
5+
#![feature(generic_associated_types)]
6+
#![feature(type_alias_impl_trait)]
7+
8+
pub trait Stream {
9+
type Item;
10+
}
11+
12+
impl Stream for () {
13+
type Item = i32;
14+
}
15+
16+
trait Yay<AdditionalValue> {
17+
type InnerStream<'s>: Stream<Item = i32> + 's;
18+
fn foo<'s>() -> Self::InnerStream<'s>;
19+
}
20+
21+
impl<'a> Yay<&'a ()> for () {
22+
type InnerStream<'s> = impl Stream<Item = i32> + 's;
23+
//~^ the type
24+
fn foo<'s>() -> Self::InnerStream<'s> { todo!() }
25+
}
26+
27+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0477]: the type `impl Stream<Item = i32>` does not fulfill the required lifetime
2+
--> $DIR/issue-86218.rs:22:28
3+
|
4+
LL | type InnerStream<'s> = impl Stream<Item = i32> + 's;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: type must outlive the lifetime `'s` as defined here as required by this binding
8+
--> $DIR/issue-86218.rs:22:22
9+
|
10+
LL | type InnerStream<'s> = impl Stream<Item = i32> + 's;
11+
| ^^
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0477`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// check-fail
2+
3+
// This should pass, but we need an extension of implied bounds (probably).
4+
5+
#![feature(generic_associated_types)]
6+
7+
pub trait AsRef2 {
8+
type Output<'a> where Self: 'a;
9+
10+
fn as_ref2<'a>(&'a self) -> Self::Output<'a>;
11+
}
12+
13+
impl<T> AsRef2 for Vec<T> {
14+
type Output<'a> where Self: 'a = &'a [T];
15+
16+
fn as_ref2<'a>(&'a self) -> Self::Output<'a> {
17+
&self[..]
18+
}
19+
}
20+
21+
#[derive(Debug)]
22+
struct Foo<T>(T);
23+
#[derive(Debug)]
24+
struct FooRef<'a, U>(&'a [U]);
25+
26+
impl<'b, T, U> AsRef2 for Foo<T> //~ the type parameter
27+
where
28+
// * `for<'b, 'c> T: AsRef2<Output<'b> = &'c [U]>>` does not work
29+
//
30+
// * `U` is unconstrained but should be allowed in this context because `Output` is
31+
// an associated type
32+
T: AsRef2<Output<'b> = &'b [U]>,
33+
U: 'b
34+
{
35+
type Output<'a> where Self: 'a = FooRef<'a, U>;
36+
37+
fn as_ref2<'a>(&'a self) -> Self::Output<'a> {
38+
FooRef(self.0.as_ref2())
39+
}
40+
}
41+
42+
fn main() {
43+
let foo = Foo(vec![1, 2, 3]);
44+
dbg!(foo.as_ref2());
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
2+
--> $DIR/issue-87735.rs:26:13
3+
|
4+
LL | impl<'b, T, U> AsRef2 for Foo<T>
5+
| ^ unconstrained type parameter
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0207`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// check-fail
2+
3+
// This should pass, but unnormalized input args aren't treated as implied.
4+
5+
#![feature(generic_associated_types)]
6+
7+
trait MyTrait {
8+
type Assoc<'a, 'b> where 'b: 'a;
9+
fn do_sth(arg: Self::Assoc<'_, '_>);
10+
}
11+
12+
struct Foo;
13+
14+
impl MyTrait for Foo {
15+
type Assoc<'a, 'b> where 'b: 'a = u32;
16+
17+
fn do_sth(_: u32) {} //~ lifetime bound
18+
// fn do_sth(_: Self::Assoc<'static, 'static>) {}
19+
// fn do_sth(_: Self::Assoc<'_, '_>) {}
20+
}
21+
22+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0478]: lifetime bound not satisfied
2+
--> $DIR/issue-87748.rs:17:5
3+
|
4+
LL | fn do_sth(_: u32) {}
5+
| ^^^^^^^^^^^^^^^^^
6+
|
7+
note: lifetime parameter instantiated with the anonymous lifetime #2 defined here
8+
--> $DIR/issue-87748.rs:17:5
9+
|
10+
LL | fn do_sth(_: u32) {}
11+
| ^^^^^^^^^^^^^^^^^
12+
note: but lifetime parameter must outlive the anonymous lifetime #1 defined here
13+
--> $DIR/issue-87748.rs:17:5
14+
|
15+
LL | fn do_sth(_: u32) {}
16+
| ^^^^^^^^^^^^^^^^^
17+
18+
error: aborting due to previous error
19+
20+
For more information about this error, try `rustc --explain E0478`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// check-fail
2+
3+
// This should pass.
4+
5+
#![feature(generic_associated_types)]
6+
7+
use std::fmt::Debug;
8+
9+
trait Foo {
10+
type Ass where Self::Ass: Debug;
11+
}
12+
13+
#[derive(Debug)]
14+
struct Bar;
15+
16+
impl Foo for Bar {
17+
type Ass = Bar;
18+
//~^ overflow
19+
}
20+
21+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0275]: overflow evaluating the requirement `<Bar as Foo>::Ass == _`
2+
--> $DIR/issue-87755.rs:17:16
3+
|
4+
LL | type Ass = Bar;
5+
| ^^^
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0275`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// check-fail
2+
3+
// This should pass, but using a type alias vs a reference directly
4+
// changes late-bound -> early-bound.
5+
6+
#![feature(generic_associated_types)]
7+
8+
trait Scanner {
9+
type Input<'a>;
10+
type Token<'a>;
11+
12+
fn scan<'a>(&mut self, i : Self::Input<'a>) -> Self::Token<'a>;
13+
}
14+
15+
struct IdScanner();
16+
17+
impl Scanner for IdScanner {
18+
type Input<'a> = &'a str;
19+
type Token<'a> = &'a str;
20+
21+
fn scan<'a>(&mut self, s : &'a str) -> &'a str { //~ lifetime parameters
22+
s
23+
}
24+
}
25+
26+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0195]: lifetime parameters or bounds on method `scan` do not match the trait declaration
2+
--> $DIR/issue-87803.rs:21:12
3+
|
4+
LL | fn scan<'a>(&mut self, i : Self::Input<'a>) -> Self::Token<'a>;
5+
| ---- lifetimes in impl do not match this method in trait
6+
...
7+
LL | fn scan<'a>(&mut self, s : &'a str) -> &'a str {
8+
| ^^^^ lifetimes do not match method in trait
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0195`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// check-fail
2+
3+
// This should pass, but has a missed normalization due to HRTB.
4+
5+
#![feature(generic_associated_types)]
6+
7+
trait Iterable {
8+
type Iterator<'a> where Self: 'a;
9+
fn iter(&self) -> Self::Iterator<'_>;
10+
}
11+
12+
struct SomeImplementation();
13+
14+
impl Iterable for SomeImplementation {
15+
type Iterator<'a> = std::iter::Empty<usize>;
16+
fn iter(&self) -> Self::Iterator<'_> {
17+
std::iter::empty()
18+
}
19+
}
20+
21+
fn do_something<I: Iterable>(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>)) {
22+
f(&mut i.iter());
23+
}
24+
25+
fn main() {
26+
do_something(SomeImplementation(), |_| ());
27+
do_something(SomeImplementation(), test);
28+
//~^ type mismatch
29+
}
30+
31+
fn test<'a, I: Iterable>(_: &mut I::Iterator<'a>) {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0631]: type mismatch in function arguments
2+
--> $DIR/issue-88382.rs:27:40
3+
|
4+
LL | do_something(SomeImplementation(), test);
5+
| ------------ ^^^^ expected signature of `for<'a> fn(&mut <SomeImplementation as Iterable>::Iterator<'a>) -> _`
6+
| |
7+
| required by a bound introduced by this call
8+
...
9+
LL | fn test<'a, I: Iterable>(_: &mut I::Iterator<'a>) {}
10+
| ------------------------------------------------- found signature of `for<'r> fn(&'r mut std::iter::Empty<usize>) -> _`
11+
|
12+
note: required by a bound in `do_something`
13+
--> $DIR/issue-88382.rs:21:56
14+
|
15+
LL | fn do_something<I: Iterable>(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>)) {
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `do_something`
17+
18+
error: aborting due to previous error
19+
20+
For more information about this error, try `rustc --explain E0631`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// check-fail
2+
3+
// This should pass, but has a missed normalization due to HRTB.
4+
5+
#![feature(generic_associated_types)]
6+
7+
pub trait Marker {}
8+
9+
pub trait Trait {
10+
type Assoc<'a>;
11+
}
12+
13+
fn test<T>(value: T)
14+
where
15+
T: Trait,
16+
for<'a> T::Assoc<'a>: Marker,
17+
{
18+
}
19+
20+
impl Marker for () {}
21+
22+
struct Foo;
23+
24+
impl Trait for Foo {
25+
type Assoc<'a> = ();
26+
}
27+
28+
fn main() {
29+
test(Foo);
30+
//~^ the trait bound
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error[E0277]: the trait bound `for<'a> <_ as Trait>::Assoc<'a>: Marker` is not satisfied
2+
--> $DIR/issue-88460.rs:29:5
3+
|
4+
LL | test(Foo);
5+
| ^^^^ the trait `for<'a> Marker` is not implemented for `<_ as Trait>::Assoc<'a>`
6+
|
7+
note: required by a bound in `test`
8+
--> $DIR/issue-88460.rs:16:27
9+
|
10+
LL | fn test<T>(value: T)
11+
| ---- required by a bound in this
12+
...
13+
LL | for<'a> T::Assoc<'a>: Marker,
14+
| ^^^^^^ required by this bound in `test`
15+
16+
error: aborting due to previous error
17+
18+
For more information about this error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// check-fail
2+
3+
// This should pass, but requires more logic.
4+
5+
#![feature(generic_associated_types)]
6+
7+
trait A {
8+
type I<'a>;
9+
}
10+
11+
pub struct TestA<F>
12+
{
13+
f: F,
14+
}
15+
16+
impl<F> A for TestA<F> {
17+
type I<'a> = &'a F;
18+
}
19+
20+
struct TestB<Q, F>
21+
{
22+
q: Q,
23+
f: F,
24+
}
25+
26+
impl<'q, Q, I, F> A for TestB<Q, F> //~ the type parameter
27+
where
28+
Q: A<I<'q> = &'q I>,
29+
F: Fn(I),
30+
{
31+
type I<'a> = ();
32+
}
33+
34+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0207]: the type parameter `I` is not constrained by the impl trait, self type, or predicates
2+
--> $DIR/issue-88526.rs:26:13
3+
|
4+
LL | impl<'q, Q, I, F> A for TestB<Q, F>
5+
| ^ unconstrained type parameter
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0207`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// check-fail
2+
// edition:2021
3+
4+
// This should pass, but seems to run into a TAIT bug.
5+
6+
#![feature(type_alias_impl_trait)]
7+
#![feature(generic_associated_types)]
8+
9+
use std::future::Future;
10+
11+
trait Stream {
12+
type Item;
13+
}
14+
15+
struct Empty<T>(T);
16+
impl<T> Stream for Empty<T> {
17+
type Item = ();
18+
}
19+
fn empty<T>() -> Empty<T> {
20+
todo!()
21+
}
22+
23+
trait X {
24+
type LineStream<'a, Repr>: Stream<Item = Repr> where Self: 'a;
25+
26+
type LineStreamFut<'a,Repr>: Future<Output = Self::LineStream<'a, Repr>> where Self: 'a;
27+
28+
fn line_stream<'a,Repr>(&'a self) -> Self::LineStreamFut<'a,Repr>;
29+
}
30+
31+
struct Y;
32+
33+
impl X for Y {
34+
type LineStream<'a, Repr> = impl Stream<Item = Repr>; //~ could not find
35+
36+
type LineStreamFut<'a, Repr> = impl Future<Output = Self::LineStream<'a, Repr>> ;
37+
38+
fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> { //~ type mismatch
39+
async {empty()}
40+
}
41+
}
42+
43+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0271]: type mismatch resolving `<impl Future<Output = [async output]> as Future>::Output == impl Stream<Item = Repr>`
2+
--> $DIR/issue-89008.rs:38:43
3+
|
4+
LL | type LineStream<'a, Repr> = impl Stream<Item = Repr>;
5+
| ------------------------ the expected opaque type
6+
...
7+
LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found struct `Empty`
9+
|
10+
= note: expected opaque type `impl Stream<Item = Repr>`
11+
found struct `Empty<_>`
12+
13+
error: could not find defining uses
14+
--> $DIR/issue-89008.rs:34:33
15+
|
16+
LL | type LineStream<'a, Repr> = impl Stream<Item = Repr>;
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^
18+
19+
error: aborting due to 2 previous errors
20+
21+
For more information about this error, try `rustc --explain E0271`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// check-pass
2+
3+
#![feature(generic_associated_types)]
4+
5+
trait Foo<T> {
6+
type Type<'a>
7+
where
8+
T: 'a;
9+
}
10+
11+
impl<T> Foo<T> for () {
12+
type Type<'a>
13+
where
14+
T: 'a,
15+
= ();
16+
}
17+
18+
fn foo<T>() {
19+
let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
20+
}
21+
22+
pub fn main() {}
+11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
11
fn main() {
22
f<'a,>
33
//~^ ERROR expected
4+
//~| ERROR expected
5+
}
6+
7+
fn bar(a: usize, b: usize) -> usize {
8+
a + b
9+
}
10+
11+
fn foo() {
12+
let x = 1;
13+
bar('y, x);
14+
//~^ ERROR expected
415
}

‎src/test/ui/parser/issues/issue-93282.stderr

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
error: expected `while`, `for`, `loop` or `{` after a label
2+
--> $DIR/issue-93282.rs:2:9
3+
|
4+
LL | f<'a,>
5+
| ^ expected `while`, `for`, `loop` or `{` after a label
6+
17
error: expected one of `.`, `:`, `;`, `?`, `for`, `loop`, `while`, `{`, `}`, or an operator, found `,`
28
--> $DIR/issue-93282.rs:2:9
39
|
@@ -9,5 +15,11 @@ help: use `::<...>` instead of `<...>` to specify lifetime, type, or const argum
915
LL | f::<'a,>
1016
| ++
1117

12-
error: aborting due to previous error
18+
error: expected `while`, `for`, `loop` or `{` after a label
19+
--> $DIR/issue-93282.rs:13:11
20+
|
21+
LL | bar('y, x);
22+
| ^ expected `while`, `for`, `loop` or `{` after a label
23+
24+
error: aborting due to 3 previous errors
1325

‎src/test/ui/parser/require-parens-for-chained-comparison.rs

+2
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ fn main() {
2222
let _ = f<'_, i8>();
2323
//~^ ERROR expected one of
2424
//~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
25+
//~| ERROR expected
2526

2627
f<'_>();
2728
//~^ comparison operators cannot be chained
2829
//~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
30+
//~| ERROR expected
2931

3032
let _ = f<u8>;
3133
//~^ ERROR comparison operators cannot be chained

‎src/test/ui/parser/require-parens-for-chained-comparison.stderr

+15-3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ help: use `::<...>` instead of `<...>` to specify lifetime, type, or const argum
5353
LL | let _ = f::<u8, i8>();
5454
| ++
5555

56+
error: expected `while`, `for`, `loop` or `{` after a label
57+
--> $DIR/require-parens-for-chained-comparison.rs:22:17
58+
|
59+
LL | let _ = f<'_, i8>();
60+
| ^ expected `while`, `for`, `loop` or `{` after a label
61+
5662
error: expected one of `.`, `:`, `;`, `?`, `else`, `for`, `loop`, `while`, `{`, or an operator, found `,`
5763
--> $DIR/require-parens-for-chained-comparison.rs:22:17
5864
|
@@ -64,8 +70,14 @@ help: use `::<...>` instead of `<...>` to specify lifetime, type, or const argum
6470
LL | let _ = f::<'_, i8>();
6571
| ++
6672

73+
error: expected `while`, `for`, `loop` or `{` after a label
74+
--> $DIR/require-parens-for-chained-comparison.rs:27:9
75+
|
76+
LL | f<'_>();
77+
| ^ expected `while`, `for`, `loop` or `{` after a label
78+
6779
error: comparison operators cannot be chained
68-
--> $DIR/require-parens-for-chained-comparison.rs:26:6
80+
--> $DIR/require-parens-for-chained-comparison.rs:27:6
6981
|
7082
LL | f<'_>();
7183
| ^ ^
@@ -76,13 +88,13 @@ LL | f::<'_>();
7688
| ++
7789

7890
error: comparison operators cannot be chained
79-
--> $DIR/require-parens-for-chained-comparison.rs:30:14
91+
--> $DIR/require-parens-for-chained-comparison.rs:32:14
8092
|
8193
LL | let _ = f<u8>;
8294
| ^ ^
8395
|
8496
= help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
8597
= help: or use `(...)` if you meant to specify fn arguments
8698

87-
error: aborting due to 8 previous errors
99+
error: aborting due to 10 previous errors
88100

‎src/tools/linkchecker/main.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,9 @@ impl Checker {
182182
fn walk(&mut self, dir: &Path, report: &mut Report) {
183183
for entry in t!(dir.read_dir()).map(|e| t!(e)) {
184184
let path = entry.path();
185-
let kind = t!(entry.file_type());
186-
if kind.is_dir() {
185+
// Goes through symlinks
186+
let metadata = t!(fs::metadata(&path));
187+
if metadata.is_dir() {
187188
self.walk(&path, report);
188189
} else {
189190
self.check(&path, report);

‎src/tools/tidy/src/error_codes_check.rs

+29-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Checks that all error codes have at least one test to prevent having error
22
//! codes that are silently not thrown by the compiler anymore.
33
4-
use std::collections::HashMap;
4+
use std::collections::{HashMap, HashSet};
55
use std::ffi::OsStr;
66
use std::fs::read_to_string;
77
use std::path::Path;
@@ -205,6 +205,7 @@ pub fn check(paths: &[&Path], bad: &mut bool) {
205205
let mut found_explanations = 0;
206206
let mut found_tests = 0;
207207
let mut error_codes: HashMap<String, ErrorCodeStatus> = HashMap::new();
208+
let mut explanations: HashSet<String> = HashSet::new();
208209
// We want error codes which match the following cases:
209210
//
210211
// * foo(a, E0111, a)
@@ -218,17 +219,27 @@ pub fn check(paths: &[&Path], bad: &mut bool) {
218219
for path in paths {
219220
super::walk(path, &mut |path| super::filter_dirs(path), &mut |entry, contents| {
220221
let file_name = entry.file_name();
222+
let entry_path = entry.path();
223+
221224
if file_name == "error_codes.rs" {
222225
extract_error_codes(contents, &mut error_codes, entry.path(), &mut errors);
223226
found_explanations += 1;
224-
} else if entry.path().extension() == Some(OsStr::new("stderr")) {
227+
} else if entry_path.extension() == Some(OsStr::new("stderr")) {
225228
extract_error_codes_from_tests(contents, &mut error_codes);
226229
found_tests += 1;
227-
} else if entry.path().extension() == Some(OsStr::new("rs")) {
230+
} else if entry_path.extension() == Some(OsStr::new("rs")) {
228231
let path = entry.path().to_string_lossy();
229232
if PATHS_TO_IGNORE_FOR_EXTRACTION.iter().all(|c| !path.contains(c)) {
230233
extract_error_codes_from_source(contents, &mut error_codes, &regex);
231234
}
235+
} else if entry_path
236+
.parent()
237+
.and_then(|p| p.file_name())
238+
.map(|p| p == "error_codes")
239+
.unwrap_or(false)
240+
&& entry_path.extension() == Some(OsStr::new("md"))
241+
{
242+
explanations.insert(file_name.to_str().unwrap().replace(".md", ""));
232243
}
233244
});
234245
}
@@ -240,6 +251,10 @@ pub fn check(paths: &[&Path], bad: &mut bool) {
240251
eprintln!("No error code was found in compilation errors!");
241252
*bad = true;
242253
}
254+
if explanations.is_empty() {
255+
eprintln!("No error code explanation was found!");
256+
*bad = true;
257+
}
243258
if errors.is_empty() {
244259
println!("Found {} error codes", error_codes.len());
245260

@@ -282,11 +297,21 @@ pub fn check(paths: &[&Path], bad: &mut bool) {
282297
}
283298
}
284299
}
300+
if errors.is_empty() {
301+
for explanation in explanations {
302+
if !error_codes.contains_key(&explanation) {
303+
errors.push(format!(
304+
"{} error code explanation should be listed in `error_codes.rs`",
305+
explanation
306+
));
307+
}
308+
}
309+
}
285310
errors.sort();
286311
for err in &errors {
287312
eprintln!("{}", err);
288313
}
289-
println!("Found {} error codes with no tests", errors.len());
314+
println!("Found {} error(s) in error codes", errors.len());
290315
if !errors.is_empty() {
291316
*bad = true;
292317
}

0 commit comments

Comments
 (0)
Please sign in to comment.