diff options
| author | Dylan MacKenzie <ecstaticmorse@gmail.com> | 2020-01-13 20:30:32 -0800 |
|---|---|---|
| committer | Dylan MacKenzie <ecstaticmorse@gmail.com> | 2020-01-20 00:00:08 -0800 |
| commit | d2aefbb286c94240e25cbe0b8cc92a1336db5408 (patch) | |
| tree | 0fa0e7fb17b128b2fcdd454efc945bca905159ae | |
| parent | ab3081a70e5d402188c26c6f3e671a3c44812d1b (diff) | |
| download | rust-d2aefbb286c94240e25cbe0b8cc92a1336db5408.tar.gz rust-d2aefbb286c94240e25cbe0b8cc92a1336db5408.zip | |
Add `ConstnessAnd` that implements `ToPredicate`
| -rw-r--r-- | src/librustc/traits/engine.rs | 4 | ||||
| -rw-r--r-- | src/librustc/traits/error_reporting/mod.rs | 28 | ||||
| -rw-r--r-- | src/librustc/traits/error_reporting/suggestions.rs | 17 | ||||
| -rw-r--r-- | src/librustc/traits/mod.rs | 4 | ||||
| -rw-r--r-- | src/librustc/traits/object_safety.rs | 6 | ||||
| -rw-r--r-- | src/librustc/traits/project.rs | 11 | ||||
| -rw-r--r-- | src/librustc/traits/select.rs | 4 | ||||
| -rw-r--r-- | src/librustc/traits/util.rs | 25 | ||||
| -rw-r--r-- | src/librustc/traits/wf.rs | 10 | ||||
| -rw-r--r-- | src/librustc/ty/mod.rs | 56 | ||||
| -rw-r--r-- | src/librustc/ty/sty.rs | 10 | ||||
| -rw-r--r-- | src/librustc_ty/ty.rs | 3 | ||||
| -rw-r--r-- | src/librustc_typeck/astconv.rs | 4 | ||||
| -rw-r--r-- | src/librustc_typeck/check/autoderef.rs | 9 | ||||
| -rw-r--r-- | src/librustc_typeck/check/method/mod.rs | 4 | ||||
| -rw-r--r-- | src/librustc_typeck/check/method/probe.rs | 3 | ||||
| -rw-r--r-- | src/librustc_typeck/check/method/suggest.rs | 4 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 4 | ||||
| -rw-r--r-- | src/librustc_typeck/check/wfcheck.rs | 7 | ||||
| -rw-r--r-- | src/librustc_typeck/collect.rs | 12 | ||||
| -rw-r--r-- | src/librustdoc/clean/blanket_impl.rs | 4 |
21 files changed, 155 insertions, 74 deletions
diff --git a/src/librustc/traits/engine.rs b/src/librustc/traits/engine.rs index 5b804480119..84bfc86e6a9 100644 --- a/src/librustc/traits/engine.rs +++ b/src/librustc/traits/engine.rs @@ -1,6 +1,6 @@ use crate::infer::InferCtxt; use crate::traits::Obligation; -use crate::ty::{self, ToPredicate, Ty, TyCtxt}; +use crate::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness}; use rustc_hir::def_id::DefId; use super::{ChalkFulfillmentContext, FulfillmentContext, FulfillmentError}; @@ -33,7 +33,7 @@ pub trait TraitEngine<'tcx>: 'tcx { cause, recursion_depth: 0, param_env, - predicate: trait_ref.to_predicate(), + predicate: trait_ref.without_const().to_predicate(), }, ); } diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs index db3173989ac..2d02dbf8230 100644 --- a/src/librustc/traits/error_reporting/mod.rs +++ b/src/librustc/traits/error_reporting/mod.rs @@ -19,7 +19,9 @@ use crate::ty::error::ExpectedFound; use crate::ty::fast_reject; use crate::ty::fold::TypeFolder; use crate::ty::SubtypePredicate; -use crate::ty::{self, AdtKind, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{ + self, AdtKind, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, +}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; @@ -130,7 +132,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } let (cond, error) = match (cond, error) { - (&ty::Predicate::Trait(..), &ty::Predicate::Trait(ref error)) => (cond, error), + (&ty::Predicate::Trait(..), &ty::Predicate::Trait(ref error, _)) => (cond, error), _ => { // FIXME: make this work in other cases too. return false; @@ -138,7 +140,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }; for implication in super::elaborate_predicates(self.tcx, vec![cond.clone()]) { - if let ty::Predicate::Trait(implication) = implication { + if let ty::Predicate::Trait(implication, _) = implication { let error = error.to_poly_trait_ref(); let implication = implication.to_poly_trait_ref(); // FIXME: I'm just not taking associated types at all here. @@ -530,7 +532,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { return; } match obligation.predicate { - ty::Predicate::Trait(ref trait_predicate) => { + ty::Predicate::Trait(ref trait_predicate, _) => { let trait_predicate = self.resolve_vars_if_possible(trait_predicate); if self.tcx.sess.has_errors() && trait_predicate.references_error() { @@ -583,7 +585,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "{}", message.unwrap_or_else(|| format!( "the trait bound `{}` is not satisfied{}", - trait_ref.to_predicate(), + trait_ref.without_const().to_predicate(), post_message, )) ); @@ -695,7 +697,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { trait_pred }); let unit_obligation = Obligation { - predicate: ty::Predicate::Trait(predicate), + predicate: ty::Predicate::Trait( + predicate, + ast::Constness::NotConst, + ), ..obligation.clone() }; if self.predicate_may_hold(&unit_obligation) { @@ -988,7 +993,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ) -> PredicateObligation<'tcx> { let new_trait_ref = ty::TraitRef { def_id, substs: self.tcx.mk_substs_trait(output_ty, &[]) }; - Obligation::new(cause, param_env, new_trait_ref.to_predicate()) + Obligation::new(cause, param_env, new_trait_ref.without_const().to_predicate()) } } @@ -1076,7 +1081,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } let mut err = match predicate { - ty::Predicate::Trait(ref data) => { + ty::Predicate::Trait(ref data, _) => { let trait_ref = data.to_poly_trait_ref(); let self_ty = trait_ref.self_ty(); debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.kind, trait_ref); @@ -1269,8 +1274,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ) .value; - let obligation = - Obligation::new(ObligationCause::dummy(), param_env, cleaned_pred.to_predicate()); + let obligation = Obligation::new( + ObligationCause::dummy(), + param_env, + cleaned_pred.without_const().to_predicate(), + ); self.predicate_may_hold(&obligation) }) diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index c09fd307973..9d8fa362ebb 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -6,7 +6,7 @@ use super::{ use crate::infer::InferCtxt; use crate::traits::object_safety::object_safety_violations; use crate::ty::TypeckTables; -use crate::ty::{self, AdtKind, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{self, AdtKind, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; use rustc_errors::{ error_code, pluralize, struct_span_err, Applicability, DiagnosticBuilder, Style, @@ -50,7 +50,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } else { " where" }, - trait_ref.to_predicate(), + trait_ref.without_const().to_predicate(), ), Applicability::MachineApplicable, ); @@ -340,8 +340,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let new_self_ty = self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, self_ty); let substs = self.tcx.mk_substs_trait(new_self_ty, &[]); let new_trait_ref = ty::TraitRef::new(obligation.parent_trait_ref.def_id(), substs); - let new_obligation = - Obligation::new(ObligationCause::dummy(), param_env, new_trait_ref.to_predicate()); + let new_obligation = Obligation::new( + ObligationCause::dummy(), + param_env, + new_trait_ref.without_const().to_predicate(), + ); if self.predicate_must_hold_modulo_regions(&new_obligation) { if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { // We have a very specific type of error, where just borrowing this argument @@ -1122,7 +1125,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // the type. The last generator has information about where the bound was introduced. At // least one generator should be present for this diagnostic to be modified. let (mut trait_ref, mut target_ty) = match obligation.predicate { - ty::Predicate::Trait(p) => { + ty::Predicate::Trait(p, _) => { (Some(p.skip_binder().trait_ref), Some(p.skip_binder().self_ty())) } _ => (None, None), @@ -1545,7 +1548,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err.note(&format!("required because it appears within the type `{}`", ty)); obligated_types.push(ty); - let parent_predicate = parent_trait_ref.to_predicate(); + let parent_predicate = parent_trait_ref.without_const().to_predicate(); if !self.is_recursive_obligation(obligated_types, &data.parent_code) { self.note_obligation_cause_code( err, @@ -1562,7 +1565,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { parent_trait_ref.print_only_trait_path(), parent_trait_ref.skip_binder().self_ty() )); - let parent_predicate = parent_trait_ref.to_predicate(); + let parent_predicate = parent_trait_ref.without_const().to_predicate(); self.note_obligation_cause_code( err, &parent_predicate, diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 2e5da2b0382..7819366f892 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -29,7 +29,7 @@ use crate::mir::interpret::ErrorHandled; use crate::ty::error::{ExpectedFound, TypeError}; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::subst::{InternalSubsts, SubstsRef}; -use crate::ty::{self, AdtKind, GenericParamDefKind, List, ToPredicate, Ty, TyCtxt}; +use crate::ty::{self, AdtKind, GenericParamDefKind, List, ToPredicate, Ty, TyCtxt, WithConstness}; use crate::util::common::ErrorReported; use chalk_engine; use rustc_hir as hir; @@ -732,7 +732,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>( param_env, cause: ObligationCause::misc(span, hir::DUMMY_HIR_ID), recursion_depth: 0, - predicate: trait_ref.to_predicate(), + predicate: trait_ref.without_const().to_predicate(), }; let result = infcx.predicate_must_hold_modulo_regions(&obligation); diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index ad6b821b1d7..15f81bb3f47 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -12,7 +12,7 @@ use super::elaborate_predicates; use crate::traits::{self, Obligation, ObligationCause}; use crate::ty::subst::{InternalSubsts, Subst}; -use crate::ty::{self, Predicate, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{self, Predicate, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY; @@ -585,6 +585,7 @@ fn receiver_is_dispatchable<'tcx>( def_id: unsize_did, substs: tcx.mk_substs_trait(tcx.types.self_param, &[unsized_self_ty.into()]), } + .without_const() .to_predicate(); // U: Trait<Arg1, ..., ArgN> @@ -598,7 +599,7 @@ fn receiver_is_dispatchable<'tcx>( } }); - ty::TraitRef { def_id: unsize_did, substs }.to_predicate() + ty::TraitRef { def_id: unsize_did, substs }.without_const().to_predicate() }; let caller_bounds: Vec<Predicate<'tcx>> = param_env @@ -620,6 +621,7 @@ fn receiver_is_dispatchable<'tcx>( def_id: dispatch_from_dyn_did, substs: tcx.mk_substs_trait(receiver_ty, &[unsized_receiver_ty.into()]), } + .without_const() .to_predicate(); Obligation::new(ObligationCause::dummy(), param_env, predicate) diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 5bc211ade40..62672a78104 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -16,7 +16,7 @@ use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime}; use crate::ty::fold::{TypeFoldable, TypeFolder}; use crate::ty::subst::{InternalSubsts, Subst}; -use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt}; +use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness}; use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap}; use rustc_hir::def_id::DefId; use rustc_macros::HashStable; @@ -738,7 +738,12 @@ fn get_paranoid_cache_value_obligation<'a, 'tcx>( depth: usize, ) -> PredicateObligation<'tcx> { let trait_ref = projection_ty.trait_ref(infcx.tcx).to_poly_trait_ref(); - Obligation { cause, recursion_depth: depth, param_env, predicate: trait_ref.to_predicate() } + Obligation { + cause, + recursion_depth: depth, + param_env, + predicate: trait_ref.without_const().to_predicate(), + } } /// If we are projecting `<T as Trait>::Item`, but `T: Trait` does not @@ -772,7 +777,7 @@ fn normalize_to_error<'a, 'tcx>( cause, recursion_depth: depth, param_env, - predicate: trait_ref.to_predicate(), + predicate: trait_ref.without_const().to_predicate(), }; let tcx = selcx.infcx().tcx; let def_id = projection_ty.item_def_id; diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 9db907e88fa..ac1ca4db9d6 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -37,7 +37,7 @@ use crate::middle::lang_items; use crate::ty::fast_reject; use crate::ty::relate::TypeRelation; use crate::ty::subst::{Subst, SubstsRef}; -use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; use rustc_hir::def_id::DefId; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -3368,7 +3368,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { tcx.require_lang_item(lang_items::SizedTraitLangItem, None), tcx.mk_substs_trait(source, &[]), ); - nested.push(predicate_to_obligation(tr.to_predicate())); + nested.push(predicate_to_obligation(tr.without_const().to_predicate())); // If the type is `Foo + 'a`, ensure that the type // being cast to `Foo + 'a` outlives `'a`: diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index a5a16a14712..f3bd98b8551 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -4,7 +4,7 @@ use smallvec::SmallVec; use crate::ty::outlives::Component; use crate::ty::subst::{GenericArg, Subst, SubstsRef}; -use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt}; +use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness}; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -99,14 +99,14 @@ pub fn elaborate_trait_ref<'tcx>( tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, ) -> Elaborator<'tcx> { - elaborate_predicates(tcx, vec![trait_ref.to_predicate()]) + elaborate_predicates(tcx, vec![trait_ref.without_const().to_predicate()]) } pub fn elaborate_trait_refs<'tcx>( tcx: TyCtxt<'tcx>, trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>, ) -> Elaborator<'tcx> { - let predicates = trait_refs.map(|trait_ref| trait_ref.to_predicate()).collect(); + let predicates = trait_refs.map(|trait_ref| trait_ref.without_const().to_predicate()).collect(); elaborate_predicates(tcx, predicates) } @@ -358,7 +358,7 @@ impl<'tcx> TraitAliasExpander<'tcx> { fn expand(&mut self, item: &TraitAliasExpansionInfo<'tcx>) -> bool { let tcx = self.tcx; let trait_ref = item.trait_ref(); - let pred = trait_ref.to_predicate(); + let pred = trait_ref.without_const().to_predicate(); debug!("expand_trait_aliases: trait_ref={:?}", trait_ref); @@ -370,13 +370,9 @@ impl<'tcx> TraitAliasExpander<'tcx> { // Don't recurse if this trait alias is already on the stack for the DFS search. let anon_pred = anonymize_predicate(tcx, &pred); - if item - .path - .iter() - .rev() - .skip(1) - .any(|(tr, _)| anonymize_predicate(tcx, &tr.to_predicate()) == anon_pred) - { + if item.path.iter().rev().skip(1).any(|(tr, _)| { + anonymize_predicate(tcx, &tr.without_const().to_predicate()) == anon_pred + }) { return false; } @@ -545,7 +541,12 @@ pub fn predicate_for_trait_ref<'tcx>( trait_ref: ty::TraitRef<'tcx>, recursion_depth: usize, ) -> PredicateObligation<'tcx> { - Obligation { cause, param_env, recursion_depth, predicate: trait_ref.to_predicate() } + Obligation { + cause, + param_env, + recursion_depth, + predicate: trait_ref.without_const().to_predicate(), + } } pub fn predicate_for_trait_def( diff --git a/src/librustc/traits/wf.rs b/src/librustc/traits/wf.rs index aba09c3c818..a0cb8446c92 100644 --- a/src/librustc/traits/wf.rs +++ b/src/librustc/traits/wf.rs @@ -3,7 +3,7 @@ use crate::infer::InferCtxt; use crate::middle::lang_items; use crate::traits::{self, AssocTypeBoundData}; use crate::ty::subst::SubstsRef; -use crate::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_span::symbol::{kw, Ident}; @@ -350,7 +350,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { self.compute_trait_ref(&trait_ref, Elaborate::None); if !data.has_escaping_bound_vars() { - let predicate = trait_ref.to_predicate(); + let predicate = trait_ref.without_const().to_predicate(); let cause = self.cause(traits::ProjectionWf(data)); self.out.push(traits::Obligation::new(cause, self.param_env, predicate)); } @@ -378,7 +378,11 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { def_id: self.infcx.tcx.require_lang_item(lang_items::SizedTraitLangItem, None), substs: self.infcx.tcx.mk_substs_trait(subty, &[]), }; - self.out.push(traits::Obligation::new(cause, self.param_env, trait_ref.to_predicate())); + self.out.push(traits::Obligation::new( + cause, + self.param_env, + trait_ref.without_const().to_predicate(), + )); } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index c5fbf2896a4..0470ab20dc4 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -52,7 +52,7 @@ use std::ops::Deref; use std::ops::Range; use std::slice; use std::{mem, ptr}; -use syntax::ast::{self, Ident, Name, NodeId}; +use syntax::ast::{self, Constness, Ident, Name, NodeId}; use syntax::attr; pub use self::sty::BoundRegion::*; @@ -1072,7 +1072,7 @@ pub enum Predicate<'tcx> { /// A trait predicate will have `Constness::Const` if it originates /// from a bound on a `const fn` without the `?const` opt-out (e.g., /// `const fn foobar<Foo: Bar>() {}`). - Trait(PolyTraitPredicate<'tcx>, ast::Constness), + Trait(PolyTraitPredicate<'tcx>, Constness), /// `where 'a: 'b` RegionOutlives(PolyRegionOutlivesPredicate<'tcx>), @@ -1340,18 +1340,33 @@ pub trait ToPredicate<'tcx> { fn to_predicate(&self) -> Predicate<'tcx>; } -impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> { +impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<TraitRef<'tcx>> { fn to_predicate(&self) -> Predicate<'tcx> { ty::Predicate::Trait( - ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.clone() }), - ast::Constness::NotConst, + ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.value.clone() }), + self.constness, ) } } -impl<'tcx> ToPredicate<'tcx> for PolyTraitRef<'tcx> { +impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<&TraitRef<'tcx>> { fn to_predicate(&self) -> Predicate<'tcx> { - ty::Predicate::Trait(self.to_poly_trait_predicate(), ast::Constness::NotConst) + ty::Predicate::Trait( + ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.value.clone() }), + self.constness, + ) + } +} + +impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<PolyTraitRef<'tcx>> { + fn to_predicate(&self) -> Predicate<'tcx> { + ty::Predicate::Trait(self.value.to_poly_trait_predicate(), self.constness) + } +} + +impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<&PolyTraitRef<'tcx>> { + fn to_predicate(&self) -> Predicate<'tcx> { + ty::Predicate::Trait(self.value.to_poly_trait_predicate(), self.constness) } } @@ -1707,6 +1722,33 @@ impl<'tcx> ParamEnv<'tcx> { } } +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub struct ConstnessAnd<T> { + pub constness: Constness, + pub value: T, +} + +// FIXME(ecstaticmorse): Audit all occurrences of `without_const().to_predicate()` to ensure that +// the constness of trait bounds is being propagated correctly. +pub trait WithConstness: Sized { + #[inline] + fn with_constness(self, constness: Constness) -> ConstnessAnd<Self> { + ConstnessAnd { constness, value: self } + } + + #[inline] + fn with_const(self) -> ConstnessAnd<Self> { + self.with_constness(Constness::Const) + } + + #[inline] + fn without_const(self) -> ConstnessAnd<Self> { + self.with_constness(Constness::NotConst) + } +} + +impl<T> WithConstness for T {} + #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)] pub struct ParamEnvAnd<'tcx, T> { pub param_env: ParamEnv<'tcx>, diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 84236128482..13f623aadb1 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -12,7 +12,9 @@ use crate::mir::interpret::Scalar; use crate::mir::Promoted; use crate::ty::layout::VariantIdx; use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef}; -use crate::ty::{self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable}; +use crate::ty::{ + self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable, WithConstness, +}; use crate::ty::{List, ParamEnv, ParamEnvAnd, TyS}; use polonius_engine::Atom; use rustc_data_structures::captures::Captures; @@ -665,14 +667,16 @@ impl<'tcx> Binder<ExistentialPredicate<'tcx>> { pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> { use crate::ty::ToPredicate; match *self.skip_binder() { - ExistentialPredicate::Trait(tr) => Binder(tr).with_self_ty(tcx, self_ty).to_predicate(), + ExistentialPredicate::Trait(tr) => { + Binder(tr).with_self_ty(tcx, self_ty).without_const().to_predicate() + } ExistentialPredicate::Projection(p) => { ty::Predicate::Projection(Binder(p.with_self_ty(tcx, self_ty))) } ExistentialPredicate::AutoTrait(did) => { let trait_ref = Binder(ty::TraitRef { def_id: did, substs: tcx.mk_substs_trait(self_ty, &[]) }); - trait_ref.to_predicate() + trait_ref.without_const().to_predicate() } } } diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs index d47e54366b5..8b62403e6ce 100644 --- a/src/librustc_ty/ty.rs +++ b/src/librustc_ty/ty.rs @@ -2,7 +2,7 @@ use rustc::hir::map as hir_map; use rustc::session::CrateDisambiguator; use rustc::traits::{self}; use rustc::ty::subst::Subst; -use rustc::ty::{self, ToPredicate, Ty, TyCtxt}; +use rustc::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness}; use rustc_data_structures::svh::Svh; use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; @@ -58,6 +58,7 @@ fn sized_constraint_for_ty(tcx: TyCtxt<'tcx>, adtdef: &ty::AdtDef, ty: Ty<'tcx>) def_id: sized_trait, substs: tcx.mk_substs_trait(ty, &[]), }) + .without_const() .to_predicate(); let predicates = tcx.predicates_of(adtdef.did).predicates; if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 7f196b2c4d3..9253c00e5ae 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -17,7 +17,7 @@ use rustc::traits::astconv_object_safety_violations; use rustc::traits::error_reporting::report_object_safety_error; use rustc::traits::wf::object_region_bounds; use rustc::ty::subst::{self, InternalSubsts, Subst, SubstsRef}; -use rustc::ty::{self, Const, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use rustc::ty::{self, Const, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; use rustc::ty::{GenericParamDef, GenericParamDefKind}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId}; @@ -2980,7 +2980,7 @@ impl<'tcx> Bounds<'tcx> { def_id: sized, substs: tcx.mk_substs_trait(param_ty, &[]), }); - (trait_ref.to_predicate(), span) + (trait_ref.without_const().to_predicate(), span) }) }); diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs index 8d6b74c3015..367fe0c3cc1 100644 --- a/src/librustc_typeck/check/autoderef.rs +++ b/src/librustc_typeck/check/autoderef.rs @@ -5,7 +5,7 @@ use rustc::infer::{InferCtxt, InferOk}; use rustc::session::DiagnosticMessageId; use rustc::traits::{self, TraitEngine}; use rustc::ty::adjustment::{Adjust, Adjustment, OverloadedDeref}; -use rustc::ty::{self, TraitRef, Ty, TyCtxt}; +use rustc::ty::{self, TraitRef, Ty, TyCtxt, WithConstness}; use rustc::ty::{ToPredicate, TypeFoldable}; use rustc_errors::struct_span_err; use rustc_hir as hir; @@ -124,8 +124,11 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { let cause = traits::ObligationCause::misc(self.span, self.body_id); - let obligation = - traits::Obligation::new(cause.clone(), self.param_env, trait_ref.to_predicate()); + let obligation = traits::Obligation::new( + cause.clone(), + self.param_env, + trait_ref.without_const().to_predicate(), + ); if !self.infcx.predicate_may_hold(&obligation) { debug!("overloaded_deref_ty: cannot match obligation"); return None; diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 711c285d17e..c1cf3522b5d 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -17,7 +17,7 @@ use rustc::traits; use rustc::ty::subst::Subst; use rustc::ty::subst::{InternalSubsts, SubstsRef}; use rustc::ty::GenericParamDefKind; -use rustc::ty::{self, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TypeFoldable}; +use rustc::ty::{self, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TypeFoldable, WithConstness}; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir as hir; @@ -322,7 +322,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span, self.body_id, self.param_env, - poly_trait_ref.to_predicate(), + poly_trait_ref.without_const().to_predicate(), ); // Now we want to know if this can be matched diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 67526bb70d1..ff2f150c633 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -25,6 +25,7 @@ use rustc::ty::subst::{InternalSubsts, Subst, SubstsRef}; use rustc::ty::GenericParamDefKind; use rustc::ty::{ self, ParamEnvAnd, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable, + WithConstness, }; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; @@ -1396,7 +1397,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } TraitCandidate(trait_ref) => { - let predicate = trait_ref.to_predicate(); + let predicate = trait_ref.without_const().to_predicate(); let obligation = traits::Obligation::new(cause, self.param_env, predicate); if !self.predicate_may_hold(&obligation) { if self.probe(|_| self.select_trait_candidate(trait_ref).is_err()) { diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index d6c0d9c77b4..35fffd3bcd4 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -9,7 +9,7 @@ use rustc::hir::map::Map; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc::traits::Obligation; use rustc::ty::print::with_crate_prefix; -use rustc::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use rustc::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; @@ -59,7 +59,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span, self.body_id, self.param_env, - poly_trait_ref.to_predicate(), + poly_trait_ref.without_const().to_predicate(), ); self.predicate_may_hold(&obligation) }) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 7c1876f5d44..1e3927f33a7 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -112,7 +112,7 @@ use rustc::ty::subst::{GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSel use rustc::ty::util::{Discr, IntTypeExt, Representability}; use rustc::ty::{ self, AdtKind, CanonicalUserType, Const, GenericParamDefKind, RegionKind, ToPolyTraitRef, - ToPredicate, Ty, TyCtxt, UserType, + ToPredicate, Ty, TyCtxt, UserType, WithConstness, }; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -1423,7 +1423,7 @@ fn check_fn<'a, 'tcx>( inherited.register_predicate(traits::Obligation::new( cause, param_env, - trait_ref.to_predicate(), + trait_ref.without_const().to_predicate(), )); } } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 5e91e98a7df..e4df69993c5 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -6,7 +6,9 @@ use rustc::middle::lang_items; use rustc::session::parse::feature_err; use rustc::traits::{self, ObligationCause, ObligationCauseCode}; use rustc::ty::subst::{InternalSubsts, Subst}; -use rustc::ty::{self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use rustc::ty::{ + self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, +}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{struct_span_err, DiagnosticBuilder}; use rustc_hir::def_id::DefId; @@ -955,7 +957,8 @@ fn receiver_is_implemented( substs: fcx.tcx.mk_substs_trait(receiver_ty, &[]), }; - let obligation = traits::Obligation::new(cause, fcx.param_env, trait_ref.to_predicate()); + let obligation = + traits::Obligation::new(cause, fcx.param_env, trait_ref.without_const().to_predicate()); if fcx.predicate_must_hold_modulo_regions(&obligation) { true diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 35f9a4fa68e..1211075d942 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -30,7 +30,7 @@ use rustc::ty::subst::GenericArgKind; use rustc::ty::subst::{InternalSubsts, Subst}; use rustc::ty::util::Discr; use rustc::ty::util::IntTypeExt; -use rustc::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt}; +use rustc::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt, WithConstness}; use rustc::ty::{ReprOptions, ToPredicate}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; @@ -411,7 +411,8 @@ fn type_param_predicates( // Implied `Self: Trait` and supertrait bounds. if param_id == item_hir_id { let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id); - extend = Some((identity_trait_ref.to_predicate(), item.span)); + extend = + Some((identity_trait_ref.without_const().to_predicate(), item.span)); } generics } @@ -2056,7 +2057,7 @@ fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> { let span = tcx.def_span(def_id); result.predicates = tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once(( - ty::TraitRef::identity(tcx, def_id).to_predicate(), + ty::TraitRef::identity(tcx, def_id).without_const().to_predicate(), span, )))); } @@ -2230,7 +2231,10 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat // (see below). Recall that a default impl is not itself an impl, but rather a // set of defaults that can be incorporated into another impl. if let Some(trait_ref) = is_default_impl_trait { - predicates.push((trait_ref.to_poly_trait_ref().to_predicate(), tcx.def_span(def_id))); + predicates.push(( + trait_ref.to_poly_trait_ref().without_const().to_predicate(), + tcx.def_span(def_id), + )); } // Collect the region predicates that were declared inline as diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 525b1b2e6ec..18ebd254507 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -1,7 +1,7 @@ use rustc::infer::InferOk; use rustc::traits; use rustc::ty::subst::Subst; -use rustc::ty::ToPredicate; +use rustc::ty::{ToPredicate, WithConstness}; use rustc_hir as hir; use rustc_hir::def_id::LOCAL_CRATE; use rustc_span::DUMMY_SP; @@ -64,7 +64,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { match infcx.evaluate_obligation(&traits::Obligation::new( cause, param_env, - trait_ref.to_predicate(), + trait_ref.without_const().to_predicate(), )) { Ok(eval_result) => eval_result.may_apply(), Err(traits::OverflowError) => true, // overflow doesn't mean yes *or* no |
