From 6dea1554798c78b5fae171ca601e362bae5138f8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 3 Feb 2024 01:20:59 +0000 Subject: [PATCH] No need to validate_alias_bound_self_from_param_env in assemble_alias_bound_candidates --- .../src/solve/assembly/mod.rs | 116 +----------------- tests/ui/for/issue-20605.next.stderr | 42 +------ tests/ui/for/issue-20605.rs | 7 +- .../ui/traits/next-solver/object-unsafety.rs | 1 - .../traits/next-solver/object-unsafety.stderr | 15 +-- 5 files changed, 6 insertions(+), 175 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index 915d722dd0206..8da3c92698b49 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -5,7 +5,6 @@ use crate::solve::GoalSource; use crate::traits::coherence; use rustc_hir::def_id::DefId; use rustc_infer::traits::query::NoSolution; -use rustc_infer::traits::Reveal; use rustc_middle::traits::solve::inspect::ProbeKind; use rustc_middle::traits::solve::{ CandidateSource, CanonicalResponse, Certainty, Goal, QueryResult, @@ -70,20 +69,6 @@ pub(super) trait GoalKind<'tcx>: }) } - /// Consider a bound originating from the item bounds of an alias. For this we - /// require that the well-formed requirements of the self type of the goal - /// are "satisfied from the param-env". - /// See [`EvalCtxt::validate_alias_bound_self_from_param_env`]. - fn consider_alias_bound_candidate( - ecx: &mut EvalCtxt<'_, 'tcx>, - goal: Goal<'tcx, Self>, - assumption: ty::Clause<'tcx>, - ) -> QueryResult<'tcx> { - Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| { - ecx.validate_alias_bound_self_from_param_env(goal) - }) - } - /// Consider a clause specifically for a `dyn Trait` self type. This requires /// additionally checking all of the supertraits and object bounds to hold, /// since they're not implied by the well-formedness of the object type. @@ -557,7 +542,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { for assumption in self.tcx().item_bounds(alias_ty.def_id).instantiate(self.tcx(), alias_ty.args) { - match G::consider_alias_bound_candidate(self, goal, assumption) { + match G::consider_implied_clause(self, goal, assumption, []) { Ok(result) => { candidates.push(Candidate { source: CandidateSource::AliasBound, result }) } @@ -566,105 +551,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } - /// Check that we are allowed to use an alias bound originating from the self - /// type of this goal. This means something different depending on the self type's - /// alias kind. - /// - /// * Projection: Given a goal with a self type such as `::Assoc`, - /// we require that the bound `Ty: Trait` can be proven using either a nested alias - /// bound candidate, or a param-env candidate. - /// - /// * Opaque: The param-env must be in `Reveal::UserFacing` mode. Otherwise, - /// the goal should be proven by using the hidden type instead. - #[instrument(level = "debug", skip(self), ret)] - pub(super) fn validate_alias_bound_self_from_param_env>( - &mut self, - goal: Goal<'tcx, G>, - ) -> QueryResult<'tcx> { - match *goal.predicate.self_ty().kind() { - ty::Alias(ty::Projection, projection_ty) => { - let mut param_env_candidates = vec![]; - let self_trait_ref = projection_ty.trait_ref(self.tcx()); - - if self_trait_ref.self_ty().is_ty_var() { - return self - .evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS); - } - - let trait_goal: Goal<'_, ty::TraitPredicate<'tcx>> = goal.with( - self.tcx(), - ty::TraitPredicate { - trait_ref: self_trait_ref, - polarity: ty::ImplPolarity::Positive, - }, - ); - - self.assemble_param_env_candidates(trait_goal, &mut param_env_candidates); - // FIXME: We probably need some sort of recursion depth check here. - // Can't come up with an example yet, though, and the worst case - // we can have is a compiler stack overflow... - self.assemble_alias_bound_candidates(trait_goal, &mut param_env_candidates); - - // FIXME: We must also consider alias-bound candidates for a peculiar - // class of built-in candidates that I'll call "defaulted" built-ins. - // - // For example, we always know that `T: Pointee` is implemented, but - // we do not always know what `::Metadata` actually is, - // similar to if we had a user-defined impl with a `default type ...`. - // For these traits, since we're not able to always normalize their - // associated types to a concrete type, we must consider their alias bounds - // instead, so we can prove bounds such as `::Metadata: Copy`. - self.assemble_alias_bound_candidates_for_builtin_impl_default_items( - trait_goal, - &mut param_env_candidates, - ); - - self.merge_candidates(param_env_candidates) - } - ty::Alias(ty::Opaque, _opaque_ty) => match goal.param_env.reveal() { - Reveal::UserFacing => { - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - } - Reveal::All => return Err(NoSolution), - }, - _ => bug!("only expected to be called on alias tys"), - } - } - - /// Assemble a subset of builtin impl candidates for a class of candidates called - /// "defaulted" built-in traits. - /// - /// For example, we always know that `T: Pointee` is implemented, but we do not - /// always know what `::Metadata` actually is! See the comment in - /// [`EvalCtxt::validate_alias_bound_self_from_param_env`] for more detail. - #[instrument(level = "debug", skip_all)] - fn assemble_alias_bound_candidates_for_builtin_impl_default_items>( - &mut self, - goal: Goal<'tcx, G>, - candidates: &mut Vec>, - ) { - let lang_items = self.tcx().lang_items(); - let trait_def_id = goal.predicate.trait_def_id(self.tcx()); - - // You probably shouldn't add anything to this list unless you - // know what you're doing. - let result = if lang_items.pointee_trait() == Some(trait_def_id) { - G::consider_builtin_pointee_candidate(self, goal) - } else if lang_items.discriminant_kind_trait() == Some(trait_def_id) { - G::consider_builtin_discriminant_kind_candidate(self, goal) - } else { - Err(NoSolution) - }; - - match result { - Ok(result) => candidates.push(Candidate { - source: CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), - result, - }), - Err(NoSolution) => (), - } - } - #[instrument(level = "debug", skip_all)] fn assemble_object_bound_candidates>( &mut self, diff --git a/tests/ui/for/issue-20605.next.stderr b/tests/ui/for/issue-20605.next.stderr index 3d753b9c8b884..a44faa5491d3d 100644 --- a/tests/ui/for/issue-20605.next.stderr +++ b/tests/ui/for/issue-20605.next.stderr @@ -4,30 +4,12 @@ error[E0277]: the trait bound `dyn Iterator: IntoIterator` is LL | for item in *things { *item = 0 } | ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator` -error[E0277]: the size for values of type ` as IntoIterator>::IntoIter` cannot be known at compilation time - --> $DIR/issue-20605.rs:5:17 - | -LL | for item in *things { *item = 0 } - | ^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for ` as IntoIterator>::IntoIter` - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature - error: the type ` as IntoIterator>::IntoIter` is not well-formed --> $DIR/issue-20605.rs:5:17 | LL | for item in *things { *item = 0 } | ^^^^^^^ -error[E0277]: ` as IntoIterator>::IntoIter` is not an iterator - --> $DIR/issue-20605.rs:5:17 - | -LL | for item in *things { *item = 0 } - | ^^^^^^^ ` as IntoIterator>::IntoIter` is not an iterator - | - = help: the trait `Iterator` is not implemented for ` as IntoIterator>::IntoIter` - error: the type `&mut as IntoIterator>::IntoIter` is not well-formed --> $DIR/issue-20605.rs:5:17 | @@ -40,33 +22,13 @@ error: the type `Option<< as IntoIterator>::Into LL | for item in *things { *item = 0 } | ^^^^^^^ -error[E0277]: the size for values of type `< as IntoIterator>::IntoIter as Iterator>::Item` cannot be known at compilation time - --> $DIR/issue-20605.rs:5:5 - | -LL | for item in *things { *item = 0 } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `< as IntoIterator>::IntoIter as Iterator>::Item` -note: required by a bound in `None` - --> $SRC_DIR/core/src/option.rs:LL:COL - -error[E0277]: the size for values of type `< as IntoIterator>::IntoIter as Iterator>::Item` cannot be known at compilation time - --> $DIR/issue-20605.rs:5:9 - | -LL | for item in *things { *item = 0 } - | ^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `< as IntoIterator>::IntoIter as Iterator>::Item` - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature - -error[E0614]: type `< as IntoIterator>::IntoIter as Iterator>::Item` cannot be dereferenced +error[E0614]: type ` as IntoIterator>::Item` cannot be dereferenced --> $DIR/issue-20605.rs:5:27 | LL | for item in *things { *item = 0 } | ^^^^^ -error: aborting due to 9 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0277, E0614. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/for/issue-20605.rs b/tests/ui/for/issue-20605.rs index 8ae9494faf8b0..2cd57a8572278 100644 --- a/tests/ui/for/issue-20605.rs +++ b/tests/ui/for/issue-20605.rs @@ -5,14 +5,11 @@ fn changer<'a>(mut things: Box>) { for item in *things { *item = 0 } //[current]~^ ERROR the size for values of type //[next]~^^ ERROR the trait bound `dyn Iterator: IntoIterator` is not satisfied - //[next]~| ERROR the size for values of type ` as IntoIterator>::IntoIter` cannot be known at compilation time //[next]~| ERROR the type ` as IntoIterator>::IntoIter` is not well-formed - //[next]~| ERROR ` as IntoIterator>::IntoIter` is not an iterator //[next]~| ERROR the type `&mut as IntoIterator>::IntoIter` is not well-formed - //[next]~| ERROR the size for values of type `< as IntoIterator>::IntoIter as Iterator>::Item` cannot be known at compilation time //[next]~| ERROR the type `Option<< as IntoIterator>::IntoIter as Iterator>::Item>` is not well-formed - //[next]~| ERROR the size for values of type `< as IntoIterator>::IntoIter as Iterator>::Item` cannot be known at compilation time - //[next]~| ERROR type `< as IntoIterator>::IntoIter as Iterator>::Item` cannot be dereferenced + //[next]~| ERROR type ` as IntoIterator>::Item` cannot be dereferenced + // FIXME(-Znext-solver): these error messages are horrible and have to be // improved before we stabilize the new solver. } diff --git a/tests/ui/traits/next-solver/object-unsafety.rs b/tests/ui/traits/next-solver/object-unsafety.rs index cfa53948b97fd..31a1a0ab2e98d 100644 --- a/tests/ui/traits/next-solver/object-unsafety.rs +++ b/tests/ui/traits/next-solver/object-unsafety.rs @@ -14,7 +14,6 @@ pub fn copy_any(t: &T) -> T { //~| ERROR the trait bound `dyn Setup: Setup` is not satisfied //~| ERROR mismatched types //~| ERROR the type ` as Setup>::From` is not well-formed - //~| ERROR the size for values of type ` as Setup>::From` cannot be known at compilation time // FIXME(-Znext-solver): These error messages are horrible and some of them // are even simple fallout from previous error. diff --git a/tests/ui/traits/next-solver/object-unsafety.stderr b/tests/ui/traits/next-solver/object-unsafety.stderr index eedca879b0c8a..a9cbb721511ca 100644 --- a/tests/ui/traits/next-solver/object-unsafety.stderr +++ b/tests/ui/traits/next-solver/object-unsafety.stderr @@ -42,20 +42,7 @@ error: the type ` as Setup>::From` is not well-formed LL | copy::>(t) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: the size for values of type ` as Setup>::From` cannot be known at compilation time - --> $DIR/object-unsafety.rs:12:5 - | -LL | copy::>(t) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for ` as Setup>::From` - = note: the return type of a function must have a statically known size -help: consider further restricting the associated type - | -LL | pub fn copy_any(t: &T) -> T where as Setup>::From: Sized { - | +++++++++++++++++++++++++++++++++++++++++++++++++ - -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`.