Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions compiler/rustc_borrowck/src/region_infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1726,9 +1726,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// `BoringNoLocation` constraints can point to user-written code, but are less
// specific, and are not used for relations that would make sense to blame.
ConstraintCategory::BoringNoLocation => 6,
// Do not blame internal constraints.
ConstraintCategory::OutlivesUnnameablePlaceholder(_) => 7,
ConstraintCategory::Internal => 8,
// Do not blame internal constraints if we can avoid it. Never blame
// the `'region: 'static` constraints introduced by placeholder outlives.
ConstraintCategory::Internal => 7,
ConstraintCategory::OutlivesUnnameablePlaceholder(_) => 8,
};

debug!("constraint {constraint:?} category: {category:?}, interest: {interest:?}");
Expand Down
13 changes: 13 additions & 0 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,13 +505,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let mut constraints = Default::default();
let mut liveness_constraints =
LivenessValues::without_specific_points(Rc::new(DenseLocationMap::new(promoted_body)));
let mut deferred_closure_requirements = Default::default();

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

swap_constraints(self);
Expand All @@ -536,6 +538,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
self.constraints.outlives_constraints.push(constraint)
}

// If there are nested bodies in promoteds, we also need to update their
// location to something in the actually body, not the promoted.
//
// We don't update the constraint categories of the resulting constraints
// as returns in nested bodies are a proper return, even if that nested body
// is in a promoted.
for (closure_def_id, args, _locations) in deferred_closure_requirements {
self.deferred_closure_requirements.push((closure_def_id, args, locations));
}

// If the region is live at least one location in the promoted MIR,
// then add a liveness constraint to the main MIR for this region
// at the location provided as an argument to this method
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//@ compile-flags: -Zdeduplicate-diagnostics=yes

// Regression test for #146467.
#![feature(inherent_associated_types)]
//~^ WARN the feature `inherent_associated_types` is incomplete

struct Foo<T>(T);

impl<'a> Foo<fn(&())> {
//~^ ERROR the lifetime parameter `'a` is not constrained by the impl trait
type Assoc = &'a ();
}

fn foo(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {}
//~^ ERROR mismatched types
//~| ERROR higher-ranked subtype error
fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
warning: the feature `inherent_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/hr-do-not-blame-outlives-static-ice.rs:4:12
|
LL | #![feature(inherent_associated_types)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information
= note: `#[warn(incomplete_features)]` on by default

error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
--> $DIR/hr-do-not-blame-outlives-static-ice.rs:9:6
|
LL | impl<'a> Foo<fn(&())> {
| ^^ unconstrained lifetime parameter

error[E0308]: mismatched types
--> $DIR/hr-do-not-blame-outlives-static-ice.rs:14:11
|
LL | fn foo(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected struct `Foo<for<'a> fn(&'a ())>`
found struct `Foo<for<'a> fn(&'a ())>`

error: higher-ranked subtype error
--> $DIR/hr-do-not-blame-outlives-static-ice.rs:14:1
|
LL | fn foo(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 3 previous errors; 1 warning emitted

Some errors have detailed explanations: E0207, E0308.
For more information about an error, try `rustc --explain E0207`.
12 changes: 12 additions & 0 deletions tests/ui/higher-ranked/do-not-blame-outlives-static-ice.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//@ compile-flags: -Zdeduplicate-diagnostics=yes

// Regression test for #146467.
trait Trait { type Assoc; }

impl Trait for fn(&()) { type Assoc = (); }

fn f(_: for<'a> fn(<fn(&'a ()) as Trait>::Assoc)) {}
//~^ ERROR implementation of `Trait` is not general enough
//~| ERROR higher-ranked subtype error

fn main() {}
17 changes: 17 additions & 0 deletions tests/ui/higher-ranked/do-not-blame-outlives-static-ice.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error: implementation of `Trait` is not general enough
--> $DIR/do-not-blame-outlives-static-ice.rs:8:9
|
LL | fn f(_: for<'a> fn(<fn(&'a ()) as Trait>::Assoc)) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough
|
= note: `for<'a> fn(&'a ())` must implement `Trait`, for any lifetime `'0`...
= note: ...but `Trait` is actually implemented for the type `for<'a> fn(&'a ())`

error: higher-ranked subtype error
--> $DIR/do-not-blame-outlives-static-ice.rs:8:1
|
LL | fn f(_: for<'a> fn(<fn(&'a ()) as Trait>::Assoc)) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

Loading