diff --git a/Cargo.lock b/Cargo.lock index 3175e98e81e53..6298d1e366bc6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -351,7 +351,7 @@ dependencies = [ "cargo-test-macro", "cargo-test-support", "cargo-util", - "clap 4.1.3", + "clap 4.1.4", "crates-io", "curl", "curl-sys", @@ -655,9 +655,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.1.3" +version = "4.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8d93d855ce6a0aa87b8473ef9169482f40abaa2e9e0993024c35c902cbd5920" +checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76" dependencies = [ "bitflags", "clap_derive 4.1.0", @@ -675,7 +675,7 @@ version = "4.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10861370d2ba66b0f5989f83ebf35db6421713fd92351790e7fdd6c36774c56b" dependencies = [ - "clap 4.1.3", + "clap 4.1.4", ] [[package]] @@ -2294,7 +2294,7 @@ name = "jsondoclint" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.1.3", + "clap 4.1.4", "fs-err", "rustdoc-json-types", "serde", @@ -2557,7 +2557,7 @@ dependencies = [ "ammonia", "anyhow", "chrono", - "clap 4.1.3", + "clap 4.1.4", "clap_complete", "elasticlunr-rs", "env_logger 0.10.0", @@ -3528,7 +3528,7 @@ dependencies = [ name = "rustbook" version = "0.1.0" dependencies = [ - "clap 4.1.3", + "clap 4.1.4", "env_logger 0.7.1", "mdbook", ] diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 70f094014453e..f44648c95d742 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -277,12 +277,15 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { param_env, predicate: (def_id, substs, kind), }), + ty::PredicateKind::ObjectSafe(trait_def_id) => { + self.compute_object_safe_goal(trait_def_id) + } + ty::PredicateKind::WellFormed(arg) => { + self.compute_well_formed_goal(Goal { param_env, predicate: arg }) + } ty::PredicateKind::Ambiguous => self.make_canonical_response(Certainty::AMBIGUOUS), // FIXME: implement these predicates :) - ty::PredicateKind::WellFormed(_) - | ty::PredicateKind::ObjectSafe(_) - | ty::PredicateKind::ConstEvaluatable(_) - | ty::PredicateKind::ConstEquate(_, _) => { + ty::PredicateKind::ConstEvaluatable(_) | ty::PredicateKind::ConstEquate(_, _) => { self.make_canonical_response(Certainty::Yes) } ty::PredicateKind::TypeWellFormedFromEnv(..) => { @@ -362,6 +365,32 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { Err(NoSolution) } } + + fn compute_object_safe_goal(&mut self, trait_def_id: DefId) -> QueryResult<'tcx> { + if self.tcx().is_object_safe(trait_def_id) { + self.make_canonical_response(Certainty::Yes) + } else { + Err(NoSolution) + } + } + + fn compute_well_formed_goal( + &mut self, + goal: Goal<'tcx, ty::GenericArg<'tcx>>, + ) -> QueryResult<'tcx> { + self.infcx.probe(|_| { + match crate::traits::wf::unnormalized_obligations( + self.infcx, + goal.param_env, + goal.predicate, + ) { + Some(obligations) => self.evaluate_all_and_make_canonical_response( + obligations.into_iter().map(|o| o.into()).collect(), + ), + None => self.make_canonical_response(Certainty::AMBIGUOUS), + } + }) + } } impl<'tcx> EvalCtxt<'_, 'tcx> { diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index d9556848099f1..767e31ddf781a 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -4,8 +4,8 @@ use rustc_hir as hir; use rustc_hir::lang_items::LangItem; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable}; -use rustc_span::def_id::{DefId, LocalDefId}; -use rustc_span::Span; +use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; +use rustc_span::{Span, DUMMY_SP}; use std::iter; /// Returns the set of obligations needed to make `arg` well-formed. @@ -75,6 +75,34 @@ pub fn obligations<'tcx>( Some(result) } +/// Compute the predicates that are required for a type to be well-formed. +/// +/// This is only intended to be used in the new solver, since it does not +/// take into account recursion depth or proper error-reporting spans. +pub fn unnormalized_obligations<'tcx>( + infcx: &InferCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + arg: GenericArg<'tcx>, +) -> Option>> { + if let ty::GenericArgKind::Lifetime(..) = arg.unpack() { + return Some(vec![]); + } + + debug_assert_eq!(arg, infcx.resolve_vars_if_possible(arg)); + + let mut wf = WfPredicates { + tcx: infcx.tcx, + param_env, + body_id: CRATE_DEF_ID, + span: DUMMY_SP, + out: vec![], + recursion_depth: 0, + item: None, + }; + wf.compute(arg); + Some(wf.out) +} + /// Returns the obligations that make this trait reference /// well-formed. For example, if there is a trait `Set` defined like /// `trait Set`, then the trait reference `Foo: Set` is WF