From 3aea46979a103fc7415d6e211cc21734196adde5 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 6 Mar 2023 19:45:03 +0000 Subject: [PATCH] Emit alias-eq when equating numeric var and projection --- compiler/rustc_infer/src/infer/combine.rs | 28 +++++++++++++------ compiler/rustc_middle/src/ty/mod.rs | 2 +- .../ui/traits/new-solver/int-var-alias-eq.rs | 18 ++++++++++++ 3 files changed, 38 insertions(+), 10 deletions(-) create mode 100644 tests/ui/traits/new-solver/int-var-alias-eq.rs diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 33292e871b11..b0613abeb484 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -119,20 +119,30 @@ impl<'tcx> InferCtxt<'tcx> { self.unify_float_variable(!a_is_expected, v_id, v) } + // We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm. + ( + ty::Alias(AliasKind::Projection, _), + ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)), + ) + | ( + ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)), + ty::Alias(AliasKind::Projection, _), + ) if self.tcx.trait_solver_next() => { + bug!() + } + + (_, ty::Alias(AliasKind::Projection, _)) | (ty::Alias(AliasKind::Projection, _), _) + if self.tcx.trait_solver_next() => + { + relation.register_type_equate_obligation(a, b); + Ok(a) + } + // All other cases of inference are errors (&ty::Infer(_), _) | (_, &ty::Infer(_)) => { Err(TypeError::Sorts(ty::relate::expected_found(relation, a, b))) } - (ty::Alias(AliasKind::Projection, _), _) if self.tcx.trait_solver_next() => { - relation.register_type_equate_obligation(a, b); - Ok(b) - } - (_, ty::Alias(AliasKind::Projection, _)) if self.tcx.trait_solver_next() => { - relation.register_type_equate_obligation(b, a); - Ok(a) - } - _ => ty::relate::super_relate_tys(relation, a, b), } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 8cc8a0573bb0..d9bfacd6e3cf 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -995,7 +995,7 @@ impl<'tcx> Term<'tcx> { pub fn is_infer(&self) -> bool { match self.unpack() { - TermKind::Ty(ty) => ty.is_ty_or_numeric_infer(), + TermKind::Ty(ty) => ty.is_ty_var(), TermKind::Const(ct) => ct.is_ct_infer(), } } diff --git a/tests/ui/traits/new-solver/int-var-alias-eq.rs b/tests/ui/traits/new-solver/int-var-alias-eq.rs new file mode 100644 index 000000000000..2da387db4a99 --- /dev/null +++ b/tests/ui/traits/new-solver/int-var-alias-eq.rs @@ -0,0 +1,18 @@ +// check-pass +// compile-flags: -Ztrait-solver=next + +// HIR typeck ends up equating `<_#0i as Add>::Output == _#0i`. +// Want to make sure that we emit an alias-eq goal for this, +// instead of treating it as a type error and bailing. + +fn test() { + // fallback + let x = 1 + 2; +} + +fn test2() -> u32 { + // expectation from return ty + 1 + 2 +} + +fn main() {}