Skip to content

Commit 8727a68

Browse files
authored
Unrolled build for #146711
Rollup merge of #146711 - lcnr:fix-placeholder-ice, r=lqd fix 2 borrowck issues fixes #146467 cc ``@amandasystems`` our understanding here is as follows: region constraints from computing implied bounds gets `ConstraintCategory::Internal`. If there's a higher-ranked subtyping errors while computing implied bounds we then ended up with only `ConstraintCategory::Internal` and `ConstraintCategory::OutlivesUnnameablePlaceholder(_)` constraints. The path was something like - `'placeholderU2: 'placeholderU1` (`Internal`) - `'placeholderU1: 'static` (`OutlivesUnnameablePlaceholder('placeholderU2)`) It's generally somewhat subtle here as ideally relating placeholders doesn't introduce `'static` constraints. Relating the placeholders themselves will always error regardless, cc #142623. --- separately fixes #145925 (comment) by updating the location for deferred closure requirements inside of promoteds. I am not updating their category as doing so is 1) effort and 2) imo actually undesirable 🤔 see the comments in `TypeChecker::check_promoted` cc ``@lqd`` r? lqd
2 parents 15283f6 + 3378997 commit 8727a68

File tree

6 files changed

+97
-3
lines changed

6 files changed

+97
-3
lines changed

compiler/rustc_borrowck/src/region_infer/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,9 +1736,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
17361736
// `BoringNoLocation` constraints can point to user-written code, but are less
17371737
// specific, and are not used for relations that would make sense to blame.
17381738
ConstraintCategory::BoringNoLocation => 6,
1739-
// Do not blame internal constraints.
1740-
ConstraintCategory::OutlivesUnnameablePlaceholder(_) => 7,
1741-
ConstraintCategory::Internal => 8,
1739+
// Do not blame internal constraints if we can avoid it. Never blame
1740+
// the `'region: 'static` constraints introduced by placeholder outlives.
1741+
ConstraintCategory::Internal => 7,
1742+
ConstraintCategory::OutlivesUnnameablePlaceholder(_) => 8,
17421743
};
17431744

17441745
debug!("constraint {constraint:?} category: {category:?}, interest: {interest:?}");

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,13 +505,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
505505
let mut constraints = Default::default();
506506
let mut liveness_constraints =
507507
LivenessValues::without_specific_points(Rc::new(DenseLocationMap::new(promoted_body)));
508+
let mut deferred_closure_requirements = Default::default();
508509

509510
// Don't try to add borrow_region facts for the promoted MIR as they refer
510511
// to the wrong locations.
511512
let mut swap_constraints = |this: &mut Self| {
512513
mem::swap(this.polonius_facts, polonius_facts);
513514
mem::swap(&mut this.constraints.outlives_constraints, &mut constraints);
514515
mem::swap(&mut this.constraints.liveness_constraints, &mut liveness_constraints);
516+
mem::swap(this.deferred_closure_requirements, &mut deferred_closure_requirements);
515517
};
516518

517519
swap_constraints(self);
@@ -536,6 +538,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
536538
}
537539
self.constraints.outlives_constraints.push(constraint)
538540
}
541+
542+
// If there are nested bodies in promoteds, we also need to update their
543+
// location to something in the actual body, not the promoted.
544+
//
545+
// We don't update the constraint categories of the resulting constraints
546+
// as returns in nested bodies are a proper return, even if that nested body
547+
// is in a promoted.
548+
for (closure_def_id, args, _locations) in deferred_closure_requirements {
549+
self.deferred_closure_requirements.push((closure_def_id, args, locations));
550+
}
551+
539552
// If the region is live at least one location in the promoted MIR,
540553
// then add a liveness constraint to the main MIR for this region
541554
// at the location provided as an argument to this method
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//@ compile-flags: -Zdeduplicate-diagnostics=yes
2+
3+
// Regression test for #146467.
4+
#![feature(inherent_associated_types)]
5+
//~^ WARN the feature `inherent_associated_types` is incomplete
6+
7+
struct Foo<T>(T);
8+
9+
impl<'a> Foo<fn(&())> {
10+
//~^ ERROR the lifetime parameter `'a` is not constrained by the impl trait
11+
type Assoc = &'a ();
12+
}
13+
14+
fn foo(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {}
15+
//~^ ERROR mismatched types
16+
//~| ERROR higher-ranked subtype error
17+
fn main() {}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
warning: the feature `inherent_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/hr-do-not-blame-outlives-static-ice.rs:4:12
3+
|
4+
LL | #![feature(inherent_associated_types)]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
11+
--> $DIR/hr-do-not-blame-outlives-static-ice.rs:9:6
12+
|
13+
LL | impl<'a> Foo<fn(&())> {
14+
| ^^ unconstrained lifetime parameter
15+
16+
error[E0308]: mismatched types
17+
--> $DIR/hr-do-not-blame-outlives-static-ice.rs:14:11
18+
|
19+
LL | fn foo(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {}
20+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
21+
|
22+
= note: expected struct `Foo<for<'a> fn(&'a ())>`
23+
found struct `Foo<for<'a> fn(&'a ())>`
24+
25+
error: higher-ranked subtype error
26+
--> $DIR/hr-do-not-blame-outlives-static-ice.rs:14:1
27+
|
28+
LL | fn foo(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {}
29+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
30+
31+
error: aborting due to 3 previous errors; 1 warning emitted
32+
33+
Some errors have detailed explanations: E0207, E0308.
34+
For more information about an error, try `rustc --explain E0207`.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//@ compile-flags: -Zdeduplicate-diagnostics=yes
2+
3+
// Regression test for #146467.
4+
trait Trait { type Assoc; }
5+
6+
impl Trait for fn(&()) { type Assoc = (); }
7+
8+
fn f(_: for<'a> fn(<fn(&'a ()) as Trait>::Assoc)) {}
9+
//~^ ERROR implementation of `Trait` is not general enough
10+
//~| ERROR higher-ranked subtype error
11+
12+
fn main() {}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error: implementation of `Trait` is not general enough
2+
--> $DIR/do-not-blame-outlives-static-ice.rs:8:9
3+
|
4+
LL | fn f(_: for<'a> fn(<fn(&'a ()) as Trait>::Assoc)) {}
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough
6+
|
7+
= note: `for<'a> fn(&'a ())` must implement `Trait`, for any lifetime `'0`...
8+
= note: ...but `Trait` is actually implemented for the type `for<'a> fn(&'a ())`
9+
10+
error: higher-ranked subtype error
11+
--> $DIR/do-not-blame-outlives-static-ice.rs:8:1
12+
|
13+
LL | fn f(_: for<'a> fn(<fn(&'a ()) as Trait>::Assoc)) {}
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15+
16+
error: aborting due to 2 previous errors
17+

0 commit comments

Comments
 (0)