diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-01-18 22:00:47 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-01-18 22:00:47 +0100 |
| commit | 5a4f47460b14780d63303a4a52319a7f44654bb5 (patch) | |
| tree | 454e2359ed3de519e6e812a12386fd5b6ff4a8e2 | |
| parent | ff476b3009bd0f0137ade6eb02af2794c19066d2 (diff) | |
| parent | 7dac6260920bc4fbd6988609bd80af05aa60a400 (diff) | |
| download | rust-5a4f47460b14780d63303a4a52319a7f44654bb5.tar.gz rust-5a4f47460b14780d63303a4a52319a7f44654bb5.zip | |
Rollup merge of #92780 - b-naber:postpone-const-eval-coherence, r=lcnr
Directly use ConstValue for single literals in blocks Addresses the minimal repro in https://github.com/rust-lang/rust/issues/92186, but doesn't fix the underlying problem (which would be solved by solving the anon subst problem afaict). I do, however, think that it makes sense in general to treat single literals in anon blocks as const values directly, especially in light of the problem that the issue refers to (anon const evaluation being postponed until infer variables in substs can be resolved, which was introduced by https://github.com/rust-lang/rust/pull/90023), i.e. while we do get warnings for those unnecessary braces, we should try to avoid errors caused by those braces if possible.
7 files changed, 55 insertions, 21 deletions
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index d6c35dfef88..19a73732fca 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -36,6 +36,7 @@ impl<'tcx> Const<'tcx> { Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id)) } + #[instrument(skip(tcx), level = "debug")] pub fn from_opt_const_arg_anon_const( tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalDefId>, @@ -51,6 +52,7 @@ impl<'tcx> Const<'tcx> { }; let expr = &tcx.hir().body(body_id).value; + debug!(?expr); let ty = tcx.type_of(def.def_id_for_type_of()); @@ -67,11 +69,21 @@ impl<'tcx> Const<'tcx> { } } + #[instrument(skip(tcx), level = "debug")] fn try_eval_lit_or_param( tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, expr: &'tcx hir::Expr<'tcx>, ) -> Option<&'tcx Self> { + // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments + // currently have to be wrapped in curly brackets, so it's necessary to special-case. + let expr = match &expr.kind { + hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => { + block.expr.as_ref().unwrap() + } + _ => expr, + }; + let lit_input = match expr.kind { hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }), hir::ExprKind::Unary(hir::UnOp::Neg, ref expr) => match expr.kind { @@ -97,15 +109,6 @@ impl<'tcx> Const<'tcx> { } } - // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments - // currently have to be wrapped in curly brackets, so it's necessary to special-case. - let expr = match &expr.kind { - hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => { - block.expr.as_ref().unwrap() - } - _ => expr, - }; - use hir::{def::DefKind::ConstParam, def::Res, ExprKind, Path, QPath}; match expr.kind { ExprKind::Path(QPath::Resolved(_, &Path { res: Res::Def(ConstParam, def_id), .. })) => { diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index d174e00df77..af3540386f9 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -53,6 +53,7 @@ pub fn add_placeholder_note(err: &mut rustc_errors::DiagnosticBuilder<'_>) { /// If there are types that satisfy both impls, invokes `on_overlap` /// with a suitably-freshened `ImplHeader` with those types /// substituted. Otherwise, invokes `no_overlap`. +#[instrument(skip(tcx, skip_leak_check, on_overlap, no_overlap), level = "debug")] pub fn overlapping_impls<F1, F2, R>( tcx: TyCtxt<'_>, impl1_def_id: DefId, @@ -65,12 +66,6 @@ where F1: FnOnce(OverlapResult<'_>) -> R, F2: FnOnce() -> R, { - debug!( - "overlapping_impls(\ - impl1_def_id={:?}, \ - impl2_def_id={:?})", - impl1_def_id, impl2_def_id, - ); // Before doing expensive operations like entering an inference context, do // a quick check via fast_reject to tell if the impl headers could possibly // unify. @@ -85,6 +80,7 @@ where .any(|(ty1, ty2)| { let t1 = fast_reject::simplify_type(tcx, ty1, SimplifyParams::No, StripReferences::No); let t2 = fast_reject::simplify_type(tcx, ty2, SimplifyParams::No, StripReferences::No); + if let (Some(t1), Some(t2)) = (t1, t2) { // Simplified successfully t1 != t2 diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index ab732f510ff..cd2e0f18e0c 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -117,9 +117,8 @@ pub fn translate_substs<'a, 'tcx>( /// Specialization is determined by the sets of types to which the impls apply; /// `impl1` specializes `impl2` if it applies to a subset of the types `impl2` applies /// to. +#[instrument(skip(tcx), level = "debug")] pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, DefId)) -> bool { - debug!("specializes({:?}, {:?})", impl1_def_id, impl2_def_id); - // The feature gate should prevent introducing new specializations, but not // taking advantage of upstream ones. let features = tcx.features(); diff --git a/src/test/ui/const-generics/issues/issue-92186.rs b/src/test/ui/const-generics/issues/issue-92186.rs new file mode 100644 index 00000000000..9ced4667d24 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-92186.rs @@ -0,0 +1,12 @@ +// check-pass + +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +pub struct Foo<const N: usize>; +pub trait Bar<T> {} + +impl<T> Bar<T> for Foo<{ 1 }> {} +impl<T> Bar<T> for Foo<{ 2 }> {} + +fn main() {} diff --git a/src/test/ui/const-generics/types-mismatch-const-args.full.stderr b/src/test/ui/const-generics/types-mismatch-const-args.full.stderr index 565c9ba1ff1..4d6b752867f 100644 --- a/src/test/ui/const-generics/types-mismatch-const-args.full.stderr +++ b/src/test/ui/const-generics/types-mismatch-const-args.full.stderr @@ -15,9 +15,20 @@ LL | let _: A<'a, u16, {2u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data | | | expected due to this | - = note: expected struct `A<'a, u16, {2u32}, {3u32}>` - found struct `A<'b, u32, {2u32}, {3u32}>` + = note: expected struct `A<'a, u16, _, _>` + found struct `A<'b, u32, _, _>` -error: aborting due to 2 previous errors +error[E0308]: mismatched types + --> $DIR/types-mismatch-const-args.rs:18:41 + | +LL | let _: A<'a, u16, {4u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data: PhantomData }; + | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u16`, found `u32` + | | + | expected due to this + | + = note: expected struct `A<'a, u16, 4_u32, _>` + found struct `A<'b, u32, 2_u32, _>` + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/types-mismatch-const-args.min.stderr b/src/test/ui/const-generics/types-mismatch-const-args.min.stderr index ec9221d2486..8b60238cb0c 100644 --- a/src/test/ui/const-generics/types-mismatch-const-args.min.stderr +++ b/src/test/ui/const-generics/types-mismatch-const-args.min.stderr @@ -20,6 +20,17 @@ LL | let _: A<'a, u16, {2u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data = note: expected struct `A<'a, u16, _, _>` found struct `A<'b, u32, _, _>` -error: aborting due to 2 previous errors +error[E0308]: mismatched types + --> $DIR/types-mismatch-const-args.rs:18:41 + | +LL | let _: A<'a, u16, {4u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data: PhantomData }; + | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u16`, found `u32` + | | + | expected due to this + | + = note: expected struct `A<'a, u16, 4_u32, _>` + found struct `A<'b, u32, 2_u32, _>` + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/types-mismatch-const-args.rs b/src/test/ui/const-generics/types-mismatch-const-args.rs index c2092c4268e..43ef28b268f 100644 --- a/src/test/ui/const-generics/types-mismatch-const-args.rs +++ b/src/test/ui/const-generics/types-mismatch-const-args.rs @@ -15,6 +15,8 @@ fn a<'a, 'b>() { //~^ ERROR mismatched types let _: A<'a, u16, {2u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data: PhantomData }; //~^ ERROR mismatched types + let _: A<'a, u16, {4u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data: PhantomData }; + //~^ ERROR mismatched types } pub fn main() {} |
