Rollup merge of #120598 - compiler-errors:no-rigid-check, r=lcnr
No need to `validate_alias_bound_self_from_param_env` in `assemble_alias_bound_candidates` We already fully normalize the self type before we reach `assemble_alias_bound_candidates`, so there's no reason to double check that a projection is truly rigid by checking param-env bounds. I think this is also blocked on us making sure to always normalize opaques: #120549. r? lcnr
This commit is contained in:
commit
702225e290
@ -5,7 +5,6 @@ use crate::solve::GoalSource;
|
|||||||
use crate::traits::coherence;
|
use crate::traits::coherence;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_infer::traits::query::NoSolution;
|
use rustc_infer::traits::query::NoSolution;
|
||||||
use rustc_infer::traits::Reveal;
|
|
||||||
use rustc_middle::traits::solve::inspect::ProbeKind;
|
use rustc_middle::traits::solve::inspect::ProbeKind;
|
||||||
use rustc_middle::traits::solve::{
|
use rustc_middle::traits::solve::{
|
||||||
CandidateSource, CanonicalResponse, Certainty, Goal, MaybeCause, QueryResult,
|
CandidateSource, CanonicalResponse, Certainty, Goal, MaybeCause, 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
|
/// Consider a clause specifically for a `dyn Trait` self type. This requires
|
||||||
/// additionally checking all of the supertraits and object bounds to hold,
|
/// additionally checking all of the supertraits and object bounds to hold,
|
||||||
/// since they're not implied by the well-formedness of the object type.
|
/// since they're not implied by the well-formedness of the object type.
|
||||||
@ -636,7 +621,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||||||
for assumption in
|
for assumption in
|
||||||
self.tcx().item_bounds(alias_ty.def_id).instantiate(self.tcx(), alias_ty.args)
|
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) => {
|
Ok(result) => {
|
||||||
candidates.push(Candidate { source: CandidateSource::AliasBound, result });
|
candidates.push(Candidate { source: CandidateSource::AliasBound, result });
|
||||||
}
|
}
|
||||||
@ -657,105 +642,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 `<Ty as Trait>::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<G: GoalKind<'tcx>>(
|
|
||||||
&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 `<T as Pointee>::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 `<T as Pointee>::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 `<T as Pointee>::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<G: GoalKind<'tcx>>(
|
|
||||||
&mut self,
|
|
||||||
goal: Goal<'tcx, G>,
|
|
||||||
candidates: &mut Vec<Candidate<'tcx>>,
|
|
||||||
) {
|
|
||||||
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)]
|
#[instrument(level = "debug", skip_all)]
|
||||||
fn assemble_object_bound_candidates<G: GoalKind<'tcx>>(
|
fn assemble_object_bound_candidates<G: GoalKind<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -4,30 +4,12 @@ error[E0277]: the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is
|
|||||||
LL | for item in *things { *item = 0 }
|
LL | for item in *things { *item = 0 }
|
||||||
| ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>`
|
| ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>`
|
||||||
|
|
||||||
error[E0277]: the size for values of type `<dyn Iterator<Item = &'a mut u8> 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 `<dyn Iterator<Item = &'a mut u8> 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 `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed
|
error: the type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed
|
||||||
--> $DIR/issue-20605.rs:5:17
|
--> $DIR/issue-20605.rs:5:17
|
||||||
|
|
|
|
||||||
LL | for item in *things { *item = 0 }
|
LL | for item in *things { *item = 0 }
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error[E0277]: `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not an iterator
|
|
||||||
--> $DIR/issue-20605.rs:5:17
|
|
||||||
|
|
|
||||||
LL | for item in *things { *item = 0 }
|
|
||||||
| ^^^^^^^ `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not an iterator
|
|
||||||
|
|
|
||||||
= help: the trait `Iterator` is not implemented for `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter`
|
|
||||||
|
|
||||||
error: the type `&mut <dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed
|
error: the type `&mut <dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed
|
||||||
--> $DIR/issue-20605.rs:5:17
|
--> $DIR/issue-20605.rs:5:17
|
||||||
|
|
|
|
||||||
@ -40,33 +22,13 @@ error: the type `Option<<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::Into
|
|||||||
LL | for item in *things { *item = 0 }
|
LL | for item in *things { *item = 0 }
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error[E0277]: the size for values of type `<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item` cannot be known at compilation time
|
error[E0614]: type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::Item` cannot be dereferenced
|
||||||
--> $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 `<<dyn Iterator<Item = &'a mut u8> 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 `<<dyn Iterator<Item = &'a mut u8> 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 `<<dyn Iterator<Item = &'a mut u8> 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 `<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item` cannot be dereferenced
|
|
||||||
--> $DIR/issue-20605.rs:5:27
|
--> $DIR/issue-20605.rs:5:27
|
||||||
|
|
|
|
||||||
LL | for item in *things { *item = 0 }
|
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.
|
Some errors have detailed explanations: E0277, E0614.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
@ -5,14 +5,11 @@ fn changer<'a>(mut things: Box<dyn Iterator<Item=&'a mut u8>>) {
|
|||||||
for item in *things { *item = 0 }
|
for item in *things { *item = 0 }
|
||||||
//[current]~^ ERROR the size for values of type
|
//[current]~^ ERROR the size for values of type
|
||||||
//[next]~^^ ERROR the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied
|
//[next]~^^ ERROR the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied
|
||||||
//[next]~| ERROR the size for values of type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` cannot be known at compilation time
|
|
||||||
//[next]~| ERROR the type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed
|
//[next]~| ERROR the type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed
|
||||||
//[next]~| ERROR `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not an iterator
|
|
||||||
//[next]~| ERROR the type `&mut <dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed
|
//[next]~| ERROR the type `&mut <dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed
|
||||||
//[next]~| ERROR the size for values of type `<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item` cannot be known at compilation time
|
|
||||||
//[next]~| ERROR the type `Option<<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item>` is not well-formed
|
//[next]~| ERROR the type `Option<<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item>` is not well-formed
|
||||||
//[next]~| ERROR the size for values of type `<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item` cannot be known at compilation time
|
//[next]~| ERROR type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::Item` cannot be dereferenced
|
||||||
//[next]~| ERROR type `<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item` cannot be dereferenced
|
|
||||||
// FIXME(-Znext-solver): these error messages are horrible and have to be
|
// FIXME(-Znext-solver): these error messages are horrible and have to be
|
||||||
// improved before we stabilize the new solver.
|
// improved before we stabilize the new solver.
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ pub fn copy_any<T>(t: &T) -> T {
|
|||||||
//~| ERROR the trait bound `dyn Setup<From = T>: Setup` is not satisfied
|
//~| ERROR the trait bound `dyn Setup<From = T>: Setup` is not satisfied
|
||||||
//~| ERROR mismatched types
|
//~| ERROR mismatched types
|
||||||
//~| ERROR the type `<dyn Setup<From = T> as Setup>::From` is not well-formed
|
//~| ERROR the type `<dyn Setup<From = T> as Setup>::From` is not well-formed
|
||||||
//~| ERROR the size for values of type `<dyn Setup<From = T> as Setup>::From` cannot be known at compilation time
|
|
||||||
|
|
||||||
// FIXME(-Znext-solver): These error messages are horrible and some of them
|
// FIXME(-Znext-solver): These error messages are horrible and some of them
|
||||||
// are even simple fallout from previous error.
|
// are even simple fallout from previous error.
|
||||||
|
@ -42,20 +42,7 @@ error: the type `<dyn Setup<From = T> as Setup>::From` is not well-formed
|
|||||||
LL | copy::<dyn Setup<From=T>>(t)
|
LL | copy::<dyn Setup<From=T>>(t)
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0277]: the size for values of type `<dyn Setup<From = T> as Setup>::From` cannot be known at compilation time
|
error: aborting due to 4 previous errors
|
||||||
--> $DIR/object-unsafety.rs:12:5
|
|
||||||
|
|
|
||||||
LL | copy::<dyn Setup<From=T>>(t)
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
|
||||||
|
|
|
||||||
= help: the trait `Sized` is not implemented for `<dyn Setup<From = T> 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) -> T where <dyn Setup<From = T> as Setup>::From: Sized {
|
|
||||||
| +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0308.
|
Some errors have detailed explanations: E0277, E0308.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user