Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 4 pull requests #124388

Merged
merged 8 commits into from
Apr 26, 2024
9 changes: 7 additions & 2 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,11 +328,16 @@ pub enum ObligationCauseCode<'tcx> {
/// `static` items must have `Sync` type.
SharedStatic,

/// Derived obligation (i.e. theoretical `where` clause) on a built-in
/// implementation like `Copy` or `Sized`.
BuiltinDerivedObligation(DerivedObligationCause<'tcx>),

/// Derived obligation (i.e. `where` clause) on an user-provided impl
/// or a trait alias.
ImplDerivedObligation(Box<ImplDerivedObligationCause<'tcx>>),

DerivedObligation(DerivedObligationCause<'tcx>),
/// Derived obligation for WF goals.
WellFormedDerivedObligation(DerivedObligationCause<'tcx>),

FunctionArgumentObligation {
/// The node of the relevant argument in the function call.
Expand Down Expand Up @@ -534,7 +539,7 @@ impl<'tcx> ObligationCauseCode<'tcx> {
match self {
FunctionArgumentObligation { parent_code, .. } => Some((parent_code, None)),
BuiltinDerivedObligation(derived)
| DerivedObligation(derived)
| WellFormedDerivedObligation(derived)
| ImplDerivedObligation(box ImplDerivedObligationCause { derived, .. }) => {
Some((&derived.parent_code, Some(derived.parent_trait_pred)))
}
Expand Down
38 changes: 5 additions & 33 deletions compiler/rustc_middle/src/ty/fast_reject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,30 +58,6 @@ pub enum TreatParams {
/// This also treats projections with inference variables as infer vars
/// since they could be further normalized.
ForLookup,
/// Treat parameters as placeholders in the given environment. This is the
/// correct mode for *lookup*, as during candidate selection.
///
/// N.B. during deep rejection, this acts identically to `ForLookup`.
///
/// FIXME(-Znext-solver): Remove this variant and cleanup
/// the code.
NextSolverLookup,
}

/// During fast-rejection, we have the choice of treating projection types
/// as either simplifiable or not, depending on whether we expect the projection
/// to be normalized/rigid.
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
pub enum TreatProjections {
/// In the old solver we don't try to normalize projections
/// when looking up impls and only access them by using the
/// current self type. This means that if the self type is
/// a projection which could later be normalized, we must not
/// treat it as rigid.
ForLookup,
/// We can treat projections in the self type as opaque as
/// we separately look up impls for the normalized self type.
NextSolverLookup,
}

/// Tries to simplify a type by only returning the outermost injective¹ layer, if one exists.
Expand Down Expand Up @@ -139,21 +115,17 @@ pub fn simplify_type<'tcx>(
ty::FnPtr(f) => Some(SimplifiedType::Function(f.skip_binder().inputs().len())),
ty::Placeholder(..) => Some(SimplifiedType::Placeholder),
ty::Param(_) => match treat_params {
TreatParams::ForLookup | TreatParams::NextSolverLookup => {
Some(SimplifiedType::Placeholder)
}
TreatParams::ForLookup => Some(SimplifiedType::Placeholder),
TreatParams::AsCandidateKey => None,
},
ty::Alias(..) => match treat_params {
// When treating `ty::Param` as a placeholder, projections also
// don't unify with anything else as long as they are fully normalized.
//
// We will have to be careful with lazy normalization here.
// FIXME(lazy_normalization): This is probably not right...
// FIXME(-Znext-solver): Can remove this `if` and always simplify to `Placeholder`
// when the new solver is enabled by default.
TreatParams::ForLookup if !ty.has_non_region_infer() => {
Some(SimplifiedType::Placeholder)
}
TreatParams::NextSolverLookup => Some(SimplifiedType::Placeholder),
TreatParams::ForLookup | TreatParams::AsCandidateKey => None,
},
ty::Foreign(def_id) => Some(SimplifiedType::Foreign(def_id)),
Expand Down Expand Up @@ -331,7 +303,7 @@ impl DeepRejectCtxt {
// Depending on the value of `treat_obligation_params`, we either
// treat generic parameters like placeholders or like inference variables.
ty::Param(_) => match self.treat_obligation_params {
TreatParams::ForLookup | TreatParams::NextSolverLookup => false,
TreatParams::ForLookup => false,
TreatParams::AsCandidateKey => true,
},

Expand Down Expand Up @@ -373,7 +345,7 @@ impl DeepRejectCtxt {
let k = impl_ct.kind();
match obligation_ct.kind() {
ty::ConstKind::Param(_) => match self.treat_obligation_params {
TreatParams::ForLookup | TreatParams::NextSolverLookup => false,
TreatParams::ForLookup => false,
TreatParams::AsCandidateKey => true,
},

Expand Down
27 changes: 4 additions & 23 deletions compiler/rustc_middle/src/ty/trait_def.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::traits::specialization_graph;
use crate::ty::fast_reject::{self, SimplifiedType, TreatParams, TreatProjections};
use crate::ty::fast_reject::{self, SimplifiedType, TreatParams};
use crate::ty::{Ident, Ty, TyCtxt};
use hir::def_id::LOCAL_CRATE;
use rustc_hir as hir;
Expand Down Expand Up @@ -135,21 +135,6 @@ impl<'tcx> TyCtxt<'tcx> {
self,
trait_def_id: DefId,
self_ty: Ty<'tcx>,
f: impl FnMut(DefId),
) {
self.for_each_relevant_impl_treating_projections(
trait_def_id,
self_ty,
TreatProjections::ForLookup,
f,
)
}

pub fn for_each_relevant_impl_treating_projections(
self,
trait_def_id: DefId,
self_ty: Ty<'tcx>,
treat_projections: TreatProjections,
mut f: impl FnMut(DefId),
) {
// FIXME: This depends on the set of all impls for the trait. That is
Expand All @@ -163,17 +148,13 @@ impl<'tcx> TyCtxt<'tcx> {
f(impl_def_id);
}

// Note that we're using `TreatParams::ForLookup` to query `non_blanket_impls` while using
// `TreatParams::AsCandidateKey` while actually adding them.
let treat_params = match treat_projections {
TreatProjections::NextSolverLookup => TreatParams::NextSolverLookup,
TreatProjections::ForLookup => TreatParams::ForLookup,
};
// This way, when searching for some impl for `T: Trait`, we do not look at any impls
// whose outer level is not a parameter or projection. Especially for things like
// `T: Clone` this is incredibly useful as we would otherwise look at all the impls
// of `Clone` for `Option<T>`, `Vec<T>`, `ConcreteType` and so on.
if let Some(simp) = fast_reject::simplify_type(self, self_ty, treat_params) {
// Note that we're using `TreatParams::ForLookup` to query `non_blanket_impls` while using
// `TreatParams::AsCandidateKey` while actually adding them.
if let Some(simp) = fast_reject::simplify_type(self, self_ty, TreatParams::ForLookup) {
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
for &impl_def_id in impls {
f(impl_def_id);
Expand Down
16 changes: 9 additions & 7 deletions compiler/rustc_trait_selection/src/solve/trait_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_middle::traits::solve::{
CandidateSource, CanonicalResponse, Certainty, Goal, QueryResult,
};
use rustc_middle::traits::{BuiltinImplSource, Reveal};
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, TreatProjections};
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
use rustc_middle::ty::{TraitPredicate, TypeVisitableExt};
use rustc_span::{ErrorGuaranteed, DUMMY_SP};
Expand Down Expand Up @@ -1045,6 +1045,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
}
}

// If we still have an alias here, it must be rigid. For opaques, it's always
// okay to consider auto traits because that'll reveal its hidden type. For
// non-opaque aliases, we will not assemble any candidates since there's no way
// to further look into its type.
ty::Alias(..) => None,

// For rigid types, any possible implementation that could apply to
// the type (even if after unification and processing nested goals
// it does not hold) will disqualify the built-in auto impl.
Expand Down Expand Up @@ -1072,15 +1078,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
| ty::CoroutineWitness(..)
| ty::Never
| ty::Tuple(_)
| ty::Adt(_, _)
// FIXME: Handling opaques here is kinda sus. Especially because we
// simplify them to SimplifiedType::Placeholder.
| ty::Alias(ty::Opaque, _) => {
| ty::Adt(_, _) => {
let mut disqualifying_impl = None;
self.tcx().for_each_relevant_impl_treating_projections(
self.tcx().for_each_relevant_impl(
goal.predicate.def_id(),
goal.predicate.self_ty(),
TreatProjections::NextSolverLookup,
|impl_def_id| {
disqualifying_impl = Some(impl_def_id);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
match obligation.cause.code() {
ObligationCauseCode::BuiltinDerivedObligation(..)
| ObligationCauseCode::ImplDerivedObligation(..)
| ObligationCauseCode::DerivedObligation(..) => {}
| ObligationCauseCode::WellFormedDerivedObligation(..) => {}
_ => {
// this is a "direct", user-specified, rather than derived,
// obligation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2294,7 +2294,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {

next_code = Some(&cause.derived.parent_code);
}
ObligationCauseCode::DerivedObligation(derived_obligation)
ObligationCauseCode::WellFormedDerivedObligation(derived_obligation)
| ObligationCauseCode::BuiltinDerivedObligation(derived_obligation) => {
let ty = derived_obligation.parent_trait_pred.skip_binder().self_ty();
debug!(
Expand Down Expand Up @@ -3423,7 +3423,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
)
});
}
ObligationCauseCode::DerivedObligation(ref data) => {
ObligationCauseCode::WellFormedDerivedObligation(ref data) => {
let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred);
let parent_predicate = parent_trait_ref;
// #74711: avoid a stack overflow
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/wf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
if let Some(parent_trait_pred) = predicate.to_opt_poly_trait_pred() {
cause = cause.derived_cause(
parent_trait_pred,
traits::ObligationCauseCode::DerivedObligation,
traits::ObligationCauseCode::WellFormedDerivedObligation,
);
}
extend_cause_with_original_assoc_item_obligation(tcx, item, &mut cause, predicate);
Expand Down
4 changes: 1 addition & 3 deletions library/std/src/io/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -869,8 +869,6 @@ impl Error {
/// # Examples
///
/// ```
/// #![feature(io_error_downcast)]
///
/// use std::fmt;
/// use std::io;
/// use std::error::Error;
Expand Down Expand Up @@ -923,7 +921,7 @@ impl Error {
/// assert!(io_error.raw_os_error().is_none());
/// # }
/// ```
#[unstable(feature = "io_error_downcast", issue = "99262")]
#[stable(feature = "io_error_downcast", since = "CURRENT_RUSTC_VERSION")]
pub fn downcast<E>(self) -> result::Result<E, Self>
where
E: error::Error + Send + Sync + 'static,
Expand Down
5 changes: 4 additions & 1 deletion tests/run-make/compiler-builtins/rmake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ fn main() {
.env("RUSTC", rustc)
.env("RUSTFLAGS", "-Copt-level=0 -Cdebug-assertions=yes")
.env("CARGO_TARGET_DIR", &target_dir)
.env("RUSTC_BOOTSTRAP", "1");
.env("RUSTC_BOOTSTRAP", "1")
// Visual Studio 2022 requires that the LIB env var be set so it can
// find the Windows SDK.
.env("LIB", std::env::var("LIB").unwrap_or_default());
set_host_rpath(&mut cmd);

let status = cmd.status().unwrap();
Expand Down
Loading