borrowck: defer opaque type errors
This commit is contained in:
parent
8b95291cd4
commit
4eee55691a
18 changed files with 193 additions and 84 deletions
|
|
@ -51,7 +51,7 @@ mod conflict_errors;
|
|||
mod explain_borrow;
|
||||
mod move_errors;
|
||||
mod mutability_errors;
|
||||
mod opaque_suggestions;
|
||||
mod opaque_types;
|
||||
mod region_errors;
|
||||
|
||||
pub(crate) use bound_region_errors::{ToUniverseInfo, UniverseInfo};
|
||||
|
|
|
|||
|
|
@ -18,9 +18,28 @@ use rustc_trait_selection::errors::impl_trait_overcapture_suggestion;
|
|||
use crate::MirBorrowckCtxt;
|
||||
use crate::borrow_set::BorrowData;
|
||||
use crate::consumers::RegionInferenceContext;
|
||||
use crate::region_infer::opaque_types::DeferredOpaqueTypeError;
|
||||
use crate::type_check::Locations;
|
||||
|
||||
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
pub(crate) fn report_opaque_type_errors(&mut self, errors: Vec<DeferredOpaqueTypeError<'tcx>>) {
|
||||
if errors.is_empty() {
|
||||
return;
|
||||
}
|
||||
let mut guar = None;
|
||||
for error in errors {
|
||||
guar = Some(match error {
|
||||
DeferredOpaqueTypeError::InvalidOpaqueTypeArgs(err) => err.report(self.infcx),
|
||||
DeferredOpaqueTypeError::LifetimeMismatchOpaqueParam(err) => {
|
||||
self.infcx.dcx().emit_err(err)
|
||||
}
|
||||
});
|
||||
}
|
||||
let guar = guar.unwrap();
|
||||
self.root_cx.set_tainted_by_errors(guar);
|
||||
self.infcx.set_tainted_by_errors(guar);
|
||||
}
|
||||
|
||||
/// Try to note when an opaque is involved in a borrowck error and that
|
||||
/// opaque captures lifetimes due to edition 2024.
|
||||
// FIXME: This code is otherwise somewhat general, and could easily be adapted
|
||||
|
|
@ -92,9 +92,6 @@ impl<'tcx> RegionErrors<'tcx> {
|
|||
) -> impl Iterator<Item = (RegionErrorKind<'tcx>, ErrorGuaranteed)> {
|
||||
self.0.into_iter()
|
||||
}
|
||||
pub(crate) fn has_errors(&self) -> Option<ErrorGuaranteed> {
|
||||
self.0.get(0).map(|x| x.1)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for RegionErrors<'_> {
|
||||
|
|
|
|||
|
|
@ -375,7 +375,7 @@ fn do_mir_borrowck<'tcx>(
|
|||
polonius_context,
|
||||
);
|
||||
|
||||
regioncx.infer_opaque_types(root_cx, &infcx, opaque_type_values);
|
||||
let opaque_type_errors = regioncx.infer_opaque_types(root_cx, &infcx, opaque_type_values);
|
||||
|
||||
// Dump MIR results into a file, if that is enabled. This lets us
|
||||
// write unit-tests, as well as helping with debugging.
|
||||
|
|
@ -471,7 +471,11 @@ fn do_mir_borrowck<'tcx>(
|
|||
};
|
||||
|
||||
// Compute and report region errors, if any.
|
||||
mbcx.report_region_errors(nll_errors);
|
||||
if nll_errors.is_empty() {
|
||||
mbcx.report_opaque_type_errors(opaque_type_errors);
|
||||
} else {
|
||||
mbcx.report_region_errors(nll_errors);
|
||||
}
|
||||
|
||||
let (mut flow_analysis, flow_entry_states) =
|
||||
get_flow_results(tcx, body, &move_data, &borrow_set, ®ioncx);
|
||||
|
|
|
|||
|
|
@ -148,11 +148,6 @@ pub(crate) fn compute_regions<'tcx>(
|
|||
let (closure_region_requirements, nll_errors) =
|
||||
regioncx.solve(infcx, body, polonius_output.clone());
|
||||
|
||||
if let Some(guar) = nll_errors.has_errors() {
|
||||
// Suppress unhelpful extra errors in `infer_opaque_types`.
|
||||
infcx.set_tainted_by_errors(guar);
|
||||
}
|
||||
|
||||
NllOutput {
|
||||
regioncx,
|
||||
polonius_input: polonius_facts.map(Box::new),
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ use crate::{
|
|||
|
||||
mod dump_mir;
|
||||
mod graphviz;
|
||||
mod opaque_types;
|
||||
pub(crate) mod opaque_types;
|
||||
mod reverse_sccs;
|
||||
|
||||
pub(crate) mod values;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ use rustc_middle::ty::{
|
|||
TypeVisitableExt, fold_regions,
|
||||
};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::opaque_types::check_opaque_type_parameter_valid;
|
||||
use rustc_trait_selection::opaque_types::{
|
||||
InvalidOpaqueTypeArgs, check_opaque_type_parameter_valid,
|
||||
};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use super::RegionInferenceContext;
|
||||
|
|
@ -14,6 +16,11 @@ use crate::BorrowCheckRootCtxt;
|
|||
use crate::session_diagnostics::LifetimeMismatchOpaqueParam;
|
||||
use crate::universal_regions::RegionClassification;
|
||||
|
||||
pub(crate) enum DeferredOpaqueTypeError<'tcx> {
|
||||
InvalidOpaqueTypeArgs(InvalidOpaqueTypeArgs<'tcx>),
|
||||
LifetimeMismatchOpaqueParam(LifetimeMismatchOpaqueParam<'tcx>),
|
||||
}
|
||||
|
||||
impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
/// 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.
|
||||
|
|
@ -58,13 +65,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
///
|
||||
/// [rustc-dev-guide chapter]:
|
||||
/// https://rustc-dev-guide.rust-lang.org/opaque-types-region-infer-restrictions.html
|
||||
#[instrument(level = "debug", skip(self, root_cx, infcx), ret)]
|
||||
#[instrument(level = "debug", skip(self, root_cx, infcx))]
|
||||
pub(crate) fn infer_opaque_types(
|
||||
&self,
|
||||
root_cx: &mut BorrowCheckRootCtxt<'tcx>,
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
opaque_ty_decls: FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
|
||||
) {
|
||||
) -> Vec<DeferredOpaqueTypeError<'tcx>> {
|
||||
let mut errors = Vec::new();
|
||||
let mut decls_modulo_regions: FxIndexMap<OpaqueTypeKey<'tcx>, (OpaqueTypeKey<'tcx>, Span)> =
|
||||
FxIndexMap::default();
|
||||
|
||||
|
|
@ -124,8 +132,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
});
|
||||
debug!(?concrete_type);
|
||||
|
||||
let ty =
|
||||
infcx.infer_opaque_definition_from_instantiation(opaque_type_key, concrete_type);
|
||||
let ty = match infcx
|
||||
.infer_opaque_definition_from_instantiation(opaque_type_key, concrete_type)
|
||||
{
|
||||
Ok(ty) => ty,
|
||||
Err(err) => {
|
||||
errors.push(DeferredOpaqueTypeError::InvalidOpaqueTypeArgs(err));
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
// Sometimes, when the hidden type is an inference variable, it can happen that
|
||||
// the hidden type becomes the opaque type itself. In this case, this was an opaque
|
||||
|
|
@ -149,25 +164,27 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
// 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.
|
||||
if !ty.references_error()
|
||||
&& let Some((prev_decl_key, prev_span)) = decls_modulo_regions.insert(
|
||||
infcx.tcx.erase_regions(opaque_type_key),
|
||||
(opaque_type_key, concrete_type.span),
|
||||
)
|
||||
&& let Some((arg1, arg2)) = std::iter::zip(
|
||||
prev_decl_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg),
|
||||
opaque_type_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg),
|
||||
)
|
||||
.find(|(arg1, arg2)| arg1 != arg2)
|
||||
if let Some((prev_decl_key, prev_span)) = decls_modulo_regions.insert(
|
||||
infcx.tcx.erase_regions(opaque_type_key),
|
||||
(opaque_type_key, concrete_type.span),
|
||||
) && let Some((arg1, arg2)) = std::iter::zip(
|
||||
prev_decl_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg),
|
||||
opaque_type_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg),
|
||||
)
|
||||
.find(|(arg1, arg2)| arg1 != arg2)
|
||||
{
|
||||
infcx.dcx().emit_err(LifetimeMismatchOpaqueParam {
|
||||
arg: arg1,
|
||||
prev: arg2,
|
||||
span: prev_span,
|
||||
prev_span: concrete_type.span,
|
||||
});
|
||||
errors.push(DeferredOpaqueTypeError::LifetimeMismatchOpaqueParam(
|
||||
LifetimeMismatchOpaqueParam {
|
||||
arg: arg1,
|
||||
prev: arg2,
|
||||
span: prev_span,
|
||||
prev_span: concrete_type.span,
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
errors
|
||||
}
|
||||
|
||||
/// Map the regions in the type to named regions. This is similar to what
|
||||
|
|
@ -260,19 +277,13 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
&self,
|
||||
opaque_type_key: OpaqueTypeKey<'tcx>,
|
||||
instantiated_ty: OpaqueHiddenType<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
if let Some(e) = self.tainted_by_errors() {
|
||||
return Ty::new_error(self.tcx, e);
|
||||
}
|
||||
|
||||
if let Err(err) = check_opaque_type_parameter_valid(
|
||||
) -> Result<Ty<'tcx>, InvalidOpaqueTypeArgs<'tcx>> {
|
||||
check_opaque_type_parameter_valid(
|
||||
self,
|
||||
opaque_type_key,
|
||||
instantiated_ty.span,
|
||||
DefiningScopeKind::MirBorrowck,
|
||||
) {
|
||||
return Ty::new_error(self.tcx, err.report(self));
|
||||
}
|
||||
)?;
|
||||
|
||||
let definition_ty = instantiated_ty
|
||||
.remap_generic_params_to_declaration_params(
|
||||
|
|
@ -282,10 +293,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
)
|
||||
.ty;
|
||||
|
||||
if let Err(e) = definition_ty.error_reported() {
|
||||
return Ty::new_error(self.tcx, e);
|
||||
}
|
||||
|
||||
definition_ty
|
||||
definition_ty.error_reported()?;
|
||||
Ok(definition_ty)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
//@ known-bug: #135528
|
||||
//@ compile-flags: -Zvalidate-mir -Zinline-mir=yes
|
||||
#![feature(type_alias_impl_trait)]
|
||||
type Tait = impl Copy;
|
||||
|
||||
fn set(x: &isize) -> isize {
|
||||
*x
|
||||
}
|
||||
|
||||
#[define_opaque(Tait)]
|
||||
fn d(x: Tait) {
|
||||
set(x);
|
||||
}
|
||||
|
||||
#[define_opaque(Tait)]
|
||||
fn other_define() -> Tait {
|
||||
()
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
//@ compile-flags: -Zvalidate-mir -Zinline-mir=yes
|
||||
|
||||
// This previously introduced a `{type_error}`` in the MIR body
|
||||
// during the `PostAnalysisNormalize` pass. While the underlying issue
|
||||
// #135528 did not get fixed, this reproducer no longer ICEs.
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
type Tait = impl Copy;
|
||||
|
||||
fn set(x: &isize) -> isize {
|
||||
*x
|
||||
}
|
||||
|
||||
#[define_opaque(Tait)]
|
||||
fn d(x: Tait) {
|
||||
set(x);
|
||||
}
|
||||
|
||||
#[define_opaque(Tait)]
|
||||
fn other_define() -> Tait {
|
||||
() //~^ ERROR concrete type differs from previous defining opaque type use
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
error: concrete type differs from previous defining opaque type use
|
||||
--> $DIR/type-error-post-normalization-test.rs:20:22
|
||||
|
|
||||
LL | fn other_define() -> Tait {
|
||||
| ^^^^ expected `&isize`, got `()`
|
||||
|
|
||||
note: previous use here
|
||||
--> $DIR/type-error-post-normalization-test.rs:16:9
|
||||
|
|
||||
LL | set(x);
|
||||
| ^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
@ -41,6 +41,7 @@ mod capture_tait_complex_pass {
|
|||
#[define_opaque(Opq2)]
|
||||
fn test() -> Opq2 {}
|
||||
//~^ ERROR: expected generic lifetime parameter, found `'a`
|
||||
//~| ERROR: expected generic lifetime parameter, found `'b`
|
||||
}
|
||||
|
||||
// Same as the above, but make sure that different placeholder regions are not equal.
|
||||
|
|
@ -80,6 +81,7 @@ mod constrain_pass {
|
|||
#[define_opaque(Opq2)]
|
||||
fn test() -> Opq2 {}
|
||||
//~^ ERROR: expected generic lifetime parameter, found `'a`
|
||||
//~| ERROR: expected generic lifetime parameter, found `'a`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -36,8 +36,17 @@ LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'b>>; // <- Note 'b
|
|||
LL | fn test() -> Opq2 {}
|
||||
| ^^
|
||||
|
||||
error[E0792]: expected generic lifetime parameter, found `'b`
|
||||
--> $DIR/higher-ranked-regions-basic.rs:42:23
|
||||
|
|
||||
LL | type Opq0<'a> = impl Sized;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
...
|
||||
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:53:23
|
||||
--> $DIR/higher-ranked-regions-basic.rs:54:23
|
||||
|
|
||||
LL | type Opq0<'a> = impl Sized;
|
||||
| ---------- opaque type defined here
|
||||
|
|
@ -48,7 +57,7 @@ LL | fn test() -> Opq2 {}
|
|||
| ^^
|
||||
|
||||
error[E0792]: expected generic lifetime parameter, found `'a`
|
||||
--> $DIR/higher-ranked-regions-basic.rs:62:65
|
||||
--> $DIR/higher-ranked-regions-basic.rs:63:65
|
||||
|
|
||||
LL | type Opq0<'a, 'b> = impl Sized;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
|
|
@ -57,7 +66,7 @@ LL | fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'static>> {}
|
|||
| ^^
|
||||
|
||||
error[E0792]: expected generic lifetime parameter, found `'a`
|
||||
--> $DIR/higher-ranked-regions-basic.rs:71:60
|
||||
--> $DIR/higher-ranked-regions-basic.rs:72:60
|
||||
|
|
||||
LL | type Opq0<'a, 'b> = impl Sized;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
|
|
@ -66,7 +75,7 @@ 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:81:23
|
||||
--> $DIR/higher-ranked-regions-basic.rs:82: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
|
||||
|
|
@ -74,7 +83,16 @@ LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a, 'b>>;
|
|||
LL | fn test() -> Opq2 {}
|
||||
| ^^
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
error[E0792]: expected generic lifetime parameter, found `'a`
|
||||
--> $DIR/higher-ranked-regions-basic.rs:82:23
|
||||
|
|
||||
LL | type Opq0<'a, 'b> = impl Sized;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
...
|
||||
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`.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ type Opaque<'a> = impl Sized + 'a;
|
|||
|
||||
#[define_opaque(Opaque)]
|
||||
fn test(s: &str) -> (impl Fn(&str) -> Opaque<'_>, impl Fn(&str) -> Opaque<'_>) {
|
||||
(id, id) //~ ERROR expected generic lifetime parameter, found `'_`
|
||||
(id, id)
|
||||
//~^ ERROR expected generic lifetime parameter, found `'_`
|
||||
//~| ERROR expected generic lifetime parameter, found `'_`
|
||||
}
|
||||
|
||||
fn id2<'a, 'b>(s: (&'a str, &'b str)) -> (&'a str, &'b str) {
|
||||
|
|
@ -19,7 +21,9 @@ type Opaque2<'a> = impl Sized + 'a;
|
|||
|
||||
#[define_opaque(Opaque2)]
|
||||
fn test2() -> impl for<'a, 'b> Fn((&'a str, &'b str)) -> (Opaque2<'a>, Opaque2<'b>) {
|
||||
id2 //~ ERROR expected generic lifetime parameter, found `'a`
|
||||
id2
|
||||
//~^ ERROR expected generic lifetime parameter, found `'a`
|
||||
//~| ERROR expected generic lifetime parameter, found `'b`
|
||||
}
|
||||
|
||||
type Opaque3<'a> = impl Sized + 'a;
|
||||
|
|
|
|||
|
|
@ -7,8 +7,28 @@ LL | type Opaque<'a> = impl Sized + 'a;
|
|||
LL | (id, id)
|
||||
| ^^^^^^^^
|
||||
|
||||
error[E0792]: expected generic lifetime parameter, found `'_`
|
||||
--> $DIR/hkl_forbidden.rs:11:5
|
||||
|
|
||||
LL | type Opaque<'a> = impl Sized + 'a;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
...
|
||||
LL | (id, id)
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0792]: expected generic lifetime parameter, found `'a`
|
||||
--> $DIR/hkl_forbidden.rs:22:5
|
||||
--> $DIR/hkl_forbidden.rs:24: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 `'b`
|
||||
--> $DIR/hkl_forbidden.rs:24:5
|
||||
|
|
||||
LL | type Opaque2<'a> = impl Sized + 'a;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
|
|
@ -17,7 +37,7 @@ LL | id2
|
|||
| ^^^
|
||||
|
||||
error[E0792]: expected generic lifetime parameter, found `'_`
|
||||
--> $DIR/hkl_forbidden.rs:29:5
|
||||
--> $DIR/hkl_forbidden.rs:33:5
|
||||
|
|
||||
LL | type Opaque3<'a> = impl Sized + 'a;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
|
|
@ -26,7 +46,7 @@ LL | (id, s)
|
|||
| ^^^^^^^
|
||||
|
||||
error[E0792]: expected generic lifetime parameter, found `'_`
|
||||
--> $DIR/hkl_forbidden.rs:35:5
|
||||
--> $DIR/hkl_forbidden.rs:39:5
|
||||
|
|
||||
LL | type Opaque4<'a> = impl Sized + 'a;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
|
|
@ -35,7 +55,7 @@ LL | (s, id)
|
|||
| ^^^^^^^
|
||||
|
||||
error[E0792]: expected generic lifetime parameter, found `'a`
|
||||
--> $DIR/hkl_forbidden.rs:41:5
|
||||
--> $DIR/hkl_forbidden.rs:45:5
|
||||
|
|
||||
LL | type Inner<'a> = impl Sized;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
|
|
@ -43,6 +63,6 @@ LL | type Inner<'a> = impl Sized;
|
|||
LL | |x| x
|
||||
| ^^^^^
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0792`.
|
||||
|
|
|
|||
|
|
@ -11,7 +11,9 @@ type Opaque<'a> = impl Sized + 'a;
|
|||
|
||||
#[define_opaque(Opaque)]
|
||||
fn test(s: &str) -> (impl Fn(&str) -> Opaque<'_>, impl Fn(&str) -> Opaque<'_>) {
|
||||
(id, id) //~ ERROR: expected generic lifetime parameter, found `'_`
|
||||
(id, id)
|
||||
//~^ ERROR: expected generic lifetime parameter, found `'_`
|
||||
//~| ERROR: expected generic lifetime parameter, found `'_`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,17 @@ LL | type Opaque<'a> = impl Sized + 'a;
|
|||
LL | (id, id)
|
||||
| ^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error[E0792]: expected generic lifetime parameter, found `'_`
|
||||
--> $DIR/param_mismatch2.rs:14:5
|
||||
|
|
||||
LL | type Opaque<'a> = impl Sized + 'a;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
...
|
||||
LL | (id, id)
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0792`.
|
||||
|
|
|
|||
|
|
@ -11,7 +11,9 @@ type Opaque<'a> = impl Sized + 'a;
|
|||
|
||||
#[define_opaque(Opaque)]
|
||||
fn test() -> impl for<'a, 'b> Fn((&'a str, &'b str)) -> (Opaque<'a>, Opaque<'b>) {
|
||||
id2 //~ ERROR expected generic lifetime parameter, found `'a`
|
||||
id2
|
||||
//~^ ERROR expected generic lifetime parameter, found `'a`
|
||||
//~| ERROR expected generic lifetime parameter, found `'b`
|
||||
}
|
||||
|
||||
fn id(s: &str) -> &str {
|
||||
|
|
|
|||
|
|
@ -7,8 +7,17 @@ LL | type Opaque<'a> = impl Sized + 'a;
|
|||
LL | id2
|
||||
| ^^^
|
||||
|
||||
error[E0792]: expected generic lifetime parameter, found `'b`
|
||||
--> $DIR/param_mismatch3.rs:14: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:25:5
|
||||
--> $DIR/param_mismatch3.rs:27:5
|
||||
|
|
||||
LL | type Opaque2<'a> = impl Sized + 'a;
|
||||
| -- this generic parameter must be used with a generic lifetime parameter
|
||||
|
|
@ -16,6 +25,6 @@ LL | type Opaque2<'a> = impl Sized + 'a;
|
|||
LL | (id, s)
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0792`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue