Skip to content

Commit 50148a9

Browse files
authoredDec 6, 2018
Rollup merge of rust-lang#56446 - arielb1:special-env-implications, r=nikomatsakis
pass the parameter environment to `traits::find_associated_item` dropping the param-env on the floor is obviously the wrong thing to do. The ICE was probably exposed by rust-lang#54490 adding the problem-exposing use of `traits::find_associated_item`. Fixes rust-lang#55380. r? @nikomatsakis

File tree

4 files changed

+54
-5
lines changed

4 files changed

+54
-5
lines changed
 

‎src/librustc/traits/specialize/mod.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ pub fn translate_substs<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
8585
source_substs: &'tcx Substs<'tcx>,
8686
target_node: specialization_graph::Node)
8787
-> &'tcx Substs<'tcx> {
88+
debug!("translate_substs({:?}, {:?}, {:?}, {:?})",
89+
param_env, source_impl, source_substs, target_node);
8890
let source_trait_ref = infcx.tcx
8991
.impl_trait_ref(source_impl)
9092
.unwrap()
@@ -119,10 +121,13 @@ pub fn translate_substs<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
119121
/// whichever applies.
120122
pub fn find_associated_item<'a, 'tcx>(
121123
tcx: TyCtxt<'a, 'tcx, 'tcx>,
124+
param_env: ty::ParamEnv<'tcx>,
122125
item: &ty::AssociatedItem,
123126
substs: &'tcx Substs<'tcx>,
124127
impl_data: &super::VtableImplData<'tcx, ()>,
125128
) -> (DefId, &'tcx Substs<'tcx>) {
129+
debug!("find_associated_item({:?}, {:?}, {:?}, {:?})",
130+
param_env, item, substs, impl_data);
126131
assert!(!substs.needs_infer());
127132

128133
let trait_def_id = tcx.trait_id_of_impl(impl_data.impl_def_id).unwrap();
@@ -132,7 +137,7 @@ pub fn find_associated_item<'a, 'tcx>(
132137
match ancestors.defs(tcx, item.ident, item.kind, trait_def_id).next() {
133138
Some(node_item) => {
134139
let substs = tcx.infer_ctxt().enter(|infcx| {
135-
let param_env = ty::ParamEnv::reveal_all();
140+
let param_env = param_env.with_reveal_all();
136141
let substs = substs.rebase_onto(tcx, trait_def_id, impl_data.substs);
137142
let substs = translate_substs(&infcx, param_env, impl_data.impl_def_id,
138143
substs, node_item.node);
@@ -219,12 +224,17 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
219224
source_trait_ref: ty::TraitRef<'tcx>,
220225
target_impl: DefId)
221226
-> Result<&'tcx Substs<'tcx>, ()> {
227+
debug!("fulfill_implication({:?}, trait_ref={:?} |- {:?} applies)",
228+
param_env, source_trait_ref, target_impl);
229+
222230
let selcx = &mut SelectionContext::new(&infcx);
223231
let target_substs = infcx.fresh_substs_for_item(DUMMY_SP, target_impl);
224232
let (target_trait_ref, mut obligations) = impl_trait_ref_and_oblig(selcx,
225233
param_env,
226234
target_impl,
227235
target_substs);
236+
debug!("fulfill_implication: target_trait_ref={:?}, obligations={:?}",
237+
target_trait_ref, obligations);
228238

229239
// do the impls unify? If not, no specialization.
230240
match infcx.at(&ObligationCause::dummy(), param_env)

‎src/librustc/traits/structural_impls.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for traits::Obligation<'tcx, O> {
3333
if ty::tls::with(|tcx| tcx.sess.verbose()) {
3434
write!(
3535
f,
36-
"Obligation(predicate={:?},cause={:?},depth={})",
37-
self.predicate, self.cause, self.recursion_depth
36+
"Obligation(predicate={:?},cause={:?},param_env={:?},depth={})",
37+
self.predicate, self.cause, self.param_env, self.recursion_depth
3838
)
3939
} else {
4040
write!(

‎src/librustc/ty/instance.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -347,9 +347,10 @@ fn resolve_associated_item<'a, 'tcx>(
347347
) -> Option<Instance<'tcx>> {
348348
let def_id = trait_item.def_id;
349349
debug!("resolve_associated_item(trait_item={:?}, \
350+
param_env={:?}, \
350351
trait_id={:?}, \
351352
rcvr_substs={:?})",
352-
def_id, trait_id, rcvr_substs);
353+
def_id, param_env, trait_id, rcvr_substs);
353354

354355
let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs);
355356
let vtbl = tcx.codegen_fulfill_obligation((param_env, ty::Binder::bind(trait_ref)));
@@ -359,7 +360,7 @@ fn resolve_associated_item<'a, 'tcx>(
359360
match vtbl {
360361
traits::VtableImpl(impl_data) => {
361362
let (def_id, substs) = traits::find_associated_item(
362-
tcx, trait_item, rcvr_substs, &impl_data);
363+
tcx, param_env, trait_item, rcvr_substs, &impl_data);
363364
let substs = tcx.erase_regions(&substs);
364365
Some(ty::Instance::new(def_id, substs))
365366
}

‎src/test/run-pass/issue-55380.rs

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// run-pass
12+
13+
#![feature(specialization)]
14+
15+
pub trait Foo {
16+
fn abc() -> u32;
17+
fn def() -> u32;
18+
}
19+
20+
pub trait Marker {}
21+
22+
impl Marker for () {}
23+
24+
impl<T> Foo for T {
25+
default fn abc() -> u32 { 16 }
26+
default fn def() -> u32 { 42 }
27+
}
28+
29+
impl<T: Marker> Foo for T {
30+
fn def() -> u32 {
31+
Self::abc()
32+
}
33+
}
34+
35+
fn main() {
36+
assert_eq!(<()>::def(), 16);
37+
assert_eq!(<i32>::def(), 42);
38+
}

0 commit comments

Comments
 (0)
Please sign in to comment.