From 316742edb73a81edc231b1c8dc086fae1f3142d9 Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Sun, 22 Jan 2023 15:46:53 +0100 Subject: io: soften ‘at most one write attempt’ requirement in io::Write::write MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At the moment, documentation of std::io::Write::write indicates that call to it ‘represents at most one attempt to write to any wrapped object’. It seems that such wording was put there to contrast it with pre-1.0 interface which attempted to write all the data (it has since been changed in [RFC 517]). However, the requirement puts unnecessary constraints and may complicate adaptors which perform non-trivial transformations on the data. For example, they may maintain an internal buffer which needs to be written out before the write method accepts more data. It might be natural to code the method such that it flushes the buffer and then grabs another chunk of user data. With the current wording in the documentation, the adaptor would be forced to return Ok(0). This commit softens the wording such that implementations can choose code structure which makes most sense for their particular use case. While at it, elaborate on the meaning of `Ok(0)` return pointing out that the write_all methods interprets it as an error. [RFC 517]: https://rust-lang.github.io/rfcs/0517-io-os-reform.html --- library/std/src/io/mod.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index de528e85368..aa34d4be192 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -1385,17 +1385,18 @@ pub trait Write { /// /// This function will attempt to write the entire contents of `buf`, but /// the entire write might not succeed, or the write may also generate an - /// error. A call to `write` represents *at most one* attempt to write to + /// error. Typically, a call to `write` represents one attempt to write to /// any wrapped object. /// /// Calls to `write` are not guaranteed to block waiting for data to be /// written, and a write which would otherwise block can be indicated through /// an [`Err`] variant. /// - /// If the return value is [`Ok(n)`] then it must be guaranteed that - /// `n <= buf.len()`. A return value of `0` typically means that the - /// underlying object is no longer able to accept bytes and will likely not - /// be able to in the future as well, or that the buffer provided is empty. + /// If the return value is [`Ok(n)`] then it must be guaranteed that `n <= + /// buf.len()`. Unless `input` is empty, this function shouldn’t return `0` + /// since caller may interpret that as an error (the default implementation + /// of [`Write::write_all`] does exactly that). To indicate lack of space + /// function should return [`ErrorKind::StorageFull`] error instead. /// /// # Errors /// -- cgit 1.4.1-3-g733a5 From 8654669ed4569216fde2c16edb49d05cd373f038 Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Fri, 3 Feb 2023 18:38:51 +0100 Subject: Update library/std/src/io/mod.rs --- library/std/src/io/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index aa34d4be192..d4f8c3123b2 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -1392,10 +1392,10 @@ pub trait Write { /// written, and a write which would otherwise block can be indicated through /// an [`Err`] variant. /// - /// If the return value is [`Ok(n)`] then it must be guaranteed that `n <= - /// buf.len()`. Unless `input` is empty, this function shouldn’t return `0` - /// since caller may interpret that as an error (the default implementation - /// of [`Write::write_all`] does exactly that). To indicate lack of space + /// If this method consumed `n > 0` bytes of `buf` it must return [`Ok(n)`]. + /// If the return value is `Ok(n)` it must hold than `n <= buf.len()`. + /// Unless `input` is empty, this function shouldn’t return `Ok(0)` since + /// caller may interpret that as an error. To indicate lack of space /// function should return [`ErrorKind::StorageFull`] error instead. /// /// # Errors -- cgit 1.4.1-3-g733a5 From 5451dfe6c0c841c0a01d812eebb62e60576dbf89 Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Wed, 1 Mar 2023 00:48:22 +0100 Subject: Update library/std/src/io/mod.rs Co-authored-by: Andrew Gallant --- library/std/src/io/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index d4f8c3123b2..8e8fa147c0d 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -1394,9 +1394,9 @@ pub trait Write { /// /// If this method consumed `n > 0` bytes of `buf` it must return [`Ok(n)`]. /// If the return value is `Ok(n)` it must hold than `n <= buf.len()`. - /// Unless `input` is empty, this function shouldn’t return `Ok(0)` since - /// caller may interpret that as an error. To indicate lack of space - /// function should return [`ErrorKind::StorageFull`] error instead. + /// Unless `buf` is empty, this function shouldn’t return `Ok(0)` since the + /// caller may interpret that as an error. To indicate lack of space, + /// implementors should return [`ErrorKind::StorageFull`] error instead. /// /// # Errors /// -- cgit 1.4.1-3-g733a5 From 7d57cd524a33179be58287737b7fd603a9d4a759 Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Fri, 3 Mar 2023 03:16:56 +0100 Subject: Update library/std/src/io/mod.rs Co-authored-by: Jacob Lifshay --- library/std/src/io/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 8e8fa147c0d..b2fcb966032 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -1393,7 +1393,7 @@ pub trait Write { /// an [`Err`] variant. /// /// If this method consumed `n > 0` bytes of `buf` it must return [`Ok(n)`]. - /// If the return value is `Ok(n)` it must hold than `n <= buf.len()`. + /// If the return value is `Ok(n)` then `n` must satisfy `n <= buf.len()`. /// Unless `buf` is empty, this function shouldn’t return `Ok(0)` since the /// caller may interpret that as an error. To indicate lack of space, /// implementors should return [`ErrorKind::StorageFull`] error instead. -- cgit 1.4.1-3-g733a5 From 886085a4d567bc882038ce5ec8498c45b436412d Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 15 Jun 2023 15:56:00 -0700 Subject: std: only depend on dlmalloc for wasm*-unknown It was already filtered out for emscripten, but wasi doesn't need dlmalloc either since it reuses `unix/alloc.rs`. --- library/std/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index e6b05183886..af74efa6bf8 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -38,7 +38,7 @@ features = ['read_core', 'elf', 'macho', 'pe', 'unaligned', 'archive'] rand = { version = "0.8.5", default-features = false, features = ["alloc"] } rand_xorshift = "0.3.0" -[target.'cfg(any(all(target_family = "wasm", not(target_os = "emscripten")), all(target_vendor = "fortanix", target_env = "sgx")))'.dependencies] +[target.'cfg(any(all(target_family = "wasm", target_os = "unknown"), all(target_vendor = "fortanix", target_env = "sgx")))'.dependencies] dlmalloc = { version = "0.2.3", features = ['rustc-dep-of-std'] } [target.x86_64-fortanix-unknown-sgx.dependencies] -- cgit 1.4.1-3-g733a5 From 3078de76368a78ed0b481295393327b7296dcc95 Mon Sep 17 00:00:00 2001 From: DrMeepster <19316085+DrMeepster@users.noreply.github.com> Date: Fri, 16 Jun 2023 13:39:55 -0700 Subject: add dry_run check --- src/bootstrap/test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 13a10b0d3a5..01d0dbafd1e 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1766,7 +1766,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the // // Note that if we encounter `PATH` we make sure to append to our own `PATH` // rather than stomp over it. - if target.contains("msvc") { + if !builder.config.dry_run() && target.contains("msvc") { for &(ref k, ref v) in builder.cc.borrow()[&target].env() { if k != "PATH" { cmd.env(k, v); -- cgit 1.4.1-3-g733a5 From f874345784b0e1ac3cb7d03eb73cd23b2fc4dd85 Mon Sep 17 00:00:00 2001 From: dswij Date: Sat, 17 Jun 2023 15:59:56 +0800 Subject: `Bound::predicates` to return `Clause` --- compiler/rustc_hir_analysis/src/astconv/mod.rs | 6 +++-- compiler/rustc_hir_analysis/src/bounds.rs | 29 ++++++++++++++-------- .../rustc_hir_analysis/src/collect/item_bounds.rs | 12 +++++++-- .../src/collect/predicates_of.rs | 21 +++++++++++----- compiler/rustc_middle/src/ty/mod.rs | 7 ++++++ compiler/rustc_privacy/src/lib.rs | 6 ++--- 6 files changed, 57 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 221c7ce4f6f..7827890c51e 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -31,9 +31,10 @@ use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt}; use rustc_infer::traits::ObligationCause; use rustc_middle::middle::stability::AllowUnstable; use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef}; +use rustc_middle::ty::DynKind; use rustc_middle::ty::GenericParamDefKind; +use rustc_middle::ty::ToPredicate; use rustc_middle::ty::{self, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; -use rustc_middle::ty::{DynKind, ToPredicate}; use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::symbol::{kw, Ident, Symbol}; @@ -1509,7 +1510,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let mut trait_bounds = vec![]; let mut projection_bounds = vec![]; - for (pred, span) in bounds.predicates() { + for (clause, span) in bounds.predicates() { + let pred: ty::Predicate<'tcx> = clause.to_predicate(tcx); let bound_pred = pred.kind(); match bound_pred.skip_binder() { ty::PredicateKind::Clause(clause) => match clause { diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 686066abbf0..8a318e984d7 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -2,6 +2,7 @@ //! `ty` form from the HIR. use rustc_hir::LangItem; +use rustc_middle::ty::Binder; use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt}; use rustc_span::Span; @@ -23,52 +24,58 @@ use rustc_span::Span; /// include the self type (e.g., `trait_bounds`) but in others we do not #[derive(Default, PartialEq, Eq, Clone, Debug)] pub struct Bounds<'tcx> { - pub predicates: Vec<(ty::Predicate<'tcx>, Span)>, + pub predicates: Vec<(Binder<'tcx, ty::Clause<'tcx>>, Span)>, } impl<'tcx> Bounds<'tcx> { pub fn push_region_bound( &mut self, - tcx: TyCtxt<'tcx>, + _tcx: TyCtxt<'tcx>, region: ty::PolyTypeOutlivesPredicate<'tcx>, span: Span, ) { - self.predicates.push((region.to_predicate(tcx), span)); + self.predicates.push((region.map_bound(|p| ty::Clause::TypeOutlives(p)), span)); } pub fn push_trait_bound( &mut self, - tcx: TyCtxt<'tcx>, + _tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, span: Span, constness: ty::BoundConstness, polarity: ty::ImplPolarity, ) { self.predicates.push(( - trait_ref - .map_bound(|trait_ref| ty::TraitPredicate { trait_ref, constness, polarity }) - .to_predicate(tcx), + trait_ref.map_bound(|trait_ref| { + ty::Clause::Trait(ty::TraitPredicate { trait_ref, constness, polarity }) + }), span, )); } pub fn push_projection_bound( &mut self, - tcx: TyCtxt<'tcx>, + _tcx: TyCtxt<'tcx>, projection: ty::PolyProjectionPredicate<'tcx>, span: Span, ) { - self.predicates.push((projection.to_predicate(tcx), span)); + self.predicates.push((projection.map_bound(|proj| ty::Clause::Projection(proj)), span)); } pub fn push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) { let sized_def_id = tcx.require_lang_item(LangItem::Sized, Some(span)); let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [ty]); // Preferable to put this obligation first, since we report better errors for sized ambiguity. - self.predicates.insert(0, (trait_ref.without_const().to_predicate(tcx), span)); + self.predicates.insert( + 0, + ( + ty::Binder::dummy(ty::Clause::Trait(trait_ref.without_const().to_predicate(tcx))), + span, + ), + ); } - pub fn predicates(&self) -> impl Iterator, Span)> + '_ { + pub fn predicates(&self) -> impl Iterator>, Span)> + '_ { self.predicates.iter().cloned() } } diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 90e8e523ea3..0479efceaad 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -3,6 +3,7 @@ use crate::astconv::{AstConv, OnlySelfBounds}; use rustc_hir as hir; use rustc_infer::traits::util; use rustc_middle::ty::subst::InternalSubsts; +use rustc_middle::ty::ToPredicate; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::Span; @@ -44,7 +45,12 @@ fn associated_type_bounds<'tcx>( } }); - let all_bounds = tcx.arena.alloc_from_iter(bounds.predicates().chain(bounds_from_parent)); + let all_bounds = tcx.arena.alloc_from_iter( + bounds + .predicates() + .map(|(clause, span)| (clause.to_predicate(tcx), span)) + .chain(bounds_from_parent), + ); debug!( "associated_type_bounds({}) = {:?}", tcx.def_path_str(assoc_item_def_id.to_def_id()), @@ -72,7 +78,9 @@ fn opaque_type_bounds<'tcx>( icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span); debug!(?bounds); - tcx.arena.alloc_from_iter(bounds.predicates()) + tcx.arena.alloc_from_iter( + bounds.predicates().map(|(clause, span)| (clause.to_predicate(tcx), span)), + ) }) } diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index dcb57902928..fcbc5d5fcc1 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -126,7 +126,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen predicates.extend( icx.astconv() .compute_bounds(tcx.types.self_param, self_bounds, OnlySelfBounds(false)) - .predicates(), + .predicates() + .map(|(clause, span)| (clause.to_predicate(tcx), span)), ); } @@ -175,7 +176,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen param.span, ); trace!(?bounds); - predicates.extend(bounds.predicates()); + predicates.extend( + bounds.predicates().map(|(clause, span)| (clause.to_predicate(tcx), span)), + ); trace!(?predicates); } GenericParamKind::Const { .. } => { @@ -234,7 +237,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen bound_vars, OnlySelfBounds(false), ); - predicates.extend(bounds.predicates()); + predicates.extend( + bounds.predicates().map(|(clause, span)| (clause.to_predicate(tcx), span)), + ); } hir::WherePredicate::RegionPredicate(region_pred) => { @@ -658,8 +663,12 @@ pub(super) fn implied_predicates_with_filter( }; // Combine the two lists to form the complete set of superbounds: - let implied_bounds = - &*tcx.arena.alloc_from_iter(superbounds.predicates().chain(where_bounds_that_match)); + let implied_bounds = &*tcx.arena.alloc_from_iter( + superbounds + .predicates() + .map(|(clause, span)| (clause.to_predicate(tcx), span)) + .chain(where_bounds_that_match), + ); debug!(?implied_bounds); // Now require that immediate supertraits are converted, which will, in @@ -816,7 +825,7 @@ impl<'tcx> ItemCtxt<'tcx> { ); } - bounds.predicates().collect() + bounds.predicates().map(|(clause, span)| (clause.to_predicate(self.tcx), span)).collect() } #[instrument(level = "trace", skip(self))] diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index ff5d99794f1..32aeecea33e 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1214,6 +1214,13 @@ impl<'tcx> ToPredicate<'tcx> for Clause<'tcx> { } } +impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, Clause<'tcx>> { + #[inline(always)] + fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { + tcx.mk_predicate(self.map_bound(|clause| ty::PredicateKind::Clause(clause))) + } +} + impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> { #[inline(always)] fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 5ef11acadce..c2bbca737e5 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1270,13 +1270,13 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> { ); for (pred, _) in bounds.predicates() { - match pred.kind().skip_binder() { - ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) => { + match pred.skip_binder() { + ty::Clause::Trait(trait_predicate) => { if self.visit_trait(trait_predicate.trait_ref).is_break() { return; } } - ty::PredicateKind::Clause(ty::Clause::Projection(proj_predicate)) => { + ty::Clause::Projection(proj_predicate) => { let term = self.visit(proj_predicate.term); if term.is_break() || self.visit_projection_ty(proj_predicate.projection_ty).is_break() -- cgit 1.4.1-3-g733a5 From 52d3fc93f2194b0646e5447f29e6702b7c71ddae Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 15 Jun 2023 16:59:01 +0000 Subject: Move WF goal to clause --- compiler/rustc_borrowck/src/region_infer/opaque_types.rs | 3 ++- compiler/rustc_borrowck/src/type_check/mod.rs | 10 ++++++---- compiler/rustc_hir_analysis/src/astconv/mod.rs | 7 ++++--- compiler/rustc_hir_analysis/src/check/check.rs | 3 ++- .../rustc_hir_analysis/src/check/compare_impl_item.rs | 4 +++- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 5 +++-- compiler/rustc_hir_analysis/src/collect/predicates_of.rs | 2 +- compiler/rustc_hir_analysis/src/hir_wf_check.rs | 2 +- .../src/impl_wf_check/min_specialization.rs | 2 +- compiler/rustc_hir_analysis/src/outlives/explicit.rs | 2 +- compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 4 ++-- compiler/rustc_hir_typeck/src/method/mod.rs | 2 +- compiler/rustc_hir_typeck/src/method/probe.rs | 2 +- compiler/rustc_hir_typeck/src/method/suggest.rs | 5 ++++- compiler/rustc_infer/src/infer/combine.rs | 2 +- compiler/rustc_infer/src/infer/outlives/mod.rs | 2 +- compiler/rustc_infer/src/traits/util.rs | 2 +- compiler/rustc_lint/src/builtin.rs | 2 +- compiler/rustc_middle/src/ty/flags.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 16 ++++++++-------- compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- compiler/rustc_middle/src/ty/structural_impls.rs | 2 +- compiler/rustc_privacy/src/lib.rs | 2 +- compiler/rustc_trait_selection/src/solve/eval_ctxt.rs | 2 +- compiler/rustc_trait_selection/src/solve/fulfill.rs | 1 - compiler/rustc_trait_selection/src/traits/auto_trait.rs | 2 +- .../src/traits/error_reporting/mod.rs | 4 ++-- compiler/rustc_trait_selection/src/traits/fulfill.rs | 4 ++-- .../rustc_trait_selection/src/traits/object_safety.rs | 4 ++-- .../src/traits/query/type_op/ascribe_user_type.rs | 9 ++++++--- .../src/traits/query/type_op/implied_outlives_bounds.rs | 2 +- compiler/rustc_trait_selection/src/traits/select/mod.rs | 2 +- compiler/rustc_trait_selection/src/traits/wf.rs | 16 ++++++++++------ compiler/rustc_traits/src/chalk/lowering.rs | 8 ++++---- compiler/rustc_traits/src/normalize_erasing_regions.rs | 2 +- src/librustdoc/clean/mod.rs | 2 +- .../clippy/clippy_utils/src/qualify_min_const_fn.rs | 2 +- 37 files changed, 81 insertions(+), 64 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index b5d5071dc05..6ca702cfdfc 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -330,7 +330,8 @@ fn check_opaque_type_well_formed<'tcx>( // Require the hidden type to be well-formed with only the generics of the opaque type. // Defining use functions may have more bounds than the opaque type, which is ok, as long as the // hidden type is well formed even without those bounds. - let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into())); + let predicate = + ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(definition_ty.into()))); ocx.register_obligation(Obligation::misc(tcx, definition_span, def_id, param_env, predicate)); // Check that all obligations are satisfied by the implementation's diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 6697e1aff7d..33f75437478 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1419,9 +1419,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // // See #91068 for an example. self.prove_predicates( - sig.inputs_and_output - .iter() - .map(|ty| ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into()))), + sig.inputs_and_output.iter().map(|ty| { + ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed( + ty.into(), + ))) + }), term_location.to_locations(), ConstraintCategory::Boring, ); @@ -1850,7 +1852,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let array_ty = rvalue.ty(body.local_decls(), tcx); self.prove_predicate( - ty::PredicateKind::WellFormed(array_ty.into()), + ty::PredicateKind::Clause(ty::Clause::WellFormed(array_ty.into())), Locations::Single(location), ConstraintCategory::Boring, ); diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 221c7ce4f6f..3b55c52c342 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1527,10 +1527,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ty::Clause::TypeOutlives(_) => { // Do nothing, we deal with regions separately } - ty::Clause::RegionOutlives(_) | ty::Clause::ConstArgHasType(..) => bug!(), + ty::Clause::RegionOutlives(_) + | ty::Clause::ConstArgHasType(..) + | ty::Clause::WellFormed(_) => bug!(), }, - ty::PredicateKind::WellFormed(_) - | ty::PredicateKind::AliasRelate(..) + ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::ObjectSafe(_) | ty::PredicateKind::ClosureKind(_, _, _) | ty::PredicateKind::Subtype(_) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 17be5fe66cf..c09734d6e69 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -439,7 +439,8 @@ fn check_opaque_meets_bounds<'tcx>( // Additionally require the hidden type to be well-formed with only the generics of the opaque type. // Defining use functions may have more bounds than the opaque type, which is ok, as long as the // hidden type is well formed even without those bounds. - let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(hidden_ty.into())); + let predicate = + ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(hidden_ty.into()))); ocx.register_obligation(Obligation::new(tcx, misc_cause, param_env, predicate)); // Check that all obligations are satisfied by the implementation's diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 4fbe68b8b6c..838b212ef87 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -321,7 +321,9 @@ fn compare_method_predicate_entailment<'tcx>( infcx.tcx, ObligationCause::dummy(), param_env, - ty::Binder::dummy(ty::PredicateKind::WellFormed(unnormalized_impl_fty.into())), + ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed( + unnormalized_impl_fty.into(), + ))), )); } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index f93f395caed..132335e74ef 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -81,7 +81,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { self.tcx(), cause, param_env, - ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)), + ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(arg))), )); } } @@ -1876,7 +1876,8 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { // We lower empty bounds like `Vec:` as // `WellFormed(Vec)`, which will later get checked by // regular WF checking - if let ty::PredicateKind::WellFormed(..) = pred.kind().skip_binder() { + if let ty::PredicateKind::Clause(ty::Clause::WellFormed(..)) = pred.kind().skip_binder() + { continue; } // Match the existing behavior. diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index dcb57902928..843896d85aa 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -219,7 +219,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen } else { let span = bound_pred.bounded_ty.span; let predicate = ty::Binder::bind_with_vars( - ty::PredicateKind::WellFormed(ty.into()), + ty::PredicateKind::Clause(ty::Clause::WellFormed(ty.into())), bound_vars, ); predicates.insert((predicate.to_predicate(tcx), span)); diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index a653a652231..f2618b3daf1 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -79,7 +79,7 @@ fn diagnostic_hir_wf_check<'tcx>( self.tcx, cause, self.param_env, - ty::PredicateKind::WellFormed(tcx_ty.into()), + ty::PredicateKind::Clause(ty::Clause::WellFormed(tcx_ty.into())), )); for error in ocx.select_all_or_error() { diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index e84da2519ae..4517d24d154 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -542,7 +542,7 @@ fn trait_predicate_kind<'tcx>( | ty::PredicateKind::Clause(ty::Clause::Projection(_)) | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::AliasRelate(..) - | ty::PredicateKind::WellFormed(_) + | ty::PredicateKind::Clause(ty::Clause::WellFormed(_)) | ty::PredicateKind::Subtype(_) | ty::PredicateKind::Coerce(_) | ty::PredicateKind::ObjectSafe(_) diff --git a/compiler/rustc_hir_analysis/src/outlives/explicit.rs b/compiler/rustc_hir_analysis/src/outlives/explicit.rs index 7ce48fe1c01..ecdf8dca5c1 100644 --- a/compiler/rustc_hir_analysis/src/outlives/explicit.rs +++ b/compiler/rustc_hir_analysis/src/outlives/explicit.rs @@ -55,7 +55,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> { ty::PredicateKind::Clause(ty::Clause::Trait(..)) | ty::PredicateKind::Clause(ty::Clause::Projection(..)) | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) - | ty::PredicateKind::WellFormed(..) + | ty::PredicateKind::Clause(ty::Clause::WellFormed(..)) | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ClosureKind(..) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index fb56b7e74cb..9b593ddccfd 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -483,7 +483,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx, cause, self.param_env, - ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)), + ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(arg))), )); } @@ -668,7 +668,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::PredicateKind::Coerce(..) | ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..)) - | ty::PredicateKind::WellFormed(..) + | ty::PredicateKind::Clause(ty::Clause::WellFormed(..)) | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::ConstEvaluatable(..) diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 6f4d674ba10..cca97d10517 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -452,7 +452,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tcx, obligation.cause, self.param_env, - ty::Binder::dummy(ty::PredicateKind::WellFormed(method_ty.into())), + ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(method_ty.into()))), )); let callee = MethodCallee { def_id, substs, sig: fn_sig }; diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index b7b11ff8942..e4c2f61da56 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -838,7 +838,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { | ty::PredicateKind::Coerce(..) | ty::PredicateKind::Clause(ty::Clause::Projection(..)) | ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) - | ty::PredicateKind::WellFormed(..) + | ty::PredicateKind::Clause(ty::Clause::WellFormed(..)) | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..)) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 7a484e7ddc5..66e771b794a 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -696,7 +696,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // Don't point out the span of `WellFormed` predicates. - if !matches!(p.kind().skip_binder(), ty::PredicateKind::Clause(_)) { + if !matches!( + p.kind().skip_binder(), + ty::PredicateKind::Clause(ty::Clause::Projection(..) | ty::Clause::Trait(..)) + ) { continue; }; diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index bb2bd2faec2..152c56572b6 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -417,7 +417,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { self.tcx(), self.trace.cause.clone(), self.param_env, - ty::Binder::dummy(ty::PredicateKind::WellFormed(b_ty.into())), + ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(b_ty.into()))), )); } diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index 8a44d503159..3edf98cc869 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -29,7 +29,7 @@ pub fn explicit_outlives_bounds<'tcx>( | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::Subtype(..) - | ty::PredicateKind::WellFormed(..) + | ty::PredicateKind::Clause(ty::Clause::WellFormed(..)) | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..)) diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 74a78f38024..66056de03b5 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -227,7 +227,7 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> { debug!(?data, ?obligations, "super_predicates"); self.extend_deduped(obligations); } - ty::PredicateKind::WellFormed(..) => { + ty::PredicateKind::Clause(ty::Clause::WellFormed(..)) => { // Currently, we do not elaborate WF predicates, // although we easily could. } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index f02f3668dc1..6262d875552 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1610,7 +1610,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { Clause(Clause::Projection(..)) | AliasRelate(..) | // Ignore bounds that a user can't type - WellFormed(..) | + Clause(Clause::WellFormed(..)) | ObjectSafe(..) | ClosureKind(..) | Subtype(..) | diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 9cce9d64d5d..aa2af5bb2b0 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -270,7 +270,7 @@ impl FlagComputation { self.add_alias_ty(projection_ty); self.add_term(term); } - ty::PredicateKind::WellFormed(arg) => { + ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => { self.add_substs(slice::from_ref(&arg)); } ty::PredicateKind::ObjectSafe(_def_id) => {} diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index ff5d99794f1..155adda02a9 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -523,7 +523,7 @@ impl<'tcx> Predicate<'tcx> { ty::PredicateKind::Clause(ty::Clause::Trait(data)) => { tcx.trait_is_coinductive(data.def_id()) } - ty::PredicateKind::WellFormed(_) => true, + ty::PredicateKind::Clause(ty::Clause::WellFormed(_)) => true, _ => false, } } @@ -536,7 +536,7 @@ impl<'tcx> Predicate<'tcx> { #[inline] pub fn allow_normalization(self) -> bool { match self.kind().skip_binder() { - PredicateKind::WellFormed(_) => false, + PredicateKind::Clause(Clause::WellFormed(_)) => false, PredicateKind::Clause(Clause::Trait(_)) | PredicateKind::Clause(Clause::RegionOutlives(_)) | PredicateKind::Clause(Clause::TypeOutlives(_)) @@ -584,6 +584,9 @@ pub enum Clause<'tcx> { /// Ensures that a const generic argument to a parameter `const N: u8` /// is of type `u8`. ConstArgHasType(Const<'tcx>, Ty<'tcx>), + + /// No syntax: `T` well-formed. + WellFormed(GenericArg<'tcx>), } impl<'tcx> Binder<'tcx, Clause<'tcx>> { @@ -610,9 +613,6 @@ pub enum PredicateKind<'tcx> { /// Prove a clause Clause(Clause<'tcx>), - /// No syntax: `T` well-formed. - WellFormed(GenericArg<'tcx>), - /// Trait must be object-safe. ObjectSafe(DefId), @@ -1324,7 +1324,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::Subtype(..) | PredicateKind::Coerce(..) | PredicateKind::Clause(Clause::RegionOutlives(..)) - | PredicateKind::WellFormed(..) + | PredicateKind::Clause(Clause::WellFormed(..)) | PredicateKind::ObjectSafe(..) | PredicateKind::ClosureKind(..) | PredicateKind::Clause(Clause::TypeOutlives(..)) @@ -1345,7 +1345,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::Subtype(..) | PredicateKind::Coerce(..) | PredicateKind::Clause(Clause::RegionOutlives(..)) - | PredicateKind::WellFormed(..) + | PredicateKind::Clause(Clause::WellFormed(..)) | PredicateKind::ObjectSafe(..) | PredicateKind::ClosureKind(..) | PredicateKind::Clause(Clause::TypeOutlives(..)) @@ -1367,7 +1367,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::Subtype(..) | PredicateKind::Coerce(..) | PredicateKind::Clause(Clause::RegionOutlives(..)) - | PredicateKind::WellFormed(..) + | PredicateKind::Clause(Clause::WellFormed(..)) | PredicateKind::ObjectSafe(..) | PredicateKind::ClosureKind(..) | PredicateKind::ConstEvaluatable(..) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index f36b8ad8df6..4f8566c215c 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2877,7 +2877,7 @@ define_print_and_forward_display! { ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => { p!("the constant `", print(ct), "` has type `", print(ty), "`") }, - ty::PredicateKind::WellFormed(arg) => p!(print(arg), " well-formed"), + ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => p!(print(arg), " well-formed"), ty::PredicateKind::ObjectSafe(trait_def_id) => { p!("the trait `", print_def_path(trait_def_id, &[]), "` is object-safe") } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index a965450d27d..6db49c7300f 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -179,6 +179,7 @@ impl<'tcx> fmt::Debug for ty::Clause<'tcx> { ty::Clause::RegionOutlives(ref pair) => pair.fmt(f), ty::Clause::TypeOutlives(ref pair) => pair.fmt(f), ty::Clause::Projection(ref pair) => pair.fmt(f), + ty::Clause::WellFormed(ref data) => write!(f, "WellFormed({:?})", data), } } } @@ -189,7 +190,6 @@ impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> { ty::PredicateKind::Clause(ref a) => a.fmt(f), ty::PredicateKind::Subtype(ref pair) => pair.fmt(f), ty::PredicateKind::Coerce(ref pair) => pair.fmt(f), - ty::PredicateKind::WellFormed(data) => write!(f, "WellFormed({:?})", data), ty::PredicateKind::ObjectSafe(trait_def_id) => { write!(f, "ObjectSafe({:?})", trait_def_id) } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 5ef11acadce..0c23ae2b68f 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -183,7 +183,7 @@ where ty.visit_with(self) } ty::PredicateKind::ConstEvaluatable(ct) => ct.visit_with(self), - ty::PredicateKind::WellFormed(arg) => arg.visit_with(self), + ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => arg.visit_with(self), ty::PredicateKind::ObjectSafe(_) | ty::PredicateKind::ClosureKind(_, _, _) diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index 8592fc164d0..c353ddf6fdd 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -319,7 +319,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { ty::PredicateKind::ObjectSafe(trait_def_id) => { self.compute_object_safe_goal(trait_def_id) } - ty::PredicateKind::WellFormed(arg) => { + ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => { self.compute_well_formed_goal(Goal { param_env, predicate: arg }) } ty::PredicateKind::Ambiguous => { diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 212327448c8..ddc28e6128d 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -119,7 +119,6 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { ) } ty::PredicateKind::Clause(_) - | ty::PredicateKind::WellFormed(_) | ty::PredicateKind::ObjectSafe(_) | ty::PredicateKind::ClosureKind(_, _, _) | ty::PredicateKind::ConstEvaluatable(_) diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 62d2aad5277..03e01d61996 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -826,7 +826,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { // we start out with a `ParamEnv` with no inference variables, // and these don't correspond to adding any new bounds to // the `ParamEnv`. - ty::PredicateKind::WellFormed(..) + ty::PredicateKind::Clause(ty::Clause::WellFormed(..)) | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::ObjectSafe(..) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index ffbe2888bf8..558cd9ebf21 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1048,7 +1048,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.report_closure_error(&obligation, closure_def_id, found_kind, kind) } - ty::PredicateKind::WellFormed(ty) => { + ty::PredicateKind::Clause(ty::Clause::WellFormed(ty)) => { match self.tcx.sess.opts.unstable_opts.trait_solver { TraitSolver::Classic => { // WF predicates cannot themselves make @@ -2415,7 +2415,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err } - ty::PredicateKind::WellFormed(arg) => { + ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => { // Same hacky approach as above to avoid deluging user // with error messages. if arg.references_error() diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 88d2091de0f..c29e0178601 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -354,7 +354,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ty::PredicateKind::Clause(ty::Clause::RegionOutlives(_)) | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(_)) | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) - | ty::PredicateKind::WellFormed(_) + | ty::PredicateKind::Clause(ty::Clause::WellFormed(_)) | ty::PredicateKind::ObjectSafe(_) | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Subtype(_) @@ -433,7 +433,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { } } - ty::PredicateKind::WellFormed(arg) => { + ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => { match wf::obligations( self.selcx.infcx, obligation.param_env, diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index b2771915eef..3a197d78c5f 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -310,7 +310,7 @@ fn predicate_references_self<'tcx>( ty::PredicateKind::AliasRelate(..) => bug!("`AliasRelate` not allowed as assumption"), - ty::PredicateKind::WellFormed(..) + ty::PredicateKind::Clause(ty::Clause::WellFormed(..)) | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..)) | ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) @@ -361,7 +361,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool { | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) - | ty::PredicateKind::WellFormed(..) + | ty::PredicateKind::Clause(ty::Clause::WellFormed(..)) | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..)) diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs index 01d7a1e7913..7405ca31cde 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs @@ -67,7 +67,8 @@ fn relate_mir_and_user_ty<'tcx>( ocx.eq(&cause, param_env, mir_ty, user_ty)?; // FIXME(#104764): We should check well-formedness before normalization. - let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(user_ty.into())); + let predicate = + ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(user_ty.into()))); ocx.register_obligation(Obligation::new(ocx.infcx.tcx, cause, param_env, predicate)); Ok(()) } @@ -119,7 +120,9 @@ fn relate_mir_and_user_substs<'tcx>( let impl_self_ty = ocx.normalize(&cause, param_env, impl_self_ty); ocx.eq(&cause, param_env, self_ty, impl_self_ty)?; - let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(impl_self_ty.into())); + let predicate = ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed( + impl_self_ty.into(), + ))); ocx.register_obligation(Obligation::new(tcx, cause.clone(), param_env, predicate)); } @@ -134,7 +137,7 @@ fn relate_mir_and_user_substs<'tcx>( // them? This would only be relevant if some input // type were ill-formed but did not appear in `ty`, // which...could happen with normalization... - let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())); + let predicate = ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(ty.into()))); ocx.register_obligation(Obligation::new(tcx, cause, param_env, predicate)); Ok(()) } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index 9989fc9c479..90683d7e066 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -137,7 +137,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( | ty::PredicateKind::TypeWellFormedFromEnv(..) => {} // We need to search through *all* WellFormed predicates - ty::PredicateKind::WellFormed(arg) => { + ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => { wf_args.push(arg); } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index e72d3ca97d7..0a64ffc42b2 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -674,7 +674,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } - ty::PredicateKind::WellFormed(arg) => { + ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => { // So, there is a bit going on here. First, `WellFormed` predicates // are coinductive, like trait predicates with auto traits. // This means that we need to detect if we have recursively diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 92d899b0f13..ee609c34d1b 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -160,7 +160,7 @@ pub fn predicate_obligations<'tcx>( wf.compute(ct.into()); wf.compute(ty.into()); } - ty::PredicateKind::WellFormed(arg) => { + ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => { wf.compute(arg); } @@ -386,7 +386,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { cause, depth, param_env, - ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)), + ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(arg))), ) }), ); @@ -478,7 +478,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { cause.clone(), depth, param_env, - ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)), + ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(arg))), ) }), ); @@ -541,7 +541,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { cause, self.recursion_depth, self.param_env, - ty::Binder::dummy(ty::PredicateKind::WellFormed(ct.into())), + ty::Binder::dummy(ty::PredicateKind::Clause( + ty::Clause::WellFormed(ct.into()), + )), )); } ty::ConstKind::Expr(_) => { @@ -784,7 +786,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { cause, self.recursion_depth, param_env, - ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())), + ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed( + ty.into(), + ))), )); } } @@ -969,7 +973,7 @@ pub(crate) fn required_region_bounds<'tcx>( | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) - | ty::PredicateKind::WellFormed(..) + | ty::PredicateKind::Clause(ty::Clause::WellFormed(..)) | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index f9a7c8c386a..8112c3ed3b1 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -122,7 +122,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment match arg.unpack() { + ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => match arg.unpack() { ty::GenericArgKind::Type(ty) => chalk_ir::DomainGoal::WellFormed( chalk_ir::WellFormed::Ty(ty.lower_into(interner)), ), @@ -192,7 +192,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi chalk_ir::WhereClause::AliasEq(predicate.lower_into(interner)), )) } - ty::PredicateKind::WellFormed(arg) => match arg.unpack() { + ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => match arg.unpack() { GenericArgKind::Type(ty) => match ty.kind() { // FIXME(chalk): In Chalk, a placeholder is WellFormed if it // `FromEnv`. However, when we "lower" Params, we don't update @@ -672,7 +672,7 @@ impl<'tcx> LowerInto<'tcx, Option { Some(chalk_ir::WhereClause::AliasEq(predicate.lower_into(interner))) } - ty::PredicateKind::WellFormed(_ty) => None, + ty::PredicateKind::Clause(ty::Clause::WellFormed(_ty)) => None, ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => None, ty::PredicateKind::ObjectSafe(..) @@ -807,7 +807,7 @@ impl<'tcx> LowerInto<'tcx, Option None, - ty::PredicateKind::WellFormed(_ty) => None, + ty::PredicateKind::Clause(ty::Clause::WellFormed(_ty)) => None, ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => None, ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index 94c33efaeff..71357efae9b 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -62,7 +62,7 @@ fn not_outlives_predicate(p: ty::Predicate<'_>) -> bool { | ty::PredicateKind::Clause(ty::Clause::Projection(..)) | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::AliasRelate(..) - | ty::PredicateKind::WellFormed(..) + | ty::PredicateKind::Clause(ty::Clause::WellFormed(..)) | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Subtype(..) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 9f698a3b6bf..4ebe7e32276 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -345,7 +345,7 @@ pub(crate) fn clean_predicate<'tcx>( } // FIXME(generic_const_exprs): should this do something? ty::PredicateKind::ConstEvaluatable(..) => None, - ty::PredicateKind::WellFormed(..) => None, + ty::PredicateKind::Clause(ty::Clause::WellFormed(..)) => None, ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => None, ty::PredicateKind::Subtype(..) diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index c0d2c835d63..b132e69269d 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -33,7 +33,7 @@ pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv) | ty::Clause::Trait(..) | ty::Clause::ConstArgHasType(..), ) - | ty::PredicateKind::WellFormed(_) + | ty::PredicateKind::Clause(ty::Clause::WellFormed(_)) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => continue, -- cgit 1.4.1-3-g733a5 From 6594c75449fcf53474fb47182f1326b230cbcbe8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 15 Jun 2023 18:35:52 +0000 Subject: Move ConstEvaluatable to Clause --- compiler/rustc_hir_analysis/src/astconv/mod.rs | 4 ++-- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 4 ++-- compiler/rustc_hir_analysis/src/collect/predicates_of.rs | 2 +- .../src/impl_wf_check/min_specialization.rs | 2 +- compiler/rustc_hir_analysis/src/outlives/explicit.rs | 2 +- compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 +- .../src/fn_ctxt/adjust_fulfillment_errors.rs | 2 +- compiler/rustc_hir_typeck/src/method/probe.rs | 2 +- compiler/rustc_infer/src/infer/outlives/mod.rs | 2 +- compiler/rustc_infer/src/traits/util.rs | 2 +- compiler/rustc_lint/src/builtin.rs | 4 ++-- compiler/rustc_middle/src/ty/flags.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 16 +++++++--------- compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- compiler/rustc_middle/src/ty/structural_impls.rs | 6 +++--- compiler/rustc_privacy/src/lib.rs | 2 +- compiler/rustc_trait_selection/src/solve/eval_ctxt.rs | 2 +- compiler/rustc_trait_selection/src/solve/fulfill.rs | 1 - compiler/rustc_trait_selection/src/traits/auto_trait.rs | 2 +- .../src/traits/const_evaluatable.rs | 2 +- .../src/traits/error_reporting/mod.rs | 6 +++--- compiler/rustc_trait_selection/src/traits/fulfill.rs | 4 ++-- .../rustc_trait_selection/src/traits/object_safety.rs | 4 ++-- .../src/traits/query/type_op/implied_outlives_bounds.rs | 2 +- compiler/rustc_trait_selection/src/traits/select/mod.rs | 2 +- compiler/rustc_trait_selection/src/traits/wf.rs | 14 ++++++++------ compiler/rustc_traits/src/chalk/lowering.rs | 8 ++++---- compiler/rustc_traits/src/normalize_erasing_regions.rs | 2 +- src/librustdoc/clean/mod.rs | 2 +- .../clippy/clippy_utils/src/qualify_min_const_fn.rs | 2 +- 30 files changed, 54 insertions(+), 55 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 3b55c52c342..f29ed903c95 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1529,14 +1529,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } ty::Clause::RegionOutlives(_) | ty::Clause::ConstArgHasType(..) - | ty::Clause::WellFormed(_) => bug!(), + | ty::Clause::WellFormed(_) + | ty::Clause::ConstEvaluatable(_) => bug!(), }, ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::ObjectSafe(_) | ty::PredicateKind::ClosureKind(_, _, _) | ty::PredicateKind::Subtype(_) | ty::PredicateKind::Coerce(_) - | ty::PredicateKind::ConstEvaluatable(_) | ty::PredicateKind::ConstEquate(_, _) | ty::PredicateKind::TypeWellFormedFromEnv(_) | ty::PredicateKind::Ambiguous => bug!(), diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 132335e74ef..73a7ba005b3 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1032,9 +1032,9 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b tcx, cause, wfcx.param_env, - ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable( + ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable( ty::Const::from_anon_const(tcx, discr_def_id.expect_local()), - )), + ))), )); } } diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 843896d85aa..c67f82968f0 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -353,7 +353,7 @@ fn const_evaluatable_predicates_of( if let ty::ConstKind::Unevaluated(_) = ct.kind() { let span = self.tcx.def_span(c.def_id); self.preds.insert(( - ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ct)) + ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(ct))) .to_predicate(self.tcx), span, )); diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 4517d24d154..201cb94f0b3 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -547,7 +547,7 @@ fn trait_predicate_kind<'tcx>( | ty::PredicateKind::Coerce(_) | ty::PredicateKind::ObjectSafe(_) | ty::PredicateKind::ClosureKind(..) - | ty::PredicateKind::ConstEvaluatable(..) + | ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..)) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, diff --git a/compiler/rustc_hir_analysis/src/outlives/explicit.rs b/compiler/rustc_hir_analysis/src/outlives/explicit.rs index ecdf8dca5c1..79c56490f3c 100644 --- a/compiler/rustc_hir_analysis/src/outlives/explicit.rs +++ b/compiler/rustc_hir_analysis/src/outlives/explicit.rs @@ -61,7 +61,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> { | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) - | ty::PredicateKind::ConstEvaluatable(..) + | ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..)) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => (), diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 9b593ddccfd..34f98f4310e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -671,7 +671,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::PredicateKind::Clause(ty::Clause::WellFormed(..)) | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::AliasRelate(..) - | ty::PredicateKind::ConstEvaluatable(..) + | ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..)) | ty::PredicateKind::ConstEquate(..) // N.B., this predicate is created by breaking down a // `ClosureType: FnFoo()` predicate, where diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index 3efdab53438..2135643cbeb 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -32,7 +32,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(arg, ty)) => { vec![ty.into(), arg.into()] } - ty::PredicateKind::ConstEvaluatable(e) => vec![e.into()], + ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(e)) => vec![e.into()], _ => return false, }; diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index e4c2f61da56..91347c01327 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -842,7 +842,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..)) - | ty::PredicateKind::ConstEvaluatable(..) + | ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..)) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::Ambiguous | ty::PredicateKind::AliasRelate(..) diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index 3edf98cc869..c1f0b9253a5 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -33,7 +33,7 @@ pub fn explicit_outlives_bounds<'tcx>( | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..)) - | ty::PredicateKind::ConstEvaluatable(..) + | ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..)) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 66056de03b5..5622062ef7e 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -249,7 +249,7 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> { ty::PredicateKind::ClosureKind(..) => { // Nothing to elaborate when waiting for a closure's kind to be inferred. } - ty::PredicateKind::ConstEvaluatable(..) => { + ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..)) => { // Currently, we do not elaborate const-evaluatable // predicates. } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 6262d875552..785adc0b4fb 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1611,12 +1611,12 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { AliasRelate(..) | // Ignore bounds that a user can't type Clause(Clause::WellFormed(..)) | + // FIXME(generic_const_exprs): `ConstEvaluatable` can be written + Clause(Clause::ConstEvaluatable(..)) | ObjectSafe(..) | ClosureKind(..) | Subtype(..) | Coerce(..) | - // FIXME(generic_const_exprs): `ConstEvaluatable` can be written - ConstEvaluatable(..) | ConstEquate(..) | Ambiguous | TypeWellFormedFromEnv(..) => continue, diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index aa2af5bb2b0..684af1abdf6 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -277,7 +277,7 @@ impl FlagComputation { ty::PredicateKind::ClosureKind(_def_id, substs, _kind) => { self.add_substs(substs); } - ty::PredicateKind::ConstEvaluatable(uv) => { + ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(uv)) => { self.add_const(uv); } ty::PredicateKind::ConstEquate(expected, found) => { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 155adda02a9..e516e843d06 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -547,7 +547,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::ClosureKind(_, _, _) | PredicateKind::Subtype(_) | PredicateKind::Coerce(_) - | PredicateKind::ConstEvaluatable(_) + | PredicateKind::Clause(Clause::ConstEvaluatable(_)) | PredicateKind::ConstEquate(_, _) | PredicateKind::Ambiguous | PredicateKind::TypeWellFormedFromEnv(_) => true, @@ -587,6 +587,9 @@ pub enum Clause<'tcx> { /// No syntax: `T` well-formed. WellFormed(GenericArg<'tcx>), + + /// Constant initializer must evaluate successfully. + ConstEvaluatable(ty::Const<'tcx>), } impl<'tcx> Binder<'tcx, Clause<'tcx>> { @@ -638,9 +641,6 @@ pub enum PredicateKind<'tcx> { /// logic. Coerce(CoercePredicate<'tcx>), - /// Constant initializer must evaluate successfully. - ConstEvaluatable(ty::Const<'tcx>), - /// Constants must be equal. The first component is the const that is expected. ConstEquate(Const<'tcx>, Const<'tcx>), @@ -1328,7 +1328,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::ObjectSafe(..) | PredicateKind::ClosureKind(..) | PredicateKind::Clause(Clause::TypeOutlives(..)) - | PredicateKind::ConstEvaluatable(..) + | PredicateKind::Clause(Clause::ConstEvaluatable(..)) | PredicateKind::ConstEquate(..) | PredicateKind::Ambiguous | PredicateKind::TypeWellFormedFromEnv(..) => None, @@ -1349,7 +1349,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::ObjectSafe(..) | PredicateKind::ClosureKind(..) | PredicateKind::Clause(Clause::TypeOutlives(..)) - | PredicateKind::ConstEvaluatable(..) + | PredicateKind::Clause(Clause::ConstEvaluatable(..)) | PredicateKind::ConstEquate(..) | PredicateKind::Ambiguous | PredicateKind::TypeWellFormedFromEnv(..) => None, @@ -1370,7 +1370,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::Clause(Clause::WellFormed(..)) | PredicateKind::ObjectSafe(..) | PredicateKind::ClosureKind(..) - | PredicateKind::ConstEvaluatable(..) + | PredicateKind::Clause(Clause::ConstEvaluatable(..)) | PredicateKind::ConstEquate(..) | PredicateKind::Ambiguous | PredicateKind::TypeWellFormedFromEnv(..) => None, @@ -1384,10 +1384,8 @@ impl<'tcx> Predicate<'tcx> { PredicateKind::AliasRelate(..) | PredicateKind::Subtype(..) | PredicateKind::Coerce(..) - | PredicateKind::WellFormed(..) | PredicateKind::ObjectSafe(..) | PredicateKind::ClosureKind(..) - | PredicateKind::ConstEvaluatable(..) | PredicateKind::ConstEquate(..) | PredicateKind::Ambiguous | PredicateKind::TypeWellFormedFromEnv(..) => None, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 4f8566c215c..4bfed74f705 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2886,7 +2886,7 @@ define_print_and_forward_display! { print_value_path(closure_def_id, &[]), write("` implements the trait `{}`", kind) ), - ty::PredicateKind::ConstEvaluatable(ct) => { + ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(ct)) => { p!("the constant `", print(ct), "` can be evaluated") } ty::PredicateKind::ConstEquate(c1, c2) => { diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 6db49c7300f..a4a2fec07ec 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -180,6 +180,9 @@ impl<'tcx> fmt::Debug for ty::Clause<'tcx> { ty::Clause::TypeOutlives(ref pair) => pair.fmt(f), ty::Clause::Projection(ref pair) => pair.fmt(f), ty::Clause::WellFormed(ref data) => write!(f, "WellFormed({:?})", data), + ty::Clause::ConstEvaluatable(ct) => { + write!(f, "ConstEvaluatable({ct:?})") + } } } } @@ -196,9 +199,6 @@ impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> { ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => { write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind) } - ty::PredicateKind::ConstEvaluatable(ct) => { - write!(f, "ConstEvaluatable({ct:?})") - } ty::PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({:?}, {:?})", c1, c2), ty::PredicateKind::TypeWellFormedFromEnv(ty) => { write!(f, "TypeWellFormedFromEnv({:?})", ty) diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 0c23ae2b68f..08099190168 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -182,7 +182,7 @@ where ct.visit_with(self)?; ty.visit_with(self) } - ty::PredicateKind::ConstEvaluatable(ct) => ct.visit_with(self), + ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(ct)) => ct.visit_with(self), ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => arg.visit_with(self), ty::PredicateKind::ObjectSafe(_) diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index c353ddf6fdd..8625958ff5a 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -326,7 +326,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) } // FIXME: implement this predicate :) - ty::PredicateKind::ConstEvaluatable(_) => { + ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(_)) => { self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } ty::PredicateKind::ConstEquate(_, _) => { diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index ddc28e6128d..65c8d9c8f69 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -121,7 +121,6 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { ty::PredicateKind::Clause(_) | ty::PredicateKind::ObjectSafe(_) | ty::PredicateKind::ClosureKind(_, _, _) - | ty::PredicateKind::ConstEvaluatable(_) | ty::PredicateKind::Ambiguous => { FulfillmentErrorCode::CodeSelectionError( SelectionError::Unimplemented, diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 03e01d61996..56fde8cd70c 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -833,7 +833,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Subtype(..) // FIXME(generic_const_exprs): you can absolutely add this as a where clauses - | ty::PredicateKind::ConstEvaluatable(..) + | ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..)) | ty::PredicateKind::Coerce(..) => {} ty::PredicateKind::TypeWellFormedFromEnv(..) => { bug!("predicate should only exist in the environment: {bound_predicate:?}") diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index bd1ea43a78e..f8789b554b1 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -207,7 +207,7 @@ fn satisfied_from_param_env<'tcx>( for pred in param_env.caller_bounds() { match pred.kind().skip_binder() { - ty::PredicateKind::ConstEvaluatable(ce) => { + ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(ce)) => { let b_ct = tcx.expand_abstract_consts(ce); let mut v = Visitor { ct, infcx, param_env, single_match }; let _ = b_ct.visit_with(&mut v); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 558cd9ebf21..398ec28a426 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1069,7 +1069,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } - ty::PredicateKind::ConstEvaluatable(..) => { + ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..)) => { // Errors for `ConstEvaluatable` predicates show up as // `SelectionError::ConstEvalFailure`, // not `Unimplemented`. @@ -2487,7 +2487,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } - ty::PredicateKind::ConstEvaluatable(data) => { + ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(data)) => { if predicate.references_error() || self.tainted_by_errors().is_some() { return; } @@ -3325,7 +3325,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } match obligation.predicate.kind().skip_binder() { - ty::PredicateKind::ConstEvaluatable(ct) => { + ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(ct)) => { let ty::ConstKind::Unevaluated(uv) = ct.kind() else { bug!("const evaluatable failed for non-unevaluated const `{ct:?}`"); }; diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index c29e0178601..6e4bda3df03 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -359,7 +359,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Subtype(_) | ty::PredicateKind::Coerce(_) - | ty::PredicateKind::ConstEvaluatable(..) + | ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..)) | ty::PredicateKind::ConstEquate(..) => { let pred = ty::Binder::dummy(infcx.instantiate_binder_with_placeholders(binder)); @@ -498,7 +498,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { } } - ty::PredicateKind::ConstEvaluatable(uv) => { + ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(uv)) => { match const_evaluatable::is_const_evaluatable( self.selcx.infcx, uv, diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 3a197d78c5f..8c42df6e012 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -318,7 +318,7 @@ fn predicate_references_self<'tcx>( | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) // FIXME(generic_const_exprs): this can mention `Self` - | ty::PredicateKind::ConstEvaluatable(..) + | ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..)) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, @@ -365,7 +365,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool { | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..)) - | ty::PredicateKind::ConstEvaluatable(..) + | ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..)) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::Ambiguous diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index 90683d7e066..8761f4fea6c 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -130,7 +130,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( | ty::PredicateKind::Clause(ty::Clause::Projection(..)) | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::ObjectSafe(..) - | ty::PredicateKind::ConstEvaluatable(..) + | ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..)) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::Ambiguous | ty::PredicateKind::AliasRelate(..) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 0a64ffc42b2..ca2ae9b5235 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -862,7 +862,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } - ty::PredicateKind::ConstEvaluatable(uv) => { + ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(uv)) => { match const_evaluatable::is_const_evaluatable( self.infcx, uv, diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index ee609c34d1b..676978fabe4 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -164,7 +164,7 @@ pub fn predicate_obligations<'tcx>( wf.compute(arg); } - ty::PredicateKind::ConstEvaluatable(ct) => { + ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(ct)) => { wf.compute(ct.into()); } @@ -521,8 +521,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { let obligations = self.nominal_obligations(uv.def, uv.substs); self.out.extend(obligations); - let predicate = - ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ct)); + let predicate = ty::Binder::dummy(ty::PredicateKind::Clause( + ty::Clause::ConstEvaluatable(ct), + )); let cause = self.cause(traits::WellFormed(None)); self.out.push(traits::Obligation::with_depth( self.tcx(), @@ -554,8 +555,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { // the future we may allow directly lowering to `ConstKind::Expr` in which case // we would not be proving bounds we should. - let predicate = - ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ct)); + let predicate = ty::Binder::dummy(ty::PredicateKind::Clause( + ty::Clause::ConstEvaluatable(ct), + )); let cause = self.cause(traits::WellFormed(None)); self.out.push(traits::Obligation::with_depth( self.tcx(), @@ -977,7 +979,7 @@ pub(crate) fn required_region_bounds<'tcx>( | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) - | ty::PredicateKind::ConstEvaluatable(..) + | ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..)) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::Ambiguous | ty::PredicateKind::AliasRelate(..) diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 8112c3ed3b1..1d4219bc0c0 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -137,7 +137,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment bug!("unexpected predicate {}", predicate), }; @@ -231,7 +231,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::Coerce(..) - | ty::PredicateKind::ConstEvaluatable(..) + | ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..)) | ty::PredicateKind::Ambiguous | ty::PredicateKind::ConstEquate(..) => { chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner)) @@ -680,7 +680,7 @@ impl<'tcx> LowerInto<'tcx, Option { @@ -816,7 +816,7 @@ impl<'tcx> LowerInto<'tcx, Option { diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index 71357efae9b..7f6d53fe860 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -67,7 +67,7 @@ fn not_outlives_predicate(p: ty::Predicate<'_>) -> bool { | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) - | ty::PredicateKind::ConstEvaluatable(..) + | ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..)) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => true, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 4ebe7e32276..29c11e1f335 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -344,7 +344,7 @@ pub(crate) fn clean_predicate<'tcx>( Some(clean_projection_predicate(bound_predicate.rebind(pred), cx)) } // FIXME(generic_const_exprs): should this do something? - ty::PredicateKind::ConstEvaluatable(..) => None, + ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..)) => None, ty::PredicateKind::Clause(ty::Clause::WellFormed(..)) => None, ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => None, diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index b132e69269d..860a489494c 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -34,7 +34,7 @@ pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv) | ty::Clause::ConstArgHasType(..), ) | ty::PredicateKind::Clause(ty::Clause::WellFormed(_)) - | ty::PredicateKind::ConstEvaluatable(..) + | ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..)) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => continue, ty::PredicateKind::AliasRelate(..) => panic!("alias relate predicate on function: {predicate:#?}"), -- cgit 1.4.1-3-g733a5 From 4343d360793e428460f69d6df81acf6944d48fe8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 16 Jun 2023 18:24:43 +0000 Subject: Move some bounds computation out of astconv into its own file --- compiler/rustc_hir_analysis/src/astconv/bounds.rs | 583 ++++++++++++++++++++++ compiler/rustc_hir_analysis/src/astconv/mod.rs | 569 +-------------------- 2 files changed, 585 insertions(+), 567 deletions(-) create mode 100644 compiler/rustc_hir_analysis/src/astconv/bounds.rs diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs new file mode 100644 index 00000000000..e4eb0e6abd4 --- /dev/null +++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs @@ -0,0 +1,583 @@ +use rustc_data_structures::fx::FxHashMap; +use rustc_errors::struct_span_err; +use rustc_hir as hir; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_lint_defs::Applicability; +use rustc_middle::ty::{self as ty, Ty, TypeVisitableExt}; +use rustc_span::symbol::Ident; +use rustc_span::{ErrorGuaranteed, Span}; +use rustc_trait_selection::traits; + +use crate::astconv::{AstConv, ConvertedBinding, ConvertedBindingKind}; +use crate::bounds::Bounds; +use crate::errors::{MultipleRelaxedDefaultBounds, ValueOfAssociatedStructAlreadySpecified}; + +use super::OnlySelfBounds; + +impl<'tcx> dyn AstConv<'tcx> + '_ { + /// Sets `implicitly_sized` to true on `Bounds` if necessary + pub(crate) fn add_implicitly_sized( + &self, + bounds: &mut Bounds<'tcx>, + self_ty: Ty<'tcx>, + ast_bounds: &'tcx [hir::GenericBound<'tcx>], + self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, + span: Span, + ) { + let tcx = self.tcx(); + + // Try to find an unbound in bounds. + let mut unbound = None; + let mut search_bounds = |ast_bounds: &'tcx [hir::GenericBound<'tcx>]| { + for ab in ast_bounds { + if let hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = ab { + if unbound.is_none() { + unbound = Some(&ptr.trait_ref); + } else { + tcx.sess.emit_err(MultipleRelaxedDefaultBounds { span }); + } + } + } + }; + search_bounds(ast_bounds); + if let Some((self_ty, where_clause)) = self_ty_where_predicates { + for clause in where_clause { + if let hir::WherePredicate::BoundPredicate(pred) = clause { + if pred.is_param_bound(self_ty.to_def_id()) { + search_bounds(pred.bounds); + } + } + } + } + + let sized_def_id = tcx.lang_items().sized_trait(); + match (&sized_def_id, unbound) { + (Some(sized_def_id), Some(tpb)) + if tpb.path.res == Res::Def(DefKind::Trait, *sized_def_id) => + { + // There was in fact a `?Sized` bound, return without doing anything + return; + } + (_, Some(_)) => { + // There was a `?Trait` bound, but it was not `?Sized`; warn. + tcx.sess.span_warn( + span, + "default bound relaxed for a type parameter, but \ + this does nothing because the given bound is not \ + a default; only `?Sized` is supported", + ); + // Otherwise, add implicitly sized if `Sized` is available. + } + _ => { + // There was no `?Sized` bound; add implicitly sized if `Sized` is available. + } + } + if sized_def_id.is_none() { + // No lang item for `Sized`, so we can't add it as a bound. + return; + } + bounds.push_sized(tcx, self_ty, span); + } + + /// This helper takes a *converted* parameter type (`param_ty`) + /// and an *unconverted* list of bounds: + /// + /// ```text + /// fn foo + /// ^ ^^^^^ `ast_bounds` parameter, in HIR form + /// | + /// `param_ty`, in ty form + /// ``` + /// + /// It adds these `ast_bounds` into the `bounds` structure. + /// + /// **A note on binders:** there is an implied binder around + /// `param_ty` and `ast_bounds`. See `instantiate_poly_trait_ref` + /// for more details. + #[instrument(level = "debug", skip(self, ast_bounds, bounds))] + pub(crate) fn add_bounds<'hir, I: Iterator>>( + &self, + param_ty: Ty<'tcx>, + ast_bounds: I, + bounds: &mut Bounds<'tcx>, + bound_vars: &'tcx ty::List, + only_self_bounds: OnlySelfBounds, + ) { + for ast_bound in ast_bounds { + match ast_bound { + hir::GenericBound::Trait(poly_trait_ref, modifier) => { + let (constness, polarity) = match modifier { + hir::TraitBoundModifier::MaybeConst => { + (ty::BoundConstness::ConstIfConst, ty::ImplPolarity::Positive) + } + hir::TraitBoundModifier::None => { + (ty::BoundConstness::NotConst, ty::ImplPolarity::Positive) + } + hir::TraitBoundModifier::Negative => { + (ty::BoundConstness::NotConst, ty::ImplPolarity::Negative) + } + hir::TraitBoundModifier::Maybe => continue, + }; + let _ = self.instantiate_poly_trait_ref( + &poly_trait_ref.trait_ref, + poly_trait_ref.span, + constness, + polarity, + param_ty, + bounds, + false, + only_self_bounds, + ); + } + &hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => { + self.instantiate_lang_item_trait_ref( + lang_item, + span, + hir_id, + args, + param_ty, + bounds, + only_self_bounds, + ); + } + hir::GenericBound::Outlives(lifetime) => { + let region = self.ast_region_to_region(lifetime, None); + bounds.push_region_bound( + self.tcx(), + ty::Binder::bind_with_vars( + ty::OutlivesPredicate(param_ty, region), + bound_vars, + ), + lifetime.ident.span, + ); + } + } + } + } + + /// Translates a list of bounds from the HIR into the `Bounds` data structure. + /// The self-type for the bounds is given by `param_ty`. + /// + /// Example: + /// + /// ```ignore (illustrative) + /// fn foo() { } + /// // ^ ^^^^^^^^^ ast_bounds + /// // param_ty + /// ``` + /// + /// The `sized_by_default` parameter indicates if, in this context, the `param_ty` should be + /// considered `Sized` unless there is an explicit `?Sized` bound. This would be true in the + /// example above, but is not true in supertrait listings like `trait Foo: Bar + Baz`. + /// + /// `span` should be the declaration size of the parameter. + pub(crate) fn compute_bounds( + &self, + param_ty: Ty<'tcx>, + ast_bounds: &[hir::GenericBound<'_>], + only_self_bounds: OnlySelfBounds, + ) -> Bounds<'tcx> { + let mut bounds = Bounds::default(); + self.add_bounds( + param_ty, + ast_bounds.iter(), + &mut bounds, + ty::List::empty(), + only_self_bounds, + ); + debug!(?bounds); + + bounds + } + + /// Convert the bounds in `ast_bounds` that refer to traits which define an associated type + /// named `assoc_name` into ty::Bounds. Ignore the rest. + pub(crate) fn compute_bounds_that_match_assoc_item( + &self, + param_ty: Ty<'tcx>, + ast_bounds: &[hir::GenericBound<'_>], + assoc_name: Ident, + ) -> Bounds<'tcx> { + let mut result = Vec::new(); + + for ast_bound in ast_bounds { + if let Some(trait_ref) = ast_bound.trait_ref() + && let Some(trait_did) = trait_ref.trait_def_id() + && self.tcx().trait_may_define_assoc_item(trait_did, assoc_name) + { + result.push(ast_bound.clone()); + } + } + + let mut bounds = Bounds::default(); + self.add_bounds( + param_ty, + result.iter(), + &mut bounds, + ty::List::empty(), + OnlySelfBounds(true), + ); + debug!(?bounds); + + bounds + } + + /// Given an HIR binding like `Item = Foo` or `Item: Foo`, pushes the corresponding predicates + /// onto `bounds`. + /// + /// **A note on binders:** given something like `T: for<'a> Iterator`, the + /// `trait_ref` here will be `for<'a> T: Iterator`. The `binding` data however is from *inside* + /// the binder (e.g., `&'a u32`) and hence may reference bound regions. + #[instrument(level = "debug", skip(self, bounds, speculative, dup_bindings, path_span))] + pub(super) fn add_predicates_for_ast_type_binding( + &self, + hir_ref_id: hir::HirId, + trait_ref: ty::PolyTraitRef<'tcx>, + binding: &ConvertedBinding<'_, 'tcx>, + bounds: &mut Bounds<'tcx>, + speculative: bool, + dup_bindings: &mut FxHashMap, + path_span: Span, + constness: ty::BoundConstness, + only_self_bounds: OnlySelfBounds, + polarity: ty::ImplPolarity, + ) -> Result<(), ErrorGuaranteed> { + // Given something like `U: SomeTrait`, we want to produce a + // predicate like `::T = X`. This is somewhat + // subtle in the event that `T` is defined in a supertrait of + // `SomeTrait`, because in that case we need to upcast. + // + // That is, consider this case: + // + // ``` + // trait SubTrait: SuperTrait { } + // trait SuperTrait { type T; } + // + // ... B: SubTrait ... + // ``` + // + // We want to produce `>::T == foo`. + + let tcx = self.tcx(); + + let return_type_notation = + binding.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation; + + let candidate = if return_type_notation { + if self.trait_defines_associated_item_named( + trait_ref.def_id(), + ty::AssocKind::Fn, + binding.item_name, + ) { + trait_ref + } else { + self.one_bound_for_assoc_method( + traits::supertraits(tcx, trait_ref), + trait_ref.print_only_trait_path(), + binding.item_name, + path_span, + )? + } + } else if self.trait_defines_associated_item_named( + trait_ref.def_id(), + ty::AssocKind::Type, + binding.item_name, + ) { + // Simple case: X is defined in the current trait. + trait_ref + } else { + // Otherwise, we have to walk through the supertraits to find + // those that do. + self.one_bound_for_assoc_type( + || traits::supertraits(tcx, trait_ref), + trait_ref.skip_binder().print_only_trait_name(), + binding.item_name, + path_span, + match binding.kind { + ConvertedBindingKind::Equality(term) => Some(term), + _ => None, + }, + )? + }; + + let (assoc_ident, def_scope) = + tcx.adjust_ident_and_get_scope(binding.item_name, candidate.def_id(), hir_ref_id); + + // We have already adjusted the item name above, so compare with `ident.normalize_to_macros_2_0()` instead + // of calling `filter_by_name_and_kind`. + let find_item_of_kind = |kind| { + tcx.associated_items(candidate.def_id()) + .filter_by_name_unhygienic(assoc_ident.name) + .find(|i| i.kind == kind && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident) + }; + let assoc_item = if return_type_notation { + find_item_of_kind(ty::AssocKind::Fn) + } else { + find_item_of_kind(ty::AssocKind::Type) + .or_else(|| find_item_of_kind(ty::AssocKind::Const)) + } + .expect("missing associated type"); + + if !assoc_item.visibility(tcx).is_accessible_from(def_scope, tcx) { + tcx.sess + .struct_span_err( + binding.span, + format!("{} `{}` is private", assoc_item.kind, binding.item_name), + ) + .span_label(binding.span, format!("private {}", assoc_item.kind)) + .emit(); + } + tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), binding.span, None); + + if !speculative { + dup_bindings + .entry(assoc_item.def_id) + .and_modify(|prev_span| { + tcx.sess.emit_err(ValueOfAssociatedStructAlreadySpecified { + span: binding.span, + prev_span: *prev_span, + item_name: binding.item_name, + def_path: tcx.def_path_str(assoc_item.container_id(tcx)), + }); + }) + .or_insert(binding.span); + } + + let projection_ty = if return_type_notation { + let mut emitted_bad_param_err = false; + // If we have an method return type bound, then we need to substitute + // the method's early bound params with suitable late-bound params. + let mut num_bound_vars = candidate.bound_vars().len(); + let substs = + candidate.skip_binder().substs.extend_to(tcx, assoc_item.def_id, |param, _| { + let subst = match param.kind { + ty::GenericParamDefKind::Lifetime => ty::Region::new_late_bound( + tcx, + ty::INNERMOST, + ty::BoundRegion { + var: ty::BoundVar::from_usize(num_bound_vars), + kind: ty::BoundRegionKind::BrNamed(param.def_id, param.name), + }, + ) + .into(), + ty::GenericParamDefKind::Type { .. } => { + if !emitted_bad_param_err { + tcx.sess.emit_err( + crate::errors::ReturnTypeNotationIllegalParam::Type { + span: path_span, + param_span: tcx.def_span(param.def_id), + }, + ); + emitted_bad_param_err = true; + } + tcx.mk_bound( + ty::INNERMOST, + ty::BoundTy { + var: ty::BoundVar::from_usize(num_bound_vars), + kind: ty::BoundTyKind::Param(param.def_id, param.name), + }, + ) + .into() + } + ty::GenericParamDefKind::Const { .. } => { + if !emitted_bad_param_err { + tcx.sess.emit_err( + crate::errors::ReturnTypeNotationIllegalParam::Const { + span: path_span, + param_span: tcx.def_span(param.def_id), + }, + ); + emitted_bad_param_err = true; + } + let ty = tcx + .type_of(param.def_id) + .no_bound_vars() + .expect("ct params cannot have early bound vars"); + tcx.mk_const( + ty::ConstKind::Bound( + ty::INNERMOST, + ty::BoundVar::from_usize(num_bound_vars), + ), + ty, + ) + .into() + } + }; + num_bound_vars += 1; + subst + }); + + // Next, we need to check that the return-type notation is being used on + // an RPITIT (return-position impl trait in trait) or AFIT (async fn in trait). + let output = tcx.fn_sig(assoc_item.def_id).skip_binder().output(); + let output = if let ty::Alias(ty::Projection, alias_ty) = *output.skip_binder().kind() + && tcx.def_kind(alias_ty.def_id) == DefKind::ImplTraitPlaceholder + { + alias_ty + } else { + return Err(self.tcx().sess.emit_err( + crate::errors::ReturnTypeNotationOnNonRpitit { + span: binding.span, + ty: tcx.liberate_late_bound_regions(assoc_item.def_id, output), + fn_span: tcx.hir().span_if_local(assoc_item.def_id), + note: (), + }, + )); + }; + + // Finally, move the fn return type's bound vars over to account for the early bound + // params (and trait ref's late bound params). This logic is very similar to + // `Predicate::subst_supertrait`, and it's no coincidence why. + let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output); + let subst_output = ty::EarlyBinder::bind(shifted_output).subst(tcx, substs); + + let bound_vars = tcx.late_bound_vars(binding.hir_id); + ty::Binder::bind_with_vars(subst_output, bound_vars) + } else { + // Include substitutions for generic parameters of associated types + candidate.map_bound(|trait_ref| { + let ident = Ident::new(assoc_item.name, binding.item_name.span); + let item_segment = hir::PathSegment { + ident, + hir_id: binding.hir_id, + res: Res::Err, + args: Some(binding.gen_args), + infer_args: false, + }; + + let substs_trait_ref_and_assoc_item = self.create_substs_for_associated_item( + path_span, + assoc_item.def_id, + &item_segment, + trait_ref.substs, + ); + + debug!(?substs_trait_ref_and_assoc_item); + + tcx.mk_alias_ty(assoc_item.def_id, substs_trait_ref_and_assoc_item) + }) + }; + + if !speculative { + // Find any late-bound regions declared in `ty` that are not + // declared in the trait-ref or assoc_item. These are not well-formed. + // + // Example: + // + // for<'a> ::Item = &'a str // <-- 'a is bad + // for<'a> >::Output = &'a str // <-- 'a is ok + if let ConvertedBindingKind::Equality(ty) = binding.kind { + let late_bound_in_trait_ref = + tcx.collect_constrained_late_bound_regions(&projection_ty); + let late_bound_in_ty = + tcx.collect_referenced_late_bound_regions(&trait_ref.rebind(ty)); + debug!(?late_bound_in_trait_ref); + debug!(?late_bound_in_ty); + + // FIXME: point at the type params that don't have appropriate lifetimes: + // struct S1 Fn(&i32, &i32) -> &'a i32>(F); + // ---- ---- ^^^^^^^ + self.validate_late_bound_regions( + late_bound_in_trait_ref, + late_bound_in_ty, + |br_name| { + struct_span_err!( + tcx.sess, + binding.span, + E0582, + "binding for associated type `{}` references {}, \ + which does not appear in the trait input types", + binding.item_name, + br_name + ) + }, + ); + } + } + + match binding.kind { + ConvertedBindingKind::Equality(..) if return_type_notation => { + return Err(self.tcx().sess.emit_err( + crate::errors::ReturnTypeNotationEqualityBound { span: binding.span }, + )); + } + ConvertedBindingKind::Equality(mut term) => { + // "Desugar" a constraint like `T: Iterator` this to + // the "projection predicate" for: + // + // `::Item = u32` + let assoc_item_def_id = projection_ty.skip_binder().def_id; + let def_kind = tcx.def_kind(assoc_item_def_id); + match (def_kind, term.unpack()) { + (hir::def::DefKind::AssocTy, ty::TermKind::Ty(_)) + | (hir::def::DefKind::AssocConst, ty::TermKind::Const(_)) => (), + (_, _) => { + let got = if let Some(_) = term.ty() { "type" } else { "constant" }; + let expected = tcx.def_descr(assoc_item_def_id); + let mut err = tcx.sess.struct_span_err( + binding.span, + format!("expected {expected} bound, found {got}"), + ); + err.span_note( + tcx.def_span(assoc_item_def_id), + format!("{expected} defined here"), + ); + + if let hir::def::DefKind::AssocConst = def_kind + && let Some(t) = term.ty() && (t.is_enum() || t.references_error()) + && tcx.features().associated_const_equality { + err.span_suggestion( + binding.span, + "if equating a const, try wrapping with braces", + format!("{} = {{ const }}", binding.item_name), + Applicability::HasPlaceholders, + ); + } + let reported = err.emit(); + term = match def_kind { + hir::def::DefKind::AssocTy => tcx.ty_error(reported).into(), + hir::def::DefKind::AssocConst => tcx + .const_error( + tcx.type_of(assoc_item_def_id) + .subst(tcx, projection_ty.skip_binder().substs), + reported, + ) + .into(), + _ => unreachable!(), + }; + } + } + bounds.push_projection_bound( + tcx, + projection_ty + .map_bound(|projection_ty| ty::ProjectionPredicate { projection_ty, term }), + binding.span, + ); + } + ConvertedBindingKind::Constraint(ast_bounds) => { + // "Desugar" a constraint like `T: Iterator` to + // + // `::Item: Debug` + // + // Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty` + // parameter to have a skipped binder. + // + // NOTE: If `only_self_bounds` is true, do NOT expand this associated + // type bound into a trait predicate, since we only want to add predicates + // for the `Self` type. + if !only_self_bounds.0 { + let param_ty = tcx.mk_alias(ty::Projection, projection_ty.skip_binder()); + self.add_bounds( + param_ty, + ast_bounds.iter(), + bounds, + projection_ty.bound_vars(), + only_self_bounds, + ); + } + } + } + Ok(()) + } +} diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index f29ed903c95..d6645b784c4 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -2,6 +2,7 @@ //! The main routine here is `ast_ty_to_ty()`; each use is parameterized by an //! instance of `AstConv`. +mod bounds; mod errors; pub mod generics; mod lint; @@ -11,8 +12,7 @@ use crate::astconv::generics::{check_generic_arg_count, create_substs_for_generi use crate::bounds::Bounds; use crate::collect::HirPlaceholderCollector; use crate::errors::{ - AmbiguousLifetimeBound, MultipleRelaxedDefaultBounds, TraitObjectDeclaredWithNoTraits, - TypeofReservedKeywordUsed, ValueOfAssociatedStructAlreadySpecified, + AmbiguousLifetimeBound, TraitObjectDeclaredWithNoTraits, TypeofReservedKeywordUsed, }; use crate::middle::resolve_bound_vars as rbv; use crate::require_c_abi_if_c_variadic; @@ -885,571 +885,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .is_some() } - /// Sets `implicitly_sized` to true on `Bounds` if necessary - pub(crate) fn add_implicitly_sized( - &self, - bounds: &mut Bounds<'tcx>, - self_ty: Ty<'tcx>, - ast_bounds: &'tcx [hir::GenericBound<'tcx>], - self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, - span: Span, - ) { - let tcx = self.tcx(); - - // Try to find an unbound in bounds. - let mut unbound = None; - let mut search_bounds = |ast_bounds: &'tcx [hir::GenericBound<'tcx>]| { - for ab in ast_bounds { - if let hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = ab { - if unbound.is_none() { - unbound = Some(&ptr.trait_ref); - } else { - tcx.sess.emit_err(MultipleRelaxedDefaultBounds { span }); - } - } - } - }; - search_bounds(ast_bounds); - if let Some((self_ty, where_clause)) = self_ty_where_predicates { - for clause in where_clause { - if let hir::WherePredicate::BoundPredicate(pred) = clause { - if pred.is_param_bound(self_ty.to_def_id()) { - search_bounds(pred.bounds); - } - } - } - } - - let sized_def_id = tcx.lang_items().sized_trait(); - match (&sized_def_id, unbound) { - (Some(sized_def_id), Some(tpb)) - if tpb.path.res == Res::Def(DefKind::Trait, *sized_def_id) => - { - // There was in fact a `?Sized` bound, return without doing anything - return; - } - (_, Some(_)) => { - // There was a `?Trait` bound, but it was not `?Sized`; warn. - tcx.sess.span_warn( - span, - "default bound relaxed for a type parameter, but \ - this does nothing because the given bound is not \ - a default; only `?Sized` is supported", - ); - // Otherwise, add implicitly sized if `Sized` is available. - } - _ => { - // There was no `?Sized` bound; add implicitly sized if `Sized` is available. - } - } - if sized_def_id.is_none() { - // No lang item for `Sized`, so we can't add it as a bound. - return; - } - bounds.push_sized(tcx, self_ty, span); - } - - /// This helper takes a *converted* parameter type (`param_ty`) - /// and an *unconverted* list of bounds: - /// - /// ```text - /// fn foo - /// ^ ^^^^^ `ast_bounds` parameter, in HIR form - /// | - /// `param_ty`, in ty form - /// ``` - /// - /// It adds these `ast_bounds` into the `bounds` structure. - /// - /// **A note on binders:** there is an implied binder around - /// `param_ty` and `ast_bounds`. See `instantiate_poly_trait_ref` - /// for more details. - #[instrument(level = "debug", skip(self, ast_bounds, bounds))] - pub(crate) fn add_bounds<'hir, I: Iterator>>( - &self, - param_ty: Ty<'tcx>, - ast_bounds: I, - bounds: &mut Bounds<'tcx>, - bound_vars: &'tcx ty::List, - only_self_bounds: OnlySelfBounds, - ) { - for ast_bound in ast_bounds { - match ast_bound { - hir::GenericBound::Trait(poly_trait_ref, modifier) => { - let (constness, polarity) = match modifier { - hir::TraitBoundModifier::MaybeConst => { - (ty::BoundConstness::ConstIfConst, ty::ImplPolarity::Positive) - } - hir::TraitBoundModifier::None => { - (ty::BoundConstness::NotConst, ty::ImplPolarity::Positive) - } - hir::TraitBoundModifier::Negative => { - (ty::BoundConstness::NotConst, ty::ImplPolarity::Negative) - } - hir::TraitBoundModifier::Maybe => continue, - }; - let _ = self.instantiate_poly_trait_ref( - &poly_trait_ref.trait_ref, - poly_trait_ref.span, - constness, - polarity, - param_ty, - bounds, - false, - only_self_bounds, - ); - } - &hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => { - self.instantiate_lang_item_trait_ref( - lang_item, - span, - hir_id, - args, - param_ty, - bounds, - only_self_bounds, - ); - } - hir::GenericBound::Outlives(lifetime) => { - let region = self.ast_region_to_region(lifetime, None); - bounds.push_region_bound( - self.tcx(), - ty::Binder::bind_with_vars( - ty::OutlivesPredicate(param_ty, region), - bound_vars, - ), - lifetime.ident.span, - ); - } - } - } - } - - /// Translates a list of bounds from the HIR into the `Bounds` data structure. - /// The self-type for the bounds is given by `param_ty`. - /// - /// Example: - /// - /// ```ignore (illustrative) - /// fn foo() { } - /// // ^ ^^^^^^^^^ ast_bounds - /// // param_ty - /// ``` - /// - /// The `sized_by_default` parameter indicates if, in this context, the `param_ty` should be - /// considered `Sized` unless there is an explicit `?Sized` bound. This would be true in the - /// example above, but is not true in supertrait listings like `trait Foo: Bar + Baz`. - /// - /// `span` should be the declaration size of the parameter. - pub(crate) fn compute_bounds( - &self, - param_ty: Ty<'tcx>, - ast_bounds: &[hir::GenericBound<'_>], - only_self_bounds: OnlySelfBounds, - ) -> Bounds<'tcx> { - let mut bounds = Bounds::default(); - self.add_bounds( - param_ty, - ast_bounds.iter(), - &mut bounds, - ty::List::empty(), - only_self_bounds, - ); - debug!(?bounds); - - bounds - } - - /// Convert the bounds in `ast_bounds` that refer to traits which define an associated type - /// named `assoc_name` into ty::Bounds. Ignore the rest. - pub(crate) fn compute_bounds_that_match_assoc_item( - &self, - param_ty: Ty<'tcx>, - ast_bounds: &[hir::GenericBound<'_>], - assoc_name: Ident, - ) -> Bounds<'tcx> { - let mut result = Vec::new(); - - for ast_bound in ast_bounds { - if let Some(trait_ref) = ast_bound.trait_ref() - && let Some(trait_did) = trait_ref.trait_def_id() - && self.tcx().trait_may_define_assoc_item(trait_did, assoc_name) - { - result.push(ast_bound.clone()); - } - } - - let mut bounds = Bounds::default(); - self.add_bounds( - param_ty, - result.iter(), - &mut bounds, - ty::List::empty(), - OnlySelfBounds(true), - ); - debug!(?bounds); - - bounds - } - - /// Given an HIR binding like `Item = Foo` or `Item: Foo`, pushes the corresponding predicates - /// onto `bounds`. - /// - /// **A note on binders:** given something like `T: for<'a> Iterator`, the - /// `trait_ref` here will be `for<'a> T: Iterator`. The `binding` data however is from *inside* - /// the binder (e.g., `&'a u32`) and hence may reference bound regions. - #[instrument(level = "debug", skip(self, bounds, speculative, dup_bindings, path_span))] - fn add_predicates_for_ast_type_binding( - &self, - hir_ref_id: hir::HirId, - trait_ref: ty::PolyTraitRef<'tcx>, - binding: &ConvertedBinding<'_, 'tcx>, - bounds: &mut Bounds<'tcx>, - speculative: bool, - dup_bindings: &mut FxHashMap, - path_span: Span, - constness: ty::BoundConstness, - only_self_bounds: OnlySelfBounds, - polarity: ty::ImplPolarity, - ) -> Result<(), ErrorGuaranteed> { - // Given something like `U: SomeTrait`, we want to produce a - // predicate like `::T = X`. This is somewhat - // subtle in the event that `T` is defined in a supertrait of - // `SomeTrait`, because in that case we need to upcast. - // - // That is, consider this case: - // - // ``` - // trait SubTrait: SuperTrait { } - // trait SuperTrait { type T; } - // - // ... B: SubTrait ... - // ``` - // - // We want to produce `>::T == foo`. - - let tcx = self.tcx(); - - let return_type_notation = - binding.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation; - - let candidate = if return_type_notation { - if self.trait_defines_associated_item_named( - trait_ref.def_id(), - ty::AssocKind::Fn, - binding.item_name, - ) { - trait_ref - } else { - self.one_bound_for_assoc_method( - traits::supertraits(tcx, trait_ref), - trait_ref.print_only_trait_path(), - binding.item_name, - path_span, - )? - } - } else if self.trait_defines_associated_item_named( - trait_ref.def_id(), - ty::AssocKind::Type, - binding.item_name, - ) { - // Simple case: X is defined in the current trait. - trait_ref - } else { - // Otherwise, we have to walk through the supertraits to find - // those that do. - self.one_bound_for_assoc_type( - || traits::supertraits(tcx, trait_ref), - trait_ref.skip_binder().print_only_trait_name(), - binding.item_name, - path_span, - match binding.kind { - ConvertedBindingKind::Equality(term) => Some(term), - _ => None, - }, - )? - }; - - let (assoc_ident, def_scope) = - tcx.adjust_ident_and_get_scope(binding.item_name, candidate.def_id(), hir_ref_id); - - // We have already adjusted the item name above, so compare with `ident.normalize_to_macros_2_0()` instead - // of calling `filter_by_name_and_kind`. - let find_item_of_kind = |kind| { - tcx.associated_items(candidate.def_id()) - .filter_by_name_unhygienic(assoc_ident.name) - .find(|i| i.kind == kind && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident) - }; - let assoc_item = if return_type_notation { - find_item_of_kind(ty::AssocKind::Fn) - } else { - find_item_of_kind(ty::AssocKind::Type) - .or_else(|| find_item_of_kind(ty::AssocKind::Const)) - } - .expect("missing associated type"); - - if !assoc_item.visibility(tcx).is_accessible_from(def_scope, tcx) { - tcx.sess - .struct_span_err( - binding.span, - format!("{} `{}` is private", assoc_item.kind, binding.item_name), - ) - .span_label(binding.span, format!("private {}", assoc_item.kind)) - .emit(); - } - tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), binding.span, None); - - if !speculative { - dup_bindings - .entry(assoc_item.def_id) - .and_modify(|prev_span| { - tcx.sess.emit_err(ValueOfAssociatedStructAlreadySpecified { - span: binding.span, - prev_span: *prev_span, - item_name: binding.item_name, - def_path: tcx.def_path_str(assoc_item.container_id(tcx)), - }); - }) - .or_insert(binding.span); - } - - let projection_ty = if return_type_notation { - let mut emitted_bad_param_err = false; - // If we have an method return type bound, then we need to substitute - // the method's early bound params with suitable late-bound params. - let mut num_bound_vars = candidate.bound_vars().len(); - let substs = - candidate.skip_binder().substs.extend_to(tcx, assoc_item.def_id, |param, _| { - let subst = match param.kind { - GenericParamDefKind::Lifetime => ty::Region::new_late_bound( - tcx, - ty::INNERMOST, - ty::BoundRegion { - var: ty::BoundVar::from_usize(num_bound_vars), - kind: ty::BoundRegionKind::BrNamed(param.def_id, param.name), - }, - ) - .into(), - GenericParamDefKind::Type { .. } => { - if !emitted_bad_param_err { - tcx.sess.emit_err( - crate::errors::ReturnTypeNotationIllegalParam::Type { - span: path_span, - param_span: tcx.def_span(param.def_id), - }, - ); - emitted_bad_param_err = true; - } - tcx.mk_bound( - ty::INNERMOST, - ty::BoundTy { - var: ty::BoundVar::from_usize(num_bound_vars), - kind: ty::BoundTyKind::Param(param.def_id, param.name), - }, - ) - .into() - } - GenericParamDefKind::Const { .. } => { - if !emitted_bad_param_err { - tcx.sess.emit_err( - crate::errors::ReturnTypeNotationIllegalParam::Const { - span: path_span, - param_span: tcx.def_span(param.def_id), - }, - ); - emitted_bad_param_err = true; - } - let ty = tcx - .type_of(param.def_id) - .no_bound_vars() - .expect("ct params cannot have early bound vars"); - tcx.mk_const( - ty::ConstKind::Bound( - ty::INNERMOST, - ty::BoundVar::from_usize(num_bound_vars), - ), - ty, - ) - .into() - } - }; - num_bound_vars += 1; - subst - }); - - // Next, we need to check that the return-type notation is being used on - // an RPITIT (return-position impl trait in trait) or AFIT (async fn in trait). - let output = tcx.fn_sig(assoc_item.def_id).skip_binder().output(); - let output = if let ty::Alias(ty::Projection, alias_ty) = *output.skip_binder().kind() - && tcx.def_kind(alias_ty.def_id) == DefKind::ImplTraitPlaceholder - { - alias_ty - } else { - return Err(self.tcx().sess.emit_err( - crate::errors::ReturnTypeNotationOnNonRpitit { - span: binding.span, - ty: tcx.liberate_late_bound_regions(assoc_item.def_id, output), - fn_span: tcx.hir().span_if_local(assoc_item.def_id), - note: (), - }, - )); - }; - - // Finally, move the fn return type's bound vars over to account for the early bound - // params (and trait ref's late bound params). This logic is very similar to - // `Predicate::subst_supertrait`, and it's no coincidence why. - let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output); - let subst_output = ty::EarlyBinder::bind(shifted_output).subst(tcx, substs); - - let bound_vars = tcx.late_bound_vars(binding.hir_id); - ty::Binder::bind_with_vars(subst_output, bound_vars) - } else { - // Include substitutions for generic parameters of associated types - candidate.map_bound(|trait_ref| { - let ident = Ident::new(assoc_item.name, binding.item_name.span); - let item_segment = hir::PathSegment { - ident, - hir_id: binding.hir_id, - res: Res::Err, - args: Some(binding.gen_args), - infer_args: false, - }; - - let substs_trait_ref_and_assoc_item = self.create_substs_for_associated_item( - path_span, - assoc_item.def_id, - &item_segment, - trait_ref.substs, - ); - - debug!(?substs_trait_ref_and_assoc_item); - - tcx.mk_alias_ty(assoc_item.def_id, substs_trait_ref_and_assoc_item) - }) - }; - - if !speculative { - // Find any late-bound regions declared in `ty` that are not - // declared in the trait-ref or assoc_item. These are not well-formed. - // - // Example: - // - // for<'a> ::Item = &'a str // <-- 'a is bad - // for<'a> >::Output = &'a str // <-- 'a is ok - if let ConvertedBindingKind::Equality(ty) = binding.kind { - let late_bound_in_trait_ref = - tcx.collect_constrained_late_bound_regions(&projection_ty); - let late_bound_in_ty = - tcx.collect_referenced_late_bound_regions(&trait_ref.rebind(ty)); - debug!(?late_bound_in_trait_ref); - debug!(?late_bound_in_ty); - - // FIXME: point at the type params that don't have appropriate lifetimes: - // struct S1 Fn(&i32, &i32) -> &'a i32>(F); - // ---- ---- ^^^^^^^ - self.validate_late_bound_regions( - late_bound_in_trait_ref, - late_bound_in_ty, - |br_name| { - struct_span_err!( - tcx.sess, - binding.span, - E0582, - "binding for associated type `{}` references {}, \ - which does not appear in the trait input types", - binding.item_name, - br_name - ) - }, - ); - } - } - - match binding.kind { - ConvertedBindingKind::Equality(..) if return_type_notation => { - return Err(self.tcx().sess.emit_err( - crate::errors::ReturnTypeNotationEqualityBound { span: binding.span }, - )); - } - ConvertedBindingKind::Equality(mut term) => { - // "Desugar" a constraint like `T: Iterator` this to - // the "projection predicate" for: - // - // `::Item = u32` - let assoc_item_def_id = projection_ty.skip_binder().def_id; - let def_kind = tcx.def_kind(assoc_item_def_id); - match (def_kind, term.unpack()) { - (hir::def::DefKind::AssocTy, ty::TermKind::Ty(_)) - | (hir::def::DefKind::AssocConst, ty::TermKind::Const(_)) => (), - (_, _) => { - let got = if let Some(_) = term.ty() { "type" } else { "constant" }; - let expected = tcx.def_descr(assoc_item_def_id); - let mut err = tcx.sess.struct_span_err( - binding.span, - format!("expected {expected} bound, found {got}"), - ); - err.span_note( - tcx.def_span(assoc_item_def_id), - format!("{expected} defined here"), - ); - - if let hir::def::DefKind::AssocConst = def_kind - && let Some(t) = term.ty() && (t.is_enum() || t.references_error()) - && tcx.features().associated_const_equality { - err.span_suggestion( - binding.span, - "if equating a const, try wrapping with braces", - format!("{} = {{ const }}", binding.item_name), - Applicability::HasPlaceholders, - ); - } - let reported = err.emit(); - term = match def_kind { - hir::def::DefKind::AssocTy => tcx.ty_error(reported).into(), - hir::def::DefKind::AssocConst => tcx - .const_error( - tcx.type_of(assoc_item_def_id) - .subst(tcx, projection_ty.skip_binder().substs), - reported, - ) - .into(), - _ => unreachable!(), - }; - } - } - bounds.push_projection_bound( - tcx, - projection_ty - .map_bound(|projection_ty| ty::ProjectionPredicate { projection_ty, term }), - binding.span, - ); - } - ConvertedBindingKind::Constraint(ast_bounds) => { - // "Desugar" a constraint like `T: Iterator` to - // - // `::Item: Debug` - // - // Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty` - // parameter to have a skipped binder. - // - // NOTE: If `only_self_bounds` is true, do NOT expand this associated - // type bound into a trait predicate, since we only want to add predicates - // for the `Self` type. - if !only_self_bounds.0 { - let param_ty = tcx.mk_alias(ty::Projection, projection_ty.skip_binder()); - self.add_bounds( - param_ty, - ast_bounds.iter(), - bounds, - projection_ty.bound_vars(), - only_self_bounds, - ); - } - } - } - Ok(()) - } - fn ast_path_to_ty( &self, span: Span, -- cgit 1.4.1-3-g733a5