diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:13 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:13 +0000 |
commit | 218caa410aa38c29984be31a5229b9fa717560ee (patch) | |
tree | c54bd55eeb6e4c508940a30e94c0032fbd45d677 /compiler/rustc_trait_selection/src/traits/select/mod.rs | |
parent | Releasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip |
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits/select/mod.rs')
-rw-r--r-- | compiler/rustc_trait_selection/src/traits/select/mod.rs | 99 |
1 files changed, 49 insertions, 50 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 035deb616..f90da95d5 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -430,7 +430,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // impl<T:Clone> Vec<T> { fn push_clone(...) { ... } } // // and we were to see some code `foo.push_clone()` where `boo` - // is a `Vec<Bar>` and `Bar` does not implement `Clone`. If + // is a `Vec<Bar>` and `Bar` does not implement `Clone`. If // we were to winnow, we'd wind up with zero candidates. // Instead, we select the right impl now but report "`Bar` does // not implement `Clone`". @@ -755,7 +755,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // contain the "'static" lifetime (any other lifetime // would either be late-bound or local), so it is guaranteed // to outlive any other lifetime - if pred.0.is_global() && !pred.0.has_late_bound_regions() { + if pred.0.is_global() && !pred.0.has_late_bound_vars() { Ok(EvaluatedToOk) } else { Ok(EvaluatedToOkModuloRegions) @@ -1171,19 +1171,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { where I: Iterator<Item = ty::Predicate<'tcx>>, { - cycle.all(|predicate| self.coinductive_predicate(predicate)) - } - - fn coinductive_predicate(&self, predicate: ty::Predicate<'tcx>) -> bool { - let result = match predicate.kind().skip_binder() { - ty::PredicateKind::Clause(ty::Clause::Trait(ref data)) => { - self.tcx().trait_is_coinductive(data.def_id()) - } - ty::PredicateKind::WellFormed(_) => true, - _ => false, - }; - debug!(?predicate, ?result, "coinductive_predicate"); - result + cycle.all(|predicate| predicate.is_coinductive(self.tcx())) } /// Further evaluates `candidate` to decide whether all type parameters match and whether nested @@ -1377,16 +1365,27 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // const param ParamCandidate(trait_pred) if trait_pred.is_const_if_const() => {} // const projection - ProjectionCandidate(_, ty::BoundConstness::ConstIfConst) => {} + ProjectionCandidate(_, ty::BoundConstness::ConstIfConst) // auto trait impl - AutoImplCandidate => {} + | AutoImplCandidate // generator / future, this will raise error in other places // or ignore error with const_async_blocks feature - GeneratorCandidate => {} - FutureCandidate => {} + | GeneratorCandidate + | FutureCandidate // FnDef where the function is const - FnPointerCandidate { is_const: true } => {} - ConstDestructCandidate(_) => {} + | FnPointerCandidate { is_const: true } + | ConstDestructCandidate(_) + | ClosureCandidate { is_const: true } => {} + + FnPointerCandidate { is_const: false } => { + if let ty::FnDef(def_id, _) = obligation.self_ty().skip_binder().kind() && tcx.trait_of_item(*def_id).is_some() { + // Trait methods are not seen as const unless the trait is implemented as const. + // We do not filter that out in here, but nested obligations will be needed to confirm this. + } else { + continue + } + } + _ => { // reject all other types of candidates continue; @@ -1595,8 +1594,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let tcx = self.infcx.tcx; let (def_id, substs) = match *placeholder_trait_predicate.trait_ref.self_ty().kind() { - ty::Projection(ref data) => (data.item_def_id, data.substs), - ty::Opaque(def_id, substs) => (def_id, substs), + ty::Alias(_, ty::AliasTy { def_id, substs, .. }) => (def_id, substs), _ => { span_bug!( obligation.cause.span, @@ -1606,7 +1604,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); } }; - let bounds = tcx.bound_item_bounds(def_id).subst(tcx, substs); + let bounds = tcx.item_bounds(def_id).subst(tcx, substs); // The bounds returned by `item_bounds` may contain duplicates after // normalization, so try to deduplicate when possible to avoid @@ -1745,7 +1743,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }); if is_match { - let generics = self.tcx().generics_of(obligation.predicate.item_def_id); + let generics = self.tcx().generics_of(obligation.predicate.def_id); // FIXME(generic-associated-types): Addresses aggressive inference in #92917. // If this type is a GAT, and of the GAT substs resolve to something new, // that means that we must have newly inferred something about the GAT. @@ -1790,9 +1788,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Check if a bound would previously have been removed when normalizing // the param_env so that it can be given the lowest priority. See // #50825 for the motivation for this. - let is_global = |cand: &ty::PolyTraitPredicate<'tcx>| { - cand.is_global() && !cand.has_late_bound_regions() - }; + let is_global = + |cand: &ty::PolyTraitPredicate<'tcx>| cand.is_global() && !cand.has_late_bound_vars(); // (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`, // `DiscriminantKindCandidate`, `ConstDestructCandidate` @@ -1850,7 +1847,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ( ParamCandidate(ref cand), ImplCandidate(..) - | ClosureCandidate + | ClosureCandidate { .. } | GeneratorCandidate | FutureCandidate | FnPointerCandidate { .. } @@ -1869,7 +1866,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ( ImplCandidate(_) - | ClosureCandidate + | ClosureCandidate { .. } | GeneratorCandidate | FutureCandidate | FnPointerCandidate { .. } @@ -1900,7 +1897,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ( ObjectCandidate(_) | ProjectionCandidate(..), ImplCandidate(..) - | ClosureCandidate + | ClosureCandidate { .. } | GeneratorCandidate | FutureCandidate | FnPointerCandidate { .. } @@ -1913,7 +1910,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ( ImplCandidate(..) - | ClosureCandidate + | ClosureCandidate { .. } | GeneratorCandidate | FutureCandidate | FnPointerCandidate { .. } @@ -1995,7 +1992,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Everything else is ambiguous ( ImplCandidate(_) - | ClosureCandidate + | ClosureCandidate { .. } | GeneratorCandidate | FutureCandidate | FnPointerCandidate { .. } @@ -2005,7 +2002,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | BuiltinCandidate { has_nested: true } | TraitAliasCandidate, ImplCandidate(_) - | ClosureCandidate + | ClosureCandidate { .. } | GeneratorCandidate | FutureCandidate | FnPointerCandidate { .. } @@ -2067,7 +2064,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { })) } - ty::Projection(_) | ty::Param(_) | ty::Opaque(..) => None, + ty::Alias(..) | ty::Param(_) => None, ty::Infer(ty::TyVar(_)) => Ambiguous, ty::Placeholder(..) @@ -2167,7 +2164,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } - ty::Adt(..) | ty::Projection(..) | ty::Param(..) | ty::Opaque(..) => { + ty::Adt(..) | ty::Alias(..) | ty::Param(..) => { // Fallback to whatever user-defined impls exist in this case. None } @@ -2220,7 +2217,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Dynamic(..) | ty::Param(..) | ty::Foreign(..) - | ty::Projection(..) + | ty::Alias(ty::Projection, ..) | ty::Bound(..) | ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { bug!("asked to assemble constituent types of unexpected type: {:?}", t); @@ -2260,7 +2257,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { t.rebind(def.all_fields().map(|f| f.ty(self.tcx(), substs)).collect()) } - ty::Opaque(def_id, substs) => { + ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => { // We can resolve the `impl Trait` to its concrete type, // which enforces a DAG between the functions requiring // the auto trait bounds in question. @@ -2327,7 +2324,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Matching // // Matching is a common path used for both evaluation and - // confirmation. It basically unifies types that appear in impls + // confirmation. It basically unifies types that appear in impls // and traits. This does affect the surrounding environment; // therefore, when used during evaluation, match routines must be // run inside of a `probe()` so that their side-effects are @@ -2338,7 +2335,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { impl_def_id: DefId, obligation: &TraitObligation<'tcx>, ) -> Normalized<'tcx, SubstsRef<'tcx>> { - let impl_trait_ref = self.tcx().bound_impl_trait_ref(impl_def_id).unwrap(); + let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap(); match self.match_impl(impl_def_id, impl_trait_ref, obligation) { Ok(substs) => substs, Err(()) => { @@ -2383,6 +2380,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id); let impl_trait_ref = impl_trait_ref.subst(self.tcx(), impl_substs); + if impl_trait_ref.references_error() { + return Err(()); + } debug!(?impl_trait_ref); @@ -2558,12 +2558,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // obligation will normalize to `<$0 as Iterator>::Item = $1` and // `$1: Copy`, so we must ensure the obligations are emitted in // that order. - let predicates = tcx.bound_predicates_of(def_id); - debug!(?predicates); - assert_eq!(predicates.0.parent, None); - let mut obligations = Vec::with_capacity(predicates.0.predicates.len()); - for (predicate, span) in predicates.0.predicates { - let span = *span; + let predicates = tcx.predicates_of(def_id); + assert_eq!(predicates.parent, None); + let predicates = predicates.instantiate_own(tcx, substs); + let mut obligations = Vec::with_capacity(predicates.len()); + for (predicate, span) in predicates { let cause = cause.clone().derived_cause(parent_trait_pred, |derived| { ImplDerivedObligation(Box::new(ImplDerivedObligationCause { derived, @@ -2576,7 +2575,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { param_env, cause.clone(), recursion_depth, - predicates.rebind(*predicate).subst(tcx, substs), + predicate, &mut obligations, ); obligations.push(Obligation { cause, recursion_depth, param_env, predicate }); @@ -2644,7 +2643,7 @@ impl<'o, 'tcx> TraitObligationStack<'o, 'tcx> { /// In Issue #60010, we found a bug in rustc where it would cache /// these intermediate results. This was fixed in #60444 by disabling /// *all* caching for things involved in a cycle -- in our example, -/// that would mean we don't cache that `Bar<T>: Send`. But this led +/// that would mean we don't cache that `Bar<T>: Send`. But this led /// to large slowdowns. /// /// Specifically, imagine this scenario, where proving `Baz<T>: Send` @@ -2670,7 +2669,7 @@ impl<'o, 'tcx> TraitObligationStack<'o, 'tcx> { /// a result at `reached_depth`, so it marks the *current* solution as /// provisional as well. If an error is encountered, we toss out any /// provisional results added from the subtree that encountered the -/// error. When we pop the node at `reached_depth` from the stack, we +/// error. When we pop the node at `reached_depth` from the stack, we /// can commit all the things that remain in the provisional cache. struct ProvisionalEvaluationCache<'tcx> { /// next "depth first number" to issue -- just a counter @@ -2781,7 +2780,7 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> { } /// Invoked when the node with dfn `dfn` does not get a successful - /// result. This will clear out any provisional cache entries + /// result. This will clear out any provisional cache entries /// that were added since `dfn` was created. This is because the /// provisional entries are things which must assume that the /// things on the stack at the time of their creation succeeded -- |