Rollup merge of #132757 - compiler-errors:yeet-check-wf, r=lcnr

Get rid of `check_opaque_type_well_formed`

Instead, replicate it by improving the span of the opaque in `check_opaque_meets_bounds`.

This has two consequences:
1. We now prefer "concrete type differs" errors, since we'll hit those first before we check the opaque is WF.
2. Spans have gotten slightly worse.

Specifically, (2.) could be improved by adding a new obligation cause that explains that the definition's environment has stronger assumptions than the declaration.

r? lcnr
This commit is contained in:
Jubilee 2024-11-08 20:46:12 -08:00 committed by GitHub
commit 7a4970476e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
35 changed files with 395 additions and 418 deletions

View File

@ -1,10 +1,7 @@
use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::ErrorGuaranteed;
use rustc_hir::OpaqueTyOrigin;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::LocalDefId;
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, TyCtxtInferExt as _};
use rustc_infer::traits::{Obligation, ObligationCause};
use rustc_macros::extension;
use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::{
@ -12,7 +9,6 @@
TypingMode,
};
use rustc_span::Span;
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
use rustc_trait_selection::traits::ObligationCtxt;
use tracing::{debug, instrument};
@ -303,91 +299,7 @@ fn infer_opaque_definition_from_instantiation(
return Ty::new_error(self.tcx, e);
}
// `definition_ty` does not live in of the current inference context,
// so lets make sure that we don't accidentally misuse our current `infcx`.
match check_opaque_type_well_formed(
self.tcx,
self.next_trait_solver(),
opaque_type_key.def_id,
instantiated_ty.span,
definition_ty,
) {
Ok(hidden_ty) => hidden_ty,
Err(guar) => Ty::new_error(self.tcx, guar),
}
}
}
/// This logic duplicates most of `check_opaque_meets_bounds`.
/// FIXME(oli-obk): Also do region checks here and then consider removing
/// `check_opaque_meets_bounds` entirely.
fn check_opaque_type_well_formed<'tcx>(
tcx: TyCtxt<'tcx>,
next_trait_solver: bool,
def_id: LocalDefId,
definition_span: Span,
definition_ty: Ty<'tcx>,
) -> Result<Ty<'tcx>, ErrorGuaranteed> {
// Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs`
// on stable and we'd break that.
let opaque_ty_hir = tcx.hir().expect_opaque_ty(def_id);
let OpaqueTyOrigin::TyAlias { .. } = opaque_ty_hir.origin else {
return Ok(definition_ty);
};
let param_env = tcx.param_env(def_id);
let mut parent_def_id = def_id;
while tcx.def_kind(parent_def_id) == DefKind::OpaqueTy {
parent_def_id = tcx.local_parent(parent_def_id);
}
// FIXME(#132279): This should eventually use the already defined hidden types
// instead. Alternatively we'll entirely remove this function given we also check
// the opaque in `check_opaque_meets_bounds` later.
let infcx = tcx
.infer_ctxt()
.with_next_trait_solver(next_trait_solver)
.build(TypingMode::analysis_in_body(tcx, parent_def_id));
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
let identity_args = GenericArgs::identity_for_item(tcx, def_id);
// Require that the hidden type actually fulfills all the bounds of the opaque type, even without
// the bounds that the function supplies.
let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), identity_args);
ocx.eq(&ObligationCause::misc(definition_span, def_id), param_env, opaque_ty, definition_ty)
.map_err(|err| {
infcx
.err_ctxt()
.report_mismatched_types(
&ObligationCause::misc(definition_span, def_id),
param_env,
opaque_ty,
definition_ty,
err,
)
.emit()
})?;
// Require the hidden type to be well-formed with only the generics of the opaque type.
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the
// hidden type is well formed even without those bounds.
let predicate = ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(
definition_ty.into(),
)));
ocx.register_obligation(Obligation::misc(tcx, definition_span, def_id, param_env, predicate));
// Check that all obligations are satisfied by the implementation's
// version.
let errors = ocx.select_all_or_error();
// This is fishy, but we check it again in `check_opaque_meets_bounds`.
// Remove once we can prepopulate with known hidden types.
let _ = infcx.take_opaque_types();
if errors.is_empty() {
Ok(definition_ty)
} else {
Err(infcx.err_ctxt().report_fulfillment_errors(errors))
definition_ty
}
}

View File

@ -5,13 +5,14 @@
use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_errors::MultiSpan;
use rustc_errors::codes::*;
use rustc_hir::Node;
use rustc_hir::def::{CtorKind, DefKind};
use rustc_hir::{Node, intravisit};
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
use rustc_infer::traits::Obligation;
use rustc_infer::traits::{Obligation, ObligationCauseCode};
use rustc_lint_defs::builtin::{
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS, UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS,
};
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
use rustc_middle::middle::stability::EvalResult;
use rustc_middle::span_bug;
@ -190,7 +191,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
/// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
/// projections that would result in "inheriting lifetimes".
fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) {
let hir::OpaqueTy { origin, .. } = tcx.hir().expect_opaque_ty(def_id);
let hir::OpaqueTy { origin, .. } = *tcx.hir().expect_opaque_ty(def_id);
// HACK(jynelson): trying to infer the type of `impl trait` breaks documenting
// `async-std` (and `pub async fn` in general).
@ -200,23 +201,20 @@ fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) {
return;
}
let span = tcx.def_span(def_id);
if tcx.type_of(def_id).instantiate_identity().references_error() {
return;
}
if check_opaque_for_cycles(tcx, def_id, span).is_err() {
if check_opaque_for_cycles(tcx, def_id).is_err() {
return;
}
let _ = check_opaque_meets_bounds(tcx, def_id, span, origin);
let _ = check_opaque_meets_bounds(tcx, def_id, origin);
}
/// Checks that an opaque type does not contain cycles.
pub(super) fn check_opaque_for_cycles<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
span: Span,
) -> Result<(), ErrorGuaranteed> {
let args = GenericArgs::identity_for_item(tcx, def_id);
@ -233,7 +231,7 @@ pub(super) fn check_opaque_for_cycles<'tcx>(
.try_expand_impl_trait_type(def_id.to_def_id(), args, InspectCoroutineFields::No)
.is_err()
{
let reported = opaque_type_cycle_error(tcx, def_id, span);
let reported = opaque_type_cycle_error(tcx, def_id);
return Err(reported);
}
@ -267,10 +265,16 @@ pub(super) fn check_opaque_for_cycles<'tcx>(
fn check_opaque_meets_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
span: Span,
origin: &hir::OpaqueTyOrigin<LocalDefId>,
origin: hir::OpaqueTyOrigin<LocalDefId>,
) -> Result<(), ErrorGuaranteed> {
let defining_use_anchor = match *origin {
let (span, definition_def_id) =
if let Some((span, def_id)) = best_definition_site_of_opaque(tcx, def_id, origin) {
(span, Some(def_id))
} else {
(tcx.def_span(def_id), None)
};
let defining_use_anchor = match origin {
hir::OpaqueTyOrigin::FnReturn { parent, .. }
| hir::OpaqueTyOrigin::AsyncFn { parent, .. }
| hir::OpaqueTyOrigin::TyAlias { parent, .. } => parent,
@ -281,7 +285,7 @@ fn check_opaque_meets_bounds<'tcx>(
let infcx = tcx.infer_ctxt().build(TypingMode::analysis_in_body(tcx, defining_use_anchor));
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
let args = match *origin {
let args = match origin {
hir::OpaqueTyOrigin::FnReturn { parent, .. }
| hir::OpaqueTyOrigin::AsyncFn { parent, .. }
| hir::OpaqueTyOrigin::TyAlias { parent, .. } => GenericArgs::identity_for_item(
@ -306,8 +310,33 @@ fn check_opaque_meets_bounds<'tcx>(
_ => re,
});
let misc_cause = traits::ObligationCause::misc(span, def_id);
// HACK: We eagerly instantiate some bounds to report better errors for them...
// This isn't necessary for correctness, since we register these bounds when
// equating the opaque below, but we should clean this up in the new solver.
for (predicate, pred_span) in
tcx.explicit_item_bounds(def_id).iter_instantiated_copied(tcx, args)
{
let predicate = predicate.fold_with(&mut BottomUpFolder {
tcx,
ty_op: |ty| if ty == opaque_ty { hidden_ty } else { ty },
lt_op: |lt| lt,
ct_op: |ct| ct,
});
ocx.register_obligation(Obligation::new(
tcx,
ObligationCause::new(
span,
def_id,
ObligationCauseCode::OpaqueTypeBound(pred_span, definition_def_id),
),
param_env,
predicate,
));
}
let misc_cause = ObligationCause::misc(span, def_id);
// FIXME: We should just register the item bounds here, rather than equating.
match ocx.eq(&misc_cause, param_env, opaque_ty, hidden_ty) {
Ok(()) => {}
Err(ty_err) => {
@ -364,6 +393,97 @@ fn check_opaque_meets_bounds<'tcx>(
}
}
fn best_definition_site_of_opaque<'tcx>(
tcx: TyCtxt<'tcx>,
opaque_def_id: LocalDefId,
origin: hir::OpaqueTyOrigin<LocalDefId>,
) -> Option<(Span, LocalDefId)> {
struct TaitConstraintLocator<'tcx> {
opaque_def_id: LocalDefId,
tcx: TyCtxt<'tcx>,
}
impl<'tcx> TaitConstraintLocator<'tcx> {
fn check(&self, item_def_id: LocalDefId) -> ControlFlow<(Span, LocalDefId)> {
if !self.tcx.has_typeck_results(item_def_id) {
return ControlFlow::Continue(());
}
if let Some(hidden_ty) =
self.tcx.mir_borrowck(item_def_id).concrete_opaque_types.get(&self.opaque_def_id)
{
ControlFlow::Break((hidden_ty.span, item_def_id))
} else {
ControlFlow::Continue(())
}
}
}
impl<'tcx> intravisit::Visitor<'tcx> for TaitConstraintLocator<'tcx> {
type NestedFilter = nested_filter::All;
type Result = ControlFlow<(Span, LocalDefId)>;
fn nested_visit_map(&mut self) -> Self::Map {
self.tcx.hir()
}
fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) -> Self::Result {
if let hir::ExprKind::Closure(closure) = ex.kind {
self.check(closure.def_id)?;
}
intravisit::walk_expr(self, ex)
}
fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) -> Self::Result {
self.check(it.owner_id.def_id)?;
intravisit::walk_item(self, it)
}
fn visit_impl_item(&mut self, it: &'tcx hir::ImplItem<'tcx>) -> Self::Result {
self.check(it.owner_id.def_id)?;
intravisit::walk_impl_item(self, it)
}
fn visit_trait_item(&mut self, it: &'tcx hir::TraitItem<'tcx>) -> Self::Result {
self.check(it.owner_id.def_id)?;
intravisit::walk_trait_item(self, it)
}
fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem<'tcx>) -> Self::Result {
intravisit::walk_foreign_item(self, it)
}
}
let mut locator = TaitConstraintLocator { tcx, opaque_def_id };
match origin {
hir::OpaqueTyOrigin::FnReturn { parent, .. }
| hir::OpaqueTyOrigin::AsyncFn { parent, .. } => locator.check(parent).break_value(),
hir::OpaqueTyOrigin::TyAlias { parent, in_assoc_ty: true } => {
let impl_def_id = tcx.local_parent(parent);
for assoc in tcx.associated_items(impl_def_id).in_definition_order() {
match assoc.kind {
ty::AssocKind::Const | ty::AssocKind::Fn => {
if let ControlFlow::Break(span) = locator.check(assoc.def_id.expect_local())
{
return Some(span);
}
}
ty::AssocKind::Type => {}
}
}
None
}
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => {
let scope = tcx.hir().get_defining_scope(tcx.local_def_id_to_hir_id(opaque_def_id));
let found = if scope == hir::CRATE_HIR_ID {
tcx.hir().walk_toplevel_module(&mut locator)
} else {
match tcx.hir_node(scope) {
Node::Item(it) => locator.visit_item(it),
Node::ImplItem(it) => locator.visit_impl_item(it),
Node::TraitItem(it) => locator.visit_trait_item(it),
Node::ForeignItem(it) => locator.visit_foreign_item(it),
other => bug!("{:?} is not a valid scope for an opaque type item", other),
}
};
found.break_value()
}
}
}
fn sanity_check_found_hidden_type<'tcx>(
tcx: TyCtxt<'tcx>,
key: ty::OpaqueTypeKey<'tcx>,
@ -1535,11 +1655,8 @@ fn check_type_alias_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalD
///
/// If all the return expressions evaluate to `!`, then we explain that the error will go away
/// after changing it. This can happen when a user uses `panic!()` or similar as a placeholder.
fn opaque_type_cycle_error(
tcx: TyCtxt<'_>,
opaque_def_id: LocalDefId,
span: Span,
) -> ErrorGuaranteed {
fn opaque_type_cycle_error(tcx: TyCtxt<'_>, opaque_def_id: LocalDefId) -> ErrorGuaranteed {
let span = tcx.def_span(opaque_def_id);
let mut err = struct_span_code_err!(tcx.dcx(), span, E0720, "cannot resolve opaque type");
let mut label = false;

View File

@ -104,6 +104,7 @@ pub fn register_region_obligation_with_cause(
infer::RelateParamBound(cause.span, sup_type, match cause.code().peel_derives() {
ObligationCauseCode::WhereClause(_, span)
| ObligationCauseCode::WhereClauseInExpr(_, span, ..)
| ObligationCauseCode::OpaqueTypeBound(span, _)
if !span.is_dummy() =>
{
Some(*span)

View File

@ -193,6 +193,11 @@ pub enum ObligationCauseCode<'tcx> {
/// The span corresponds to the clause.
WhereClause(DefId, Span),
/// Represents a bound for an opaque we are checking the well-formedness of.
/// The def-id corresponds to a specific definition site that we found the
/// hidden type from, if any.
OpaqueTypeBound(Span, Option<LocalDefId>),
/// Like `WhereClause`, but also identifies the expression
/// which requires the `where` clause to be proven, and also
/// identifies the index of the predicate in the `predicates_of`

View File

@ -2953,6 +2953,22 @@ pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>(
// We hold the `DefId` of the item introducing the obligation, but displaying it
// doesn't add user usable information. It always point at an associated item.
}
ObligationCauseCode::OpaqueTypeBound(span, definition_def_id) => {
err.span_note(span, "required by a bound in an opaque type");
if let Some(definition_def_id) = definition_def_id
// If there are any stalled coroutine obligations, then this
// error may be due to that, and not because the body has more
// where-clauses.
&& self.tcx.typeck(definition_def_id).coroutine_stalled_predicates.is_empty()
{
// FIXME(compiler-errors): We could probably point to something
// specific here if we tried hard enough...
err.span_note(
tcx.def_span(definition_def_id),
"this definition site has more where clauses than the opaque type",
);
}
}
ObligationCauseCode::Coercion { source, target } => {
let source =
tcx.short_ty_string(self.resolve_vars_if_possible(source), long_ty_file);

View File

@ -14,8 +14,8 @@ async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> {
fn foo(x: NotSync) -> impl Future + Send {
//~^ ERROR `*mut ()` cannot be shared between threads safely
//~| ERROR `*mut ()` cannot be shared between threads safely
async move {
//~^ ERROR `*mut ()` cannot be shared between threads safely
baz(|| async {
foo(x.clone());
}).await;

View File

@ -1,8 +1,13 @@
error[E0277]: `*mut ()` cannot be shared between threads safely
--> $DIR/issue-70935-complex-spans.rs:15:23
--> $DIR/issue-70935-complex-spans.rs:17:5
|
LL | fn foo(x: NotSync) -> impl Future + Send {
| ^^^^^^^^^^^^^^^^^^ `*mut ()` cannot be shared between threads safely
LL | / async move {
LL | |
LL | | baz(|| async {
LL | | foo(x.clone());
LL | | }).await;
LL | | }
| |_____^ `*mut ()` cannot be shared between threads safely
|
= help: within `NotSync`, the trait `Sync` is not implemented for `*mut ()`
note: required because it appears within the type `PhantomData<*mut ()>`
@ -26,10 +31,15 @@ LL | async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> {
LL | | }
| |_^
note: required because it's used within this `async` block
--> $DIR/issue-70935-complex-spans.rs:18:5
--> $DIR/issue-70935-complex-spans.rs:17:5
|
LL | async move {
| ^^^^^^^^^^
note: required by a bound in an opaque type
--> $DIR/issue-70935-complex-spans.rs:15:37
|
LL | fn foo(x: NotSync) -> impl Future + Send {
| ^^^^
error[E0277]: `*mut ()` cannot be shared between threads safely
--> $DIR/issue-70935-complex-spans.rs:15:23
@ -59,11 +69,10 @@ LL | async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> {
LL | | }
| |_^
note: required because it's used within this `async` block
--> $DIR/issue-70935-complex-spans.rs:18:5
--> $DIR/issue-70935-complex-spans.rs:17:5
|
LL | async move {
| ^^^^^^^^^^
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 2 previous errors

View File

@ -25,6 +25,20 @@ LL | _ => {}
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error[E0004]: non-exhaustive patterns: type `impl Copy` is non-empty
--> $DIR/impl-trait.rs:23:11
|
LL | match return_never_rpit(x) {}
| ^^^^^^^^^^^^^^^^^^^^
|
= note: the matched value is of type `impl Copy`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match return_never_rpit(x) {
LL + _ => todo!(),
LL + }
|
error: unreachable pattern
--> $DIR/impl-trait.rs:45:13
|
@ -93,6 +107,20 @@ LL | _ => {}
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error[E0004]: non-exhaustive patterns: type `T` is non-empty
--> $DIR/impl-trait.rs:37:11
|
LL | match return_never_tait(x) {}
| ^^^^^^^^^^^^^^^^^^^^
|
= note: the matched value is of type `T`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match return_never_tait(x) {
LL + _ => todo!(),
LL + }
|
error: unreachable pattern
--> $DIR/impl-trait.rs:105:9
|
@ -131,34 +159,6 @@ LL | _ => {}
|
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
error[E0004]: non-exhaustive patterns: type `impl Copy` is non-empty
--> $DIR/impl-trait.rs:23:11
|
LL | match return_never_rpit(x) {}
| ^^^^^^^^^^^^^^^^^^^^
|
= note: the matched value is of type `impl Copy`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match return_never_rpit(x) {
LL + _ => todo!(),
LL + }
|
error[E0004]: non-exhaustive patterns: type `T` is non-empty
--> $DIR/impl-trait.rs:37:11
|
LL | match return_never_tait(x) {}
| ^^^^^^^^^^^^^^^^^^^^
|
= note: the matched value is of type `T`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match return_never_tait(x) {
LL + _ => todo!(),
LL + }
|
error: aborting due to 15 previous errors
For more information about this error, try `rustc --explain E0004`.

View File

@ -4,6 +4,16 @@ error[E0277]: the trait bound `T: Clone` is not satisfied
LL | t
| ^ the trait `Clone` is not implemented for `T`
|
note: required by a bound in an opaque type
--> $DIR/bounds-are-checked-2.rs:7:26
|
LL | pub type X<T> = impl Clone;
| ^^^^^
note: this definition site has more where clauses than the opaque type
--> $DIR/bounds-are-checked-2.rs:9:5
|
LL | fn f<T: Clone>(t: T) -> X<T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider restricting type parameter `T`
|
LL | pub type X<T: std::clone::Clone> = impl Clone;

View File

@ -12,20 +12,19 @@
// requires `'a: 'b` bound
mod test1 {
type Opaque<'a, 'b> = impl Sized + 'a + 'b;
//~^ ERROR lifetime bound not satisfied
fn define<'a, 'b>() -> Opaque<'a, 'b>
where
'a: 'b,
{
|| {}
//~^ ERROR lifetime bound not satisfied
}
}
// Same as the above but through indirection `'x`
mod test2 {
type Opaque<'a, 'b> = impl Sized + 'a + 'b;
//~^ ERROR cannot infer an appropriate lifetime
fn define<'a, 'b, 'x>() -> Opaque<'a, 'b>
where
@ -33,6 +32,7 @@ fn define<'a, 'b, 'x>() -> Opaque<'a, 'b>
'x: 'b,
{
|| {}
//~^ ERROR cannot infer an appropriate lifetime
}
}
@ -52,13 +52,13 @@ fn define<'a, 'b, 'x>() -> Opaque<'a, 'b>
// requires `T: 'static`
mod test3 {
type Opaque<T> = impl Sized;
//~^ ERROR the parameter type `T` may not live long enough
fn define<T>() -> Opaque<T>
where
T: 'static,
{
|| {}
//~^ ERROR the parameter type `T` may not live long enough
}
}

View File

@ -1,8 +1,8 @@
error[E0478]: lifetime bound not satisfied
--> $DIR/closure_wf_outlives.rs:14:27
--> $DIR/closure_wf_outlives.rs:20:9
|
LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b;
| ^^^^^^^^^^^^^^^^^^^^
LL | || {}
| ^^^^^
|
note: lifetime parameter instantiated with the lifetime `'a` as defined here
--> $DIR/closure_wf_outlives.rs:14:17
@ -16,10 +16,10 @@ LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b;
| ^^
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> $DIR/closure_wf_outlives.rs:27:27
--> $DIR/closure_wf_outlives.rs:34:9
|
LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b;
| ^^^^^^^^^^^^^^^^^^^^
LL | || {}
| ^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined here...
--> $DIR/closure_wf_outlives.rs:27:17
@ -27,32 +27,32 @@ note: first, the lifetime cannot outlive the lifetime `'a` as defined here...
LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b;
| ^^
note: ...so that the declared lifetime parameter bounds are satisfied
--> $DIR/closure_wf_outlives.rs:27:27
--> $DIR/closure_wf_outlives.rs:34:9
|
LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b;
| ^^^^^^^^^^^^^^^^^^^^
LL | || {}
| ^^^^^
note: but, the lifetime must be valid for the lifetime `'b` as defined here...
--> $DIR/closure_wf_outlives.rs:27:21
|
LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b;
| ^^
note: ...so that the declared lifetime parameter bounds are satisfied
--> $DIR/closure_wf_outlives.rs:27:27
--> $DIR/closure_wf_outlives.rs:34:9
|
LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b;
| ^^^^^^^^^^^^^^^^^^^^
LL | || {}
| ^^^^^
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/closure_wf_outlives.rs:54:22
--> $DIR/closure_wf_outlives.rs:60:9
|
LL | type Opaque<T> = impl Sized;
| ^^^^^^^^^^
| |
| the parameter type `T` must be valid for the static lifetime...
| ...so that the type `T` will meet its required lifetime bounds...
LL | || {}
| ^^^^^
| |
| the parameter type `T` must be valid for the static lifetime...
| ...so that the type `T` will meet its required lifetime bounds...
|
note: ...that is required by this bound
--> $DIR/closure_wf_outlives.rs:59:12
--> $DIR/closure_wf_outlives.rs:58:12
|
LL | T: 'static,
| ^^^^^^^

View File

@ -4,6 +4,16 @@ error[E0277]: `T` doesn't implement `Debug`
LL | t
| ^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
note: required by a bound in an opaque type
--> $DIR/generic_duplicate_param_use2.rs:8:23
|
LL | type Two<T, U> = impl Debug;
| ^^^^^
note: this definition site has more where clauses than the opaque type
--> $DIR/generic_duplicate_param_use2.rs:10:1
|
LL | fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider restricting type parameter `T`
|
LL | type Two<T: std::fmt::Debug, U> = impl Debug;

View File

@ -9,10 +9,9 @@ fn main() {}
fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
t
//~^ ERROR `T` doesn't implement `Debug`
}
fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
u
//~^ ERROR `U` doesn't implement `Debug`
//~^ ERROR concrete type differs
}

View File

@ -1,25 +1,14 @@
error[E0277]: `T` doesn't implement `Debug`
error: concrete type differs from previous defining opaque type use
--> $DIR/generic_duplicate_param_use3.rs:15:5
|
LL | u
| ^ expected `T`, got `U`
|
note: previous use here
--> $DIR/generic_duplicate_param_use3.rs:11:5
|
LL | t
| ^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
help: consider restricting type parameter `T`
|
LL | type Two<T: std::fmt::Debug, U> = impl Debug;
| +++++++++++++++++
| ^
error[E0277]: `U` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use3.rs:16:5
|
LL | u
| ^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
help: consider restricting type parameter `U`
|
LL | type Two<T, U: std::fmt::Debug> = impl Debug;
| +++++++++++++++++
error: aborting due to 1 previous error
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -4,6 +4,16 @@ error[E0277]: `U` doesn't implement `Debug`
LL | u
| ^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
note: required by a bound in an opaque type
--> $DIR/generic_duplicate_param_use4.rs:8:23
|
LL | type Two<T, U> = impl Debug;
| ^^^^^
note: this definition site has more where clauses than the opaque type
--> $DIR/generic_duplicate_param_use4.rs:10:1
|
LL | fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider restricting type parameter `U`
|
LL | type Two<T, U: std::fmt::Debug> = impl Debug;

View File

@ -9,12 +9,9 @@ fn main() {}
fn two<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
(t, u)
//~^ ERROR `T` doesn't implement `Debug`
//~| ERROR `U` doesn't implement `Debug`
}
fn three<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
(u, t)
//~^ ERROR `T` doesn't implement `Debug`
//~| ERROR `U` doesn't implement `Debug`
//~^ ERROR concrete type differs
}

View File

@ -1,51 +1,14 @@
error[E0277]: `T` doesn't implement `Debug`
error: concrete type differs from previous defining opaque type use
--> $DIR/generic_duplicate_param_use5.rs:15:5
|
LL | (u, t)
| ^^^^^^ expected `(T, U)`, got `(U, T)`
|
note: previous use here
--> $DIR/generic_duplicate_param_use5.rs:11:5
|
LL | (t, u)
| ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required for `(T, U)` to implement `Debug`
help: consider restricting type parameter `T`
|
LL | type Two<T: std::fmt::Debug, U> = impl Debug;
| +++++++++++++++++
| ^^^^^^
error[E0277]: `U` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use5.rs:11:5
|
LL | (t, u)
| ^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required for `(T, U)` to implement `Debug`
help: consider restricting type parameter `U`
|
LL | type Two<T, U: std::fmt::Debug> = impl Debug;
| +++++++++++++++++
error: aborting due to 1 previous error
error[E0277]: `U` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use5.rs:17:5
|
LL | (u, t)
| ^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required for `(U, T)` to implement `Debug`
help: consider restricting type parameter `U`
|
LL | type Two<T, U: std::fmt::Debug> = impl Debug;
| +++++++++++++++++
error[E0277]: `T` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use5.rs:17:5
|
LL | (u, t)
| ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required for `(U, T)` to implement `Debug`
help: consider restricting type parameter `T`
|
LL | type Two<T: std::fmt::Debug, U> = impl Debug;
| +++++++++++++++++
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -9,11 +9,9 @@ fn main() {}
fn two<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
(t, t)
//~^ ERROR `T` doesn't implement `Debug`
}
fn three<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
(u, t)
//~^ ERROR `T` doesn't implement `Debug`
//~| ERROR `U` doesn't implement `Debug`
//~^ ERROR concrete type differs
}

View File

@ -1,39 +1,14 @@
error[E0277]: `T` doesn't implement `Debug`
error: concrete type differs from previous defining opaque type use
--> $DIR/generic_duplicate_param_use6.rs:15:5
|
LL | (u, t)
| ^^^^^^ expected `(T, T)`, got `(U, T)`
|
note: previous use here
--> $DIR/generic_duplicate_param_use6.rs:11:5
|
LL | (t, t)
| ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required for `(T, T)` to implement `Debug`
help: consider restricting type parameter `T`
|
LL | type Two<T: std::fmt::Debug, U> = impl Debug;
| +++++++++++++++++
| ^^^^^^
error[E0277]: `U` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use6.rs:16:5
|
LL | (u, t)
| ^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required for `(U, T)` to implement `Debug`
help: consider restricting type parameter `U`
|
LL | type Two<T, U: std::fmt::Debug> = impl Debug;
| +++++++++++++++++
error: aborting due to 1 previous error
error[E0277]: `T` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use6.rs:16:5
|
LL | (u, t)
| ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required for `(U, T)` to implement `Debug`
help: consider restricting type parameter `T`
|
LL | type Two<T: std::fmt::Debug, U> = impl Debug;
| +++++++++++++++++
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -8,10 +8,9 @@ fn main() {}
fn two<T: Debug, U: Debug>(t: T, _: U) -> Two<T, U> {
(t, 4u32)
//~^ ERROR `T` doesn't implement `Debug`
}
fn three<T: Debug, U: Debug>(_: T, u: U) -> Two<T, U> {
(u, 4u32)
//~^ ERROR `U` doesn't implement `Debug`
//~^ concrete type differs
}

View File

@ -1,27 +1,14 @@
error[E0277]: `T` doesn't implement `Debug`
error: concrete type differs from previous defining opaque type use
--> $DIR/generic_duplicate_param_use8.rs:14:5
|
LL | (u, 4u32)
| ^^^^^^^^^ expected `(T, u32)`, got `(U, u32)`
|
note: previous use here
--> $DIR/generic_duplicate_param_use8.rs:10:5
|
LL | (t, 4u32)
| ^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required for `(T, u32)` to implement `Debug`
help: consider restricting type parameter `T`
|
LL | type Two<T: std::fmt::Debug, U> = impl Debug;
| +++++++++++++++++
| ^^^^^^^^^
error[E0277]: `U` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use8.rs:15:5
|
LL | (u, 4u32)
| ^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required for `(U, u32)` to implement `Debug`
help: consider restricting type parameter `U`
|
LL | type Two<T, U: std::fmt::Debug> = impl Debug;
| +++++++++++++++++
error: aborting due to 1 previous error
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -13,13 +13,9 @@ trait Foo {
fn two<T: Debug + Foo, U: Debug>(t: T, u: U) -> Two<T, U> {
(t, u, T::BAR)
//~^ ERROR the trait bound `A: Foo` is not satisfied
//~| ERROR `A` doesn't implement `Debug`
//~| ERROR `B` doesn't implement `Debug`
}
fn three<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
(t, u, 42)
//~^ ERROR `A` doesn't implement `Debug`
//~| ERROR `B` doesn't implement `Debug`
//~^ ERROR concrete type differs
}

View File

@ -1,62 +1,14 @@
error[E0277]: the trait bound `A: Foo` is not satisfied
--> $DIR/generic_duplicate_param_use9.rs:15:5
|
LL | (t, u, T::BAR)
| ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A`
|
help: consider restricting type parameter `A`
|
LL | type Two<A: Foo, B> = impl Debug;
| +++++
error[E0277]: `A` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use9.rs:15:5
|
LL | (t, u, T::BAR)
| ^^^^^^^^^^^^^^ `A` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required for `(A, B, _)` to implement `Debug`
help: consider restricting type parameter `A`
|
LL | type Two<A: std::fmt::Debug, B> = impl Debug;
| +++++++++++++++++
error[E0277]: `B` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use9.rs:15:5
|
LL | (t, u, T::BAR)
| ^^^^^^^^^^^^^^ `B` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required for `(A, B, _)` to implement `Debug`
help: consider restricting type parameter `B`
|
LL | type Two<A, B: std::fmt::Debug> = impl Debug;
| +++++++++++++++++
error[E0277]: `A` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use9.rs:22:5
error: concrete type differs from previous defining opaque type use
--> $DIR/generic_duplicate_param_use9.rs:19:5
|
LL | (t, u, 42)
| ^^^^^^^^^^ `A` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| ^^^^^^^^^^ expected `(A, B, <A as Foo>::Bar)`, got `(A, B, i32)`
|
= note: required for `(A, B, i32)` to implement `Debug`
help: consider restricting type parameter `A`
note: previous use here
--> $DIR/generic_duplicate_param_use9.rs:15:5
|
LL | type Two<A: std::fmt::Debug, B> = impl Debug;
| +++++++++++++++++
LL | (t, u, T::BAR)
| ^^^^^^^^^^^^^^
error[E0277]: `B` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use9.rs:22:5
|
LL | (t, u, 42)
| ^^^^^^^^^^ `B` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required for `(A, B, i32)` to implement `Debug`
help: consider restricting type parameter `B`
|
LL | type Two<A, B: std::fmt::Debug> = impl Debug;
| +++++++++++++++++
error: aborting due to 1 previous error
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -21,6 +21,20 @@ LL | impl<T: Proj<Assoc = i32> + Copy> Copy for Bar<T> {}
| ----------- ^^^^ ^^^^^^
| |
| unsatisfied trait bound introduced here
note: required by a bound in an opaque type
--> $DIR/hidden_type_mismatch.rs:36:26
|
LL | pub type Tait = impl Copy + From<Bar<()>> + Into<Bar<()>>;
| ^^^^
note: this definition site has more where clauses than the opaque type
--> $DIR/hidden_type_mismatch.rs:37:5
|
LL | / pub fn define_tait() -> Tait
LL | | where
LL | | // this proves `Bar<()>: Copy`, but `define_tait` is
LL | | // now uncallable
LL | | (): Proj<Assoc = i32>,
| |______________________________^
error: aborting due to 1 previous error

View File

@ -2,9 +2,9 @@
mod test_type_param_static {
pub type Ty<A> = impl Sized + 'static;
//~^ ERROR: the parameter type `A` may not live long enough
fn defining<A: 'static>(s: A) -> Ty<A> {
s
//~^ ERROR: the parameter type `A` may not live long enough
}
pub fn assert_static<A: 'static>() {}
}

View File

@ -1,12 +1,17 @@
error[E0310]: the parameter type `A` may not live long enough
--> $DIR/implied_lifetime_wf_check4_static.rs:4:22
--> $DIR/implied_lifetime_wf_check4_static.rs:6:9
|
LL | s
| ^
| |
| the parameter type `A` must be valid for the static lifetime...
| ...so that the type `A` will meet its required lifetime bounds...
|
note: ...that is required by this bound
--> $DIR/implied_lifetime_wf_check4_static.rs:4:35
|
LL | pub type Ty<A> = impl Sized + 'static;
| ^^^^^^^^^^^^^^^^^^^^
| |
| the parameter type `A` must be valid for the static lifetime...
| ...so that the type `A` will meet its required lifetime bounds
|
| ^^^^^^^
help: consider adding an explicit lifetime bound
|
LL | pub type Ty<A: 'static> = impl Sized + 'static;

View File

@ -4,6 +4,16 @@ error[E0277]: the trait bound `T: Default` is not satisfied
LL | t
| ^ the trait `Default` is not implemented for `T`
|
note: required by a bound in an opaque type
--> $DIR/issue-52843.rs:3:20
|
LL | type Foo<T> = impl Default;
| ^^^^^^^
note: this definition site has more where clauses than the opaque type
--> $DIR/issue-52843.rs:6:1
|
LL | fn foo<T: Default>(t: T) -> Foo<T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider restricting type parameter `T`
|
LL | type Foo<T: std::default::Default> = impl Default;

View File

@ -4,11 +4,23 @@ error[E0277]: the trait bound `B: Bar` is not satisfied
LL | MyBaz(bar)
| ^^^^^^^^^^ the trait `Bar` is not implemented for `B`
|
note: required by a bound in `MyBaz`
--> $DIR/issue-90400-2.rs:29:17
note: required for `MyBaz<B>` to implement `Baz`
--> $DIR/issue-90400-2.rs:30:14
|
LL | struct MyBaz<B: Bar>(B);
| ^^^ required by this bound in `MyBaz`
LL | impl<B: Bar> Baz for MyBaz<B> {
| --- ^^^ ^^^^^^^^
| |
| unsatisfied trait bound introduced here
note: required by a bound in an opaque type
--> $DIR/issue-90400-2.rs:22:26
|
LL | type FooFn<B> = impl Baz;
| ^^^
note: this definition site has more where clauses than the opaque type
--> $DIR/issue-90400-2.rs:24:5
|
LL | fn foo<B: Bar>(&self, bar: B) -> Self::FooFn<B> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider restricting type parameter `B`
|
LL | type FooFn<B: Bar> = impl Baz;

View File

@ -8,7 +8,6 @@ fn main() {}
fn three<T: Debug, U>(t: T) -> Two<T, U> {
(t, 5i8)
//~^ ERROR `T` doesn't implement `Debug`
}
trait Bar {
@ -23,8 +22,7 @@ impl Bar for u32 {
fn four<T: Debug, U: Bar>(t: T) -> Two<T, U> {
(t, <U as Bar>::FOO)
//~^ ERROR `U: Bar` is not satisfied
//~| ERROR `T` doesn't implement `Debug`
//~^ ERROR concrete type differs
}
fn is_sync<T: Sync>() {}

View File

@ -1,38 +1,14 @@
error[E0277]: `T` doesn't implement `Debug`
error: concrete type differs from previous defining opaque type use
--> $DIR/not_a_defining_use.rs:24:5
|
LL | (t, <U as Bar>::FOO)
| ^^^^^^^^^^^^^^^^^^^^ expected `(T, i8)`, got `(T, <U as Bar>::Blub)`
|
note: previous use here
--> $DIR/not_a_defining_use.rs:10:5
|
LL | (t, 5i8)
| ^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required for `(T, i8)` to implement `Debug`
help: consider restricting type parameter `T`
|
LL | type Two<T: std::fmt::Debug, U> = impl Debug;
| +++++++++++++++++
| ^^^^^^^^
error[E0277]: the trait bound `U: Bar` is not satisfied
--> $DIR/not_a_defining_use.rs:25:5
|
LL | (t, <U as Bar>::FOO)
| ^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `U`
|
help: consider restricting type parameter `U`
|
LL | type Two<T, U: Bar> = impl Debug;
| +++++
error: aborting due to 1 previous error
error[E0277]: `T` doesn't implement `Debug`
--> $DIR/not_a_defining_use.rs:25:5
|
LL | (t, <U as Bar>::FOO)
| ^^^^^^^^^^^^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required for `(T, _)` to implement `Debug`
help: consider restricting type parameter `T`
|
LL | type Two<T: std::fmt::Debug, U> = impl Debug;
| +++++++++++++++++
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -11,6 +11,16 @@ LL | impl<X: Trait> ProofForConversion<X> for () {
| ----- ^^^^^^^^^^^^^^^^^^^^^ ^^
| |
| unsatisfied trait bound introduced here
note: required by a bound in an opaque type
--> $DIR/underconstrained_generic.rs:19:26
|
LL | type Converter<T> = impl ProofForConversion<T>;
| ^^^^^^^^^^^^^^^^^^^^^
note: this definition site has more where clauses than the opaque type
--> $DIR/underconstrained_generic.rs:21:1
|
LL | fn _defining_use<T: Trait>() -> Converter<T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider restricting type parameter `T`
|
LL | type Converter<T: Trait> = impl ProofForConversion<T>;

View File

@ -13,11 +13,11 @@ fn convert<T: ?Sized>(_: PhantomData<Self>, r: &'a T) -> &'b T {
}
type Converter<'a, 'b> = impl ProofForConversion<'a, 'b>;
//~^ ERROR reference has a longer lifetime than the data it references
// Even _defining_use with an explicit `'a: 'b` compiles fine, too.
fn _defining_use<'a, 'b>(x: &'b &'a ()) -> Converter<'a, 'b> {
x
//~^ ERROR reference has a longer lifetime than the data it references
}
fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T {

View File

@ -1,8 +1,8 @@
error[E0491]: in type `&'b &'a ()`, reference has a longer lifetime than the data it references
--> $DIR/underconstrained_lifetime.rs:15:26
--> $DIR/underconstrained_lifetime.rs:19:5
|
LL | type Converter<'a, 'b> = impl ProofForConversion<'a, 'b>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | x
| ^
|
note: the pointer is valid for the lifetime `'b` as defined here
--> $DIR/underconstrained_lifetime.rs:15:20

View File

@ -1,23 +1,30 @@
error[E0309]: the parameter type `T` may not live long enough
--> $DIR/wf-in-associated-type.rs:38:23
--> $DIR/wf-in-associated-type.rs:40:13
|
LL | impl<'a, T> Trait<'a, T> for () {
| -- the parameter type `T` must be valid for the lifetime `'a` as defined here...
LL | type Opaque = impl Sized + 'a;
| ^^^^^^^^^^^^^^^ ...so that the type `&'a T` will meet its required lifetime bounds
...
LL | req
| ^^^ ...so that the type `&'a T` will meet its required lifetime bounds...
|
note: ...that is required by this bound
--> $DIR/wf-in-associated-type.rs:38:36
|
LL | type Opaque = impl Sized + 'a;
| ^^
help: consider adding an explicit lifetime bound
|
LL | impl<'a, T: 'a> Trait<'a, T> for () {
| ++++
error[E0309]: the parameter type `T` may not live long enough
--> $DIR/wf-in-associated-type.rs:38:23
--> $DIR/wf-in-associated-type.rs:40:13
|
LL | impl<'a, T> Trait<'a, T> for () {
| -- the parameter type `T` must be valid for the lifetime `'a` as defined here...
LL | type Opaque = impl Sized + 'a;
| ^^^^^^^^^^^^^^^ ...so that the reference type `&'a T` does not outlive the data it points at
...
LL | req
| ^^^ ...so that the reference type `&'a T` does not outlive the data it points at
|
help: consider adding an explicit lifetime bound
|

View File

@ -36,10 +36,10 @@ trait Trait<'a, T> {
impl<'a, T> Trait<'a, T> for () {
type Opaque = impl Sized + 'a;
//[fail]~^ ERROR the parameter type `T` may not live long enough
//[fail]~| ERROR the parameter type `T` may not live long enough
fn constrain_opaque(req: &'a T) -> Self::Opaque {
req
//[fail]~^ ERROR the parameter type `T` may not live long enough
//[fail]~| ERROR the parameter type `T` may not live long enough
}
}
}