Skip to content

Commit

Permalink
Auto merge of rust-lang#104102 - Dylan-DPC:rollup-0eakshe, r=Dylan-DPC
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Nov 7, 2022
2 parents 391ba78 + 81b8db2 commit 68f7729
Show file tree
Hide file tree
Showing 25 changed files with 346 additions and 18 deletions.
75 changes: 71 additions & 4 deletions compiler/rustc_error_codes/src/error_codes/E0207.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
A type parameter that is specified for `impl` is not constrained.
A type, const or lifetime parameter that is specified for `impl` is not
constrained.

Erroneous code example:

Expand All @@ -14,15 +15,18 @@ impl<T: Default> Foo {
}
```

Any type parameter of an `impl` must meet at least one of
the following criteria:
Any type or const parameter of an `impl` must meet at least one of the
following criteria:

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

Any unconstrained lifetime parameter of an `impl` is not supported if the
lifetime parameter is used by an associated type.

### Error example 1

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


```
struct Foo;
Expand Down Expand Up @@ -128,6 +131,70 @@ impl<T: Default> Maker<Foo<T>> for FooMaker {
}
```

### Error example 3

Suppose we have a struct `Foo` and we would like to define some methods for it.
The following code example has a definition which leads to a compiler error:

```compile_fail,E0207
struct Foo;
impl<const T: i32> Foo {
// error: the const parameter `T` is not constrained by the impl trait, self
// type, or predicates [E0207]
fn get(&self) -> i32 {
i32::default()
}
}
```

The problem is that the const parameter `T` does not appear in the implementing
type (`Foo`) of the impl. In this case, we can fix the error by moving the type
parameter from the `impl` to the method `get`:


```
struct Foo;
// Move the const parameter from the impl to the method
impl Foo {
fn get<const T: i32>(&self) -> i32 {
i32::default()
}
}
```

### Error example 4

Suppose we have a struct `Foo` and a struct `Bar` that uses lifetime `'a`. We
would like to implement trait `Contains` for `Foo`. The trait `Contains` have
the associated type `B`. The following code example has a definition which
leads to a compiler error:

```compile_fail,E0207
struct Foo;
struct Bar<'a>;
trait Contains {
type B;
fn get(&self) -> i32;
}
impl<'a> Contains for Foo {
type B = Bar<'a>;
// error: the lifetime parameter `'a` is not constrained by the impl trait,
// self type, or predicates [E0207]
fn get(&self) -> i32 {
i32::default()
}
}
```

Please note that unconstrained lifetime parameters are not supported if they are
being used by an associated type.

### Additional information

For more information, please see [RFC 447].
Expand Down
10 changes: 7 additions & 3 deletions compiler/rustc_hir_typeck/src/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use rustc_hir_analysis::astconv::AstConv;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::LateBoundRegionConversionTime;
use rustc_infer::infer::{InferOk, InferResult};
use rustc_macros::{TypeFoldable, TypeVisitable};
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::visit::TypeVisitable;
use rustc_middle::ty::{self, Ty};
Expand All @@ -22,7 +23,7 @@ use std::cmp;
use std::iter;

/// What signature do we *expect* the closure to have from context?
#[derive(Debug)]
#[derive(Debug, Clone, TypeFoldable, TypeVisitable)]
struct ExpectedSig<'tcx> {
/// Span that gave us this expectation, if we know that.
cause_span: Option<Span>,
Expand Down Expand Up @@ -241,9 +242,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if expected_sig.is_none()
&& let ty::PredicateKind::Projection(proj_predicate) = bound_predicate.skip_binder()
{
expected_sig = self.deduce_sig_from_projection(
expected_sig = self.normalize_associated_types_in(
obligation.cause.span,
self.deduce_sig_from_projection(
Some(obligation.cause.span),
bound_predicate.rebind(proj_predicate),
bound_predicate.rebind(proj_predicate),
),
);
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_macros/src/diagnostics/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pub(crate) fn invalid_attr(attr: &Attribute, meta: &Meta) -> Diagnostic {
}
}

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

/// Emit a error diagnostic for an invalid nested attribute (optionally performing additional
/// Emit an error diagnostic for an invalid nested attribute (optionally performing additional
/// decoration using the `FnOnce` passed in `diag`) and return `Err(ErrorHandled)`.
///
/// For methods that return a `Result<_, DiagnosticDeriveError>`:
Expand Down
12 changes: 8 additions & 4 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2468,11 +2468,15 @@ impl<'a> Parser<'a> {
}

pub(crate) fn maybe_recover_unexpected_block_label(&mut self) -> bool {
let Some(label) = self.eat_label().filter(|_| {
self.eat(&token::Colon) && self.token.kind == token::OpenDelim(Delimiter::Brace)
}) else {
// Check for `'a : {`
if !(self.check_lifetime()
&& self.look_ahead(1, |tok| tok.kind == token::Colon)
&& self.look_ahead(2, |tok| tok.kind == token::OpenDelim(Delimiter::Brace)))
{
return false;
};
}
let label = self.eat_label().expect("just checked if a label exists");
self.bump(); // eat `:`
let span = label.ident.span.to(self.prev_token.span);
let mut err = self.struct_span_err(span, "block label not supported here");
err.span_label(span, "not supported here");
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/src/collections/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ impl Display for TryReserveError {
" because the computed capacity exceeded the collection's maximum"
}
TryReserveErrorKind::AllocError { .. } => {
" because the memory allocator returned a error"
" because the memory allocator returned an error"
}
};
fmt.write_str(reason)
Expand Down
3 changes: 2 additions & 1 deletion src/librustdoc/passes/collect_intra_doc_links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
})
.and_then(|self_id| match tcx.def_kind(self_id) {
DefKind::Impl => self.def_id_to_res(self_id),
DefKind::Use => None,
def_kind => Some(Res::Def(def_kind, self_id)),
})
}
Expand Down Expand Up @@ -1772,7 +1773,6 @@ fn resolution_failure(

// Otherwise, it must be an associated item or variant
let res = partial_res.expect("None case was handled by `last_found_module`");
let name = res.name(tcx);
let kind = match res {
Res::Def(kind, _) => Some(kind),
Res::Primitive(_) => None,
Expand Down Expand Up @@ -1814,6 +1814,7 @@ fn resolution_failure(
} else {
"associated item"
};
let name = res.name(tcx);
let note = format!(
"the {} `{}` has no {} named `{}`",
res.descr(),
Expand Down
6 changes: 6 additions & 0 deletions src/test/rustdoc-ui/issue-103997.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// check-pass

pub fn foo() {}

/// [`foo`](Self::foo) //~ WARNING unresolved link to `Self::foo`
pub use foo as bar;
10 changes: 10 additions & 0 deletions src/test/rustdoc-ui/issue-103997.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
warning: unresolved link to `Self::foo`
--> $DIR/issue-103997.rs:5:13
|
LL | /// [`foo`](Self::foo)
| ^^^^^^^^^ no item named `Self` in scope
|
= note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default

warning: 1 warning emitted

17 changes: 17 additions & 0 deletions src/test/ui/closures/supertrait-hint-references-assoc-ty.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// check-pass

pub trait Fn0: Fn(i32) -> Self::Out {
type Out;
}

impl<F: Fn(i32) -> ()> Fn0 for F {
type Out = ();
}

pub fn closure_typer(_: impl Fn0) {}

fn main() {
closure_typer(move |x| {
let _: i64 = x.into();
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const C: bool = true;
trait Trait {}
impl dyn Trait { fn existing() {} }

// FIXME: Should be a error for edition > 2015
// FIXME: Should be an error for edition > 2015
#[cfg_accessible(Trait::existing)] //~ ERROR not sure
const A: bool = true;
#[cfg_accessible(Trait::unresolved)] //~ ERROR not sure
Expand Down
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.
43 changes: 43 additions & 0 deletions src/test/ui/parser/label-after-block-like.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
fn a() {
if let () = () 'a {}
//~^ ERROR labeled expression must be followed by `:`
//~| ERROR expected `{`, found `'a`
}

fn b() {
if true 'a {}
//~^ ERROR labeled expression must be followed by `:`
//~| ERROR expected `{`, found `'a`
}

fn c() {
loop 'a {}
//~^ ERROR labeled expression must be followed by `:`
//~| ERROR expected `{`, found `'a`
}

fn d() {
while true 'a {}
//~^ ERROR labeled expression must be followed by `:`
//~| ERROR expected `{`, found `'a`
}

fn e() {
while let () = () 'a {}
//~^ ERROR labeled expression must be followed by `:`
//~| ERROR expected `{`, found `'a`
}

fn f() {
for _ in 0..0 'a {}
//~^ ERROR labeled expression must be followed by `:`
//~| ERROR expected `{`, found `'a`
}

fn g() {
unsafe 'a {}
//~^ ERROR labeled expression must be followed by `:`
//~| ERROR expected `{`, found `'a`
}

fn main() {}
Loading

0 comments on commit 68f7729

Please sign in to comment.