Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions compiler/rustc_hir_analysis/src/delegation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use rustc_middle::ty::{
use rustc_span::{ErrorGuaranteed, Span, kw};

use crate::collect::ItemCtxt;
use crate::errors::DelegationSelfTypeNotSpecified;
use crate::hir_ty_lowering::HirTyLowerer;

type RemapTable = FxHashMap<u32, u32>;
Expand Down Expand Up @@ -284,6 +285,12 @@ fn get_delegation_self_ty_or_err(tcx: TyCtxt<'_>, delegation_id: LocalDefId) ->
ctx.lower_ty(tcx.hir_node(id).expect_ty())
})
.unwrap_or_else(|| {
// It is possible to attempt to get self type when it is used in signature
// (i.e., `fn default() -> Self`), so emit error here in addition to possible
// `mismatched types` error (see #156388).
let err = DelegationSelfTypeNotSpecified { span: tcx.def_span(delegation_id) };
tcx.dcx().emit_err(err);

Ty::new_error_with_message(
tcx,
tcx.def_span(delegation_id),
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1670,6 +1670,14 @@ pub(crate) struct UnsupportedDelegation<'a> {
pub callee_span: Span,
}

#[derive(Diagnostic)]
#[diag("delegation self type is not specified")]
#[help("consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`")]
pub(crate) struct DelegationSelfTypeNotSpecified {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag("method should be `async` or return a future, but it is synchronous")]
pub(crate) struct MethodShouldReturnFuture {
Expand Down
6 changes: 6 additions & 0 deletions tests/ui/delegation/generics/free-to-trait-static-reuse.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//@ compile-flags: -Z deduplicate-diagnostics=yes

#![feature(fn_delegation)]

trait Bound<T> {}
Expand All @@ -19,12 +21,16 @@ reuse <usize as Trait>::static_method::<'static, Vec<i32>, false> as bar2;

reuse Trait::static_method as error { self - 123 }
//~^ ERROR: type annotations needed
//~| ERROR: delegation self type is not specified
reuse Trait::<'static, i32, 123>::static_method as error2;
//~^ ERROR: type annotations needed
//~| ERROR: delegation self type is not specified
reuse Trait::<'static, i32, 123>::static_method::<'static, String, false> as error3;
//~^ ERROR: type annotations needed
//~| ERROR: delegation self type is not specified
reuse Trait::static_method::<'static, Vec<i32>, false> as error4 { self + 4 }
//~^ ERROR: type annotations needed
//~| ERROR: delegation self type is not specified

reuse <String as Trait>::static_method as error5;
//~^ ERROR: the trait bound `String: Trait<'a, T, X>` is not satisfied
Expand Down
70 changes: 51 additions & 19 deletions tests/ui/delegation/generics/free-to-trait-static-reuse.stderr
Original file line number Diff line number Diff line change
@@ -1,21 +1,53 @@
error: delegation self type is not specified
--> $DIR/free-to-trait-static-reuse.rs:22:14
|
LL | reuse Trait::static_method as error { self - 123 }
| ^^^^^^^^^^^^^
|
= help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`

error: delegation self type is not specified
--> $DIR/free-to-trait-static-reuse.rs:25:35
|
LL | reuse Trait::<'static, i32, 123>::static_method as error2;
| ^^^^^^^^^^^^^
|
= help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`

error: delegation self type is not specified
--> $DIR/free-to-trait-static-reuse.rs:28:35
|
LL | reuse Trait::<'static, i32, 123>::static_method::<'static, String, false> as error3;
| ^^^^^^^^^^^^^
|
= help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`

error: delegation self type is not specified
--> $DIR/free-to-trait-static-reuse.rs:31:14
|
LL | reuse Trait::static_method::<'static, Vec<i32>, false> as error4 { self + 4 }
| ^^^^^^^^^^^^^
|
= help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`

error[E0277]: the trait bound `Struct: Bound<T>` is not satisfied
--> $DIR/free-to-trait-static-reuse.rs:33:49
--> $DIR/free-to-trait-static-reuse.rs:39:49
|
LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {}
| ^^^^^^ unsatisfied trait bound
|
help: the trait `Bound<T>` is not implemented for `Struct`
--> $DIR/free-to-trait-static-reuse.rs:32:1
--> $DIR/free-to-trait-static-reuse.rs:38:1
|
LL | struct Struct;
| ^^^^^^^^^^^^^
help: the trait `Bound<T>` is implemented for `usize`
--> $DIR/free-to-trait-static-reuse.rs:13:1
--> $DIR/free-to-trait-static-reuse.rs:15:1
|
LL | impl<T> Bound<T> for usize {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `Trait`
--> $DIR/free-to-trait-static-reuse.rs:7:11
--> $DIR/free-to-trait-static-reuse.rs:9:11
|
LL | trait Trait<'a, T, const X: usize>
| ----- required by a bound in this trait
Expand All @@ -24,13 +56,13 @@ LL | Self: Bound<T>,
| ^^^^^^^^ required by this bound in `Trait`

error[E0283]: type annotations needed
--> $DIR/free-to-trait-static-reuse.rs:20:14
--> $DIR/free-to-trait-static-reuse.rs:22:14
|
LL | reuse Trait::static_method as error { self - 123 }
| ^^^^^^^^^^^^^ cannot infer type
|
note: multiple `impl`s satisfying `_: Trait<'a, T, X>` found
--> $DIR/free-to-trait-static-reuse.rs:12:1
--> $DIR/free-to-trait-static-reuse.rs:14:1
|
LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -39,13 +71,13 @@ LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0283]: type annotations needed
--> $DIR/free-to-trait-static-reuse.rs:22:35
--> $DIR/free-to-trait-static-reuse.rs:25:35
|
LL | reuse Trait::<'static, i32, 123>::static_method as error2;
| ^^^^^^^^^^^^^ cannot infer type
|
note: multiple `impl`s satisfying `_: Trait<'static, i32, 123>` found
--> $DIR/free-to-trait-static-reuse.rs:12:1
--> $DIR/free-to-trait-static-reuse.rs:14:1
|
LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -54,13 +86,13 @@ LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0283]: type annotations needed
--> $DIR/free-to-trait-static-reuse.rs:24:35
--> $DIR/free-to-trait-static-reuse.rs:28:35
|
LL | reuse Trait::<'static, i32, 123>::static_method::<'static, String, false> as error3;
| ^^^^^^^^^^^^^ cannot infer type
|
note: multiple `impl`s satisfying `_: Trait<'static, i32, 123>` found
--> $DIR/free-to-trait-static-reuse.rs:12:1
--> $DIR/free-to-trait-static-reuse.rs:14:1
|
LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -69,13 +101,13 @@ LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0283]: type annotations needed
--> $DIR/free-to-trait-static-reuse.rs:26:14
--> $DIR/free-to-trait-static-reuse.rs:31:14
|
LL | reuse Trait::static_method::<'static, Vec<i32>, false> as error4 { self + 4 }
| ^^^^^^^^^^^^^ cannot infer type
|
note: multiple `impl`s satisfying `_: Trait<'a, T, X>` found
--> $DIR/free-to-trait-static-reuse.rs:12:1
--> $DIR/free-to-trait-static-reuse.rs:14:1
|
LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -84,13 +116,13 @@ LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0277]: the trait bound `String: Trait<'a, T, X>` is not satisfied
--> $DIR/free-to-trait-static-reuse.rs:29:8
--> $DIR/free-to-trait-static-reuse.rs:35:8
|
LL | reuse <String as Trait>::static_method as error5;
| ^^^^^^ the trait `Trait<'a, T, X>` is not implemented for `String`
|
help: the following other types implement trait `Trait<'a, T, X>`
--> $DIR/free-to-trait-static-reuse.rs:12:1
--> $DIR/free-to-trait-static-reuse.rs:14:1
|
LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `usize`
Expand All @@ -99,31 +131,31 @@ LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Struct`

error[E0277]: the trait bound `Struct: Bound<T>` is not satisfied
--> $DIR/free-to-trait-static-reuse.rs:36:8
--> $DIR/free-to-trait-static-reuse.rs:42:8
|
LL | reuse <Struct as Trait>::static_method as error6;
| ^^^^^^ unsatisfied trait bound
|
help: the trait `Bound<T>` is not implemented for `Struct`
--> $DIR/free-to-trait-static-reuse.rs:32:1
--> $DIR/free-to-trait-static-reuse.rs:38:1
|
LL | struct Struct;
| ^^^^^^^^^^^^^
help: the trait `Bound<T>` is implemented for `usize`
--> $DIR/free-to-trait-static-reuse.rs:13:1
--> $DIR/free-to-trait-static-reuse.rs:15:1
|
LL | impl<T> Bound<T> for usize {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `Trait::static_method`
--> $DIR/free-to-trait-static-reuse.rs:7:11
--> $DIR/free-to-trait-static-reuse.rs:9:11
|
LL | Self: Bound<T>,
| ^^^^^^^^ required by this bound in `Trait::static_method`
LL | {
LL | fn static_method<'c: 'c, U, const B: bool>(x: usize) {}
| ------------- required by a bound in this associated function

error: aborting due to 7 previous errors
error: aborting due to 11 previous errors

Some errors have detailed explanations: E0277, E0283.
For more information about an error, try `rustc --explain E0277`.
8 changes: 8 additions & 0 deletions tests/ui/delegation/self-ty-ice-156388.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//@ compile-flags: -Z deduplicate-diagnostics=yes

#![feature(fn_delegation)]

reuse Default::default;
Comment thread
aerooneqq marked this conversation as resolved.
//~^ ERROR: delegation self type is not specified

fn main() {}
10 changes: 10 additions & 0 deletions tests/ui/delegation/self-ty-ice-156388.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
error: delegation self type is not specified
--> $DIR/self-ty-ice-156388.rs:5:16
|
LL | reuse Default::default;
| ^^^^^^^
|
= help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`

error: aborting due to 1 previous error

3 changes: 3 additions & 0 deletions tests/ui/delegation/target-expr.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//@ compile-flags: -Z deduplicate-diagnostics=yes

#![feature(fn_delegation)]

trait Trait {
Expand All @@ -14,6 +16,7 @@ fn foo(x: i32) -> i32 { x }
fn bar<T: Default>(_: T) {
reuse Trait::static_method {
//~^ ERROR mismatched types
//~| ERROR: delegation self type is not specified
let _ = T::Default();
//~^ ERROR can't use generic parameters from outer item
}
Expand Down
25 changes: 17 additions & 8 deletions tests/ui/delegation/target-expr.stderr
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
error[E0401]: can't use generic parameters from outer item
--> $DIR/target-expr.rs:17:17
--> $DIR/target-expr.rs:20:17
|
LL | fn bar<T: Default>(_: T) {
| - type parameter from outer item
LL | reuse Trait::static_method {
| ------------- generic parameter used in this inner delegated function
LL |
...
LL | let _ = T::Default();
| ^ use of generic parameter from outer item
|
= note: nested items are independent from their parent item for everything except for privacy and name resolution

error[E0434]: can't capture dynamic environment in a fn item
--> $DIR/target-expr.rs:25:17
--> $DIR/target-expr.rs:28:17
|
LL | let x = y;
| ^
|
= help: use the `|| { ... }` closure form instead

error[E0424]: expected value, found module `self`
--> $DIR/target-expr.rs:32:5
--> $DIR/target-expr.rs:35:5
|
LL | fn main() {
| ---- this function can't have a `self` parameter
Expand All @@ -29,29 +29,38 @@ LL | self.0;
| ^^^^ `self` value is a keyword only available in methods with a `self` parameter

error[E0425]: cannot find value `x` in this scope
--> $DIR/target-expr.rs:34:13
--> $DIR/target-expr.rs:37:13
|
LL | let z = x;
| ^
|
help: the binding `x` is available in a different scope in the same function
--> $DIR/target-expr.rs:25:13
--> $DIR/target-expr.rs:28:13
|
LL | let x = y;
| ^

error: delegation self type is not specified
--> $DIR/target-expr.rs:17:18
|
LL | reuse Trait::static_method {
| ^^^^^^^^^^^^^
|
= help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`

error[E0308]: mismatched types
--> $DIR/target-expr.rs:15:32
--> $DIR/target-expr.rs:17:32
|
LL | reuse Trait::static_method {
| ________________________________^
LL | |
LL | |
LL | | let _ = T::Default();
LL | |
LL | | }
| |_____^ expected `i32`, found `()`

error: aborting due to 5 previous errors
error: aborting due to 6 previous errors

Some errors have detailed explanations: E0308, E0401, E0424, E0425, E0434.
For more information about an error, try `rustc --explain E0308`.
Loading
Loading