diff options
| author | bors <bors@rust-lang.org> | 2022-11-07 13:19:36 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-11-07 13:19:36 +0000 |
| commit | 68f77297c0f199e00ff98f4b6bd71a74e75ec09c (patch) | |
| tree | 7af50e3e584c436407d65d26295f28e4f5cf3b11 /compiler | |
| parent | 391ba78ab442610a63310b9a3d24646082628081 (diff) | |
| parent | 81b8db2675330c5d7c0af2db2b90311bd1aec976 (diff) | |
| download | rust-68f77297c0f199e00ff98f4b6bd71a74e75ec09c.tar.gz rust-68f77297c0f199e00ff98f4b6bd71a74e75ec09c.zip | |
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
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0207.md | 75 | ||||
| -rw-r--r-- | compiler/rustc_hir_typeck/src/closure.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/diagnostics/error.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/diagnostics.rs | 12 |
4 files changed, 88 insertions, 13 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes/E0207.md b/compiler/rustc_error_codes/src/error_codes/E0207.md index 8a7923ac93f..95e7c9fc76c 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0207.md +++ b/compiler/rustc_error_codes/src/error_codes/E0207.md @@ -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: @@ -14,8 +15,8 @@ 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. @@ -23,6 +24,9 @@ the following criteria: - 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. @@ -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; @@ -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]. diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 09df50c76b7..3001e799476 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -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}; @@ -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>, @@ -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), + ), ); } diff --git a/compiler/rustc_macros/src/diagnostics/error.rs b/compiler/rustc_macros/src/diagnostics/error.rs index 0b1ededa775..4612f54e4b1 100644 --- a/compiler/rustc_macros/src/diagnostics/error.rs +++ b/compiler/rustc_macros/src/diagnostics/error.rs @@ -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>`: @@ -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>`: diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 7dc4fd0044f..c609aa93da3 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -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"); |
