use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::ObligationCtxt;
+use crate::session_diagnostics::NonGenericOpaqueTypeParam;
+
use super::RegionInferenceContext;
impl<'tcx> RegionInferenceContext<'tcx> {
} else {
// Prevent `fn foo() -> Foo<u32>` from being defining.
let opaque_param = opaque_generics.param_at(i, tcx);
- tcx.sess
- .struct_span_err(span, "non-defining opaque type use in defining scope")
- .span_note(
- tcx.def_span(opaque_param.def_id),
- &format!(
- "used non-generic {} `{}` for generic parameter",
- opaque_param.kind.descr(),
- arg,
- ),
- )
- .emit();
+ let kind = opaque_param.kind.descr();
+ tcx.sess.emit_err(NonGenericOpaqueTypeParam {
+ ty: arg,
+ kind,
+ span,
+ param_span: tcx.def_span(opaque_param.def_id),
+ });
return false;
}
}
use rustc_errors::{IntoDiagnosticArg, MultiSpan};
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
-use rustc_middle::ty::Ty;
+use rustc_middle::ty::{GenericArg, Ty};
use rustc_span::Span;
use crate::diagnostics::RegionName;
#[label]
pub borrow_span: Span,
}
+
+#[derive(Diagnostic)]
+#[diag(borrowck_opaque_type_non_generic_param, code = "E0792")]
+pub(crate) struct NonGenericOpaqueTypeParam<'a, 'tcx> {
+ pub ty: GenericArg<'tcx>,
+ pub kind: &'a str,
+ #[primary_span]
+ pub span: Span,
+ #[label]
+ pub param_span: Span,
+}
E0788: include_str!("./error_codes/E0788.md"),
E0790: include_str!("./error_codes/E0790.md"),
E0791: include_str!("./error_codes/E0791.md"),
+E0792: include_str!("./error_codes/E0792.md"),
;
// E0006, // merged with E0005
// E0008, // cannot bind by-move into a pattern guard
--- /dev/null
+A type alias impl trait can only have its hidden type assigned
+when used fully generically (and within their defining scope).
+This means
+
+```compile_fail,E0792
+#![feature(type_alias_impl_trait)]
+
+type Foo<T> = impl std::fmt::Debug;
+
+fn foo() -> Foo<u32> {
+ 5u32
+}
+```
+
+is not accepted. If it were accepted, one could create unsound situations like
+
+```compile_fail,E0792
+#![feature(type_alias_impl_trait)]
+
+type Foo<T> = impl Default;
+
+fn foo() -> Foo<u32> {
+ 5u32
+}
+
+fn main() {
+ let x = Foo::<&'static mut String>::default();
+}
+```
+
+
+Instead you need to make the function generic:
+
+```
+#![feature(type_alias_impl_trait)]
+
+type Foo<T> = impl std::fmt::Debug;
+
+fn foo<U>() -> Foo<U> {
+ 5u32
+}
+```
+
+This means that no matter the generic parameter to `foo`,
+the hidden type will always be `u32`.
+If you want to link the generic parameter to the hidden type,
+you can do that, too:
+
+
+```
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Debug;
+
+type Foo<T: Debug> = impl Debug;
+
+fn foo<U: Debug>() -> Foo<U> {
+ Vec::<U>::new()
+}
+```
[value] value
*[other] {$value_place}
} occurs here
+
+borrowck_opaque_type_non_generic_param =
+ expected generic {$kind} parameter, found `{$ty}`
+ .label = this generic parameter must be used with a generic {$kind} parameter
impl<'tcx> IntoDiagnosticArg for Ty<'tcx> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
- format!("{}", self).into_diagnostic_arg()
+ self.to_string().into_diagnostic_arg()
}
}
use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
use rustc_data_structures::intern::Interned;
+use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
use rustc_hir::def_id::DefId;
use rustc_macros::HashStable;
use rustc_serialize::{self, Decodable, Encodable};
marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>)>,
}
+impl<'tcx> IntoDiagnosticArg for GenericArg<'tcx> {
+ fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+ self.to_string().into_diagnostic_arg()
+ }
+}
+
const TAG_MASK: usize = 0b11;
const TYPE_TAG: usize = 0b00;
const REGION_TAG: usize = 0b01;
fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
()
- //~^ ERROR non-defining opaque type use
+ //~^ ERROR expected generic type parameter, found `<T as TraitWithAssoc>::Assoc`
}
-error: non-defining opaque type use in defining scope
+error[E0792]: expected generic type parameter, found `<T as TraitWithAssoc>::Assoc`
--> $DIR/bound_reduction2.rs:16:5
|
+LL | type Foo<V> = impl Trait<V>;
+ | - this generic parameter must be used with a generic type parameter
+...
LL | ()
| ^^
- |
-note: used non-generic type `<T as TraitWithAssoc>::Assoc` for generic parameter
- --> $DIR/bound_reduction2.rs:9:10
- |
-LL | type Foo<V> = impl Trait<V>;
- | ^
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0792`.
type OneConst<const X: usize> = impl Debug;
-
// Not defining uses, because they doesn't define *all* possible generics.
fn concrete_ty() -> OneTy<u32> {
5u32
- //~^ ERROR non-defining opaque type use in defining scope
+ //~^ ERROR expected generic type parameter, found `u32`
}
fn concrete_lifetime() -> OneLifetime<'static> {
fn concrete_const() -> OneConst<{ 123 }> {
7u32
- //~^ ERROR non-defining opaque type use in defining scope
+ //~^ ERROR expected generic constant parameter, found `123`
}
-error: non-defining opaque type use in defining scope
- --> $DIR/generic_nondefining_use.rs:17:5
+error[E0792]: expected generic type parameter, found `u32`
+ --> $DIR/generic_nondefining_use.rs:16:5
|
+LL | type OneTy<T> = impl Debug;
+ | - this generic parameter must be used with a generic type parameter
+...
LL | 5u32
| ^^^^
- |
-note: used non-generic type `u32` for generic parameter
- --> $DIR/generic_nondefining_use.rs:7:12
- |
-LL | type OneTy<T> = impl Debug;
- | ^
error: non-defining opaque type use in defining scope
- --> $DIR/generic_nondefining_use.rs:22:5
+ --> $DIR/generic_nondefining_use.rs:21:5
|
LL | type OneLifetime<'a> = impl Debug;
| -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
LL | 6u32
| ^^^^
-error: non-defining opaque type use in defining scope
- --> $DIR/generic_nondefining_use.rs:27:5
+error[E0792]: expected generic constant parameter, found `123`
+ --> $DIR/generic_nondefining_use.rs:26:5
|
+LL | type OneConst<const X: usize> = impl Debug;
+ | -------------- this generic parameter must be used with a generic constant parameter
+...
LL | 7u32
| ^^^^
- |
-note: used non-generic constant `123` for generic parameter
- --> $DIR/generic_nondefining_use.rs:11:15
- |
-LL | type OneConst<const X: usize> = impl Debug;
- | ^^^^^^^^^^^^^^
error: aborting due to 3 previous errors
+For more information about this error, try `rustc --explain E0792`.
let y = 42;
let x = wrong_generic(&y);
let z: i32 = x;
- //~^ ERROR non-defining opaque type use
+ //~^ ERROR expected generic type parameter, found `&'static i32
}
type WrongGeneric<T> = impl 'static;
LL | type WrongGeneric<T> = impl 'static;
| ^^^^^^^^^^^^
-error: non-defining opaque type use in defining scope
+error[E0792]: expected generic type parameter, found `&'static i32`
--> $DIR/generic_type_does_not_live_long_enough.rs:6:18
|
LL | let z: i32 = x;
| ^
- |
-note: used non-generic type `&'static i32` for generic parameter
- --> $DIR/generic_type_does_not_live_long_enough.rs:10:19
- |
+...
LL | type WrongGeneric<T> = impl 'static;
- | ^
+ | - this generic parameter must be used with a generic type parameter
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/generic_type_does_not_live_long_enough.rs:14:5
error: aborting due to 3 previous errors
-For more information about this error, try `rustc --explain E0310`.
+Some errors have detailed explanations: E0310, E0792.
+For more information about an error, try `rustc --explain E0310`.
type BitsIter = IterBitsIter<T, E, u8>;
fn iter_bits(self, n: u8) -> Self::BitsIter {
(0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
- //~^ ERROR non-defining opaque type use in defining scope
+ //~^ ERROR expected generic type parameter, found `u8`
}
}
-error: non-defining opaque type use in defining scope
+error[E0792]: expected generic type parameter, found `u8`
--> $DIR/issue-60564.rs:20:9
|
+LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
+ | - this generic parameter must be used with a generic type parameter
+...
LL | (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-note: used non-generic type `u8` for generic parameter
- --> $DIR/issue-60564.rs:8:25
- |
-LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
- | ^
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0792`.
type Alias<'a, U> = impl Trait<U>;
fn f<'a>() -> Alias<'a, ()> {}
-//~^ ERROR non-defining opaque type use in defining scope
+//~^ ERROR expected generic type parameter, found `()`
fn main() {}
-error: non-defining opaque type use in defining scope
+error[E0792]: expected generic type parameter, found `()`
--> $DIR/issue-68368-non-defining-use-2.rs:9:29
|
+LL | type Alias<'a, U> = impl Trait<U>;
+ | - this generic parameter must be used with a generic type parameter
+LL |
LL | fn f<'a>() -> Alias<'a, ()> {}
| ^^
- |
-note: used non-generic type `()` for generic parameter
- --> $DIR/issue-68368-non-defining-use-2.rs:7:16
- |
-LL | type Alias<'a, U> = impl Trait<U>;
- | ^
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0792`.
type Alias<'a, U> = impl Trait<U>;
fn f<'a>() -> Alias<'a, ()> {}
-//~^ ERROR non-defining opaque type use in defining scope
+//~^ ERROR expected generic type parameter, found `()`
fn main() {}
-error: non-defining opaque type use in defining scope
+error[E0792]: expected generic type parameter, found `()`
--> $DIR/issue-68368-non-defining-use.rs:9:29
|
+LL | type Alias<'a, U> = impl Trait<U>;
+ | - this generic parameter must be used with a generic type parameter
+LL |
LL | fn f<'a>() -> Alias<'a, ()> {}
| ^^
- |
-note: used non-generic type `()` for generic parameter
- --> $DIR/issue-68368-non-defining-use.rs:7:16
- |
-LL | type Alias<'a, U> = impl Trait<U>;
- | ^
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0792`.
//~^ ERROR use of undeclared lifetime name `'a`
fn my_fun() -> Return<()> {}
-//~^ ERROR non-defining opaque type use in defining scope
+//~^ ERROR expected generic type parameter, found `()`
fn main() {}
LL | type Return<'a, A> = impl WithAssoc<A, AssocType = impl SomeTrait + 'a>;
| +++
-error: non-defining opaque type use in defining scope
+error[E0792]: expected generic type parameter, found `()`
--> $DIR/issue-69136-inner-lifetime-resolve-error.rs:20:27
|
+LL | type Return<A> = impl WithAssoc<A, AssocType = impl SomeTrait + 'a>;
+ | - this generic parameter must be used with a generic type parameter
+...
LL | fn my_fun() -> Return<()> {}
| ^^
- |
-note: used non-generic type `()` for generic parameter
- --> $DIR/issue-69136-inner-lifetime-resolve-error.rs:17:13
- |
-LL | type Return<A> = impl WithAssoc<A, AssocType = impl SomeTrait + 'a>;
- | ^
error: aborting due to 2 previous errors
-For more information about this error, try `rustc --explain E0261`.
+Some errors have detailed explanations: E0261, E0792.
+For more information about an error, try `rustc --explain E0261`.