Skip to content

Commit 68f7729

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

25 files changed

+346
-18
lines changed

compiler/rustc_error_codes/src/error_codes/E0207.md

+71-4
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

+7-3
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

+2-2
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

+8-4
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

+1-1
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

+2-1
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

+6
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;
+10
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+
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

+1-1
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.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
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() {}

0 commit comments

Comments
 (0)