summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/traits/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs58
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