about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir/src/hir.rs6
-rw-r--r--compiler/rustc_infer/src/infer/at.rs12
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs1
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs25
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs81
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs12
-rw-r--r--compiler/rustc_typeck/src/collect/type_of.rs64
8 files changed, 92 insertions, 110 deletions
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index a0ed72c9e9e..68fdbaa6aa0 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -2165,6 +2165,12 @@ impl TypeBinding<'_> {
             _ => panic!("expected equality type binding for parenthesized generic args"),
         }
     }
+    pub fn opt_const(&self) -> Option<&'_ AnonConst> {
+        match self.kind {
+            TypeBindingKind::Equality { term: Term::Const(ref c) } => Some(c),
+            _ => None,
+        }
+    }
 }
 
 #[derive(Debug)]
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index aa74a92ad1f..147061dafeb 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -288,13 +288,21 @@ impl<'tcx> ToTrace<'tcx> for &'tcx Const<'tcx> {
 
 impl<'tcx> ToTrace<'tcx> for ty::Term<'tcx> {
     fn to_trace(
-        _: TyCtxt<'tcx>,
+        tcx: TyCtxt<'tcx>,
         cause: &ObligationCause<'tcx>,
         a_is_expected: bool,
         a: Self,
         b: Self,
     ) -> TypeTrace<'tcx> {
-        TypeTrace { cause: cause.clone(), values: Terms(ExpectedFound::new(a_is_expected, a, b)) }
+        match (a, b) {
+            (ty::Term::Ty(a), ty::Term::Ty(b)) => {
+                ToTrace::to_trace(tcx, cause, a_is_expected, a, b)
+            }
+            (ty::Term::Const(a), ty::Term::Const(b)) => {
+                ToTrace::to_trace(tcx, cause, a_is_expected, a, b)
+            }
+            (_, _) => todo!(),
+        }
     }
 }
 
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 24a5f55d53c..1eb8190bd7d 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2127,7 +2127,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             infer::Types(exp_found) => self.expected_found_str_ty(exp_found),
             infer::Regions(exp_found) => self.expected_found_str(exp_found),
             infer::Consts(exp_found) => self.expected_found_str(exp_found),
-            infer::Terms(exp_found) => self.expected_found_str(exp_found),
             infer::TraitRefs(exp_found) => {
                 let pretty_exp_found = ty::error::ExpectedFound {
                     expected: exp_found.expected.print_only_trait_path(),
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 330c99f6073..266eec08ceb 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -371,7 +371,6 @@ pub enum ValuePairs<'tcx> {
     Types(ExpectedFound<Ty<'tcx>>),
     Regions(ExpectedFound<ty::Region<'tcx>>),
     Consts(ExpectedFound<&'tcx ty::Const<'tcx>>),
-    Terms(ExpectedFound<ty::Term<'tcx>>),
     TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
     PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
 }
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index f16601dd08e..d06e8496f59 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -1356,11 +1356,26 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
                     normalized_ty,
                     data.term,
                 ) {
-                    values = Some(infer::ValuePairs::Terms(ExpectedFound::new(
-                        is_normalized_ty_expected,
-                        normalized_ty,
-                        data.term,
-                    )));
+                    values = Some(match (normalized_ty, data.term) {
+                        (ty::Term::Ty(normalized_ty), ty::Term::Ty(ty)) => {
+                            infer::ValuePairs::Types(ExpectedFound::new(
+                                is_normalized_ty_expected,
+                                normalized_ty,
+                                ty,
+                            ))
+                        }
+                        (ty::Term::Const(normalized_ct), ty::Term::Const(ct)) => {
+                            infer::ValuePairs::Consts(ExpectedFound::new(
+                                is_normalized_ty_expected,
+                                normalized_ct,
+                                ct,
+                            ))
+                        }
+                        (_, _) => span_bug!(
+                            obligation.cause.span,
+                            "found const or type where other expected"
+                        ),
+                    });
                     err_buf = error;
                     err = &err_buf;
                 }
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 11cde60f075..bad4ee30424 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -199,61 +199,30 @@ fn project_and_unify_type<'cx, 'tcx>(
     let mut obligations = vec![];
 
     let infcx = selcx.infcx();
-    match obligation.predicate.term {
-        ty::Term::Ty(obligation_pred_ty) => {
-            let normalized_ty = match opt_normalize_projection_type(
-                selcx,
-                obligation.param_env,
-                obligation.predicate.projection_ty,
-                obligation.cause.clone(),
-                obligation.recursion_depth,
-                &mut obligations,
-            ) {
-                Ok(Some(n)) => n.ty().unwrap(),
-                Ok(None) => return Ok(Ok(None)),
-                Err(InProgress) => return Ok(Err(InProgress)),
-            };
-            debug!(?normalized_ty, ?obligations, "project_and_unify_type result");
-            match infcx
-                .at(&obligation.cause, obligation.param_env)
-                .eq(normalized_ty, obligation_pred_ty)
-            {
-                Ok(InferOk { obligations: inferred_obligations, value: () }) => {
-                    obligations.extend(inferred_obligations);
-                    Ok(Ok(Some(obligations)))
-                }
-                Err(err) => {
-                    debug!("project_and_unify_type: equating types encountered error {:?}", err);
-                    Err(MismatchedProjectionTypes { err })
-                }
-            }
+    let normalized = match opt_normalize_projection_type(
+        selcx,
+        obligation.param_env,
+        obligation.predicate.projection_ty,
+        obligation.cause.clone(),
+        obligation.recursion_depth,
+        &mut obligations,
+    ) {
+        Ok(Some(n)) => n,
+        Ok(None) => return Ok(Ok(None)),
+        Err(InProgress) => return Ok(Err(InProgress)),
+    };
+    debug!(?normalized, ?obligations, "project_and_unify_type result");
+    match infcx
+        .at(&obligation.cause, obligation.param_env)
+        .eq(normalized, obligation.predicate.term)
+    {
+        Ok(InferOk { obligations: inferred_obligations, value: () }) => {
+            obligations.extend(inferred_obligations);
+            Ok(Ok(Some(obligations)))
         }
-        ty::Term::Const(obligation_pred_const) => {
-            let normalized_const = match opt_normalize_projection_type(
-                selcx,
-                obligation.param_env,
-                obligation.predicate.projection_ty,
-                obligation.cause.clone(),
-                obligation.recursion_depth,
-                &mut obligations,
-            ) {
-                Ok(Some(n)) => n.ct().unwrap(),
-                Ok(None) => return Ok(Ok(None)),
-                Err(InProgress) => return Ok(Err(InProgress)),
-            };
-            match infcx
-                .at(&obligation.cause, obligation.param_env)
-                .eq(normalized_const, obligation_pred_const)
-            {
-                Ok(InferOk { obligations: inferred_obligations, value: () }) => {
-                    obligations.extend(inferred_obligations);
-                    Ok(Ok(Some(obligations)))
-                }
-                Err(err) => {
-                    debug!("project_and_unify_type: equating consts encountered error {:?}", err);
-                    Err(MismatchedProjectionTypes { err })
-                }
-            }
+        Err(err) => {
+            debug!("project_and_unify_type: equating types encountered error {:?}", err);
+            Err(MismatchedProjectionTypes { err })
         }
     }
 }
@@ -934,6 +903,8 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
             // created (and hence the new ones will quickly be
             // discarded as duplicated). But when doing trait
             // evaluation this is not the case, and dropping the trait
+            // evaluations can causes ICEs (e.g., #43132).
+            debug!(?ty, "found normalized ty");
             obligations.extend(ty.obligations);
             return Ok(Some(ty.value));
         }
@@ -1127,6 +1098,8 @@ fn project<'cx, 'tcx>(
             Ok(Projected::Progress(confirm_candidate(selcx, obligation, candidate)))
         }
         ProjectionCandidateSet::None => Ok(Projected::NoProgress(
+            // FIXME(associated_const_generics): this may need to change in the future?
+            // need to investigate whether or not this is fine.
             selcx
                 .tcx()
                 .mk_projection(obligation.predicate.item_def_id, obligation.predicate.substs)
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 06d472214e4..5eb9664e1d7 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -1244,17 +1244,23 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 // the "projection predicate" for:
                 //
                 // `<T as Iterator>::Item = u32`
-                let def_kind = tcx.def_kind(projection_ty.skip_binder().item_def_id);
+                let assoc_item_def_id = projection_ty.skip_binder().item_def_id;
+                let def_kind = tcx.def_kind(assoc_item_def_id);
                 match (def_kind, term) {
                     (hir::def::DefKind::AssocTy, ty::Term::Ty(_))
                     | (hir::def::DefKind::AssocConst, ty::Term::Const(_)) => (),
                     (_, _) => {
+                        let got = if let ty::Term::Ty(_) = term { "type" } else { "const" };
+                        let expected = def_kind.descr(assoc_item_def_id);
                         tcx.sess
                             .struct_span_err(
                                 binding.span,
-                                "type/const mismatch in equality bind of associated field",
+                                &format!("mismatch in bind of {expected}, got {got}"),
+                            )
+                            .span_note(
+                                tcx.def_span(assoc_item_def_id),
+                                &format!("{expected} defined here does not match {got}"),
                             )
-                            .span_label(binding.span, "type/const Mismatch")
                             .emit();
                     }
                 }
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index 63a8cab3def..7990c14f773 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -161,40 +161,26 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
             // We've encountered an `AnonConst` in some path, so we need to
             // figure out which generic parameter it corresponds to and return
             // the relevant type.
-            let filtered = path
-                .segments
-                .iter()
-                .filter_map(|seg| seg.args.map(|args| (args.args, seg)))
-                .find_map(|(args, seg)| {
-                    args.iter()
-                        .filter(|arg| arg.is_ty_or_const())
-                        .position(|arg| arg.id() == hir_id)
-                        .map(|index| (index, seg))
-                });
-            // FIXME(associated_const_equality): recursively search through the bindings instead
-            // of just top level.
+            let filtered = path.segments.iter().find_map(|seg| {
+                seg.args?
+                    .args
+                    .iter()
+                    .filter(|arg| arg.is_ty_or_const())
+                    .position(|arg| arg.id() == hir_id)
+                    .map(|index| (index, seg))
+            });
 
+            // FIXME(associated_const_generics): can we blend this with iteration above?
             let (arg_index, segment) = match filtered {
                 None => {
-                    let binding_filtered = path
-                        .segments
-                        .iter()
-                        .filter_map(|seg| seg.args.map(|args| (args.bindings, seg)))
-                        .find_map(|(bindings, seg)| {
-                            bindings
-                                .iter()
-                                .filter_map(|binding| {
-                                    if let hir::TypeBindingKind::Equality { term: Term::Const(c) } =
-                                        binding.kind
-                                    {
-                                        Some(c)
-                                    } else {
-                                        None
-                                    }
-                                })
-                                .position(|ct| ct.hir_id == hir_id)
-                                .map(|idx| (idx, seg))
-                        });
+                    let binding_filtered = path.segments.iter().find_map(|seg| {
+                        seg.args?
+                            .bindings
+                            .iter()
+                            .filter_map(TypeBinding::opt_const)
+                            .position(|ct| ct.hir_id == hir_id)
+                            .map(|idx| (idx, seg))
+                    });
                     match binding_filtered {
                         Some(inner) => inner,
                         None => {
@@ -518,20 +504,10 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                   path
                       .segments
                       .iter()
-                      .filter_map(|seg| seg.args.map(|args| (args.bindings, seg)))
-                      .find_map(|(bindings, seg)| {
-                          bindings
+                      .find_map(|seg| {
+                          seg.args?.bindings
                               .iter()
-                              .filter_map(|binding| {
-                                  if let hir::TypeBindingKind::Equality { term: Term::Const(c) } =
-                                      binding.kind
-                                  {
-                                          Some((binding, c))
-                                  } else {
-                                      None
-                                  }
-                              })
-                              .find_map(|(binding, ct)| if ct.hir_id == hir_id {
+                              .find_map(|binding| if binding.opt_const()?.hir_id == hir_id {
                                 Some((binding, seg))
                               } else {
                                 None