diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4ab5d8f9ad3f6..698b0e9bfcb87 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5446,9 +5446,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .unwrap_or(false); let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res { - let ty = self.impl_self_ty(span, impl_def_id).ty; - let adt_def = ty.ty_adt_def(); - + let ty = self.normalize_ty(span, tcx.at(span).type_of(impl_def_id)); match ty.kind { ty::Adt(adt_def, substs) if adt_def.has_ctor() => { let variant = adt_def.non_enum_variant(); @@ -5463,7 +5461,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span, "the `Self` constructor can only be used with tuple or unit structs", ); - if let Some(adt_def) = adt_def { + if let Some(adt_def) = ty.ty_adt_def() { match adt_def.adt_kind() { AdtKind::Enum => { err.help("did you mean to use one of the enum's variants?"); diff --git a/src/test/ui/issues/issue-69306.rs b/src/test/ui/issues/issue-69306.rs new file mode 100644 index 0000000000000..85d60952ac823 --- /dev/null +++ b/src/test/ui/issues/issue-69306.rs @@ -0,0 +1,45 @@ +fn main() {} + +struct S0(T); +impl S0 { + const C: S0 = Self(0); + //~^ ERROR mismatched types + //~| ERROR mismatched types + + fn foo() { + Self(0); + //~^ ERROR mismatched types + } +} + +// Testing normalization. +trait Fun { + type Out; +} +impl Fun for S0 { + type Out = Self; +} +trait Foo { + fn foo(); +} +impl Foo for as Fun>::Out { + fn foo() { + Self(0); //~ ERROR mismatched types + } +} + +struct S1(T, U); +impl S1 { + const C: S1 = Self(0, 1); + //~^ ERROR mismatched types + //~| ERROR mismatched types +} + +struct S2(T); +impl S2 { + fn map(x: U) -> S2 { + Self(x) + //~^ ERROR mismatched types + //~| ERROR mismatched types + } +} diff --git a/src/test/ui/issues/issue-69306.stderr b/src/test/ui/issues/issue-69306.stderr new file mode 100644 index 0000000000000..a2a42739ca8be --- /dev/null +++ b/src/test/ui/issues/issue-69306.stderr @@ -0,0 +1,115 @@ +error[E0308]: mismatched types + --> $DIR/issue-69306.rs:5:28 + | +LL | impl S0 { + | - this type parameter +LL | const C: S0 = Self(0); + | ^ expected type parameter `T`, found integer + | + = note: expected type parameter `T` + found type `{integer}` + = help: type parameters must be constrained to match other types + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + +error[E0308]: mismatched types + --> $DIR/issue-69306.rs:5:23 + | +LL | impl S0 { + | - this type parameter +LL | const C: S0 = Self(0); + | ^^^^^^^ expected `u8`, found type parameter `T` + | + = note: expected struct `S0` + found struct `S0` + = help: type parameters must be constrained to match other types + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + +error[E0308]: mismatched types + --> $DIR/issue-69306.rs:10:14 + | +LL | impl S0 { + | - this type parameter +... +LL | Self(0); + | ^ expected type parameter `T`, found integer + | + = note: expected type parameter `T` + found type `{integer}` + = help: type parameters must be constrained to match other types + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + +error[E0308]: mismatched types + --> $DIR/issue-69306.rs:27:14 + | +LL | impl Foo for as Fun>::Out { + | - this type parameter +LL | fn foo() { +LL | Self(0); + | ^ expected type parameter `T`, found integer + | + = note: expected type parameter `T` + found type `{integer}` + = help: type parameters must be constrained to match other types + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + +error[E0308]: mismatched types + --> $DIR/issue-69306.rs:33:32 + | +LL | impl S1 { + | - this type parameter +LL | const C: S1 = Self(0, 1); + | ^ expected type parameter `T`, found integer + | + = note: expected type parameter `T` + found type `{integer}` + = help: type parameters must be constrained to match other types + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + +error[E0308]: mismatched types + --> $DIR/issue-69306.rs:33:27 + | +LL | impl S1 { + | - this type parameter +LL | const C: S1 = Self(0, 1); + | ^^^^^^^^^^ expected `u8`, found type parameter `T` + | + = note: expected struct `S1` + found struct `S1` + = help: type parameters must be constrained to match other types + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + +error[E0308]: mismatched types + --> $DIR/issue-69306.rs:41:14 + | +LL | impl S2 { + | - expected type parameter +LL | fn map(x: U) -> S2 { + | - found type parameter +LL | Self(x) + | ^ expected type parameter `T`, found type parameter `U` + | + = note: expected type parameter `T` + found type parameter `U` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + +error[E0308]: mismatched types + --> $DIR/issue-69306.rs:41:9 + | +LL | impl S2 { + | - found type parameter +LL | fn map(x: U) -> S2 { + | - ----- expected `S2` because of return type + | | + | expected type parameter +LL | Self(x) + | ^^^^^^^ expected type parameter `U`, found type parameter `T` + | + = note: expected struct `S2` + found struct `S2` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0308`.