From fa74a9e6aa525a285cfd530cdea2ddeb9fca013c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 13 Jul 2024 16:13:55 +0200 Subject: valtree construction: keep track of which type was valtree-incompatible --- src/tools/clippy/clippy_lints/src/non_copy_const.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 09225ac3246..6f5505e8a63 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -235,7 +235,7 @@ impl<'tcx> NonCopyConst<'tcx> { fn is_value_unfrozen_raw( cx: &LateContext<'tcx>, - result: Result>, ErrorHandled>, + result: Result, Ty<'tcx>>, ErrorHandled>, ty: Ty<'tcx>, ) -> bool { result.map_or_else( -- cgit 1.4.1-3-g733a5 From 67c99d6338922d270108fc6390d3ad5224b3a7e1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 13 Jul 2024 18:32:10 +0200 Subject: avoid creating an Instance only to immediately disassemble it again --- .../rustc_error_codes/src/error_codes/E0158.md | 17 +++++------ compiler/rustc_mir_build/messages.ftl | 2 -- compiler/rustc_mir_build/src/errors.rs | 9 +----- compiler/rustc_mir_build/src/thir/pattern/mod.rs | 33 ++------------------ src/tools/tidy/src/issues.txt | 1 - .../associated-const-type-parameter-arms.rs | 29 ------------------ .../associated-const-type-parameter-arms.stderr | 15 ---------- .../associated-const-type-parameter-pattern.rs | 35 ++++++++++++++++++++++ .../associated-const-type-parameter-pattern.stderr | 27 +++++++++++++++++ tests/ui/consts/issue-73976-polymorphic.stderr | 5 ++-- tests/ui/consts/issue-79137-toogeneric.stderr | 3 +- .../ui/inline-const/const-match-pat-generic.stderr | 5 ++-- .../pattern/issue-68393-let-pat-assoc-constant.rs | 26 ---------------- .../issue-68393-let-pat-assoc-constant.stderr | 15 ---------- 14 files changed, 81 insertions(+), 141 deletions(-) delete mode 100644 tests/ui/associated-consts/associated-const-type-parameter-arms.rs delete mode 100644 tests/ui/associated-consts/associated-const-type-parameter-arms.stderr create mode 100644 tests/ui/associated-consts/associated-const-type-parameter-pattern.rs create mode 100644 tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr delete mode 100644 tests/ui/pattern/issue-68393-let-pat-assoc-constant.rs delete mode 100644 tests/ui/pattern/issue-68393-let-pat-assoc-constant.stderr (limited to 'src') diff --git a/compiler/rustc_error_codes/src/error_codes/E0158.md b/compiler/rustc_error_codes/src/error_codes/E0158.md index 03b93d925c1..c31f1e13bee 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0158.md +++ b/compiler/rustc_error_codes/src/error_codes/E0158.md @@ -1,5 +1,4 @@ -An associated `const`, `const` parameter or `static` has been referenced -in a pattern. +A generic parameter or `static` has been referenced in a pattern. Erroneous code example: @@ -15,25 +14,25 @@ trait Bar { fn test(arg: Foo) { match arg { - A::X => println!("A::X"), // error: E0158: associated consts cannot be - // referenced in patterns + A::X => println!("A::X"), // error: E0158: constant pattern depends + // on a generic parameter Foo::Two => println!("Two") } } ``` -Associated `const`s cannot be referenced in patterns because it is impossible +Generic parameters cannot be referenced in patterns because it is impossible for the compiler to prove exhaustiveness (that some pattern will always match). Take the above example, because Rust does type checking in the *generic* method, not the *monomorphized* specific instance. So because `Bar` could have -theoretically infinite implementations, there's no way to always be sure that +theoretically arbitrary implementations, there's no way to always be sure that `A::X` is `Foo::One`. So this code must be rejected. Even if code can be proven exhaustive by a programmer, the compiler cannot currently prove this. -The same holds true of `const` parameters and `static`s. +The same holds true of `static`s. -If you want to match against an associated `const`, `const` parameter or -`static` consider using a guard instead: +If you want to match against a `const` that depends on a generic parameter or a +`static`, consider using a guard instead: ``` trait Trait { diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index 0c277811fda..281f3ef6ef3 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -4,8 +4,6 @@ mir_build_already_borrowed = cannot borrow value as mutable because it is also b mir_build_already_mut_borrowed = cannot borrow value as immutable because it is also borrowed as mutable -mir_build_assoc_const_in_pattern = associated consts cannot be referenced in patterns - mir_build_bindings_with_variant_name = pattern binding `{$name}` is named the same as one of the variants of the type `{$ty_path}` .suggestion = to match on the variant, qualify the path diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 7c73d8a6d47..f6f443b64a6 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -566,13 +566,6 @@ pub(crate) struct StaticInPattern { pub(crate) span: Span, } -#[derive(Diagnostic)] -#[diag(mir_build_assoc_const_in_pattern, code = E0158)] -pub(crate) struct AssocConstInPattern { - #[primary_span] - pub(crate) span: Span, -} - #[derive(Diagnostic)] #[diag(mir_build_const_param_in_pattern, code = E0158)] pub(crate) struct ConstParamInPattern { @@ -597,7 +590,7 @@ pub(crate) struct UnreachablePattern { } #[derive(Diagnostic)] -#[diag(mir_build_const_pattern_depends_on_generic_parameter)] +#[diag(mir_build_const_pattern_depends_on_generic_parameter, code = E0158)] pub(crate) struct ConstPatternDependsOnGenericParameter { #[primary_span] pub(crate) span: Span, diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 553c5e17512..622651800f4 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -548,37 +548,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { _ => return pat_from_kind(self.lower_variant_or_leaf(res, id, span, ty, vec![])), }; - // Use `Reveal::All` here because patterns are always monomorphic even if their function - // isn't. - let param_env_reveal_all = self.param_env.with_reveal_all_normalized(self.tcx); - // N.B. There is no guarantee that args collected in typeck results are fully normalized, - // so they need to be normalized in order to pass to `Instance::resolve`, which will ICE - // if given unnormalized types. - let args = self - .tcx - .normalize_erasing_regions(param_env_reveal_all, self.typeck_results.node_args(id)); - let instance = match ty::Instance::try_resolve(self.tcx, param_env_reveal_all, def_id, args) - { - Ok(Some(i)) => i, - Ok(None) => { - // It should be assoc consts if there's no error but we cannot resolve it. - debug_assert!(is_associated_const); - - let e = self.tcx.dcx().emit_err(AssocConstInPattern { span }); - return pat_from_kind(PatKind::Error(e)); - } - - Err(_) => { - let e = self.tcx.dcx().emit_err(CouldNotEvalConstPattern { span }); - return pat_from_kind(PatKind::Error(e)); - } - }; - - let c = ty::Const::new_unevaluated( - self.tcx, - ty::UnevaluatedConst { def: instance.def_id(), args: instance.args }, - ); - + let args = self.typeck_results.node_args(id); + let c = ty::Const::new_unevaluated(self.tcx, ty::UnevaluatedConst { def: def_id, args }); let pattern = self.const_to_pat(c, ty, id, span); if !is_associated_const { diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index 3c7284ce6db..57310977704 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -3449,7 +3449,6 @@ ui/pattern/issue-6449.rs ui/pattern/issue-66270-pat-struct-parser-recovery.rs ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs ui/pattern/issue-67776-match-same-name-enum-variant-refs.rs -ui/pattern/issue-68393-let-pat-assoc-constant.rs ui/pattern/issue-72565.rs ui/pattern/issue-72574-1.rs ui/pattern/issue-72574-2.rs diff --git a/tests/ui/associated-consts/associated-const-type-parameter-arms.rs b/tests/ui/associated-consts/associated-const-type-parameter-arms.rs deleted file mode 100644 index 3f260d84e4c..00000000000 --- a/tests/ui/associated-consts/associated-const-type-parameter-arms.rs +++ /dev/null @@ -1,29 +0,0 @@ -pub enum EFoo { A, B, C, D } - -pub trait Foo { - const X: EFoo; -} - -struct Abc; - -impl Foo for Abc { - const X: EFoo = EFoo::B; -} - -struct Def; -impl Foo for Def { - const X: EFoo = EFoo::D; -} - -pub fn test(arg: EFoo) { - match arg { - A::X => println!("A::X"), - //~^ error: associated consts cannot be referenced in patterns [E0158] - B::X => println!("B::X"), - //~^ error: associated consts cannot be referenced in patterns [E0158] - _ => (), - } -} - -fn main() { -} diff --git a/tests/ui/associated-consts/associated-const-type-parameter-arms.stderr b/tests/ui/associated-consts/associated-const-type-parameter-arms.stderr deleted file mode 100644 index 1ccf9febd4b..00000000000 --- a/tests/ui/associated-consts/associated-const-type-parameter-arms.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0158]: associated consts cannot be referenced in patterns - --> $DIR/associated-const-type-parameter-arms.rs:20:9 - | -LL | A::X => println!("A::X"), - | ^^^^ - -error[E0158]: associated consts cannot be referenced in patterns - --> $DIR/associated-const-type-parameter-arms.rs:22:9 - | -LL | B::X => println!("B::X"), - | ^^^^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0158`. diff --git a/tests/ui/associated-consts/associated-const-type-parameter-pattern.rs b/tests/ui/associated-consts/associated-const-type-parameter-pattern.rs new file mode 100644 index 00000000000..b5798adc71c --- /dev/null +++ b/tests/ui/associated-consts/associated-const-type-parameter-pattern.rs @@ -0,0 +1,35 @@ +pub enum EFoo { A, B, C, D } + +pub trait Foo { + const X: EFoo; +} + +struct Abc; + +impl Foo for Abc { + const X: EFoo = EFoo::B; +} + +struct Def; +impl Foo for Def { + const X: EFoo = EFoo::D; +} + +pub fn test(arg: EFoo) { + match arg { + A::X => println!("A::X"), + //~^ error: constant pattern depends on a generic parameter + B::X => println!("B::X"), + //~^ error: constant pattern depends on a generic parameter + _ => (), + } +} + +pub fn test_let_pat(arg: EFoo, A::X: EFoo) { + //~^ ERROR constant pattern depends on a generic parameter + let A::X = arg; + //~^ ERROR constant pattern depends on a generic parameter +} + +fn main() { +} diff --git a/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr b/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr new file mode 100644 index 00000000000..adc8f399207 --- /dev/null +++ b/tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr @@ -0,0 +1,27 @@ +error[E0158]: constant pattern depends on a generic parameter + --> $DIR/associated-const-type-parameter-pattern.rs:20:9 + | +LL | A::X => println!("A::X"), + | ^^^^ + +error[E0158]: constant pattern depends on a generic parameter + --> $DIR/associated-const-type-parameter-pattern.rs:22:9 + | +LL | B::X => println!("B::X"), + | ^^^^ + +error[E0158]: constant pattern depends on a generic parameter + --> $DIR/associated-const-type-parameter-pattern.rs:30:9 + | +LL | let A::X = arg; + | ^^^^ + +error[E0158]: constant pattern depends on a generic parameter + --> $DIR/associated-const-type-parameter-pattern.rs:28:48 + | +LL | pub fn test_let_pat(arg: EFoo, A::X: EFoo) { + | ^^^^ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0158`. diff --git a/tests/ui/consts/issue-73976-polymorphic.stderr b/tests/ui/consts/issue-73976-polymorphic.stderr index 97a5fbc5747..8a44eb9854f 100644 --- a/tests/ui/consts/issue-73976-polymorphic.stderr +++ b/tests/ui/consts/issue-73976-polymorphic.stderr @@ -1,10 +1,10 @@ -error: constant pattern depends on a generic parameter +error[E0158]: constant pattern depends on a generic parameter --> $DIR/issue-73976-polymorphic.rs:20:37 | LL | matches!(GetTypeId::::VALUE, GetTypeId::::VALUE) | ^^^^^^^^^^^^^^^^^^^^^ -error: constant pattern depends on a generic parameter +error[E0158]: constant pattern depends on a generic parameter --> $DIR/issue-73976-polymorphic.rs:31:42 | LL | matches!(GetTypeNameLen::::VALUE, GetTypeNameLen::::VALUE) @@ -12,3 +12,4 @@ LL | matches!(GetTypeNameLen::::VALUE, GetTypeNameLen::::VALUE) error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0158`. diff --git a/tests/ui/consts/issue-79137-toogeneric.stderr b/tests/ui/consts/issue-79137-toogeneric.stderr index 18bdde45e2c..de81512ec6d 100644 --- a/tests/ui/consts/issue-79137-toogeneric.stderr +++ b/tests/ui/consts/issue-79137-toogeneric.stderr @@ -1,4 +1,4 @@ -error: constant pattern depends on a generic parameter +error[E0158]: constant pattern depends on a generic parameter --> $DIR/issue-79137-toogeneric.rs:12:43 | LL | matches!(GetVariantCount::::VALUE, GetVariantCount::::VALUE) @@ -6,3 +6,4 @@ LL | matches!(GetVariantCount::::VALUE, GetVariantCount::::VALUE) error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0158`. diff --git a/tests/ui/inline-const/const-match-pat-generic.stderr b/tests/ui/inline-const/const-match-pat-generic.stderr index 15c3a876afc..26f72b34eca 100644 --- a/tests/ui/inline-const/const-match-pat-generic.stderr +++ b/tests/ui/inline-const/const-match-pat-generic.stderr @@ -1,10 +1,10 @@ -error: constant pattern depends on a generic parameter +error[E0158]: constant pattern depends on a generic parameter --> $DIR/const-match-pat-generic.rs:7:9 | LL | const { V } => {}, | ^^^^^^^^^^^ -error: constant pattern depends on a generic parameter +error[E0158]: constant pattern depends on a generic parameter --> $DIR/const-match-pat-generic.rs:19:9 | LL | const { f(V) } => {}, @@ -12,3 +12,4 @@ LL | const { f(V) } => {}, error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0158`. diff --git a/tests/ui/pattern/issue-68393-let-pat-assoc-constant.rs b/tests/ui/pattern/issue-68393-let-pat-assoc-constant.rs deleted file mode 100644 index 95ead6b5d4a..00000000000 --- a/tests/ui/pattern/issue-68393-let-pat-assoc-constant.rs +++ /dev/null @@ -1,26 +0,0 @@ -pub enum EFoo { - A, -} - -pub trait Foo { - const X: EFoo; -} - -struct Abc; - -impl Foo for Abc { - const X: EFoo = EFoo::A; -} - -struct Def; -impl Foo for Def { - const X: EFoo = EFoo::A; -} - -pub fn test(arg: EFoo, A::X: EFoo) { - //~^ ERROR associated consts cannot be referenced in patterns - let A::X = arg; - //~^ ERROR associated consts cannot be referenced in patterns -} - -fn main() {} diff --git a/tests/ui/pattern/issue-68393-let-pat-assoc-constant.stderr b/tests/ui/pattern/issue-68393-let-pat-assoc-constant.stderr deleted file mode 100644 index 62c90b638d7..00000000000 --- a/tests/ui/pattern/issue-68393-let-pat-assoc-constant.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0158]: associated consts cannot be referenced in patterns - --> $DIR/issue-68393-let-pat-assoc-constant.rs:22:9 - | -LL | let A::X = arg; - | ^^^^ - -error[E0158]: associated consts cannot be referenced in patterns - --> $DIR/issue-68393-let-pat-assoc-constant.rs:20:40 - | -LL | pub fn test(arg: EFoo, A::X: EFoo) { - | ^^^^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0158`. -- cgit 1.4.1-3-g733a5