Rollup merge of #121386 - oli-obk:no_higher_ranked_opaques, r=lcnr
test that we do not support higher-ranked regions in opaque type inference We already do all the right checks in `check_opaque_type_parameter_valid`, and we have done so since at least 2 years. I collected the tests from https://github.com/rust-lang/rust/pull/116935 and https://github.com/rust-lang/rust/pull/100503 and added some more cc https://github.com/rust-lang/rust/issues/96146 r? `@lcnr`
This commit is contained in:
commit
379ef9bd36
19 changed files with 451 additions and 34 deletions
|
@ -153,12 +153,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
if let Some(prev) = result.get_mut(&opaque_type_key.def_id) {
|
||||
if prev.ty != ty {
|
||||
let guar = ty.error_reported().err().unwrap_or_else(|| {
|
||||
prev.report_mismatch(
|
||||
let (Ok(e) | Err(e)) = prev
|
||||
.build_mismatch_error(
|
||||
&OpaqueHiddenType { ty, span: concrete_type.span },
|
||||
opaque_type_key.def_id,
|
||||
infcx.tcx,
|
||||
)
|
||||
.emit()
|
||||
.map(|d| d.emit());
|
||||
e
|
||||
});
|
||||
prev.ty = Ty::new_error(infcx.tcx, guar);
|
||||
}
|
||||
|
|
|
@ -477,7 +477,7 @@ fn sanity_check_found_hidden_type<'tcx>(
|
|||
} else {
|
||||
let span = tcx.def_span(key.def_id);
|
||||
let other = ty::OpaqueHiddenType { ty: hidden_ty, span };
|
||||
Err(ty.report_mismatch(&other, key.def_id, tcx).emit())
|
||||
Err(ty.build_mismatch_error(&other, key.def_id, tcx)?.emit())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -58,10 +58,10 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type(
|
|||
// Only check against typeck if we didn't already error
|
||||
if !hidden.ty.references_error() {
|
||||
for concrete_type in locator.typeck_types {
|
||||
if concrete_type.ty != tcx.erase_regions(hidden.ty)
|
||||
&& !(concrete_type, hidden).references_error()
|
||||
{
|
||||
hidden.report_mismatch(&concrete_type, def_id, tcx).emit();
|
||||
if concrete_type.ty != tcx.erase_regions(hidden.ty) {
|
||||
if let Ok(d) = hidden.build_mismatch_error(&concrete_type, def_id, tcx) {
|
||||
d.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -134,10 +134,10 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local
|
|||
// Only check against typeck if we didn't already error
|
||||
if !hidden.ty.references_error() {
|
||||
for concrete_type in locator.typeck_types {
|
||||
if concrete_type.ty != tcx.erase_regions(hidden.ty)
|
||||
&& !(concrete_type, hidden).references_error()
|
||||
{
|
||||
hidden.report_mismatch(&concrete_type, def_id, tcx).emit();
|
||||
if concrete_type.ty != tcx.erase_regions(hidden.ty) {
|
||||
if let Ok(d) = hidden.build_mismatch_error(&concrete_type, def_id, tcx) {
|
||||
d.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -287,8 +287,10 @@ impl TaitConstraintLocator<'_> {
|
|||
if let Some(&concrete_type) = borrowck_results.concrete_opaque_types.get(&self.def_id) {
|
||||
debug!(?concrete_type, "found constraint");
|
||||
if let Some(prev) = &mut self.found {
|
||||
if concrete_type.ty != prev.ty && !(concrete_type, prev.ty).references_error() {
|
||||
let guar = prev.report_mismatch(&concrete_type, self.def_id, self.tcx).emit();
|
||||
if concrete_type.ty != prev.ty {
|
||||
let (Ok(guar) | Err(guar)) = prev
|
||||
.build_mismatch_error(&concrete_type, self.def_id, self.tcx)
|
||||
.map(|d| d.emit());
|
||||
prev.ty = Ty::new_error(self.tcx, guar);
|
||||
}
|
||||
} else {
|
||||
|
@ -361,12 +363,14 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
|
|||
hidden_type.remap_generic_params_to_declaration_params(opaque_type_key, tcx, true),
|
||||
);
|
||||
if let Some(prev) = &mut hir_opaque_ty {
|
||||
if concrete_type.ty != prev.ty && !(concrete_type, prev.ty).references_error() {
|
||||
prev.report_mismatch(&concrete_type, def_id, tcx).stash(
|
||||
if concrete_type.ty != prev.ty {
|
||||
if let Ok(d) = prev.build_mismatch_error(&concrete_type, def_id, tcx) {
|
||||
d.stash(
|
||||
tcx.def_span(opaque_type_key.def_id),
|
||||
StashKey::OpaqueHiddenTypeMismatch,
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
hir_opaque_ty = Some(concrete_type);
|
||||
}
|
||||
|
@ -436,9 +440,12 @@ impl RpitConstraintChecker<'_> {
|
|||
|
||||
debug!(?concrete_type, "found constraint");
|
||||
|
||||
if concrete_type.ty != self.found.ty && !(concrete_type, self.found).references_error()
|
||||
if concrete_type.ty != self.found.ty {
|
||||
if let Ok(d) =
|
||||
self.found.build_mismatch_error(&concrete_type, self.def_id, self.tcx)
|
||||
{
|
||||
self.found.report_mismatch(&concrete_type, self.def_id, self.tcx).emit();
|
||||
d.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -589,15 +589,19 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||
&& last_opaque_ty.ty != hidden_type.ty
|
||||
{
|
||||
assert!(!self.fcx.next_trait_solver());
|
||||
hidden_type
|
||||
.report_mismatch(&last_opaque_ty, opaque_type_key.def_id, self.tcx())
|
||||
.stash(
|
||||
if let Ok(d) = hidden_type.build_mismatch_error(
|
||||
&last_opaque_ty,
|
||||
opaque_type_key.def_id,
|
||||
self.tcx(),
|
||||
) {
|
||||
d.stash(
|
||||
self.tcx().def_span(opaque_type_key.def_id),
|
||||
StashKey::OpaqueHiddenTypeMismatch,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_field_id(&mut self, hir_id: hir::HirId) {
|
||||
if let Some(index) = self.fcx.typeck_results.borrow_mut().field_indices_mut().remove(hir_id)
|
||||
|
|
|
@ -840,12 +840,12 @@ pub struct OpaqueHiddenType<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> OpaqueHiddenType<'tcx> {
|
||||
pub fn report_mismatch(
|
||||
pub fn build_mismatch_error(
|
||||
&self,
|
||||
other: &Self,
|
||||
opaque_def_id: LocalDefId,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> DiagnosticBuilder<'tcx> {
|
||||
) -> Result<DiagnosticBuilder<'tcx>, ErrorGuaranteed> {
|
||||
if let Some(diag) = tcx
|
||||
.sess
|
||||
.dcx()
|
||||
|
@ -853,18 +853,19 @@ impl<'tcx> OpaqueHiddenType<'tcx> {
|
|||
{
|
||||
diag.cancel();
|
||||
}
|
||||
(self.ty, other.ty).error_reported()?;
|
||||
// Found different concrete types for the opaque type.
|
||||
let sub_diag = if self.span == other.span {
|
||||
TypeMismatchReason::ConflictType { span: self.span }
|
||||
} else {
|
||||
TypeMismatchReason::PreviousUse { span: self.span }
|
||||
};
|
||||
tcx.dcx().create_err(OpaqueHiddenTypeMismatch {
|
||||
Ok(tcx.dcx().create_err(OpaqueHiddenTypeMismatch {
|
||||
self_ty: self.ty,
|
||||
other_ty: other.ty,
|
||||
other_span: other.span,
|
||||
sub: sub_diag,
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(tcx), ret)]
|
||||
|
|
|
@ -98,6 +98,7 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<TyCtxt<'tcx>> + 't
|
|||
query_key: ParamEnvAnd<'tcx, Self>,
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
output_query_region_constraints: &mut QueryRegionConstraints<'tcx>,
|
||||
span: Span,
|
||||
) -> Result<
|
||||
(
|
||||
Self::QueryResponse,
|
||||
|
@ -118,7 +119,7 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<TyCtxt<'tcx>> + 't
|
|||
|
||||
let InferOk { value, obligations } = infcx
|
||||
.instantiate_nll_query_response_and_region_obligations(
|
||||
&ObligationCause::dummy(),
|
||||
&ObligationCause::dummy_with_span(span),
|
||||
old_param_env,
|
||||
&canonical_var_values,
|
||||
canonical_result,
|
||||
|
@ -160,7 +161,7 @@ where
|
|||
|
||||
let mut region_constraints = QueryRegionConstraints::default();
|
||||
let (output, error_info, mut obligations, _) =
|
||||
Q::fully_perform_into(self, infcx, &mut region_constraints).map_err(|_| {
|
||||
Q::fully_perform_into(self, infcx, &mut region_constraints, span).map_err(|_| {
|
||||
infcx.dcx().span_delayed_bug(span, format!("error performing {self:?}"))
|
||||
})?;
|
||||
|
||||
|
@ -178,6 +179,7 @@ where
|
|||
obligation.param_env.and(ProvePredicate::new(obligation.predicate)),
|
||||
infcx,
|
||||
&mut region_constraints,
|
||||
span,
|
||||
) {
|
||||
Ok(((), _, new, certainty)) => {
|
||||
obligations.extend(new);
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
error[E0792]: expected generic lifetime parameter, found `'a`
|
||||
--> $DIR/issue-90014-tait2.rs:27:9
|
||||
|
|
||||
LL | type Fut<'a> = impl Future<Output = ()>;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
...
|
||||
LL | Box::new((async { () },))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
23
tests/ui/rfcs/impl-trait/higher-ranked-regions-diag.rs
Normal file
23
tests/ui/rfcs/impl-trait/higher-ranked-regions-diag.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Regression test for #97099.
|
||||
// This was an ICE because `impl Sized` captures the lifetime 'a.
|
||||
|
||||
trait Trait<E> {
|
||||
type Assoc;
|
||||
}
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl<'a> Trait<&'a ()> for Foo {
|
||||
type Assoc = ();
|
||||
}
|
||||
|
||||
fn foo() -> impl for<'a> Trait<&'a ()> {
|
||||
Foo
|
||||
}
|
||||
|
||||
fn bar() -> impl for<'a> Trait<&'a (), Assoc = impl Sized> {
|
||||
foo()
|
||||
//~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds
|
||||
}
|
||||
|
||||
fn main() {}
|
13
tests/ui/rfcs/impl-trait/higher-ranked-regions-diag.stderr
Normal file
13
tests/ui/rfcs/impl-trait/higher-ranked-regions-diag.stderr
Normal file
|
@ -0,0 +1,13 @@
|
|||
error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds
|
||||
--> $DIR/higher-ranked-regions-diag.rs:19:5
|
||||
|
|
||||
LL | fn bar() -> impl for<'a> Trait<&'a (), Assoc = impl Sized> {
|
||||
| -- ---------- opaque type defined here
|
||||
| |
|
||||
| hidden type `<impl for<'a> Trait<&'a ()> as Trait<&'a ()>>::Assoc` captures the lifetime `'a` as defined here
|
||||
LL | foo()
|
||||
| ^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0700`.
|
|
@ -0,0 +1,80 @@
|
|||
// Basic tests for opaque type inference under for<_> binders.
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
trait Trait<'a> {
|
||||
type Ty;
|
||||
}
|
||||
impl<'a, T> Trait<'a> for T {
|
||||
type Ty = &'a ();
|
||||
}
|
||||
|
||||
mod basic_pass {
|
||||
use super::*;
|
||||
type Opq<'a> = impl Sized + 'a;
|
||||
fn test() -> impl for<'a> Trait<'a, Ty = Opq<'a>> {}
|
||||
//~^ ERROR: expected generic lifetime parameter, found `'a`
|
||||
}
|
||||
|
||||
mod capture_rpit {
|
||||
use super::*;
|
||||
fn test() -> impl for<'a> Trait<'a, Ty = impl Sized> {}
|
||||
//~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds
|
||||
}
|
||||
|
||||
mod capture_tait {
|
||||
use super::*;
|
||||
type Opq0 = impl Sized;
|
||||
type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0>;
|
||||
type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
|
||||
fn test() -> Opq2 {}
|
||||
//~^ ERROR hidden type for `capture_tait::Opq0` captures lifetime that does not appear in bounds
|
||||
}
|
||||
|
||||
mod capture_tait_complex_pass {
|
||||
use super::*;
|
||||
type Opq0<'a> = impl Sized;
|
||||
type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'b>>; // <- Note 'b
|
||||
type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
|
||||
fn test() -> Opq2 {}
|
||||
//~^ ERROR: expected generic lifetime parameter, found `'a`
|
||||
}
|
||||
|
||||
// Same as the above, but make sure that different placeholder regions are not equal.
|
||||
mod capture_tait_complex_fail {
|
||||
use super::*;
|
||||
type Opq0<'a> = impl Sized;
|
||||
type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a>>; // <- Note 'a
|
||||
type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
|
||||
fn test() -> Opq2 {}
|
||||
//~^ ERROR hidden type for `capture_tait_complex_fail::Opq0<'a>` captures lifetime that does not appear in bounds
|
||||
}
|
||||
|
||||
// non-defining use because 'static is used.
|
||||
mod constrain_fail0 {
|
||||
use super::*;
|
||||
type Opq0<'a, 'b> = impl Sized;
|
||||
fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'static>> {}
|
||||
//~^ ERROR non-defining opaque type use in defining scope
|
||||
//~| ERROR: expected generic lifetime parameter, found `'a`
|
||||
}
|
||||
|
||||
// non-defining use because generic lifetime is used multiple times.
|
||||
mod constrain_fail {
|
||||
use super::*;
|
||||
type Opq0<'a, 'b> = impl Sized;
|
||||
fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'a>> {}
|
||||
//~^ ERROR non-defining opaque type use in defining scope
|
||||
//~| ERROR: expected generic lifetime parameter, found `'a`
|
||||
}
|
||||
|
||||
mod constrain_pass {
|
||||
use super::*;
|
||||
type Opq0<'a, 'b> = impl Sized;
|
||||
type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a, 'b>>;
|
||||
type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
|
||||
fn test() -> Opq2 {}
|
||||
//~^ ERROR: expected generic lifetime parameter, found `'a`
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,101 @@
|
|||
error[E0792]: expected generic lifetime parameter, found `'a`
|
||||
--> $DIR/higher-ranked-regions-basic.rs:15:55
|
||||
|
|
||||
LL | type Opq<'a> = impl Sized + 'a;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
LL | fn test() -> impl for<'a> Trait<'a, Ty = Opq<'a>> {}
|
||||
| ^^
|
||||
|
||||
error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds
|
||||
--> $DIR/higher-ranked-regions-basic.rs:21:58
|
||||
|
|
||||
LL | fn test() -> impl for<'a> Trait<'a, Ty = impl Sized> {}
|
||||
| -- ---------- ^^
|
||||
| | |
|
||||
| | opaque type defined here
|
||||
| hidden type `&'a ()` captures the lifetime `'a` as defined here
|
||||
|
||||
error[E0700]: hidden type for `capture_tait::Opq0` captures lifetime that does not appear in bounds
|
||||
--> $DIR/higher-ranked-regions-basic.rs:30:23
|
||||
|
|
||||
LL | type Opq0 = impl Sized;
|
||||
| ---------- opaque type defined here
|
||||
LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0>;
|
||||
| -- hidden type `&'b ()` captures the lifetime `'b` as defined here
|
||||
LL | type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
|
||||
LL | fn test() -> Opq2 {}
|
||||
| ^^
|
||||
|
||||
error[E0792]: expected generic lifetime parameter, found `'a`
|
||||
--> $DIR/higher-ranked-regions-basic.rs:39:23
|
||||
|
|
||||
LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'b>>; // <- Note 'b
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
LL | type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
|
||||
LL | fn test() -> Opq2 {}
|
||||
| ^^
|
||||
|
||||
error[E0700]: hidden type for `capture_tait_complex_fail::Opq0<'a>` captures lifetime that does not appear in bounds
|
||||
--> $DIR/higher-ranked-regions-basic.rs:49:23
|
||||
|
|
||||
LL | type Opq0<'a> = impl Sized;
|
||||
| ---------- opaque type defined here
|
||||
LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a>>; // <- Note 'a
|
||||
| -- hidden type `&'b ()` captures the lifetime `'b` as defined here
|
||||
LL | type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
|
||||
LL | fn test() -> Opq2 {}
|
||||
| ^^
|
||||
|
||||
error[E0792]: non-defining opaque type use in defining scope
|
||||
--> $DIR/higher-ranked-regions-basic.rs:57:41
|
||||
|
|
||||
LL | fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'static>> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ argument `'static` is not a generic parameter
|
||||
|
|
||||
note: for this opaque type
|
||||
--> $DIR/higher-ranked-regions-basic.rs:56:25
|
||||
|
|
||||
LL | type Opq0<'a, 'b> = impl Sized;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0792]: expected generic lifetime parameter, found `'a`
|
||||
--> $DIR/higher-ranked-regions-basic.rs:57:65
|
||||
|
|
||||
LL | type Opq0<'a, 'b> = impl Sized;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
LL | fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'static>> {}
|
||||
| ^^
|
||||
|
||||
error: non-defining opaque type use in defining scope
|
||||
--> $DIR/higher-ranked-regions-basic.rs:66:41
|
||||
|
|
||||
LL | fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'a>> {}
|
||||
| ^^^^^^^^^^^^^^^^^ generic argument `'a` used twice
|
||||
|
|
||||
note: for this opaque type
|
||||
--> $DIR/higher-ranked-regions-basic.rs:65:25
|
||||
|
|
||||
LL | type Opq0<'a, 'b> = impl Sized;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0792]: expected generic lifetime parameter, found `'a`
|
||||
--> $DIR/higher-ranked-regions-basic.rs:66:60
|
||||
|
|
||||
LL | type Opq0<'a, 'b> = impl Sized;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
LL | fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'a>> {}
|
||||
| ^^
|
||||
|
||||
error[E0792]: expected generic lifetime parameter, found `'a`
|
||||
--> $DIR/higher-ranked-regions-basic.rs:76:23
|
||||
|
|
||||
LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a, 'b>>;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
LL | type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
|
||||
LL | fn test() -> Opq2 {}
|
||||
| ^^
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0700, E0792.
|
||||
For more information about an error, try `rustc --explain E0700`.
|
|
@ -0,0 +1,20 @@
|
|||
// Regression test for #97098.
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
pub trait Trait {
|
||||
type Assoc<'a>;
|
||||
}
|
||||
|
||||
pub type Foo = impl for<'a> Trait<Assoc<'a> = FooAssoc<'a>>;
|
||||
pub type FooAssoc<'a> = impl Sized;
|
||||
|
||||
struct Struct;
|
||||
impl Trait for Struct {
|
||||
type Assoc<'a> = &'a u32;
|
||||
}
|
||||
|
||||
const FOO: Foo = Struct;
|
||||
//~^ ERROR: expected generic lifetime parameter, found `'a`
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,12 @@
|
|||
error[E0792]: expected generic lifetime parameter, found `'a`
|
||||
--> $DIR/higher-ranked-regions-gat.rs:17:18
|
||||
|
|
||||
LL | pub type FooAssoc<'a> = impl Sized;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
...
|
||||
LL | const FOO: Foo = Struct;
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0792`.
|
39
tests/ui/type-alias-impl-trait/hkl_forbidden.rs
Normal file
39
tests/ui/type-alias-impl-trait/hkl_forbidden.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
fn id(s: &str) -> &str {
|
||||
s
|
||||
}
|
||||
|
||||
type Opaque<'a> = impl Sized + 'a;
|
||||
|
||||
fn test(s: &str) -> (impl Fn(&str) -> Opaque<'_>, impl Fn(&str) -> Opaque<'_>) {
|
||||
(id, id) //~ ERROR expected generic lifetime parameter, found `'_`
|
||||
}
|
||||
|
||||
fn id2<'a, 'b>(s: (&'a str, &'b str)) -> (&'a str, &'b str) {
|
||||
s
|
||||
}
|
||||
|
||||
type Opaque2<'a> = impl Sized + 'a;
|
||||
|
||||
fn test2() -> impl for<'a, 'b> Fn((&'a str, &'b str)) -> (Opaque2<'a>, Opaque2<'b>) {
|
||||
id2 //~ ERROR expected generic lifetime parameter, found `'a`
|
||||
}
|
||||
|
||||
type Opaque3<'a> = impl Sized + 'a;
|
||||
|
||||
fn test3(s: &str) -> (impl Fn(&str) -> Opaque3<'_>, Opaque3<'_>) {
|
||||
(id, s) //~ ERROR expected generic lifetime parameter, found `'_`
|
||||
}
|
||||
|
||||
type Opaque4<'a> = impl Sized + 'a;
|
||||
fn test4(s: &str) -> (Opaque4<'_>, impl Fn(&str) -> Opaque4<'_>) {
|
||||
(s, id) //~ ERROR expected generic lifetime parameter, found `'_`
|
||||
}
|
||||
|
||||
type Inner<'a> = impl Sized;
|
||||
fn outer_impl() -> impl for<'a> Fn(&'a ()) -> Inner<'a> {
|
||||
|x| x //~ ERROR expected generic lifetime parameter, found `'a`
|
||||
}
|
||||
|
||||
fn main() {}
|
48
tests/ui/type-alias-impl-trait/hkl_forbidden.stderr
Normal file
48
tests/ui/type-alias-impl-trait/hkl_forbidden.stderr
Normal file
|
@ -0,0 +1,48 @@
|
|||
error[E0792]: expected generic lifetime parameter, found `'_`
|
||||
--> $DIR/hkl_forbidden.rs:10:5
|
||||
|
|
||||
LL | type Opaque<'a> = impl Sized + 'a;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
...
|
||||
LL | (id, id)
|
||||
| ^^^^^^^^
|
||||
|
||||
error[E0792]: expected generic lifetime parameter, found `'a`
|
||||
--> $DIR/hkl_forbidden.rs:20:5
|
||||
|
|
||||
LL | type Opaque2<'a> = impl Sized + 'a;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
...
|
||||
LL | id2
|
||||
| ^^^
|
||||
|
||||
error[E0792]: expected generic lifetime parameter, found `'_`
|
||||
--> $DIR/hkl_forbidden.rs:26:5
|
||||
|
|
||||
LL | type Opaque3<'a> = impl Sized + 'a;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
...
|
||||
LL | (id, s)
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0792]: expected generic lifetime parameter, found `'_`
|
||||
--> $DIR/hkl_forbidden.rs:31:5
|
||||
|
|
||||
LL | type Opaque4<'a> = impl Sized + 'a;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
LL | fn test4(s: &str) -> (Opaque4<'_>, impl Fn(&str) -> Opaque4<'_>) {
|
||||
LL | (s, id)
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0792]: expected generic lifetime parameter, found `'a`
|
||||
--> $DIR/hkl_forbidden.rs:36:5
|
||||
|
|
||||
LL | type Inner<'a> = impl Sized;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
LL | fn outer_impl() -> impl for<'a> Fn(&'a ()) -> Inner<'a> {
|
||||
LL | |x| x
|
||||
| ^^^^^
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0792`.
|
18
tests/ui/type-alias-impl-trait/hkl_forbidden2.rs
Normal file
18
tests/ui/type-alias-impl-trait/hkl_forbidden2.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type Opaque<'a> = impl Sized + 'a;
|
||||
|
||||
trait Trait<'a> {
|
||||
type Assoc;
|
||||
}
|
||||
|
||||
impl<'a> Trait<'a> for () {
|
||||
type Assoc = ();
|
||||
}
|
||||
|
||||
fn test() -> &'static dyn for<'a> Trait<'a, Assoc = Opaque<'a>> {
|
||||
&()
|
||||
//~^ ERROR: expected generic lifetime parameter, found `'a`
|
||||
}
|
||||
|
||||
fn main() {}
|
12
tests/ui/type-alias-impl-trait/hkl_forbidden2.stderr
Normal file
12
tests/ui/type-alias-impl-trait/hkl_forbidden2.stderr
Normal file
|
@ -0,0 +1,12 @@
|
|||
error[E0792]: expected generic lifetime parameter, found `'a`
|
||||
--> $DIR/hkl_forbidden2.rs:14:5
|
||||
|
|
||||
LL | type Opaque<'a> = impl Sized + 'a;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
...
|
||||
LL | &()
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0792`.
|
13
tests/ui/type-alias-impl-trait/hkl_forbidden3.rs
Normal file
13
tests/ui/type-alias-impl-trait/hkl_forbidden3.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type Opaque<'a> = impl Sized + 'a;
|
||||
|
||||
fn foo<'a>(x: &'a ()) -> &'a () {
|
||||
x
|
||||
}
|
||||
|
||||
fn test() -> for<'a> fn(&'a ()) -> Opaque<'a> {
|
||||
foo //~ ERROR: mismatched types
|
||||
}
|
||||
|
||||
fn main() {}
|
15
tests/ui/type-alias-impl-trait/hkl_forbidden3.stderr
Normal file
15
tests/ui/type-alias-impl-trait/hkl_forbidden3.stderr
Normal file
|
@ -0,0 +1,15 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/hkl_forbidden3.rs:10:5
|
||||
|
|
||||
LL | type Opaque<'a> = impl Sized + 'a;
|
||||
| --------------- the expected opaque type
|
||||
...
|
||||
LL | foo
|
||||
| ^^^ one type is more general than the other
|
||||
|
|
||||
= note: expected fn pointer `for<'a> fn(&'a ()) -> Opaque<'a>`
|
||||
found fn pointer `for<'a> fn(&'a ()) -> &'a ()`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Add table
Add a link
Reference in a new issue