diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 7b5e1498f26..6e23c842191 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -60,12 +60,19 @@ pub fn obligations<'a, 'tcx>( GenericArgKind::Lifetime(..) => return Some(Vec::new()), }; - let mut wf = - WfPredicates { infcx, param_env, body_id, span, out: vec![], recursion_depth, item: None }; + let mut wf = WfPredicates { + tcx: infcx.tcx, + param_env, + body_id, + span, + out: vec![], + recursion_depth, + item: None, + }; wf.compute(arg); debug!("wf::obligations({:?}, body_id={:?}) = {:?}", arg, body_id, wf.out); - let result = wf.normalize(); + let result = wf.normalize(infcx); debug!("wf::obligations({:?}, body_id={:?}) ~~> {:?}", arg, body_id, result); Some(result) } @@ -83,7 +90,7 @@ pub fn trait_obligations<'a, 'tcx>( item: &'tcx hir::Item<'tcx>, ) -> Vec> { let mut wf = WfPredicates { - infcx, + tcx: infcx.tcx, param_env, body_id, span, @@ -93,7 +100,7 @@ pub fn trait_obligations<'a, 'tcx>( }; wf.compute_trait_ref(trait_ref, Elaborate::All); debug!(obligations = ?wf.out); - wf.normalize() + wf.normalize(infcx) } pub fn predicate_obligations<'a, 'tcx>( @@ -104,7 +111,7 @@ pub fn predicate_obligations<'a, 'tcx>( span: Span, ) -> Vec> { let mut wf = WfPredicates { - infcx, + tcx: infcx.tcx, param_env, body_id, span, @@ -159,11 +166,11 @@ pub fn predicate_obligations<'a, 'tcx>( } } - wf.normalize() + wf.normalize(infcx) } -struct WfPredicates<'a, 'tcx> { - infcx: &'a InferCtxt<'a, 'tcx>, +struct WfPredicates<'tcx> { + tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, body_id: hir::HirId, span: Span, @@ -260,18 +267,17 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>( } } -impl<'a, 'tcx> WfPredicates<'a, 'tcx> { +impl<'tcx> WfPredicates<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { - self.infcx.tcx + self.tcx } fn cause(&self, code: traits::ObligationCauseCode<'tcx>) -> traits::ObligationCause<'tcx> { traits::ObligationCause::new(self.span, self.body_id, code) } - fn normalize(mut self) -> Vec> { + fn normalize(self, infcx: &InferCtxt<'_, 'tcx>) -> Vec> { let cause = self.cause(traits::WellFormed(None)); - let infcx = &mut self.infcx; let param_env = self.param_env; let mut obligations = Vec::with_capacity(self.out.len()); for mut obligation in self.out { @@ -296,7 +302,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { /// Pushes the obligations required for `trait_ref` to be WF into `self.out`. fn compute_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>, elaborate: Elaborate) { - let tcx = self.infcx.tcx; + let tcx = self.tcx; let obligations = self.nominal_obligations(trait_ref.def_id, trait_ref.substs); debug!("compute_trait_ref obligations {:?}", obligations); @@ -410,14 +416,14 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { if !subty.has_escaping_bound_vars() { let cause = self.cause(cause); let trait_ref = ty::TraitRef { - def_id: self.infcx.tcx.require_lang_item(LangItem::Sized, None), - substs: self.infcx.tcx.mk_substs_trait(subty, &[]), + def_id: self.tcx.require_lang_item(LangItem::Sized, None), + substs: self.tcx.mk_substs_trait(subty, &[]), }; self.out.push(traits::Obligation::with_depth( cause, self.recursion_depth, self.param_env, - ty::Binder::dummy(trait_ref).without_const().to_predicate(self.infcx.tcx), + ty::Binder::dummy(trait_ref).without_const().to_predicate(self.tcx), )); } } @@ -452,26 +458,16 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { predicate, )); } - ty::ConstKind::Infer(infer) => { - let resolved = self.infcx.shallow_resolve(infer); - // the `InferConst` changed, meaning that we made progress. - if resolved != infer { - let cause = self.cause(traits::WellFormed(None)); + ty::ConstKind::Infer(_) => { + let cause = self.cause(traits::WellFormed(None)); - let resolved_constant = self.infcx.tcx.mk_const(ty::ConstS { - kind: ty::ConstKind::Infer(resolved), - ty: constant.ty(), - }); - self.out.push(traits::Obligation::with_depth( - cause, - self.recursion_depth, - self.param_env, - ty::Binder::dummy(ty::PredicateKind::WellFormed( - resolved_constant.into(), - )) + self.out.push(traits::Obligation::with_depth( + cause, + self.recursion_depth, + self.param_env, + ty::Binder::dummy(ty::PredicateKind::WellFormed(constant.into())) .to_predicate(self.tcx()), - )); - } + )); } ty::ConstKind::Error(_) | ty::ConstKind::Param(_) @@ -627,7 +623,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { // of whatever returned this exact `impl Trait`. // for named opaque `impl Trait` types we still need to check them - if ty::is_impl_trait_defn(self.infcx.tcx, did).is_none() { + if ty::is_impl_trait_defn(self.tcx, did).is_none() { let obligations = self.nominal_obligations(did, substs); self.out.extend(obligations); } @@ -675,22 +671,14 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { // See also the comment on `fn obligations`, describing "livelock" // prevention, which happens before this can be reached. ty::Infer(_) => { - let ty = self.infcx.shallow_resolve(ty); - if let ty::Infer(ty::TyVar(_)) = ty.kind() { - // Not yet resolved, but we've made progress. - let cause = self.cause(traits::WellFormed(None)); - self.out.push(traits::Obligation::with_depth( - cause, - self.recursion_depth, - param_env, - ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())) - .to_predicate(self.tcx()), - )); - } else { - // Yes, resolved, proceed with the result. - // FIXME(eddyb) add the type to `walker` instead of recursing. - self.compute(ty.into()); - } + let cause = self.cause(traits::WellFormed(None)); + self.out.push(traits::Obligation::with_depth( + cause, + self.recursion_depth, + param_env, + ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())) + .to_predicate(self.tcx()), + )); } } } @@ -701,15 +689,15 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { def_id: DefId, substs: SubstsRef<'tcx>, ) -> Vec> { - let predicates = self.infcx.tcx.predicates_of(def_id); + let predicates = self.tcx.predicates_of(def_id); let mut origins = vec![def_id; predicates.predicates.len()]; let mut head = predicates; while let Some(parent) = head.parent { - head = self.infcx.tcx.predicates_of(parent); + head = self.tcx.predicates_of(parent); origins.extend(iter::repeat(parent).take(head.predicates.len())); } - let predicates = predicates.instantiate(self.infcx.tcx, substs); + let predicates = predicates.instantiate(self.tcx, substs); debug_assert_eq!(predicates.predicates.len(), origins.len()); iter::zip(iter::zip(predicates.predicates, predicates.spans), origins.into_iter().rev()) @@ -764,7 +752,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { // Note: in fact we only permit builtin traits, not `Bar<'d>`, I // am looking forward to the future here. if !data.has_escaping_bound_vars() && !region.has_escaping_bound_vars() { - let implicit_bounds = object_region_bounds(self.infcx.tcx, data); + let implicit_bounds = object_region_bounds(self.tcx, data); let explicit_bound = region; @@ -777,7 +765,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { cause, self.recursion_depth, self.param_env, - outlives.to_predicate(self.infcx.tcx), + outlives.to_predicate(self.tcx), )); } } diff --git a/src/test/ui/issues/issue-98299.stderr b/src/test/ui/issues/issue-98299.stderr index a61bffa91e7..fd905392a21 100644 --- a/src/test/ui/issues/issue-98299.stderr +++ b/src/test/ui/issues/issue-98299.stderr @@ -1,8 +1,13 @@ -error[E0282]: type annotations needed - --> $DIR/issue-98299.rs:4:5 +error[E0282]: type annotations needed for `SmallCString` + --> $DIR/issue-98299.rs:4:36 | LL | SmallCString::try_from(p).map(|cstr| cstr); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for enum `Result, ()>` + | ^^^^ + | +help: consider giving this closure parameter an explicit type, where the the value of const parameter `N` is specified + | +LL | SmallCString::try_from(p).map(|cstr: SmallCString| cstr); + | +++++++++++++++++ error: aborting due to previous error