diff options
Diffstat (limited to '')
-rw-r--r-- | compiler/rustc_middle/src/traits/mod.rs | 69 | ||||
-rw-r--r-- | compiler/rustc_middle/src/traits/select.rs | 16 | ||||
-rw-r--r-- | compiler/rustc_middle/src/traits/specialization_graph.rs | 19 | ||||
-rw-r--r-- | compiler/rustc_middle/src/traits/structural_impls.rs | 24 |
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, -} |