diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 4f1eb6169209b..a4e3b664e9412 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -214,6 +214,7 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> { .into_iter() .map(|e| to_fulfillment_error(e)) .collect(); + debug!("select_all_or_error: errors={:?}", errors); if errors.is_empty() { Ok(()) } else { diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index c690bebed8c00..61af10167546b 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -472,13 +472,21 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let ret = match self.candidate_from_obligation(&stack)? { None => None, Some(candidate) => { + debug!("select: candidate={:?}", candidate); let mut candidate = self.confirm_candidate(obligation, candidate)?; - let inferred_obligations = (*self.inferred_obligations).into_iter().cloned(); + debug!("select: confirmed candidate={:?}", candidate); + let inferred_obligations: Vec<_> = + (*self.inferred_obligations).into_iter().cloned().collect(); + debug!("select: inferred_obligations={:?}", inferred_obligations); + debug!("select: candidate.nested_obligations={:?}", + candidate.nested_obligations_mut()); candidate.nested_obligations_mut().extend(inferred_obligations); Some(candidate) }, }; + debug!("select: ret={:?}", ret); + // Test whether this is a `()` which was produced by defaulting a // diverging type variable with `!` disabled. If so, we may need // to raise a warning. @@ -1420,8 +1428,36 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { -> bool { assert!(!skol_trait_ref.has_escaping_regions()); + debug!("match_projection: obligation={:?}, trait_bound={:?}", + obligation, trait_bound); + + let Normalized { value: normal_bound, obligations } = + normalize_with_depth( + self, + obligation.param_env.clone(), + obligation.cause.clone(), + obligation.recursion_depth, + &trait_bound); + debug!("match_projection: \ + normal_bound={:?}, \ + additional inferred_obligations={:?}", + normal_bound, obligations); + + let Normalized { value: normal_skol_trait_ref, obligations } = + normalize_with_depth( + self, + obligation.param_env.clone(), + obligation.cause.clone(), + obligation.recursion_depth, + &skol_trait_ref); + debug!("match_projection: \ + normal_skol_trait_ref={:?}, \ + additional inferred_obligations={:?}", + normal_skol_trait_ref, obligations); + self.inferred_obligations.extend(obligations); + match self.infcx.at(&obligation.cause, obligation.param_env) - .sup(ty::Binder(skol_trait_ref), trait_bound) { + .sup(ty::Binder(normal_skol_trait_ref), normal_bound) { Ok(InferOk { obligations, .. }) => { self.inferred_obligations.extend(obligations); } diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 46e5510296652..3f10a521f93d6 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -247,6 +247,8 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, infcx.save_and_restore_in_snapshot_flag(|infcx| { let mut fulfill_cx = FulfillmentContext::new(); for oblig in obligations.into_iter() { + debug!("fulfill_implication: registering obligation {:?}", + oblig); fulfill_cx.register_predicate_obligation(&infcx, oblig); } match fulfill_cx.select_all_or_error(infcx) { diff --git a/src/test/run-pass/issue-43475.rs b/src/test/run-pass/issue-43475.rs new file mode 100644 index 0000000000000..aef3b3e175da3 --- /dev/null +++ b/src/test/run-pass/issue-43475.rs @@ -0,0 +1,31 @@ +// Copyright 2014 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. + +trait Foo { + type FooT: Foo; +} + +impl Foo for () { + type FooT = (); +} + +trait Bar { + type BarT: Bar; +} + +impl Bar<()> for () { + type BarT = (); +} + +fn test>() {} + +fn main() { + test::<()>() +}