-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #119989 - lcnr:sub_relations-bye-bye, r=compiler-errors
remove `sub_relations` from the `InferCtxt` While doing so, I tried to remove the `delay_span_bug` in `rematch_impl` again, which lead me to discover another `freshen` bug, fixing that one in the second commit. See commit descriptions for the reasoning behind each change. r? `@compiler-errors`
- Loading branch information
Showing
47 changed files
with
409 additions
and
455 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
81 changes: 81 additions & 0 deletions
81
compiler/rustc_infer/src/infer/error_reporting/sub_relations.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
use rustc_data_structures::fx::FxHashMap; | ||
use rustc_data_structures::undo_log::NoUndo; | ||
use rustc_data_structures::unify as ut; | ||
use rustc_middle::ty; | ||
|
||
use crate::infer::InferCtxt; | ||
|
||
#[derive(Debug, Copy, Clone, PartialEq)] | ||
struct SubId(u32); | ||
impl ut::UnifyKey for SubId { | ||
type Value = (); | ||
#[inline] | ||
fn index(&self) -> u32 { | ||
self.0 | ||
} | ||
#[inline] | ||
fn from_index(i: u32) -> SubId { | ||
SubId(i) | ||
} | ||
fn tag() -> &'static str { | ||
"SubId" | ||
} | ||
} | ||
|
||
/// When reporting ambiguity errors, we sometimes want to | ||
/// treat all inference vars which are subtypes of each | ||
/// others as if they are equal. For this case we compute | ||
/// the transitive closure of our subtype obligations here. | ||
/// | ||
/// E.g. when encountering ambiguity errors, we want to suggest | ||
/// specifying some method argument or to add a type annotation | ||
/// to a local variable. Because subtyping cannot change the | ||
/// shape of a type, it's fine if the cause of the ambiguity error | ||
/// is only related to the suggested variable via subtyping. | ||
/// | ||
/// Even for something like `let x = returns_arg(); x.method();` the | ||
/// type of `x` is only a supertype of the argument of `returns_arg`. We | ||
/// still want to suggest specifying the type of the argument. | ||
#[derive(Default)] | ||
pub struct SubRelations { | ||
map: FxHashMap<ty::TyVid, SubId>, | ||
table: ut::UnificationTableStorage<SubId>, | ||
} | ||
|
||
impl SubRelations { | ||
fn get_id<'tcx>(&mut self, infcx: &InferCtxt<'tcx>, vid: ty::TyVid) -> SubId { | ||
let root_vid = infcx.root_var(vid); | ||
*self.map.entry(root_vid).or_insert_with(|| self.table.with_log(&mut NoUndo).new_key(())) | ||
} | ||
|
||
pub fn add_constraints<'tcx>( | ||
&mut self, | ||
infcx: &InferCtxt<'tcx>, | ||
obls: impl IntoIterator<Item = ty::Predicate<'tcx>>, | ||
) { | ||
for p in obls { | ||
let (a, b) = match p.kind().skip_binder() { | ||
ty::PredicateKind::Subtype(ty::SubtypePredicate { a_is_expected: _, a, b }) => { | ||
(a, b) | ||
} | ||
ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => (a, b), | ||
_ => continue, | ||
}; | ||
|
||
match (a.kind(), b.kind()) { | ||
(&ty::Infer(ty::TyVar(a_vid)), &ty::Infer(ty::TyVar(b_vid))) => { | ||
let a = self.get_id(infcx, a_vid); | ||
let b = self.get_id(infcx, b_vid); | ||
self.table.with_log(&mut NoUndo).unify_var_var(a, b).unwrap(); | ||
} | ||
_ => continue, | ||
} | ||
} | ||
} | ||
|
||
pub fn unified<'tcx>(&mut self, infcx: &InferCtxt<'tcx>, a: ty::TyVid, b: ty::TyVid) -> bool { | ||
let a = self.get_id(infcx, a); | ||
let b = self.get_id(infcx, b); | ||
self.table.with_log(&mut NoUndo).unioned(a, b) | ||
} | ||
} |
Oops, something went wrong.