Skip to content

Commit

Permalink
Rollup merge of rust-lang#121743 - compiler-errors:opportunistically-…
Browse files Browse the repository at this point in the history
…resolve-regions, r=jackh726

Opportunistically resolve regions when processing region outlives obligations

Due to the matching in `TypeOutlives` being structural, we should attempt to opportunistically resolve regions before processing region obligations. Thanks `@lcnr` for finding this.

r? lcnr
  • Loading branch information
GuillaumeGomez authored Feb 28, 2024
2 parents 74fbbaa + 5cdbe83 commit 1c10897
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 18 deletions.
10 changes: 9 additions & 1 deletion compiler/rustc_infer/src/infer/outlives/obligations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,17 @@
use crate::infer::outlives::components::{push_outlives_components, Component};
use crate::infer::outlives::env::RegionBoundPairs;
use crate::infer::outlives::verify::VerifyBoundCx;
use crate::infer::resolve::OpportunisticRegionResolver;
use crate::infer::{
self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, UndoLog, VerifyBound,
};
use crate::traits::{ObligationCause, ObligationCauseCode};
use rustc_data_structures::undo_log::UndoLogs;
use rustc_middle::mir::ConstraintCategory;
use rustc_middle::traits::query::NoSolution;
use rustc_middle::ty::{self, GenericArgsRef, Region, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::ty::{
self, GenericArgsRef, Region, Ty, TyCtxt, TypeFoldable as _, TypeVisitableExt,
};
use rustc_middle::ty::{GenericArgKind, PolyTypeOutlivesPredicate};
use rustc_span::DUMMY_SP;
use smallvec::smallvec;
Expand Down Expand Up @@ -176,6 +179,11 @@ impl<'tcx> InferCtxt<'tcx> {
.map_err(|NoSolution| (outlives, origin.clone()))?
.no_bound_vars()
.expect("started with no bound vars, should end with no bound vars");
// `TypeOutlives` is structural, so we should try to opportunistically resolve all
// region vids before processing regions, so we have a better chance to match clauses
// in our param-env.
let (sup_type, sub_region) =
(sup_type, sub_region).fold_with(&mut OpportunisticRegionResolver::new(self));

debug!(?sup_type, ?sub_region, ?origin);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub trait MessageListenersInterface {

impl<'a> MessageListenersInterface for MessageListeners<'a> {
fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
//~^ ERROR cannot infer an appropriate lifetime for lifetime parameter 'b in generic type due to conflicting requirements
//~^ ERROR in type `&'a MessageListeners<'_>`, reference has a longer lifetime than the data it references
self
}
}
Expand Down
20 changes: 4 additions & 16 deletions tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr
Original file line number Diff line number Diff line change
@@ -1,32 +1,20 @@
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'b in generic type due to conflicting requirements
error[E0491]: in type `&'a MessageListeners<'_>`, reference has a longer lifetime than the data it references
--> $DIR/impl-implied-bounds-compatibility.rs:12:5
|
LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'c` as defined here...
--> $DIR/impl-implied-bounds-compatibility.rs:12:5
|
LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that the method type is compatible with trait
--> $DIR/impl-implied-bounds-compatibility.rs:12:5
|
LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected `fn(&'c MessageListeners<'_>) -> &'c MessageListeners<'c>`
found `fn(&MessageListeners<'_>) -> &'a MessageListeners<'_>`
note: but, the lifetime must be valid for the lifetime `'a` as defined here...
note: the pointer is valid for the lifetime `'a` as defined here
--> $DIR/impl-implied-bounds-compatibility.rs:11:6
|
LL | impl<'a> MessageListenersInterface for MessageListeners<'a> {
| ^^
note: ...so that the reference type `&'a MessageListeners<'_>` does not outlive the data it points at
note: but the referenced data is only valid for the lifetime `'c` as defined here
--> $DIR/impl-implied-bounds-compatibility.rs:12:5
|
LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0495`.
For more information about this error, try `rustc --explain E0491`.

0 comments on commit 1c10897

Please sign in to comment.