From cde5bcafe89658a43b7cf865f58057db29f4d531 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Apr 2023 23:38:02 +0000 Subject: [PATCH] Don't create projection ty for const projection --- .../src/traits/project.rs | 31 ++++++++++++++----- .../projection-unspecified-but-bounded.rs | 16 ++++++++++ .../projection-unspecified-but-bounded.stderr | 17 ++++++++++ 3 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 tests/ui/associated-consts/projection-unspecified-but-bounded.rs create mode 100644 tests/ui/associated-consts/projection-unspecified-but-bounded.stderr diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 6ba0538717348..ea45412e47f11 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1272,14 +1272,29 @@ fn project<'cx, 'tcx>( ProjectionCandidateSet::Single(candidate) => { 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.def_id, obligation.predicate.substs) - .into(), - )), + ProjectionCandidateSet::None => { + let tcx = selcx.tcx(); + let term = match tcx.def_kind(obligation.predicate.def_id) { + DefKind::AssocTy | DefKind::ImplTraitPlaceholder => tcx + .mk_projection(obligation.predicate.def_id, obligation.predicate.substs) + .into(), + DefKind::AssocConst => tcx + .mk_const( + ty::ConstKind::Unevaluated(ty::UnevaluatedConst::new( + obligation.predicate.def_id, + obligation.predicate.substs, + )), + tcx.type_of(obligation.predicate.def_id) + .subst(tcx, obligation.predicate.substs), + ) + .into(), + kind => { + bug!("unknown projection def-id: {}", kind.descr(obligation.predicate.def_id)) + } + }; + + Ok(Projected::NoProgress(term)) + } // Error occurred while trying to processing impls. ProjectionCandidateSet::Error(e) => Err(ProjectionError::TraitSelectionError(e)), // Inherent ambiguity that prevents us from even enumerating the diff --git a/tests/ui/associated-consts/projection-unspecified-but-bounded.rs b/tests/ui/associated-consts/projection-unspecified-but-bounded.rs new file mode 100644 index 0000000000000..b1a0f39962b61 --- /dev/null +++ b/tests/ui/associated-consts/projection-unspecified-but-bounded.rs @@ -0,0 +1,16 @@ +#![feature(associated_const_equality)] + +// Issue 110549 + +pub trait TraitWAssocConst { + const A: usize; +} + +fn foo>() {} + +fn bar() { + foo::(); + //~^ ERROR type mismatch resolving `::A == 32` +} + +fn main() {} diff --git a/tests/ui/associated-consts/projection-unspecified-but-bounded.stderr b/tests/ui/associated-consts/projection-unspecified-but-bounded.stderr new file mode 100644 index 0000000000000..8175e510a093f --- /dev/null +++ b/tests/ui/associated-consts/projection-unspecified-but-bounded.stderr @@ -0,0 +1,17 @@ +error[E0271]: type mismatch resolving `::A == 32` + --> $DIR/projection-unspecified-but-bounded.rs:12:11 + | +LL | foo::(); + | ^ expected `32`, found `::A` + | + = note: expected constant `32` + found constant `::A` +note: required by a bound in `foo` + --> $DIR/projection-unspecified-but-bounded.rs:9:28 + | +LL | fn foo>() {} + | ^^^^^^ required by this bound in `foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`.