Prevent opaque types being instantiated twice with different regions within the same function
This commit is contained in:
parent
a42873e85b
commit
be9317d1ec
@ -132,6 +132,12 @@ borrowck_moved_due_to_usage_in_operator =
|
||||
*[false] operator
|
||||
}
|
||||
|
||||
borrowck_opaque_type_lifetime_mismatch =
|
||||
opaque type used twice with different lifetimes
|
||||
.label = lifetime `{$arg}` used here
|
||||
.prev_lifetime_label = lifetime `{$prev}` previously used here
|
||||
.note = if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types
|
||||
|
||||
borrowck_opaque_type_non_generic_param =
|
||||
expected generic {$kind} parameter, found `{$ty}`
|
||||
.label = {STREQ($ty, "'static") ->
|
||||
|
@ -9,17 +9,77 @@
|
||||
use rustc_macros::extension;
|
||||
use rustc_middle::traits::DefiningAnchor;
|
||||
use rustc_middle::ty::visit::TypeVisitableExt;
|
||||
use rustc_middle::ty::RegionVid;
|
||||
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_middle::ty::{GenericArgKind, GenericArgs};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
|
||||
use crate::session_diagnostics::LifetimeMismatchOpaqueParam;
|
||||
use crate::session_diagnostics::NonGenericOpaqueTypeParam;
|
||||
|
||||
use super::RegionInferenceContext;
|
||||
|
||||
impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
fn universal_name(&self, vid: ty::RegionVid) -> Option<ty::Region<'tcx>> {
|
||||
let scc = self.constraint_sccs.scc(vid);
|
||||
self.scc_values
|
||||
.universal_regions_outlived_by(scc)
|
||||
.find_map(|lb| self.eval_equal(vid, lb).then_some(self.definitions[lb].external_name?))
|
||||
}
|
||||
|
||||
fn generic_arg_to_region(&self, arg: ty::GenericArg<'tcx>) -> Option<RegionVid> {
|
||||
let region = arg.as_region()?;
|
||||
|
||||
if let ty::RePlaceholder(..) = region.kind() {
|
||||
None
|
||||
} else {
|
||||
Some(self.to_region_vid(region))
|
||||
}
|
||||
}
|
||||
|
||||
/// Check that all opaque types have the same region parameters if they have the same
|
||||
/// non-region parameters. This is necessary because within the new solver we perform various query operations
|
||||
/// modulo regions, and thus could unsoundly select some impls that don't hold.
|
||||
fn check_unique(
|
||||
&self,
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
opaque_ty_decls: &FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
|
||||
) {
|
||||
for (i, (a, a_ty)) in opaque_ty_decls.iter().enumerate() {
|
||||
for (b, b_ty) in opaque_ty_decls.iter().skip(i + 1) {
|
||||
if a.def_id != b.def_id {
|
||||
continue;
|
||||
}
|
||||
// Non-lifetime params differ -> ok
|
||||
if infcx.tcx.erase_regions(a.args) != infcx.tcx.erase_regions(b.args) {
|
||||
continue;
|
||||
}
|
||||
trace!(?a, ?b);
|
||||
for (a, b) in a.args.iter().zip(b.args) {
|
||||
trace!(?a, ?b);
|
||||
let Some(r1) = self.generic_arg_to_region(a) else {
|
||||
continue;
|
||||
};
|
||||
let Some(r2) = self.generic_arg_to_region(b) else {
|
||||
continue;
|
||||
};
|
||||
if self.eval_equal(r1, r2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
infcx.dcx().emit_err(LifetimeMismatchOpaqueParam {
|
||||
arg: self.universal_name(r1).unwrap().into(),
|
||||
prev: self.universal_name(r2).unwrap().into(),
|
||||
span: a_ty.span,
|
||||
prev_span: b_ty.span,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolve any opaque types that were encountered while borrow checking
|
||||
/// this item. This is then used to get the type in the `type_of` query.
|
||||
///
|
||||
@ -65,6 +125,8 @@ pub(crate) fn infer_opaque_types(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
opaque_ty_decls: FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
|
||||
) -> FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> {
|
||||
self.check_unique(infcx, &opaque_ty_decls);
|
||||
|
||||
let mut result: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> = FxIndexMap::default();
|
||||
|
||||
let member_constraints: FxIndexMap<_, _> = self
|
||||
@ -80,26 +142,20 @@ pub(crate) fn infer_opaque_types(
|
||||
|
||||
let mut arg_regions = vec![self.universal_regions.fr_static];
|
||||
|
||||
let to_universal_region = |vid, arg_regions: &mut Vec<_>| {
|
||||
trace!(?vid);
|
||||
let scc = self.constraint_sccs.scc(vid);
|
||||
trace!(?scc);
|
||||
match self.scc_values.universal_regions_outlived_by(scc).find_map(|lb| {
|
||||
self.eval_equal(vid, lb).then_some(self.definitions[lb].external_name?)
|
||||
}) {
|
||||
Some(region) => {
|
||||
let vid = self.universal_regions.to_region_vid(region);
|
||||
arg_regions.push(vid);
|
||||
region
|
||||
}
|
||||
None => {
|
||||
arg_regions.push(vid);
|
||||
ty::Region::new_error_with_message(
|
||||
infcx.tcx,
|
||||
concrete_type.span,
|
||||
"opaque type with non-universal region args",
|
||||
)
|
||||
}
|
||||
let to_universal_region = |vid, arg_regions: &mut Vec<_>| match self.universal_name(vid)
|
||||
{
|
||||
Some(region) => {
|
||||
let vid = self.universal_regions.to_region_vid(region);
|
||||
arg_regions.push(vid);
|
||||
region
|
||||
}
|
||||
None => {
|
||||
arg_regions.push(vid);
|
||||
ty::Region::new_error_with_message(
|
||||
infcx.tcx,
|
||||
concrete_type.span,
|
||||
"opaque type with non-universal region args",
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -304,6 +304,19 @@ pub(crate) struct NonGenericOpaqueTypeParam<'a, 'tcx> {
|
||||
pub param_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(borrowck_opaque_type_lifetime_mismatch)]
|
||||
pub(crate) struct LifetimeMismatchOpaqueParam<'tcx> {
|
||||
pub arg: GenericArg<'tcx>,
|
||||
pub prev: GenericArg<'tcx>,
|
||||
#[primary_span]
|
||||
#[label]
|
||||
#[note]
|
||||
pub span: Span,
|
||||
#[label(borrowck_prev_lifetime_label)]
|
||||
pub prev_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum CaptureReasonLabel<'a> {
|
||||
#[label(borrowck_moved_due_to_call)]
|
||||
|
@ -1204,7 +1204,6 @@
|
||||
"ui/impl-trait/issue-56445.rs",
|
||||
"ui/impl-trait/issue-68532.rs",
|
||||
"ui/impl-trait/issue-72911.rs",
|
||||
"ui/impl-trait/issue-86465.rs",
|
||||
"ui/impl-trait/issue-87450.rs",
|
||||
"ui/impl-trait/issue-99073-2.rs",
|
||||
"ui/impl-trait/issue-99073.rs",
|
||||
|
@ -1,10 +0,0 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type X<'a, 'b> = impl std::fmt::Debug;
|
||||
|
||||
fn f<'t, 'u>(a: &'t u32, b: &'u u32) -> (X<'t, 'u>, X<'u, 't>) {
|
||||
(a, a)
|
||||
//~^ ERROR concrete type differs from previous defining opaque type use
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -1,11 +0,0 @@
|
||||
error: concrete type differs from previous defining opaque type use
|
||||
--> $DIR/issue-86465.rs:6:5
|
||||
|
|
||||
LL | (a, a)
|
||||
| ^^^^^^
|
||||
| |
|
||||
| expected `&'a u32`, got `&'b u32`
|
||||
| this expression supplies two conflicting concrete types for the same opaque type
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
25
tests/ui/type-alias-impl-trait/lifetime_mismatch.rs
Normal file
25
tests/ui/type-alias-impl-trait/lifetime_mismatch.rs
Normal file
@ -0,0 +1,25 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type Foo<'a> = impl Sized;
|
||||
|
||||
fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> (Foo<'a>, Foo<'b>) {
|
||||
(x, y)
|
||||
//~^ ERROR opaque type used twice with different lifetimes
|
||||
//~| ERROR opaque type used twice with different lifetimes
|
||||
}
|
||||
|
||||
type Bar<'a, 'b> = impl std::fmt::Debug;
|
||||
|
||||
fn bar<'x, 'y>(i: &'x i32, j: &'y i32) -> (Bar<'x, 'y>, Bar<'y, 'x>) {
|
||||
(i, j)
|
||||
//~^ ERROR opaque type used twice with different lifetimes
|
||||
//~| ERROR opaque type used twice with different lifetimes
|
||||
//~| ERROR opaque type used twice with different lifetimes
|
||||
//~| ERROR opaque type used twice with different lifetimes
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let meh = 42;
|
||||
let muh = 69;
|
||||
println!("{:?}", bar(&meh, &muh));
|
||||
}
|
95
tests/ui/type-alias-impl-trait/lifetime_mismatch.stderr
Normal file
95
tests/ui/type-alias-impl-trait/lifetime_mismatch.stderr
Normal file
@ -0,0 +1,95 @@
|
||||
error: opaque type used twice with different lifetimes
|
||||
--> $DIR/lifetime_mismatch.rs:6:5
|
||||
|
|
||||
LL | (x, y)
|
||||
| ^^^^^^
|
||||
| |
|
||||
| lifetime `'a` used here
|
||||
| lifetime `'b` previously used here
|
||||
|
|
||||
note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types
|
||||
--> $DIR/lifetime_mismatch.rs:6:5
|
||||
|
|
||||
LL | (x, y)
|
||||
| ^^^^^^
|
||||
|
||||
error: opaque type used twice with different lifetimes
|
||||
--> $DIR/lifetime_mismatch.rs:6:5
|
||||
|
|
||||
LL | (x, y)
|
||||
| ^^^^^^
|
||||
| |
|
||||
| lifetime `'a` used here
|
||||
| lifetime `'b` previously used here
|
||||
|
|
||||
note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types
|
||||
--> $DIR/lifetime_mismatch.rs:6:5
|
||||
|
|
||||
LL | (x, y)
|
||||
| ^^^^^^
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: opaque type used twice with different lifetimes
|
||||
--> $DIR/lifetime_mismatch.rs:14:5
|
||||
|
|
||||
LL | (i, j)
|
||||
| ^^^^^^
|
||||
| |
|
||||
| lifetime `'x` used here
|
||||
| lifetime `'y` previously used here
|
||||
|
|
||||
note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types
|
||||
--> $DIR/lifetime_mismatch.rs:14:5
|
||||
|
|
||||
LL | (i, j)
|
||||
| ^^^^^^
|
||||
|
||||
error: opaque type used twice with different lifetimes
|
||||
--> $DIR/lifetime_mismatch.rs:14:5
|
||||
|
|
||||
LL | (i, j)
|
||||
| ^^^^^^
|
||||
| |
|
||||
| lifetime `'y` used here
|
||||
| lifetime `'x` previously used here
|
||||
|
|
||||
note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types
|
||||
--> $DIR/lifetime_mismatch.rs:14:5
|
||||
|
|
||||
LL | (i, j)
|
||||
| ^^^^^^
|
||||
|
||||
error: opaque type used twice with different lifetimes
|
||||
--> $DIR/lifetime_mismatch.rs:14:5
|
||||
|
|
||||
LL | (i, j)
|
||||
| ^^^^^^
|
||||
| |
|
||||
| lifetime `'x` used here
|
||||
| lifetime `'y` previously used here
|
||||
|
|
||||
note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types
|
||||
--> $DIR/lifetime_mismatch.rs:14:5
|
||||
|
|
||||
LL | (i, j)
|
||||
| ^^^^^^
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: opaque type used twice with different lifetimes
|
||||
--> $DIR/lifetime_mismatch.rs:14:5
|
||||
|
|
||||
LL | (i, j)
|
||||
| ^^^^^^
|
||||
| |
|
||||
| lifetime `'y` used here
|
||||
| lifetime `'x` previously used here
|
||||
|
|
||||
note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types
|
||||
--> $DIR/lifetime_mismatch.rs:14:5
|
||||
|
|
||||
LL | (i, j)
|
||||
| ^^^^^^
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
@ -3,7 +3,11 @@
|
||||
type Foo<'a, 'b> = impl std::fmt::Debug;
|
||||
|
||||
fn foo<'x, 'y>(i: &'x i32, j: &'y i32) -> (Foo<'x, 'y>, Foo<'y, 'x>) {
|
||||
(i, i) //~ ERROR concrete type differs from previous
|
||||
(i, i)
|
||||
//~^ ERROR opaque type used twice with different lifetimes
|
||||
//~| ERROR opaque type used twice with different lifetimes
|
||||
//~| ERROR opaque type used twice with different lifetimes
|
||||
//~| ERROR opaque type used twice with different lifetimes
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,11 +1,64 @@
|
||||
error: concrete type differs from previous defining opaque type use
|
||||
error: opaque type used twice with different lifetimes
|
||||
--> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5
|
||||
|
|
||||
LL | (i, i)
|
||||
| ^^^^^^
|
||||
| |
|
||||
| expected `&'a i32`, got `&'b i32`
|
||||
| this expression supplies two conflicting concrete types for the same opaque type
|
||||
| lifetime `'x` used here
|
||||
| lifetime `'y` previously used here
|
||||
|
|
||||
note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types
|
||||
--> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5
|
||||
|
|
||||
LL | (i, i)
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error: opaque type used twice with different lifetimes
|
||||
--> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5
|
||||
|
|
||||
LL | (i, i)
|
||||
| ^^^^^^
|
||||
| |
|
||||
| lifetime `'y` used here
|
||||
| lifetime `'x` previously used here
|
||||
|
|
||||
note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types
|
||||
--> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5
|
||||
|
|
||||
LL | (i, i)
|
||||
| ^^^^^^
|
||||
|
||||
error: opaque type used twice with different lifetimes
|
||||
--> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5
|
||||
|
|
||||
LL | (i, i)
|
||||
| ^^^^^^
|
||||
| |
|
||||
| lifetime `'x` used here
|
||||
| lifetime `'y` previously used here
|
||||
|
|
||||
note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types
|
||||
--> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5
|
||||
|
|
||||
LL | (i, i)
|
||||
| ^^^^^^
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: opaque type used twice with different lifetimes
|
||||
--> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5
|
||||
|
|
||||
LL | (i, i)
|
||||
| ^^^^^^
|
||||
| |
|
||||
| lifetime `'y` used here
|
||||
| lifetime `'x` previously used here
|
||||
|
|
||||
note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types
|
||||
--> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5
|
||||
|
|
||||
LL | (i, i)
|
||||
| ^^^^^^
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
@ -7,15 +7,11 @@ fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>)
|
||||
(a.clone(), a)
|
||||
}
|
||||
|
||||
type Foo<'a, 'b> = impl std::fmt::Debug;
|
||||
|
||||
fn foo<'x, 'y>(i: &'x i32, j: &'y i32) -> (Foo<'x, 'y>, Foo<'y, 'x>) {
|
||||
(i, j)
|
||||
type Tait<'x> = impl Sized;
|
||||
fn define<'a: 'b, 'b: 'a>(x: &'a u8, y: &'b u8) -> (Tait<'a>, Tait<'b>) {
|
||||
((), ())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("{}", <X<_, _> as ToString>::to_string(&f(42_i32, String::new()).1));
|
||||
let meh = 42;
|
||||
let muh = 69;
|
||||
println!("{:?}", foo(&meh, &muh));
|
||||
}
|
||||
|
16
tests/ui/type-alias-impl-trait/param_mismatch.rs
Normal file
16
tests/ui/type-alias-impl-trait/param_mismatch.rs
Normal file
@ -0,0 +1,16 @@
|
||||
//! This test checks that when checking for opaque types that
|
||||
//! only differ in lifetimes, we handle the case of non-generic
|
||||
//! regions correctly.
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
fn id(s: &str) -> &str {
|
||||
s
|
||||
}
|
||||
type Opaque<'a> = impl Sized + 'a;
|
||||
// The second `Opaque<'_>` has a higher kinded lifetime, not a generic parameter
|
||||
fn test(s: &str) -> (Opaque<'_>, impl Fn(&str) -> Opaque<'_>) {
|
||||
(s, id)
|
||||
//~^ ERROR: expected generic lifetime parameter, found `'_`
|
||||
}
|
||||
|
||||
fn main() {}
|
12
tests/ui/type-alias-impl-trait/param_mismatch.stderr
Normal file
12
tests/ui/type-alias-impl-trait/param_mismatch.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0792]: expected generic lifetime parameter, found `'_`
|
||||
--> $DIR/param_mismatch.rs:12:5
|
||||
|
|
||||
LL | type Opaque<'a> = impl Sized + 'a;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
...
|
||||
LL | (s, id)
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0792`.
|
16
tests/ui/type-alias-impl-trait/param_mismatch2.rs
Normal file
16
tests/ui/type-alias-impl-trait/param_mismatch2.rs
Normal file
@ -0,0 +1,16 @@
|
||||
//! This test checks that when checking for opaque types that
|
||||
//! only differ in lifetimes, we handle the case of non-generic
|
||||
//! regions correctly.
|
||||
#![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 main() {}
|
12
tests/ui/type-alias-impl-trait/param_mismatch2.stderr
Normal file
12
tests/ui/type-alias-impl-trait/param_mismatch2.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0792]: expected generic lifetime parameter, found `'_`
|
||||
--> $DIR/param_mismatch2.rs:13:5
|
||||
|
|
||||
LL | type Opaque<'a> = impl Sized + 'a;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
...
|
||||
LL | (id, id)
|
||||
| ^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0792`.
|
26
tests/ui/type-alias-impl-trait/param_mismatch3.rs
Normal file
26
tests/ui/type-alias-impl-trait/param_mismatch3.rs
Normal file
@ -0,0 +1,26 @@
|
||||
//! This test checks that when checking for opaque types that
|
||||
//! only differ in lifetimes, we handle the case of non-generic
|
||||
//! regions correctly.
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
fn id2<'a, 'b>(s: (&'a str, &'b str)) -> (&'a str, &'b str) {
|
||||
s
|
||||
}
|
||||
|
||||
type Opaque<'a> = impl Sized + 'a;
|
||||
|
||||
fn test() -> impl for<'a, 'b> Fn((&'a str, &'b str)) -> (Opaque<'a>, Opaque<'b>) {
|
||||
id2 //~ ERROR expected generic lifetime parameter, found `'a`
|
||||
}
|
||||
|
||||
fn id(s: &str) -> &str {
|
||||
s
|
||||
}
|
||||
|
||||
type Opaque2<'a> = impl Sized + 'a;
|
||||
|
||||
fn test2(s: &str) -> (impl Fn(&str) -> Opaque2<'_>, Opaque2<'_>) {
|
||||
(id, s) //~ ERROR: expected generic lifetime parameter, found `'_`
|
||||
}
|
||||
|
||||
fn main() {}
|
21
tests/ui/type-alias-impl-trait/param_mismatch3.stderr
Normal file
21
tests/ui/type-alias-impl-trait/param_mismatch3.stderr
Normal file
@ -0,0 +1,21 @@
|
||||
error[E0792]: expected generic lifetime parameter, found `'a`
|
||||
--> $DIR/param_mismatch3.rs:13:5
|
||||
|
|
||||
LL | type Opaque<'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/param_mismatch3.rs:23:5
|
||||
|
|
||||
LL | type Opaque2<'a> = impl Sized + 'a;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
...
|
||||
LL | (id, s)
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0792`.
|
Loading…
Reference in New Issue
Block a user