@@ -1730,38 +1730,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1730
1730
None
1731
1731
}
1732
1732
1733
- /// Find a path of outlives constraints from `from` to `to`,
1734
- /// taking placeholder blame constraints into account, e.g.
1735
- /// if there is a relationship where `r1` reaches `r2` and
1736
- /// r2 has a larger universe or if r1 and r2 both come from
1737
- /// placeholder regions.
1738
- ///
1739
- /// Returns the path. It panics if there is no such path.
1740
- fn path_to_modulo_placeholders (
1741
- & self ,
1742
- from : RegionVid ,
1743
- to : RegionVid ,
1744
- ) -> Vec < OutlivesConstraint < ' tcx > > {
1745
- let path = self . constraint_path_between_regions ( from, to) . unwrap ( ) ;
1746
-
1747
- // If we are looking for a path to 'static, and we are passing
1748
- // through a constraint synthesised from an illegal placeholder
1749
- // relation, redirect the search to the placeholder to blame.
1750
- // FIXME: the performance of this is Not Great, and the logic
1751
- // should be folded into the search itself if possible.
1752
- for constraint in path. iter ( ) {
1753
- let ConstraintCategory :: IllegalPlaceholder ( cl_fr, culprit) = constraint. category else {
1754
- continue ;
1755
- } ;
1756
-
1757
- debug ! ( "{culprit:?} is the reason {from:?}: 'static!" ) ;
1758
- return self . constraint_path_to ( cl_fr, |r| r == culprit, false ) . unwrap ( ) . 0 ;
1759
- }
1760
-
1761
- // No funny business; just return the path!
1762
- path
1763
- }
1764
-
1765
1733
/// Finds some region R such that `fr1: R` and `R` is live at `location`.
1766
1734
#[ instrument( skip( self ) , level = "trace" , ret) ]
1767
1735
pub ( crate ) fn find_sub_region_live_at ( & self , fr1 : RegionVid , location : Location ) -> RegionVid {
@@ -1823,8 +1791,24 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1823
1791
to_region : RegionVid ,
1824
1792
) -> ( BlameConstraint < ' tcx > , Vec < OutlivesConstraint < ' tcx > > ) {
1825
1793
assert ! ( from_region != to_region, "Trying to blame a region for itself!" ) ;
1826
- // Find all paths
1827
- let path = self . path_to_modulo_placeholders ( from_region, to_region) ;
1794
+
1795
+ let path = self . constraint_path_between_regions ( from_region, to_region) . unwrap ( ) ;
1796
+
1797
+ // If we are passing through a constraint added because `'lt: 'unnameable`,
1798
+ // where cannot name `'unnameable`, redirect search towards `'unnameable`.
1799
+ let path = if let Some ( ( lt, unnameable) ) = path. iter ( ) . find_map ( |c| {
1800
+ if let ConstraintCategory :: OutlivesUnnameablePlaceholder ( lt, unnameable) = c. category {
1801
+ Some ( ( lt, unnameable) )
1802
+ } else {
1803
+ None
1804
+ }
1805
+ } ) {
1806
+ // This the `false` argument is what prevents circular reasoning here!
1807
+ self . constraint_path_to ( lt, |r| r == unnameable, false ) . unwrap ( ) . 0
1808
+ } else {
1809
+ path
1810
+ } ;
1811
+
1828
1812
debug ! (
1829
1813
"path={:#?}" ,
1830
1814
path. iter( )
@@ -1965,7 +1949,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1965
1949
// specific, and are not used for relations that would make sense to blame.
1966
1950
ConstraintCategory :: BoringNoLocation => 6 ,
1967
1951
// Do not blame internal constraints.
1968
- ConstraintCategory :: IllegalPlaceholder ( _, _) => 7 ,
1952
+ ConstraintCategory :: OutlivesUnnameablePlaceholder ( _, _) => 7 ,
1969
1953
ConstraintCategory :: Internal => 8 ,
1970
1954
} ;
1971
1955
@@ -2003,7 +1987,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
2003
1987
} ;
2004
1988
2005
1989
assert ! (
2006
- !matches!( best_constraint. category, ConstraintCategory :: IllegalPlaceholder ( _, _) ) ,
1990
+ !matches!(
1991
+ best_constraint. category,
1992
+ ConstraintCategory :: OutlivesUnnameablePlaceholder ( _, _)
1993
+ ) ,
2007
1994
"Illegal placeholder constraint blamed; should have redirected to other region relation"
2008
1995
) ;
2009
1996
0 commit comments