Skip to content

Commit e8910f5

Browse files
Sync Instance::resolve with the projection code
1 parent 103771c commit e8910f5

File tree

4 files changed

+40
-53
lines changed

4 files changed

+40
-53
lines changed

src/librustc_trait_selection/traits/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ pub use self::project::{
5454
};
5555
pub use self::select::{EvaluationCache, SelectionCache, SelectionContext};
5656
pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
57-
pub use self::specialize::find_associated_item;
5857
pub use self::specialize::specialization_graph::FutureCompatOverlapError;
5958
pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind;
6059
pub use self::specialize::{specialization_graph, translate_substs, OverlapError};

src/librustc_trait_selection/traits/project.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
10161016
.map_err(|ErrorReported| ())?;
10171017

10181018
if node_item.is_final() {
1019-
// Non-specializable items are always projectable
1019+
// Non-specializable items are always projectable.
10201020
true
10211021
} else {
10221022
// Only reveal a specializable default if we're past type-checking

src/librustc_trait_selection/traits/specialize/mod.rs

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc_errors::struct_span_err;
2020
use rustc_hir::def_id::DefId;
2121
use rustc_middle::lint::LintDiagnosticBuilder;
2222
use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
23-
use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
23+
use rustc_middle::ty::{self, TyCtxt};
2424
use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
2525
use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS;
2626
use rustc_span::DUMMY_SP;
@@ -112,48 +112,6 @@ pub fn translate_substs<'a, 'tcx>(
112112
source_substs.rebase_onto(infcx.tcx, source_impl, target_substs)
113113
}
114114

115-
/// Given a selected impl described by `impl_data`, returns the
116-
/// definition and substitutions for the method with the name `name`
117-
/// the kind `kind`, and trait method substitutions `substs`, in
118-
/// that impl, a less specialized impl, or the trait default,
119-
/// whichever applies.
120-
pub fn find_associated_item<'tcx>(
121-
tcx: TyCtxt<'tcx>,
122-
param_env: ty::ParamEnv<'tcx>,
123-
item: &ty::AssocItem,
124-
substs: SubstsRef<'tcx>,
125-
impl_data: &super::VtableImplData<'tcx, ()>,
126-
) -> (DefId, SubstsRef<'tcx>) {
127-
debug!("find_associated_item({:?}, {:?}, {:?}, {:?})", param_env, item, substs, impl_data);
128-
assert!(!substs.needs_infer());
129-
130-
let trait_def_id = tcx.trait_id_of_impl(impl_data.impl_def_id).unwrap();
131-
let trait_def = tcx.trait_def(trait_def_id);
132-
133-
if let Ok(ancestors) = trait_def.ancestors(tcx, impl_data.impl_def_id) {
134-
match ancestors.leaf_def(tcx, item.ident, item.kind) {
135-
Some(node_item) => {
136-
let substs = tcx.infer_ctxt().enter(|infcx| {
137-
let param_env = param_env.with_reveal_all();
138-
let substs = substs.rebase_onto(tcx, trait_def_id, impl_data.substs);
139-
let substs = translate_substs(
140-
&infcx,
141-
param_env,
142-
impl_data.impl_def_id,
143-
substs,
144-
node_item.defining_node,
145-
);
146-
infcx.tcx.erase_regions(&substs)
147-
});
148-
(node_item.item.def_id, substs)
149-
}
150-
None => bug!("{:?} not found in {:?}", item, impl_data.impl_def_id),
151-
}
152-
} else {
153-
(item.def_id, substs)
154-
}
155-
}
156-
157115
/// Is `impl1` a specialization of `impl2`?
158116
///
159117
/// Specialization is determined by the sets of types to which the impls apply;

src/librustc_ty/instance.rs

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
use rustc_hir::def_id::DefId;
22
use rustc_middle::ty::subst::SubstsRef;
33
use rustc_middle::ty::{self, Instance, TyCtxt, TypeFoldable};
4+
use rustc_infer::infer::TyCtxtInferExt;
45
use rustc_span::sym;
56
use rustc_target::spec::abi::Abi;
67
use rustc_trait_selection::traits;
8+
use traits::{Reveal, translate_substs};
79

810
use log::debug;
911

@@ -82,21 +84,49 @@ fn resolve_associated_item<'tcx>(
8284
// the actual function:
8385
match vtbl {
8486
traits::VtableImpl(impl_data) => {
85-
let (def_id, substs) =
86-
traits::find_associated_item(tcx, param_env, trait_item, rcvr_substs, &impl_data);
87-
88-
let resolved_item = tcx.associated_item(def_id);
87+
debug!(
88+
"resolving VtableImpl: {:?}, {:?}, {:?}, {:?}",
89+
param_env, trait_item, rcvr_substs, impl_data
90+
);
91+
assert!(!rcvr_substs.needs_infer());
92+
93+
let trait_def_id = tcx.trait_id_of_impl(impl_data.impl_def_id).unwrap();
94+
let trait_def = tcx.trait_def(trait_def_id);
95+
let leaf_def = trait_def
96+
.ancestors(tcx, impl_data.impl_def_id)
97+
.ok()?
98+
.leaf_def(tcx, trait_item.ident, trait_item.kind)
99+
.unwrap_or_else(|| {
100+
bug!("{:?} not found in {:?}", trait_item, impl_data.impl_def_id);
101+
});
102+
let def_id = leaf_def.item.def_id;
103+
104+
let substs = tcx.infer_ctxt().enter(|infcx| {
105+
let param_env = param_env.with_reveal_all();
106+
let substs = rcvr_substs.rebase_onto(tcx, trait_def_id, impl_data.substs);
107+
let substs = translate_substs(
108+
&infcx,
109+
param_env,
110+
impl_data.impl_def_id,
111+
substs,
112+
leaf_def.defining_node,
113+
);
114+
infcx.tcx.erase_regions(&substs)
115+
});
89116

90117
// Since this is a trait item, we need to see if the item is either a trait default item
91118
// or a specialization because we can't resolve those unless we can `Reveal::All`.
92119
// NOTE: This should be kept in sync with the similar code in
93120
// `rustc_middle::traits::project::assemble_candidates_from_impls()`.
94-
let eligible = if !resolved_item.defaultness.is_default() {
121+
let eligible = if leaf_def.is_final() {
122+
// Non-specializable items are always projectable.
95123
true
96-
} else if param_env.reveal == traits::Reveal::All {
97-
!trait_ref.needs_subst()
98124
} else {
99-
false
125+
// Only reveal a specializable default if we're past type-checking
126+
// and the obligation is monomorphic, otherwise passes such as
127+
// transmute checking and polymorphic MIR optimizations could
128+
// get a result which isn't correct for all monomorphizations.
129+
if param_env.reveal == Reveal::All { !trait_ref.needs_subst() } else { false }
100130
};
101131

102132
if !eligible {

0 commit comments

Comments
 (0)