diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 960a1bfdd2d57..88198a886bfdf 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1084,15 +1084,42 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { where I: Iterator>, { - let mut matching_candidates = all_candidates().filter(|r| { - self.trait_defines_associated_item_named(r.def_id(), ty::AssocKind::Type, assoc_name) - }); - let mut const_candidates = all_candidates().filter(|r| { - self.trait_defines_associated_item_named(r.def_id(), ty::AssocKind::Const, assoc_name) - }); + let mut matching_candidates = all_candidates() + .filter(|r| { + self.trait_defines_associated_item_named( + r.def_id(), + ty::AssocKind::Type, + assoc_name, + ) + }) + // For the purposes of an associated type, we only care + // about supertraits where the host effect is set to true. + .filter(|trait_ref| { + let tcx = self.tcx(); + let generics = tcx.generics_of(trait_ref.def_id()); + generics.host_effect_index.map_or(true, |idx| { + trait_ref.skip_binder().args.const_at(idx) == tcx.consts.true_ + }) + }); + let mut const_candidates = all_candidates() + .filter(|r| { + self.trait_defines_associated_item_named( + r.def_id(), + ty::AssocKind::Const, + assoc_name, + ) + }) + // For the purposes of an associated const, we only care + // about supertraits where the host effect is set to true. + .filter(|trait_ref| { + let tcx = self.tcx(); + let generics = tcx.generics_of(trait_ref.def_id()); + generics.host_effect_index.map_or(true, |idx| { + trait_ref.skip_binder().args.const_at(idx) == tcx.consts.true_ + }) + }); - let (mut bound, mut next_cand) = match (matching_candidates.next(), const_candidates.next()) - { + let (bound, next_cand) = match (matching_candidates.next(), const_candidates.next()) { (Some(bound), _) => (bound, matching_candidates.next()), (None, Some(bound)) => (bound, const_candidates.next()), (None, None) => { @@ -1108,37 +1135,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }; debug!(?bound); - // look for a candidate that is not the same as our first bound, disregarding - // whether the bound is const. - while let Some(mut bound2) = next_cand { - debug!(?bound2); - let tcx = self.tcx(); - if bound2.bound_vars() != bound.bound_vars() { - break; - } - - let generics = tcx.generics_of(bound.def_id()); - let Some(host_index) = generics.host_effect_index else { break }; - - // always return the bound that contains the host param. - if let ty::ConstKind::Param(_) = bound2.skip_binder().args.const_at(host_index).kind() { - (bound, bound2) = (bound2, bound); - } - - let unconsted_args = bound - .skip_binder() - .args - .iter() - .enumerate() - .map(|(n, arg)| if host_index == n { tcx.consts.true_.into() } else { arg }); - - if unconsted_args.eq(bound2.skip_binder().args.iter()) { - next_cand = matching_candidates.next().or_else(|| const_candidates.next()); - } else { - break; - } - } - if let Some(bound2) = next_cand { debug!(?bound2); @@ -1226,9 +1222,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { assoc_name: Ident, span: Span, ) -> Result, ErrorGuaranteed> { - let mut matching_candidates = all_candidates.filter(|r| { - self.trait_defines_associated_item_named(r.def_id(), ty::AssocKind::Fn, assoc_name) - }); + let mut matching_candidates = all_candidates + .filter(|r| { + self.trait_defines_associated_item_named(r.def_id(), ty::AssocKind::Fn, assoc_name) + }) + // For the purposes of an RTN bound, we only care + // about supertraits where the host effect is set to true. + .filter(|trait_ref| { + let tcx = self.tcx(); + let generics = tcx.generics_of(trait_ref.def_id()); + generics.host_effect_index.map_or(true, |idx| { + trait_ref.skip_binder().args.const_at(idx) == tcx.consts.true_ + }) + }); let candidate = match matching_candidates.next() { Some(candidate) => candidate, diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index af1a4e5d99e98..1d9ae2b9cb730 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -43,33 +43,6 @@ impl<'tcx> Bounds<'tcx> { trait_ref: ty::PolyTraitRef<'tcx>, span: Span, polarity: ty::ImplPolarity, - ) { - self.push_trait_bound_inner(tcx, trait_ref, span, polarity); - - // if we have a host param, we push an unconst trait bound in addition - // to the const one. - // FIXME(effects) we should find a better way than name matching - if tcx.features().effects && trait_ref.skip_binder().args.host_effect_param().is_some() { - let generics = tcx.generics_of(trait_ref.def_id()); - let Some(host_index) = generics.host_effect_index else { return }; - let trait_ref = trait_ref.map_bound(|mut trait_ref| { - trait_ref.args = - tcx.mk_args_from_iter(trait_ref.args.iter().enumerate().map(|(n, arg)| { - if host_index == n { tcx.consts.true_.into() } else { arg } - })); - trait_ref - }); - - self.push_trait_bound_inner(tcx, trait_ref, span, polarity); - } - } - - fn push_trait_bound_inner( - &mut self, - tcx: TyCtxt<'tcx>, - trait_ref: ty::PolyTraitRef<'tcx>, - span: Span, - polarity: ty::ImplPolarity, ) { self.clauses.push(( trait_ref diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 104da581e019d..1b38f77654cfb 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -11,7 +11,7 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{GenericPredicates, ImplTraitInTraitData, ToPredicate}; use rustc_span::symbol::Ident; -use rustc_span::{sym, Span, DUMMY_SP}; +use rustc_span::{Span, DUMMY_SP}; /// Returns a list of all type predicates (explicit and implicit) for the definition with /// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus @@ -38,38 +38,11 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic // an obligation and instead be skipped. Otherwise we'd use // `tcx.def_span(def_id);` let span = rustc_span::DUMMY_SP; - let non_const_bound = if tcx.features().effects && tcx.has_attr(def_id, sym::const_trait) { - // when `Self` is a const trait, also add `Self: Trait<.., true>` as implied bound, - // because only implementing `Self: Trait<.., false>` is currently not possible. - Some(( - ty::TraitRef::new( - tcx, - def_id, - ty::GenericArgs::for_item(tcx, def_id, |param, _| { - if param.is_host_effect() { - tcx.consts.true_.into() - } else { - tcx.mk_param_from_def(param) - } - }), - ) - .to_predicate(tcx), + result.predicates = + tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once(( + ty::TraitRef::identity(tcx, def_id).to_predicate(tcx), span, - )) - } else { - None - }; - result.predicates = tcx.arena.alloc_from_iter( - result - .predicates - .iter() - .copied() - .chain(std::iter::once(( - ty::TraitRef::identity(tcx, def_id).to_predicate(tcx), - span, - ))) - .chain(non_const_bound), - ); + )))); } debug!("predicates_of(def_id={:?}) = {:?}", def_id, result); result diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 7677d6f953b6e..4a245d30c8e39 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -221,14 +221,14 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { let item_def_id = tcx.hir().ty_param_owner(def_id); let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&def_id.to_def_id()]; - // HACK(eddyb) should get the original `Span`. - let span = tcx.def_span(def_id); ty::GenericPredicates { parent: None, predicates: tcx.arena.alloc_from_iter( self.param_env.caller_bounds().iter().filter_map(|predicate| { match predicate.kind().skip_binder() { ty::ClauseKind::Trait(data) if data.self_ty().is_param(index) => { + // HACK(eddyb) should get the original `Span`. + let span = tcx.def_span(def_id); Some((predicate, span)) } _ => None, diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 250f7c9d932fb..1350acd0a4421 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -288,6 +288,22 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> { }); debug!(?data, ?obligations, "super_predicates"); self.extend_deduped(obligations); + + // Also elaborate `~const Trait` into `Trait`. + let generics = tcx.generics_of(data.def_id()); + if let Some(host_param_idx) = generics.host_effect_index + && data.trait_ref.args.const_at(host_param_idx) != tcx.consts.true_ + { + let mut trait_predicate_with_host = data; + trait_predicate_with_host.trait_ref.args = tcx.mk_args_from_iter( + data.trait_ref.args.iter().enumerate().map(|(idx, arg)| { + if idx == host_param_idx { tcx.consts.true_.into() } else { arg } + }), + ); + self.extend_deduped([ + elaboratable.child(trait_predicate_with_host.to_predicate(tcx)) + ]); + } } ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..)) => { // Currently, we do not elaborate WF predicates, diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 44e88d3e2302f..8e6c1cd4bbb66 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -79,10 +79,6 @@ impl GenericParamDef { } } - pub fn is_host_effect(&self) -> bool { - matches!(self.kind, GenericParamDefKind::Const { is_host_effect: true, .. }) - } - pub fn default_value<'tcx>( &self, tcx: TyCtxt<'tcx>,