diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 19ef3171b13fc..cb17246b15f11 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -85,6 +85,8 @@ pub fn translate_substs<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, source_substs: &'tcx Substs<'tcx>, target_node: specialization_graph::Node) -> &'tcx Substs<'tcx> { + debug!("translate_substs({:?}, {:?}, {:?}, {:?})", + param_env, source_impl, source_substs, target_node); let source_trait_ref = infcx.tcx .impl_trait_ref(source_impl) .unwrap() @@ -119,10 +121,13 @@ pub fn translate_substs<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, /// whichever applies. pub fn find_associated_item<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, + param_env: ty::ParamEnv<'tcx>, item: &ty::AssociatedItem, substs: &'tcx Substs<'tcx>, impl_data: &super::VtableImplData<'tcx, ()>, ) -> (DefId, &'tcx Substs<'tcx>) { + debug!("find_associated_item({:?}, {:?}, {:?}, {:?})", + param_env, item, substs, impl_data); assert!(!substs.needs_infer()); 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>( match ancestors.defs(tcx, item.ident, item.kind, trait_def_id).next() { Some(node_item) => { let substs = tcx.infer_ctxt().enter(|infcx| { - let param_env = ty::ParamEnv::reveal_all(); + let param_env = param_env.with_reveal_all(); let substs = substs.rebase_onto(tcx, trait_def_id, impl_data.substs); let substs = translate_substs(&infcx, param_env, impl_data.impl_def_id, substs, node_item.node); @@ -219,12 +224,17 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, source_trait_ref: ty::TraitRef<'tcx>, target_impl: DefId) -> Result<&'tcx Substs<'tcx>, ()> { + debug!("fulfill_implication({:?}, trait_ref={:?} |- {:?} applies)", + param_env, source_trait_ref, target_impl); + let selcx = &mut SelectionContext::new(&infcx); let target_substs = infcx.fresh_substs_for_item(DUMMY_SP, target_impl); let (target_trait_ref, mut obligations) = impl_trait_ref_and_oblig(selcx, param_env, target_impl, target_substs); + debug!("fulfill_implication: target_trait_ref={:?}, obligations={:?}", + target_trait_ref, obligations); // do the impls unify? If not, no specialization. match infcx.at(&ObligationCause::dummy(), param_env) diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 36538ac0889de..36e93cc774089 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -33,8 +33,8 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for traits::Obligation<'tcx, O> { if ty::tls::with(|tcx| tcx.sess.verbose()) { write!( f, - "Obligation(predicate={:?},cause={:?},depth={})", - self.predicate, self.cause, self.recursion_depth + "Obligation(predicate={:?},cause={:?},param_env={:?},depth={})", + self.predicate, self.cause, self.param_env, self.recursion_depth ) } else { write!( diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 411a6e7e6238e..a24920da158e2 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -347,9 +347,10 @@ fn resolve_associated_item<'a, 'tcx>( ) -> Option> { let def_id = trait_item.def_id; debug!("resolve_associated_item(trait_item={:?}, \ + param_env={:?}, \ trait_id={:?}, \ rcvr_substs={:?})", - def_id, trait_id, rcvr_substs); + def_id, param_env, trait_id, rcvr_substs); let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs); let vtbl = tcx.codegen_fulfill_obligation((param_env, ty::Binder::bind(trait_ref))); @@ -359,7 +360,7 @@ fn resolve_associated_item<'a, 'tcx>( match vtbl { traits::VtableImpl(impl_data) => { let (def_id, substs) = traits::find_associated_item( - tcx, trait_item, rcvr_substs, &impl_data); + tcx, param_env, trait_item, rcvr_substs, &impl_data); let substs = tcx.erase_regions(&substs); Some(ty::Instance::new(def_id, substs)) } diff --git a/src/test/run-pass/issue-55380.rs b/src/test/run-pass/issue-55380.rs new file mode 100644 index 0000000000000..29392fba8b475 --- /dev/null +++ b/src/test/run-pass/issue-55380.rs @@ -0,0 +1,38 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// run-pass + +#![feature(specialization)] + +pub trait Foo { + fn abc() -> u32; + fn def() -> u32; +} + +pub trait Marker {} + +impl Marker for () {} + +impl Foo for T { + default fn abc() -> u32 { 16 } + default fn def() -> u32 { 42 } +} + +impl Foo for T { + fn def() -> u32 { + Self::abc() + } +} + +fn main() { + assert_eq!(<()>::def(), 16); + assert_eq!(::def(), 42); +}