diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index c4eef8e77288b..b1e34dcd5f3f6 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -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>), - DerivedObligation(DerivedObligationCause<'tcx>), + /// Derived obligation for WF goals. + WellFormedDerivedObligation(DerivedObligationCause<'tcx>), FunctionArgumentObligation { /// The node of the relevant argument in the function call. @@ -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))) } diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 7c925d5fbb660..10b0909209a05 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -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. @@ -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)), @@ -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, }, @@ -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, }, diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index d85b541d36386..e06e3465eb2a8 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -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; @@ -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 @@ -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`, `Vec`, `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); diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index ed76ea74f08f9..f6d12a9a0138e 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -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}; @@ -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. @@ -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); }, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index 5fccc76978550..b418219fb957e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -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. diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index cc879c42ce95b..d24942f3f46cd 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -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!( @@ -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 diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index f1c24b6adc1ac..28ee76f7145c2 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -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); diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 21ae7b91207c1..801621c6112e0 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -869,8 +869,6 @@ impl Error { /// # Examples /// /// ``` - /// #![feature(io_error_downcast)] - /// /// use std::fmt; /// use std::io; /// use std::error::Error; @@ -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(self) -> result::Result where E: error::Error + Send + Sync + 'static, diff --git a/tests/run-make/compiler-builtins/rmake.rs b/tests/run-make/compiler-builtins/rmake.rs index 92d6895143c28..97ff12877f10a 100644 --- a/tests/run-make/compiler-builtins/rmake.rs +++ b/tests/run-make/compiler-builtins/rmake.rs @@ -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();