Rollup merge of #101578 - lcnr:resolve-hack, r=jackh726
remove bound var hack in `resolve` somehow dropped that change from #98900. r? `@jackh726`
This commit is contained in:
commit
2386ed9962
@ -1202,14 +1202,11 @@ rustc_queries! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
query codegen_fulfill_obligation(
|
query codegen_select_candidate(
|
||||||
key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)
|
key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)
|
||||||
) -> Result<&'tcx ImplSource<'tcx, ()>, traits::CodegenObligationError> {
|
) -> Result<&'tcx ImplSource<'tcx, ()>, traits::CodegenObligationError> {
|
||||||
cache_on_disk_if { true }
|
cache_on_disk_if { true }
|
||||||
desc { |tcx|
|
desc { |tcx| "computing candidate for `{}`", key.1 }
|
||||||
"checking if `{}` fulfills its obligations",
|
|
||||||
tcx.def_path_str(key.1.def_id())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return all `impl` blocks in the current crate.
|
/// Return all `impl` blocks in the current crate.
|
||||||
|
@ -1024,7 +1024,7 @@ pub enum MethodViolationCode {
|
|||||||
UndispatchableReceiver(Option<Span>),
|
UndispatchableReceiver(Option<Span>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// These are the error cases for `codegen_fulfill_obligation`.
|
/// These are the error cases for `codegen_select_candidate`.
|
||||||
#[derive(Copy, Clone, Debug, Hash, HashStable, Encodable, Decodable)]
|
#[derive(Copy, Clone, Debug, Hash, HashStable, Encodable, Decodable)]
|
||||||
pub enum CodegenObligationError {
|
pub enum CodegenObligationError {
|
||||||
/// Ambiguity can happen when monomorphizing during trans
|
/// Ambiguity can happen when monomorphizing during trans
|
||||||
|
@ -35,7 +35,7 @@ fn custom_coerce_unsize_info<'tcx>(
|
|||||||
substs: tcx.mk_substs_trait(source_ty, &[target_ty.into()]),
|
substs: tcx.mk_substs_trait(source_ty, &[target_ty.into()]),
|
||||||
});
|
});
|
||||||
|
|
||||||
match tcx.codegen_fulfill_obligation((ty::ParamEnv::reveal_all(), trait_ref)) {
|
match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), trait_ref)) {
|
||||||
Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData {
|
Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData {
|
||||||
impl_def_id,
|
impl_def_id,
|
||||||
..
|
..
|
||||||
|
@ -18,7 +18,7 @@ use rustc_middle::ty::{self, TyCtxt};
|
|||||||
/// obligations *could be* resolved if we wanted to.
|
/// obligations *could be* resolved if we wanted to.
|
||||||
///
|
///
|
||||||
/// This also expects that `trait_ref` is fully normalized.
|
/// This also expects that `trait_ref` is fully normalized.
|
||||||
pub fn codegen_fulfill_obligation<'tcx>(
|
pub fn codegen_select_candidate<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
(param_env, trait_ref): (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>),
|
(param_env, trait_ref): (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>),
|
||||||
) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> {
|
) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> {
|
||||||
|
@ -971,7 +971,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
|
|||||||
*providers = ty::query::Providers {
|
*providers = ty::query::Providers {
|
||||||
specialization_graph_of: specialize::specialization_graph_provider,
|
specialization_graph_of: specialize::specialization_graph_provider,
|
||||||
specializes: specialize::specializes,
|
specializes: specialize::specializes,
|
||||||
codegen_fulfill_obligation: codegen::codegen_fulfill_obligation,
|
codegen_select_candidate: codegen::codegen_select_candidate,
|
||||||
own_existential_vtable_entries,
|
own_existential_vtable_entries,
|
||||||
vtable_entries,
|
vtable_entries,
|
||||||
vtable_trait_upcasting_coercion_new_vptr_slot,
|
vtable_trait_upcasting_coercion_new_vptr_slot,
|
||||||
|
@ -3,113 +3,11 @@ use rustc_hir::def_id::{DefId, LocalDefId};
|
|||||||
use rustc_infer::infer::TyCtxtInferExt;
|
use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_middle::traits::CodegenObligationError;
|
use rustc_middle::traits::CodegenObligationError;
|
||||||
use rustc_middle::ty::subst::SubstsRef;
|
use rustc_middle::ty::subst::SubstsRef;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{self, Instance, TyCtxt, TypeVisitable};
|
||||||
self, Binder, Instance, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor,
|
|
||||||
};
|
|
||||||
use rustc_span::{sym, DUMMY_SP};
|
use rustc_span::{sym, DUMMY_SP};
|
||||||
use rustc_trait_selection::traits;
|
use rustc_trait_selection::traits;
|
||||||
use traits::{translate_substs, Reveal};
|
use traits::{translate_substs, Reveal};
|
||||||
|
|
||||||
use rustc_data_structures::sso::SsoHashSet;
|
|
||||||
use std::collections::btree_map::Entry;
|
|
||||||
use std::collections::BTreeMap;
|
|
||||||
use std::ops::ControlFlow;
|
|
||||||
|
|
||||||
// FIXME(#86795): `BoundVarsCollector` here should **NOT** be used
|
|
||||||
// outside of `resolve_associated_item`. It's just to address #64494,
|
|
||||||
// #83765, and #85848 which are creating bound types/regions that lose
|
|
||||||
// their `Binder` *unintentionally*.
|
|
||||||
// It's ideal to remove `BoundVarsCollector` and just use
|
|
||||||
// `ty::Binder::*` methods but we use this stopgap until we figure out
|
|
||||||
// the "real" fix.
|
|
||||||
struct BoundVarsCollector<'tcx> {
|
|
||||||
binder_index: ty::DebruijnIndex,
|
|
||||||
vars: BTreeMap<u32, ty::BoundVariableKind>,
|
|
||||||
// We may encounter the same variable at different levels of binding, so
|
|
||||||
// this can't just be `Ty`
|
|
||||||
visited: SsoHashSet<(ty::DebruijnIndex, Ty<'tcx>)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> BoundVarsCollector<'tcx> {
|
|
||||||
fn new() -> Self {
|
|
||||||
BoundVarsCollector {
|
|
||||||
binder_index: ty::INNERMOST,
|
|
||||||
vars: BTreeMap::new(),
|
|
||||||
visited: SsoHashSet::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_vars(self, tcx: TyCtxt<'tcx>) -> &'tcx ty::List<ty::BoundVariableKind> {
|
|
||||||
let max = self.vars.iter().map(|(k, _)| *k).max().unwrap_or(0);
|
|
||||||
for i in 0..max {
|
|
||||||
if let None = self.vars.get(&i) {
|
|
||||||
panic!("Unknown variable: {:?}", i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tcx.mk_bound_variable_kinds(self.vars.into_iter().map(|(_, v)| v))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> {
|
|
||||||
type BreakTy = ();
|
|
||||||
|
|
||||||
fn visit_binder<T: TypeVisitable<'tcx>>(
|
|
||||||
&mut self,
|
|
||||||
t: &Binder<'tcx, T>,
|
|
||||||
) -> ControlFlow<Self::BreakTy> {
|
|
||||||
self.binder_index.shift_in(1);
|
|
||||||
let result = t.super_visit_with(self);
|
|
||||||
self.binder_index.shift_out(1);
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
|
||||||
if t.outer_exclusive_binder() < self.binder_index
|
|
||||||
|| !self.visited.insert((self.binder_index, t))
|
|
||||||
{
|
|
||||||
return ControlFlow::CONTINUE;
|
|
||||||
}
|
|
||||||
match *t.kind() {
|
|
||||||
ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => {
|
|
||||||
match self.vars.entry(bound_ty.var.as_u32()) {
|
|
||||||
Entry::Vacant(entry) => {
|
|
||||||
entry.insert(ty::BoundVariableKind::Ty(bound_ty.kind));
|
|
||||||
}
|
|
||||||
Entry::Occupied(entry) => match entry.get() {
|
|
||||||
ty::BoundVariableKind::Ty(_) => {}
|
|
||||||
_ => bug!("Conflicting bound vars"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => (),
|
|
||||||
};
|
|
||||||
|
|
||||||
t.super_visit_with(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
|
||||||
match *r {
|
|
||||||
ty::ReLateBound(index, br) if index == self.binder_index => {
|
|
||||||
match self.vars.entry(br.var.as_u32()) {
|
|
||||||
Entry::Vacant(entry) => {
|
|
||||||
entry.insert(ty::BoundVariableKind::Region(br.kind));
|
|
||||||
}
|
|
||||||
Entry::Occupied(entry) => match entry.get() {
|
|
||||||
ty::BoundVariableKind::Region(_) => {}
|
|
||||||
_ => bug!("Conflicting bound vars"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => (),
|
|
||||||
};
|
|
||||||
|
|
||||||
r.super_visit_with(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_instance<'tcx>(
|
fn resolve_instance<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)>,
|
key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)>,
|
||||||
@ -201,19 +99,14 @@ fn resolve_associated_item<'tcx>(
|
|||||||
|
|
||||||
let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs);
|
let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs);
|
||||||
|
|
||||||
// See FIXME on `BoundVarsCollector`.
|
let vtbl = match tcx.codegen_select_candidate((param_env, ty::Binder::dummy(trait_ref))) {
|
||||||
let mut bound_vars_collector = BoundVarsCollector::new();
|
|
||||||
trait_ref.visit_with(&mut bound_vars_collector);
|
|
||||||
let trait_binder = ty::Binder::bind_with_vars(trait_ref, bound_vars_collector.into_vars(tcx));
|
|
||||||
let vtbl = match tcx.codegen_fulfill_obligation((param_env, trait_binder)) {
|
|
||||||
Ok(vtbl) => vtbl,
|
Ok(vtbl) => vtbl,
|
||||||
Err(CodegenObligationError::Ambiguity) => {
|
Err(CodegenObligationError::Ambiguity) => {
|
||||||
let reported = tcx.sess.delay_span_bug(
|
let reported = tcx.sess.delay_span_bug(
|
||||||
tcx.def_span(trait_item_id),
|
tcx.def_span(trait_item_id),
|
||||||
&format!(
|
&format!(
|
||||||
"encountered ambiguity selecting `{:?}` during codegen, presuming due to \
|
"encountered ambiguity selecting `{trait_ref:?}` during codegen, presuming due to \
|
||||||
overflow or prior type error",
|
overflow or prior type error",
|
||||||
trait_binder
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
return Err(reported);
|
return Err(reported);
|
||||||
|
@ -4,13 +4,13 @@ error[E0391]: cycle detected when resolving instance `<LazyUpdim<T, { T::DIM },
|
|||||||
LL | const DIM: usize;
|
LL | const DIM: usize;
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: ...which requires checking if `TensorDimension` fulfills its obligations...
|
note: ...which requires computing candidate for `<LazyUpdim<T, { T::DIM }, DIM> as TensorDimension>`...
|
||||||
--> $DIR/issue-83765.rs:4:1
|
--> $DIR/issue-83765.rs:4:1
|
||||||
|
|
|
|
||||||
LL | trait TensorDimension {
|
LL | trait TensorDimension {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
= note: ...which again requires resolving instance `<LazyUpdim<T, { T::DIM }, DIM> as TensorDimension>::DIM`, completing the cycle
|
= note: ...which again requires resolving instance `<LazyUpdim<T, { T::DIM }, DIM> as TensorDimension>::DIM`, completing the cycle
|
||||||
note: cycle used when checking if `TensorDimension` fulfills its obligations
|
note: cycle used when computing candidate for `<LazyUpdim<T, { T::DIM }, DIM> as TensorDimension>`
|
||||||
--> $DIR/issue-83765.rs:4:1
|
--> $DIR/issue-83765.rs:4:1
|
||||||
|
|
|
|
||||||
LL | trait TensorDimension {
|
LL | trait TensorDimension {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user