summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/traits
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs69
-rw-r--r--compiler/rustc_middle/src/traits/select.rs16
-rw-r--r--compiler/rustc_middle/src/traits/specialization_graph.rs19
-rw-r--r--compiler/rustc_middle/src/traits/structural_impls.rs24
4 files changed, 77 insertions, 51 deletions
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index e73d44bbb..143435cb2 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -203,13 +203,20 @@ pub struct UnifyReceiverContext<'tcx> {
pub substs: SubstsRef<'tcx>,
}
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift, Default)]
+#[derive(Clone, PartialEq, Eq, Hash, Lift, Default)]
pub struct InternedObligationCauseCode<'tcx> {
/// `None` for `ObligationCauseCode::MiscObligation` (a common case, occurs ~60% of
/// the time). `Some` otherwise.
code: Option<Lrc<ObligationCauseCode<'tcx>>>,
}
+impl<'tcx> std::fmt::Debug for InternedObligationCauseCode<'tcx> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ let cause: &ObligationCauseCode<'_> = self;
+ cause.fmt(f)
+ }
+}
+
impl<'tcx> ObligationCauseCode<'tcx> {
#[inline(always)]
fn into(self) -> InternedObligationCauseCode<'tcx> {
@@ -431,6 +438,8 @@ pub enum ObligationCauseCode<'tcx> {
},
AscribeUserTypeProvePredicate(Span),
+
+ RustCall,
}
/// The 'location' at which we try to perform HIR-based wf checking.
@@ -462,7 +471,7 @@ pub struct ImplDerivedObligationCause<'tcx> {
}
impl<'tcx> ObligationCauseCode<'tcx> {
- // Return the base obligation, ignoring derived obligations.
+ /// Returns the base obligation, ignoring derived obligations.
pub fn peel_derives(&self) -> &Self {
let mut base_cause = self;
while let Some((parent_code, _)) = base_cause.parent() {
@@ -567,9 +576,6 @@ pub enum SelectionError<'tcx> {
/// Signaling that an error has already been emitted, to avoid
/// multiple errors being shown.
ErrorReporting,
- /// Multiple applicable `impl`s where found. The `DefId`s correspond to
- /// all the `impl`s' Items.
- Ambiguous(Vec<DefId>),
}
/// When performing resolution, it is typically the case that there
@@ -645,15 +651,12 @@ pub enum ImplSource<'tcx, N> {
/// Same as above, but for a function pointer type with the given signature.
FnPointer(ImplSourceFnPointerData<'tcx, N>),
- /// ImplSource for a builtin `DeterminantKind` trait implementation.
- DiscriminantKind(ImplSourceDiscriminantKindData),
-
- /// ImplSource for a builtin `Pointee` trait implementation.
- Pointee(ImplSourcePointeeData),
-
/// ImplSource automatically generated for a generator.
Generator(ImplSourceGeneratorData<'tcx, N>),
+ /// ImplSource automatically generated for a generator backing an async future.
+ Future(ImplSourceFutureData<'tcx, N>),
+
/// ImplSource for a trait alias.
TraitAlias(ImplSourceTraitAliasData<'tcx, N>),
@@ -670,10 +673,9 @@ impl<'tcx, N> ImplSource<'tcx, N> {
ImplSource::AutoImpl(d) => d.nested,
ImplSource::Closure(c) => c.nested,
ImplSource::Generator(c) => c.nested,
+ ImplSource::Future(c) => c.nested,
ImplSource::Object(d) => d.nested,
ImplSource::FnPointer(d) => d.nested,
- ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
- | ImplSource::Pointee(ImplSourcePointeeData) => vec![],
ImplSource::TraitAlias(d) => d.nested,
ImplSource::TraitUpcasting(d) => d.nested,
ImplSource::ConstDestruct(i) => i.nested,
@@ -688,10 +690,9 @@ impl<'tcx, N> ImplSource<'tcx, N> {
ImplSource::AutoImpl(d) => &d.nested,
ImplSource::Closure(c) => &c.nested,
ImplSource::Generator(c) => &c.nested,
+ ImplSource::Future(c) => &c.nested,
ImplSource::Object(d) => &d.nested,
ImplSource::FnPointer(d) => &d.nested,
- ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
- | ImplSource::Pointee(ImplSourcePointeeData) => &[],
ImplSource::TraitAlias(d) => &d.nested,
ImplSource::TraitUpcasting(d) => &d.nested,
ImplSource::ConstDestruct(i) => &i.nested,
@@ -731,16 +732,15 @@ impl<'tcx, N> ImplSource<'tcx, N> {
substs: c.substs,
nested: c.nested.into_iter().map(f).collect(),
}),
+ ImplSource::Future(c) => ImplSource::Future(ImplSourceFutureData {
+ generator_def_id: c.generator_def_id,
+ substs: c.substs,
+ nested: c.nested.into_iter().map(f).collect(),
+ }),
ImplSource::FnPointer(p) => ImplSource::FnPointer(ImplSourceFnPointerData {
fn_ty: p.fn_ty,
nested: p.nested.into_iter().map(f).collect(),
}),
- ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData) => {
- ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
- }
- ImplSource::Pointee(ImplSourcePointeeData) => {
- ImplSource::Pointee(ImplSourcePointeeData)
- }
ImplSource::TraitAlias(d) => ImplSource::TraitAlias(ImplSourceTraitAliasData {
alias_def_id: d.alias_def_id,
substs: d.substs,
@@ -792,6 +792,16 @@ pub struct ImplSourceGeneratorData<'tcx, N> {
#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
#[derive(TypeFoldable, TypeVisitable)]
+pub struct ImplSourceFutureData<'tcx, N> {
+ pub generator_def_id: DefId,
+ pub substs: SubstsRef<'tcx>,
+ /// Nested obligations. This can be non-empty if the generator
+ /// signature contains associated types.
+ pub nested: Vec<N>,
+}
+
+#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
+#[derive(TypeFoldable, TypeVisitable)]
pub struct ImplSourceClosureData<'tcx, N> {
pub closure_def_id: DefId,
pub substs: SubstsRef<'tcx>,
@@ -850,13 +860,6 @@ pub struct ImplSourceFnPointerData<'tcx, N> {
pub nested: Vec<N>,
}
-// FIXME(@lcnr): This should be refactored and merged with other builtin vtables.
-#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
-pub struct ImplSourceDiscriminantKindData;
-
-#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
-pub struct ImplSourcePointeeData;
-
#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
#[derive(TypeFoldable, TypeVisitable)]
pub struct ImplSourceConstDestructData<N> {
@@ -918,10 +921,13 @@ impl ObjectSafetyViolation {
}
ObjectSafetyViolation::Method(
name,
- MethodViolationCode::ReferencesImplTraitInTrait,
+ MethodViolationCode::ReferencesImplTraitInTrait(_),
_,
) => format!("method `{}` references an `impl Trait` type in its return type", name)
.into(),
+ ObjectSafetyViolation::Method(name, MethodViolationCode::AsyncFn, _) => {
+ format!("method `{}` is `async`", name).into()
+ }
ObjectSafetyViolation::Method(
name,
MethodViolationCode::WhereClauseReferencesSelf,
@@ -1029,7 +1035,10 @@ pub enum MethodViolationCode {
ReferencesSelfOutput,
/// e.g., `fn foo(&self) -> impl Sized`
- ReferencesImplTraitInTrait,
+ ReferencesImplTraitInTrait(Span),
+
+ /// e.g., `async fn foo(&self)`
+ AsyncFn,
/// e.g., `fn foo(&self) where Self: Clone`
WhereClauseReferencesSelf,
diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs
index 85ead3171..ec69864c9 100644
--- a/compiler/rustc_middle/src/traits/select.rs
+++ b/compiler/rustc_middle/src/traits/select.rs
@@ -105,6 +105,12 @@ pub type EvaluationCache<'tcx> = Cache<
/// parameter environment.
#[derive(PartialEq, Eq, Debug, Clone, TypeFoldable, TypeVisitable)]
pub enum SelectionCandidate<'tcx> {
+ /// A builtin implementation for some specific traits, used in cases
+ /// where we cannot rely an ordinary library implementations.
+ ///
+ /// The most notable examples are `sized`, `Copy` and `Clone`. This is also
+ /// used for the `DiscriminantKind` and `Pointee` trait, both of which have
+ /// an associated type.
BuiltinCandidate {
/// `false` if there are no *further* obligations.
has_nested: bool,
@@ -131,18 +137,16 @@ pub enum SelectionCandidate<'tcx> {
/// generated for a generator.
GeneratorCandidate,
+ /// Implementation of a `Future` trait by one of the generator types
+ /// generated for an async construct.
+ FutureCandidate,
+
/// Implementation of a `Fn`-family trait by one of the anonymous
/// types generated for a fn pointer type (e.g., `fn(int) -> int`)
FnPointerCandidate {
is_const: bool,
},
- /// Builtin implementation of `DiscriminantKind`.
- DiscriminantKindCandidate,
-
- /// Builtin implementation of `Pointee`.
- PointeeCandidate,
-
TraitAliasCandidate,
/// Matching `dyn Trait` with a supertrait of `Trait`. The index is the
diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs
index 0a2819fee..cccedc9ec 100644
--- a/compiler/rustc_middle/src/traits/specialization_graph.rs
+++ b/compiler/rustc_middle/src/traits/specialization_graph.rs
@@ -1,3 +1,4 @@
+use crate::error::StrictCoherenceNeedsNegativeCoherence;
use crate::ty::fast_reject::SimplifiedType;
use crate::ty::visit::TypeVisitable;
use crate::ty::{self, TyCtxt};
@@ -65,9 +66,21 @@ impl OverlapMode {
if with_negative_coherence {
if strict_coherence { OverlapMode::Strict } else { OverlapMode::WithNegative }
- } else if strict_coherence {
- bug!("To use strict_coherence you need to set with_negative_coherence feature flag");
} else {
+ if strict_coherence {
+ let attr_span = trait_id
+ .as_local()
+ .into_iter()
+ .flat_map(|local_def_id| {
+ tcx.hir().attrs(tcx.hir().local_def_id_to_hir_id(local_def_id))
+ })
+ .find(|attr| attr.has_name(sym::rustc_strict_coherence))
+ .map(|attr| attr.span);
+ tcx.sess.emit_err(StrictCoherenceNeedsNegativeCoherence {
+ span: tcx.def_span(trait_id),
+ attr_span,
+ });
+ }
OverlapMode::Stable
}
}
@@ -249,7 +262,7 @@ pub fn ancestors<'tcx>(
if let Some(reported) = specialization_graph.has_errored {
Err(reported)
- } else if let Some(reported) = tcx.type_of(start_from_impl).error_reported() {
+ } else if let Err(reported) = tcx.type_of(start_from_impl).error_reported() {
Err(reported)
} else {
Ok(Ancestors {
diff --git a/compiler/rustc_middle/src/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs
index 7fbd57ac7..6acb7745d 100644
--- a/compiler/rustc_middle/src/traits/structural_impls.rs
+++ b/compiler/rustc_middle/src/traits/structural_impls.rs
@@ -15,11 +15,9 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> {
super::ImplSource::Generator(ref d) => write!(f, "{:?}", d),
- super::ImplSource::FnPointer(ref d) => write!(f, "({:?})", d),
-
- super::ImplSource::DiscriminantKind(ref d) => write!(f, "{:?}", d),
+ super::ImplSource::Future(ref d) => write!(f, "{:?}", d),
- super::ImplSource::Pointee(ref d) => write!(f, "{:?}", d),
+ super::ImplSource::FnPointer(ref d) => write!(f, "({:?})", d),
super::ImplSource::Object(ref d) => write!(f, "{:?}", d),
@@ -58,6 +56,16 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceGeneratorData<'tcx, N
}
}
+impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceFutureData<'tcx, N> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(
+ f,
+ "ImplSourceFutureData(generator_def_id={:?}, substs={:?}, nested={:?})",
+ self.generator_def_id, self.substs, self.nested
+ )
+ }
+}
+
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceClosureData<'tcx, N> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
@@ -125,11 +133,3 @@ impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceConstDestructData<N> {
write!(f, "ImplSourceConstDestructData(nested={:?})", self.nested)
}
}
-
-///////////////////////////////////////////////////////////////////////////
-// Lift implementations
-
-TrivialTypeTraversalAndLiftImpls! {
- super::ImplSourceDiscriminantKindData,
- super::ImplSourcePointeeData,
-}