diff options
Diffstat (limited to '')
-rw-r--r-- | compiler/rustc_middle/src/traits/mod.rs | 58 |
1 files changed, 46 insertions, 12 deletions
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 72b848c3e..e73d44bbb 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -10,9 +10,10 @@ mod structural_impls; pub mod util; use crate::infer::canonical::Canonical; +use crate::mir::ConstraintCategory; use crate::ty::abstract_const::NotConstEvaluatable; use crate::ty::subst::SubstsRef; -use crate::ty::{self, AdtKind, Predicate, Ty, TyCtxt}; +use crate::ty::{self, AdtKind, Ty, TyCtxt}; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, Diagnostic}; @@ -183,6 +184,16 @@ impl<'tcx> ObligationCause<'tcx> { variant(DerivedObligationCause { parent_trait_pred, parent_code: self.code }).into(); self } + + pub fn to_constraint_category(&self) -> ConstraintCategory<'tcx> { + match self.code() { + MatchImpl(cause, _) => cause.to_constraint_category(), + AscribeUserTypeProvePredicate(predicate_span) => { + ConstraintCategory::Predicate(*predicate_span) + } + _ => ConstraintCategory::BoringNoLocation, + } + } } #[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)] @@ -234,13 +245,23 @@ pub enum ObligationCauseCode<'tcx> { /// This is the trait reference from the given projection. ProjectionWf(ty::ProjectionTy<'tcx>), - /// In an impl of trait `X` for type `Y`, type `Y` must - /// also implement all supertraits of `X`. + /// Must satisfy all of the where-clause predicates of the + /// given item. ItemObligation(DefId), - /// Like `ItemObligation`, but with extra detail on the source of the obligation. + /// Like `ItemObligation`, but carries the span of the + /// predicate when it can be identified. BindingObligation(DefId, Span), + /// Like `ItemObligation`, but carries the `HirId` of the + /// expression that caused the obligation, and the `usize` + /// indicates exactly which predicate it is in the list of + /// instantiated predicates. + ExprItemObligation(DefId, rustc_hir::HirId, usize), + + /// Combines `ExprItemObligation` and `BindingObligation`. + ExprBindingObligation(DefId, Span, rustc_hir::HirId, usize), + /// A type like `&'a T` is WF only if `T: 'a`. ReferenceOutlivesReferent(Ty<'tcx>), @@ -406,8 +427,10 @@ pub enum ObligationCauseCode<'tcx> { BinOp { rhs_span: Option<Span>, is_lit: bool, - output_pred: Option<Predicate<'tcx>>, + output_ty: Option<Ty<'tcx>>, }, + + AscribeUserTypeProvePredicate(Span), } /// The 'location' at which we try to perform HIR-based wf checking. @@ -459,6 +482,13 @@ impl<'tcx> ObligationCauseCode<'tcx> { _ => None, } } + + pub fn peel_match_impls(&self) -> &Self { + match self { + MatchImpl(cause, _) => cause.code(), + _ => self, + } + } } // `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger. @@ -568,11 +598,6 @@ pub type SelectionResult<'tcx, T> = Result<Option<T>, SelectionError<'tcx>>; /// // type parameters, ImplSource will carry resolutions for those as well: /// concrete.clone(); // ImplSource(Impl_1, [ImplSource(Impl_2, [ImplSource(Impl_3)])]) /// -/// // Case A: ImplSource points at a specific impl. Only possible when -/// // type is concretely known. If the impl itself has bounded -/// // type parameters, ImplSource will carry resolutions for those as well: -/// concrete.clone(); // ImplSource(Impl_1, [ImplSource(Impl_2, [ImplSource(Impl_3)])]) -/// /// // Case B: ImplSource must be provided by caller. This applies when /// // type is a type parameter. /// param.clone(); // ImplSource::Param @@ -648,7 +673,7 @@ impl<'tcx, N> ImplSource<'tcx, N> { ImplSource::Object(d) => d.nested, ImplSource::FnPointer(d) => d.nested, ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData) - | ImplSource::Pointee(ImplSourcePointeeData) => Vec::new(), + | ImplSource::Pointee(ImplSourcePointeeData) => vec![], ImplSource::TraitAlias(d) => d.nested, ImplSource::TraitUpcasting(d) => d.nested, ImplSource::ConstDestruct(i) => i.nested, @@ -893,6 +918,12 @@ impl ObjectSafetyViolation { } ObjectSafetyViolation::Method( name, + MethodViolationCode::ReferencesImplTraitInTrait, + _, + ) => format!("method `{}` references an `impl Trait` type in its return type", name) + .into(), + ObjectSafetyViolation::Method( + name, MethodViolationCode::WhereClauseReferencesSelf, _, ) => { @@ -997,6 +1028,9 @@ pub enum MethodViolationCode { /// e.g., `fn foo(&self) -> Self` ReferencesSelfOutput, + /// e.g., `fn foo(&self) -> impl Sized` + ReferencesImplTraitInTrait, + /// e.g., `fn foo(&self) where Self: Clone` WhereClauseReferencesSelf, @@ -1007,7 +1041,7 @@ pub enum MethodViolationCode { UndispatchableReceiver(Option<Span>), } -/// These are the error cases for `codegen_fulfill_obligation`. +/// These are the error cases for `codegen_select_candidate`. #[derive(Copy, Clone, Debug, Hash, HashStable, Encodable, Decodable)] pub enum CodegenObligationError { /// Ambiguity can happen when monomorphizing during trans |