about summary refs log tree commit diff
path: root/compiler/rustc_middle/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src')
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs8
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs15
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs21
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs30
4 files changed, 44 insertions, 30 deletions
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 4198b4a338c..3c83d962900 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -1364,13 +1364,13 @@ impl PlaceContext {
         matches!(self, PlaceContext::MutatingUse(MutatingUseContext::Drop))
     }
 
-    /// Returns `true` if this place context represents a borrow.
+    /// Returns `true` if this place context represents a borrow, excluding fake borrows
+    /// (which are an artifact of borrowck and not actually borrows in runtime MIR).
     pub fn is_borrow(self) -> bool {
         matches!(
             self,
-            PlaceContext::NonMutatingUse(
-                NonMutatingUseContext::SharedBorrow | NonMutatingUseContext::FakeBorrow
-            ) | PlaceContext::MutatingUse(MutatingUseContext::Borrow)
+            PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow)
+                | PlaceContext::MutatingUse(MutatingUseContext::Borrow)
         )
     }
 
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 51420400b10..d033ecc75db 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -12,7 +12,7 @@ use std::borrow::Cow;
 use std::hash::{Hash, Hasher};
 use std::sync::Arc;
 
-use rustc_errors::{Applicability, Diag, EmissionGuarantee};
+use rustc_errors::{Applicability, Diag, EmissionGuarantee, ErrorGuaranteed};
 use rustc_hir as hir;
 use rustc_hir::HirId;
 use rustc_hir::def_id::DefId;
@@ -144,14 +144,6 @@ impl<'tcx> ObligationCause<'tcx> {
     }
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
-#[derive(TypeVisitable, TypeFoldable)]
-pub struct UnifyReceiverContext<'tcx> {
-    pub assoc_item: ty::AssocItem,
-    pub param_env: ty::ParamEnv<'tcx>,
-    pub args: GenericArgsRef<'tcx>,
-}
-
 /// A compact form of `ObligationCauseCode`.
 #[derive(Clone, PartialEq, Eq, Default, HashStable)]
 #[derive(TypeVisitable, TypeFoldable, TyEncodable, TyDecodable)]
@@ -360,8 +352,6 @@ pub enum ObligationCauseCode<'tcx> {
     /// Method receiver
     MethodReceiver,
 
-    UnifyReceiver(Box<UnifyReceiverContext<'tcx>>),
-
     /// `return` with no expression
     ReturnNoExpression,
 
@@ -996,4 +986,7 @@ pub enum CodegenObligationError {
     /// but was included during typeck due to the trivial_bounds feature.
     Unimplemented,
     FulfillmentError,
+    /// The selected impl has unconstrained generic parameters. This will emit an error
+    /// during impl WF checking.
+    UnconstrainedParam(ErrorGuaranteed),
 }
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index afdec7a86d4..839c1c346a4 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -79,20 +79,14 @@ impl<'tcx> Relate<TyCtxt<'tcx>> for &'tcx ty::List<ty::PolyExistentialPredicate<
         b: Self,
     ) -> RelateResult<'tcx, Self> {
         let tcx = relation.cx();
-
-        // FIXME: this is wasteful, but want to do a perf run to see how slow it is.
-        // We need to perform this deduplication as we sometimes generate duplicate projections
-        // in `a`.
-        let mut a_v: Vec<_> = a.into_iter().collect();
-        let mut b_v: Vec<_> = b.into_iter().collect();
-        a_v.dedup();
-        b_v.dedup();
-        if a_v.len() != b_v.len() {
+        // Fast path for when the auto traits do not match, or if the principals
+        // are from different traits and therefore the projections definitely don't
+        // match up.
+        if a.len() != b.len() {
             return Err(TypeError::ExistentialMismatch(ExpectedFound::new(a, b)));
         }
-
-        let v = iter::zip(a_v, b_v).map(|(ep_a, ep_b)| {
-            match (ep_a.skip_binder(), ep_b.skip_binder()) {
+        let v =
+            iter::zip(a, b).map(|(ep_a, ep_b)| match (ep_a.skip_binder(), ep_b.skip_binder()) {
                 (ty::ExistentialPredicate::Trait(a), ty::ExistentialPredicate::Trait(b)) => {
                     Ok(ep_a.rebind(ty::ExistentialPredicate::Trait(
                         relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(),
@@ -109,8 +103,7 @@ impl<'tcx> Relate<TyCtxt<'tcx>> for &'tcx ty::List<ty::PolyExistentialPredicate<
                     ty::ExistentialPredicate::AutoTrait(b),
                 ) if a == b => Ok(ep_a.rebind(ty::ExistentialPredicate::AutoTrait(a))),
                 _ => Err(TypeError::ExistentialMismatch(ExpectedFound::new(a, b))),
-            }
-        });
+            });
         tcx.mk_poly_existential_predicates_from_iter(v)
     }
 }
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 4a97b5d475f..dd4da2cf4ac 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -18,7 +18,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, extension
 use rustc_span::{DUMMY_SP, Span, Symbol, sym};
 use rustc_type_ir::TyKind::*;
 use rustc_type_ir::visit::TypeVisitableExt;
-use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind};
+use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind, elaborate};
 use tracing::instrument;
 use ty::util::{AsyncDropGlueMorphology, IntTypeExt};
 
@@ -720,6 +720,34 @@ impl<'tcx> Ty<'tcx> {
         reg: ty::Region<'tcx>,
         repr: DynKind,
     ) -> Ty<'tcx> {
+        if cfg!(debug_assertions) {
+            let projection_count = obj.projection_bounds().count();
+            let expected_count: usize = obj
+                .principal_def_id()
+                .into_iter()
+                .flat_map(|principal_def_id| {
+                    // NOTE: This should agree with `needed_associated_types` in
+                    // dyn trait lowering, or else we'll have ICEs.
+                    elaborate::supertraits(
+                        tcx,
+                        ty::Binder::dummy(ty::TraitRef::identity(tcx, principal_def_id)),
+                    )
+                    .map(|principal| {
+                        tcx.associated_items(principal.def_id())
+                            .in_definition_order()
+                            .filter(|item| item.kind == ty::AssocKind::Type)
+                            .filter(|item| !item.is_impl_trait_in_trait())
+                            .filter(|item| !tcx.generics_require_sized_self(item.def_id))
+                            .count()
+                    })
+                })
+                .sum();
+            assert_eq!(
+                projection_count, expected_count,
+                "expected {obj:?} to have {expected_count} projections, \
+                but it has {projection_count}"
+            );
+        }
         Ty::new(tcx, Dynamic(obj, reg, repr))
     }