Skip to content

Commit 68f7729

Browse files
committedNov 7, 2022
Auto merge of #104102 - Dylan-DPC:rollup-0eakshe, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #103757 (Mention const and lifetime parameters in error E0207) - #103986 (Don't silently eat label before block in block-like expr) - #104003 (Move some tests to more reasonable directories) - #104038 (Normalize types when deducing closure signature from supertraits) - #104052 (Fix `resolution_failure` ICE) - #104090 (Modify comment syntax error) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
·
1.88.01.67.0
2 parents 391ba78 + 81b8db2 commit 68f7729

File tree

25 files changed

+346
-18
lines changed

25 files changed

+346
-18
lines changed
 

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

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
A type parameter that is specified for `impl` is not constrained.
1+
A type, const or lifetime parameter that is specified for `impl` is not
2+
constrained.
23

34
Erroneous code example:
45

@@ -14,15 +15,18 @@ impl<T: Default> Foo {
1415
}
1516
```
1617

17-
Any type parameter of an `impl` must meet at least one of
18-
the following criteria:
18+
Any type or const parameter of an `impl` must meet at least one of the
19+
following criteria:
1920

2021
- it appears in the _implementing type_ of the impl, e.g. `impl<T> Foo<T>`
2122
- for a trait impl, it appears in the _implemented trait_, e.g.
2223
`impl<T> SomeTrait<T> for Foo`
2324
- it is bound as an associated type, e.g. `impl<T, U> SomeTrait for T
2425
where T: AnotherTrait<AssocType=U>`
2526

27+
Any unconstrained lifetime parameter of an `impl` is not supported if the
28+
lifetime parameter is used by an associated type.
29+
2630
### Error example 1
2731

2832
Suppose we have a struct `Foo` and we would like to define some methods for it.
@@ -32,7 +36,6 @@ The problem is that the parameter `T` does not appear in the implementing type
3236
(`Foo`) of the impl. In this case, we can fix the error by moving the type
3337
parameter from the `impl` to the method `get`:
3438

35-
3639
```
3740
struct Foo;
3841
@@ -128,6 +131,70 @@ impl<T: Default> Maker<Foo<T>> for FooMaker {
128131
}
129132
```
130133

134+
### Error example 3
135+
136+
Suppose we have a struct `Foo` and we would like to define some methods for it.
137+
The following code example has a definition which leads to a compiler error:
138+
139+
```compile_fail,E0207
140+
struct Foo;
141+
142+
impl<const T: i32> Foo {
143+
// error: the const parameter `T` is not constrained by the impl trait, self
144+
// type, or predicates [E0207]
145+
fn get(&self) -> i32 {
146+
i32::default()
147+
}
148+
}
149+
```
150+
151+
The problem is that the const parameter `T` does not appear in the implementing
152+
type (`Foo`) of the impl. In this case, we can fix the error by moving the type
153+
parameter from the `impl` to the method `get`:
154+
155+
156+
```
157+
struct Foo;
158+
159+
// Move the const parameter from the impl to the method
160+
impl Foo {
161+
fn get<const T: i32>(&self) -> i32 {
162+
i32::default()
163+
}
164+
}
165+
```
166+
167+
### Error example 4
168+
169+
Suppose we have a struct `Foo` and a struct `Bar` that uses lifetime `'a`. We
170+
would like to implement trait `Contains` for `Foo`. The trait `Contains` have
171+
the associated type `B`. The following code example has a definition which
172+
leads to a compiler error:
173+
174+
```compile_fail,E0207
175+
struct Foo;
176+
struct Bar<'a>;
177+
178+
trait Contains {
179+
type B;
180+
181+
fn get(&self) -> i32;
182+
}
183+
184+
impl<'a> Contains for Foo {
185+
type B = Bar<'a>;
186+
187+
// error: the lifetime parameter `'a` is not constrained by the impl trait,
188+
// self type, or predicates [E0207]
189+
fn get(&self) -> i32 {
190+
i32::default()
191+
}
192+
}
193+
```
194+
195+
Please note that unconstrained lifetime parameters are not supported if they are
196+
being used by an associated type.
197+
131198
### Additional information
132199

133200
For more information, please see [RFC 447].

‎compiler/rustc_hir_typeck/src/closure.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_hir_analysis::astconv::AstConv;
1010
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
1111
use rustc_infer::infer::LateBoundRegionConversionTime;
1212
use rustc_infer::infer::{InferOk, InferResult};
13+
use rustc_macros::{TypeFoldable, TypeVisitable};
1314
use rustc_middle::ty::subst::InternalSubsts;
1415
use rustc_middle::ty::visit::TypeVisitable;
1516
use rustc_middle::ty::{self, Ty};
@@ -22,7 +23,7 @@ use std::cmp;
2223
use std::iter;
2324

2425
/// What signature do we *expect* the closure to have from context?
25-
#[derive(Debug)]
26+
#[derive(Debug, Clone, TypeFoldable, TypeVisitable)]
2627
struct ExpectedSig<'tcx> {
2728
/// Span that gave us this expectation, if we know that.
2829
cause_span: Option<Span>,
@@ -241,9 +242,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
241242
if expected_sig.is_none()
242243
&& let ty::PredicateKind::Projection(proj_predicate) = bound_predicate.skip_binder()
243244
{
244-
expected_sig = self.deduce_sig_from_projection(
245+
expected_sig = self.normalize_associated_types_in(
246+
obligation.cause.span,
247+
self.deduce_sig_from_projection(
245248
Some(obligation.cause.span),
246-
bound_predicate.rebind(proj_predicate),
249+
bound_predicate.rebind(proj_predicate),
250+
),
247251
);
248252
}
249253

‎compiler/rustc_macros/src/diagnostics/error.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ pub(crate) fn invalid_attr(attr: &Attribute, meta: &Meta) -> Diagnostic {
8484
}
8585
}
8686

87-
/// Emit a error diagnostic for an invalid attribute (optionally performing additional decoration
87+
/// Emit an error diagnostic for an invalid attribute (optionally performing additional decoration
8888
/// using the `FnOnce` passed in `diag`) and return `Err(ErrorHandled)`.
8989
///
9090
/// For methods that return a `Result<_, DiagnosticDeriveError>`:
@@ -126,7 +126,7 @@ pub(crate) fn invalid_nested_attr(attr: &Attribute, nested: &NestedMeta) -> Diag
126126
}
127127
}
128128

129-
/// Emit a error diagnostic for an invalid nested attribute (optionally performing additional
129+
/// Emit an error diagnostic for an invalid nested attribute (optionally performing additional
130130
/// decoration using the `FnOnce` passed in `diag`) and return `Err(ErrorHandled)`.
131131
///
132132
/// For methods that return a `Result<_, DiagnosticDeriveError>`:

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2468,11 +2468,15 @@ impl<'a> Parser<'a> {
24682468
}
24692469

24702470
pub(crate) fn maybe_recover_unexpected_block_label(&mut self) -> bool {
2471-
let Some(label) = self.eat_label().filter(|_| {
2472-
self.eat(&token::Colon) && self.token.kind == token::OpenDelim(Delimiter::Brace)
2473-
}) else {
2471+
// Check for `'a : {`
2472+
if !(self.check_lifetime()
2473+
&& self.look_ahead(1, |tok| tok.kind == token::Colon)
2474+
&& self.look_ahead(2, |tok| tok.kind == token::OpenDelim(Delimiter::Brace)))
2475+
{
24742476
return false;
2475-
};
2477+
}
2478+
let label = self.eat_label().expect("just checked if a label exists");
2479+
self.bump(); // eat `:`
24762480
let span = label.ident.span.to(self.prev_token.span);
24772481
let mut err = self.struct_span_err(span, "block label not supported here");
24782482
err.span_label(span, "not supported here");

‎library/alloc/src/collections/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ impl Display for TryReserveError {
139139
" because the computed capacity exceeded the collection's maximum"
140140
}
141141
TryReserveErrorKind::AllocError { .. } => {
142-
" because the memory allocator returned a error"
142+
" because the memory allocator returned an error"
143143
}
144144
};
145145
fmt.write_str(reason)

‎src/librustdoc/passes/collect_intra_doc_links.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
402402
})
403403
.and_then(|self_id| match tcx.def_kind(self_id) {
404404
DefKind::Impl => self.def_id_to_res(self_id),
405+
DefKind::Use => None,
405406
def_kind => Some(Res::Def(def_kind, self_id)),
406407
})
407408
}
@@ -1772,7 +1773,6 @@ fn resolution_failure(
17721773

17731774
// Otherwise, it must be an associated item or variant
17741775
let res = partial_res.expect("None case was handled by `last_found_module`");
1775-
let name = res.name(tcx);
17761776
let kind = match res {
17771777
Res::Def(kind, _) => Some(kind),
17781778
Res::Primitive(_) => None,
@@ -1814,6 +1814,7 @@ fn resolution_failure(
18141814
} else {
18151815
"associated item"
18161816
};
1817+
let name = res.name(tcx);
18171818
let note = format!(
18181819
"the {} `{}` has no {} named `{}`",
18191820
res.descr(),

‎src/test/rustdoc-ui/issue-103997.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// check-pass
2+
3+
pub fn foo() {}
4+
5+
/// [`foo`](Self::foo) //~ WARNING unresolved link to `Self::foo`
6+
pub use foo as bar;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
warning: unresolved link to `Self::foo`
2+
--> $DIR/issue-103997.rs:5:13
3+
|
4+
LL | /// [`foo`](Self::foo)
5+
| ^^^^^^^^^ no item named `Self` in scope
6+
|
7+
= note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default
8+
9+
warning: 1 warning emitted
10+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// check-pass
2+
3+
pub trait Fn0: Fn(i32) -> Self::Out {
4+
type Out;
5+
}
6+
7+
impl<F: Fn(i32) -> ()> Fn0 for F {
8+
type Out = ();
9+
}
10+
11+
pub fn closure_typer(_: impl Fn0) {}
12+
13+
fn main() {
14+
closure_typer(move |x| {
15+
let _: i64 = x.into();
16+
});
17+
}

‎src/test/ui/conditional-compilation/cfg_accessible-not_sure.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const C: bool = true;
4646
trait Trait {}
4747
impl dyn Trait { fn existing() {} }
4848

49-
// FIXME: Should be a error for edition > 2015
49+
// FIXME: Should be an error for edition > 2015
5050
#[cfg_accessible(Trait::existing)] //~ ERROR not sure
5151
const A: bool = true;
5252
#[cfg_accessible(Trait::unresolved)] //~ ERROR not sure
File renamed without changes.
File renamed without changes.
File renamed without changes.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
fn a() {
2+
if let () = () 'a {}
3+
//~^ ERROR labeled expression must be followed by `:`
4+
//~| ERROR expected `{`, found `'a`
5+
}
6+
7+
fn b() {
8+
if true 'a {}
9+
//~^ ERROR labeled expression must be followed by `:`
10+
//~| ERROR expected `{`, found `'a`
11+
}
12+
13+
fn c() {
14+
loop 'a {}
15+
//~^ ERROR labeled expression must be followed by `:`
16+
//~| ERROR expected `{`, found `'a`
17+
}
18+
19+
fn d() {
20+
while true 'a {}
21+
//~^ ERROR labeled expression must be followed by `:`
22+
//~| ERROR expected `{`, found `'a`
23+
}
24+
25+
fn e() {
26+
while let () = () 'a {}
27+
//~^ ERROR labeled expression must be followed by `:`
28+
//~| ERROR expected `{`, found `'a`
29+
}
30+
31+
fn f() {
32+
for _ in 0..0 'a {}
33+
//~^ ERROR labeled expression must be followed by `:`
34+
//~| ERROR expected `{`, found `'a`
35+
}
36+
37+
fn g() {
38+
unsafe 'a {}
39+
//~^ ERROR labeled expression must be followed by `:`
40+
//~| ERROR expected `{`, found `'a`
41+
}
42+
43+
fn main() {}
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
error: labeled expression must be followed by `:`
2+
--> $DIR/label-after-block-like.rs:2:20
3+
|
4+
LL | if let () = () 'a {}
5+
| ---^^
6+
| | |
7+
| | help: add `:` after the label
8+
| the label
9+
|
10+
= note: labels are used before loops and blocks, allowing e.g., `break 'label` to them
11+
12+
error: expected `{`, found `'a`
13+
--> $DIR/label-after-block-like.rs:2:20
14+
|
15+
LL | if let () = () 'a {}
16+
| ^^ expected `{`
17+
|
18+
note: the `if` expression is missing a block after this condition
19+
--> $DIR/label-after-block-like.rs:2:8
20+
|
21+
LL | if let () = () 'a {}
22+
| ^^^^^^^^^^^
23+
help: try placing this code inside a block
24+
|
25+
LL | if let () = () { 'a {} }
26+
| + +
27+
28+
error: labeled expression must be followed by `:`
29+
--> $DIR/label-after-block-like.rs:8:13
30+
|
31+
LL | if true 'a {}
32+
| ---^^
33+
| | |
34+
| | help: add `:` after the label
35+
| the label
36+
|
37+
= note: labels are used before loops and blocks, allowing e.g., `break 'label` to them
38+
39+
error: expected `{`, found `'a`
40+
--> $DIR/label-after-block-like.rs:8:13
41+
|
42+
LL | if true 'a {}
43+
| ^^ expected `{`
44+
|
45+
note: the `if` expression is missing a block after this condition
46+
--> $DIR/label-after-block-like.rs:8:8
47+
|
48+
LL | if true 'a {}
49+
| ^^^^
50+
help: try placing this code inside a block
51+
|
52+
LL | if true { 'a {} }
53+
| + +
54+
55+
error: labeled expression must be followed by `:`
56+
--> $DIR/label-after-block-like.rs:14:10
57+
|
58+
LL | loop 'a {}
59+
| ---^^
60+
| | |
61+
| | help: add `:` after the label
62+
| the label
63+
|
64+
= note: labels are used before loops and blocks, allowing e.g., `break 'label` to them
65+
66+
error: expected `{`, found `'a`
67+
--> $DIR/label-after-block-like.rs:14:10
68+
|
69+
LL | loop 'a {}
70+
| ---- ^^ expected `{`
71+
| |
72+
| while parsing this `loop` expression
73+
|
74+
help: try placing this code inside a block
75+
|
76+
LL | loop { 'a {} }
77+
| + +
78+
79+
error: labeled expression must be followed by `:`
80+
--> $DIR/label-after-block-like.rs:20:16
81+
|
82+
LL | while true 'a {}
83+
| ---^^
84+
| | |
85+
| | help: add `:` after the label
86+
| the label
87+
|
88+
= note: labels are used before loops and blocks, allowing e.g., `break 'label` to them
89+
90+
error: expected `{`, found `'a`
91+
--> $DIR/label-after-block-like.rs:20:16
92+
|
93+
LL | while true 'a {}
94+
| ----- ---- ^^ expected `{`
95+
| | |
96+
| | this `while` condition successfully parsed
97+
| while parsing the body of this `while` expression
98+
|
99+
help: try placing this code inside a block
100+
|
101+
LL | while true { 'a {} }
102+
| + +
103+
104+
error: labeled expression must be followed by `:`
105+
--> $DIR/label-after-block-like.rs:26:23
106+
|
107+
LL | while let () = () 'a {}
108+
| ---^^
109+
| | |
110+
| | help: add `:` after the label
111+
| the label
112+
|
113+
= note: labels are used before loops and blocks, allowing e.g., `break 'label` to them
114+
115+
error: expected `{`, found `'a`
116+
--> $DIR/label-after-block-like.rs:26:23
117+
|
118+
LL | while let () = () 'a {}
119+
| ----- ----------- ^^ expected `{`
120+
| | |
121+
| | this `while` condition successfully parsed
122+
| while parsing the body of this `while` expression
123+
|
124+
help: try placing this code inside a block
125+
|
126+
LL | while let () = () { 'a {} }
127+
| + +
128+
129+
error: labeled expression must be followed by `:`
130+
--> $DIR/label-after-block-like.rs:32:19
131+
|
132+
LL | for _ in 0..0 'a {}
133+
| ---^^
134+
| | |
135+
| | help: add `:` after the label
136+
| the label
137+
|
138+
= note: labels are used before loops and blocks, allowing e.g., `break 'label` to them
139+
140+
error: expected `{`, found `'a`
141+
--> $DIR/label-after-block-like.rs:32:19
142+
|
143+
LL | for _ in 0..0 'a {}
144+
| ^^ expected `{`
145+
|
146+
help: try placing this code inside a block
147+
|
148+
LL | for _ in 0..0 { 'a {} }
149+
| + +
150+
151+
error: labeled expression must be followed by `:`
152+
--> $DIR/label-after-block-like.rs:38:12
153+
|
154+
LL | unsafe 'a {}
155+
| ---^^
156+
| | |
157+
| | help: add `:` after the label
158+
| the label
159+
|
160+
= note: labels are used before loops and blocks, allowing e.g., `break 'label` to them
161+
162+
error: expected `{`, found `'a`
163+
--> $DIR/label-after-block-like.rs:38:12
164+
|
165+
LL | unsafe 'a {}
166+
| ------ ^^ expected `{`
167+
| |
168+
| while parsing this `unsafe` expression
169+
|
170+
help: try placing this code inside a block
171+
|
172+
LL | unsafe { 'a {} }
173+
| + +
174+
175+
error: aborting due to 14 previous errors
176+
File renamed without changes.

‎src/tools/tidy/src/ui_tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ use std::path::Path;
99

1010
const ENTRY_LIMIT: usize = 1000;
1111
// FIXME: The following limits should be reduced eventually.
12-
const ROOT_ENTRY_LIMIT: usize = 941;
13-
const ISSUES_ENTRY_LIMIT: usize = 2117;
12+
const ROOT_ENTRY_LIMIT: usize = 939;
13+
const ISSUES_ENTRY_LIMIT: usize = 2105;
1414

1515
fn check_entries(path: &Path, bad: &mut bool) {
1616
for dir in Walk::new(&path.join("test/ui")) {

0 commit comments

Comments
 (0)
Please sign in to comment.