about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-12-12 21:03:00 +0000
committerMichael Goulet <michael@errs.io>2022-12-14 18:32:31 +0000
commit7bf36de6abeba487dbe0328685f45b8034513927 (patch)
tree801feefb2881eb782745a562e7ebe62e498ba3fd
parentba64ba8b0dfd57f7d6d7399d0df7ded37d2af18d (diff)
downloadrust-7bf36de6abeba487dbe0328685f45b8034513927.tar.gz
rust-7bf36de6abeba487dbe0328685f45b8034513927.zip
Make report_projection_error more term agnostic
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs44
-rw-r--r--src/test/ui/associated-type-bounds/const-projection-err.gce.stderr24
-rw-r--r--src/test/ui/associated-type-bounds/const-projection-err.rs18
-rw-r--r--src/test/ui/associated-type-bounds/const-projection-err.stock.stderr17
-rw-r--r--src/test/ui/issues/issue-105330.stderr8
5 files changed, 91 insertions, 20 deletions
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 c68da3e24a1..fa94f16dc29 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -1636,17 +1636,30 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     infer::LateBoundRegionConversionTime::HigherRankedType,
                     bound_predicate.rebind(data),
                 );
-                let normalized_ty = ocx.normalize(
-                    &obligation.cause,
-                    obligation.param_env,
-                    self.tcx.mk_projection(data.projection_ty.def_id, data.projection_ty.substs),
-                );
+                let unnormalized_term = match data.term.unpack() {
+                    ty::TermKind::Ty(_) => self
+                        .tcx
+                        .mk_projection(data.projection_ty.def_id, data.projection_ty.substs)
+                        .into(),
+                    ty::TermKind::Const(ct) => self
+                        .tcx
+                        .mk_const(
+                            ty::UnevaluatedConst {
+                                def: ty::WithOptConstParam::unknown(data.projection_ty.def_id),
+                                substs: data.projection_ty.substs,
+                            },
+                            ct.ty(),
+                        )
+                        .into(),
+                };
+                let normalized_term =
+                    ocx.normalize(&obligation.cause, obligation.param_env, unnormalized_term);
 
                 debug!(?obligation.cause, ?obligation.param_env);
 
-                debug!(?normalized_ty, data.ty = ?data.term);
+                debug!(?normalized_term, data.ty = ?data.term);
 
-                let is_normalized_ty_expected = !matches!(
+                let is_normalized_term_expected = !matches!(
                     obligation.cause.code().peel_derives(),
                     ObligationCauseCode::ItemObligation(_)
                         | ObligationCauseCode::BindingObligation(_, _)
@@ -1655,7 +1668,6 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         | ObligationCauseCode::ObjectCastObligation(..)
                         | ObligationCauseCode::OpaqueType
                 );
-                let expected_ty = data.term.ty().unwrap_or_else(|| self.tcx.ty_error());
 
                 // constrain inference variables a bit more to nested obligations from normalize so
                 // we can have more helpful errors.
@@ -1664,11 +1676,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 if let Err(new_err) = ocx.eq_exp(
                     &obligation.cause,
                     obligation.param_env,
-                    is_normalized_ty_expected,
-                    normalized_ty,
-                    expected_ty,
+                    is_normalized_term_expected,
+                    normalized_term,
+                    data.term,
                 ) {
-                    (Some((data, is_normalized_ty_expected, normalized_ty, expected_ty)), new_err)
+                    (Some((data, is_normalized_term_expected, normalized_term, data.term)), new_err)
                 } else {
                     (None, error.err)
                 }
@@ -1677,12 +1689,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             };
 
             let msg = values
-                .and_then(|(predicate, _, normalized_ty, expected_ty)| {
-                    self.maybe_detailed_projection_msg(
-                        predicate,
-                        normalized_ty.into(),
-                        expected_ty.into(),
-                    )
+                .and_then(|(predicate, _, normalized_term, expected_term)| {
+                    self.maybe_detailed_projection_msg(predicate, normalized_term, expected_term)
                 })
                 .unwrap_or_else(|| format!("type mismatch resolving `{}`", predicate));
             let mut diag = struct_span_err!(self.tcx.sess, obligation.cause.span, E0271, "{msg}");
diff --git a/src/test/ui/associated-type-bounds/const-projection-err.gce.stderr b/src/test/ui/associated-type-bounds/const-projection-err.gce.stderr
new file mode 100644
index 00000000000..0f1ec9ad052
--- /dev/null
+++ b/src/test/ui/associated-type-bounds/const-projection-err.gce.stderr
@@ -0,0 +1,24 @@
+warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/const-projection-err.rs:4:26
+   |
+LL | #![cfg_attr(gce, feature(generic_const_exprs))]
+   |                          ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0271]: type mismatch resolving `<T as TraitWAssocConst>::A == 1`
+  --> $DIR/const-projection-err.rs:14:11
+   |
+LL |     foo::<T>();
+   |           ^ expected `0`, found `1`
+   |
+note: required by a bound in `foo`
+  --> $DIR/const-projection-err.rs:11:28
+   |
+LL | fn foo<T: TraitWAssocConst<A = 1>>() {}
+   |                            ^^^^^ required by this bound in `foo`
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/associated-type-bounds/const-projection-err.rs b/src/test/ui/associated-type-bounds/const-projection-err.rs
new file mode 100644
index 00000000000..bead8563001
--- /dev/null
+++ b/src/test/ui/associated-type-bounds/const-projection-err.rs
@@ -0,0 +1,18 @@
+// revisions: stock gce
+
+#![feature(associated_const_equality)]
+#![cfg_attr(gce, feature(generic_const_exprs))]
+//[gce]~^ WARN the feature `generic_const_exprs` is incomplete
+
+trait TraitWAssocConst {
+    const A: usize;
+}
+
+fn foo<T: TraitWAssocConst<A = 1>>() {}
+
+fn bar<T: TraitWAssocConst<A = 0>>() {
+    foo::<T>();
+    //~^ ERROR type mismatch resolving `<T as TraitWAssocConst>::A == 1`
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-type-bounds/const-projection-err.stock.stderr b/src/test/ui/associated-type-bounds/const-projection-err.stock.stderr
new file mode 100644
index 00000000000..bf0824259a5
--- /dev/null
+++ b/src/test/ui/associated-type-bounds/const-projection-err.stock.stderr
@@ -0,0 +1,17 @@
+error[E0271]: type mismatch resolving `<T as TraitWAssocConst>::A == 1`
+  --> $DIR/const-projection-err.rs:14:11
+   |
+LL |     foo::<T>();
+   |           ^ expected `1`, found `<T as TraitWAssocConst>::A`
+   |
+   = note: expected constant `1`
+              found constant `<T as TraitWAssocConst>::A`
+note: required by a bound in `foo`
+  --> $DIR/const-projection-err.rs:11:28
+   |
+LL | fn foo<T: TraitWAssocConst<A = 1>>() {}
+   |                            ^^^^^ required by this bound in `foo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/issues/issue-105330.stderr b/src/test/ui/issues/issue-105330.stderr
index 92f2ccb6544..30c380152a5 100644
--- a/src/test/ui/issues/issue-105330.stderr
+++ b/src/test/ui/issues/issue-105330.stderr
@@ -55,8 +55,10 @@ error[E0271]: type mismatch resolving `<Demo as TraitWAssocConst>::A == 32`
   --> $DIR/issue-105330.rs:12:11
    |
 LL |     foo::<Demo>()();
-   |           ^^^^ types differ
+   |           ^^^^ expected `32`, found `<Demo as TraitWAssocConst>::A`
    |
+   = note: expected constant `32`
+              found constant `<Demo as TraitWAssocConst>::A`
 note: required by a bound in `foo`
   --> $DIR/issue-105330.rs:11:28
    |
@@ -89,8 +91,10 @@ error[E0271]: type mismatch resolving `<Demo as TraitWAssocConst>::A == 32`
   --> $DIR/issue-105330.rs:19:11
    |
 LL |     foo::<Demo>();
-   |           ^^^^ types differ
+   |           ^^^^ expected `32`, found `<Demo as TraitWAssocConst>::A`
    |
+   = note: expected constant `32`
+              found constant `<Demo as TraitWAssocConst>::A`
 note: required by a bound in `foo`
   --> $DIR/issue-105330.rs:11:28
    |