From 958a02247a8c4c1375220bdcf7098b1e848e28bf Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 20 Mar 2024 10:25:13 +0000 Subject: [PATCH 1/2] Use the more informative generic type inference failure error on method calls on raw pointers --- .../src/error_codes/E0699.md | 4 +- compiler/rustc_error_codes/src/lib.rs | 2 +- compiler/rustc_hir_typeck/messages.ftl | 3 -- compiler/rustc_hir_typeck/src/errors.rs | 7 --- compiler/rustc_hir_typeck/src/method/probe.rs | 43 +++++++++++-------- src/tools/tidy/src/error_codes.rs | 2 +- .../edition-raw-pointer-method-2018.rs | 2 +- .../edition-raw-pointer-method-2018.stderr | 16 +++++-- .../ui/methods/call_method_unknown_pointee.rs | 8 ++-- .../call_method_unknown_pointee.stderr | 40 +++++++++++++---- 10 files changed, 79 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0699.md b/compiler/rustc_error_codes/src/error_codes/E0699.md index 454d2507e5e2e..1094ebf4b8fc7 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0699.md +++ b/compiler/rustc_error_codes/src/error_codes/E0699.md @@ -1,8 +1,10 @@ +#### Note: this error code is no longer emitted by the compiler. + A method was called on a raw pointer whose inner type wasn't completely known. Erroneous code example: -```compile_fail,edition2018,E0699 +```compile_fail,edition2018 # #![deny(warnings)] # fn main() { let foo = &1; diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index da688e385aa09..f4a33a05c1b36 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -441,7 +441,7 @@ E0695: 0695, E0696: 0696, E0697: 0697, E0698: 0698, -E0699: 0699, +E0699: 0699, // REMOVED: merged into generic inference var error E0700: 0700, E0701: 0701, E0703: 0703, diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 220da19a29dc8..d4e9480eec6b6 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -93,9 +93,6 @@ hir_typeck_lossy_provenance_ptr2int = .suggestion = use `.addr()` to obtain the address of a pointer .help = if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead -hir_typeck_method_call_on_unknown_raw_pointee = - cannot call a method on a raw pointer with an unknown pointee type - hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}` hir_typeck_no_associated_item = no {$item_kind} named `{$item_name}` found for {$ty_prefix} `{$ty_str}`{$trait_missing_method -> diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index df21b84f92ef3..cabe958221f7c 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -76,13 +76,6 @@ pub struct StructExprNonExhaustive { pub what: &'static str, } -#[derive(Diagnostic)] -#[diag(hir_typeck_method_call_on_unknown_raw_pointee, code = E0699)] -pub struct MethodCallOnUnknownRawPointee { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(hir_typeck_functional_record_update_on_non_struct, code = E0436)] pub struct FunctionalRecordUpdateOnNonStruct { diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 193ea0408996c..10fb93fbeea04 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -3,7 +3,6 @@ use super::CandidateSource; use super::MethodError; use super::NoMatchData; -use crate::errors::MethodCallOnUnknownRawPointee; use crate::FnCtxt; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; @@ -433,21 +432,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if is_suggestion.0 { // Ambiguity was encountered during a suggestion. Just keep going. debug!("ProbeContext: encountered ambiguity in suggestion"); - } else if bad_ty.reached_raw_pointer && !self.tcx.features().arbitrary_self_types { + } else if bad_ty.reached_raw_pointer + && !self.tcx.features().arbitrary_self_types + && !self.tcx.sess.at_least_rust_2018() + { // this case used to be allowed by the compiler, // so we do a future-compat lint here for the 2015 edition // (see https://github.com/rust-lang/rust/issues/46906) - if self.tcx.sess.at_least_rust_2018() { - self.dcx().emit_err(MethodCallOnUnknownRawPointee { span }); - } else { - self.tcx.node_span_lint( - lint::builtin::TYVAR_BEHIND_RAW_POINTER, - scope_expr_id, - span, - "type annotations needed", - |_| {}, - ); - } + self.tcx.node_span_lint( + lint::builtin::TYVAR_BEHIND_RAW_POINTER, + scope_expr_id, + span, + "type annotations needed", + |_| {}, + ); } else { // Ended up encountering a type variable when doing autoderef, // but it may not be a type variable after processing obligations @@ -458,10 +456,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .unwrap_or_else(|_| span_bug!(span, "instantiating {:?} failed?", ty)); let ty = self.resolve_vars_if_possible(ty.value); let guar = match *ty.kind() { - ty::Infer(ty::TyVar(_)) => self - .err_ctxt() - .emit_inference_failure_err(self.body_id, span, ty.into(), E0282, true) - .emit(), + ty::Infer(ty::TyVar(_)) => { + let raw_ptr_call = + bad_ty.reached_raw_pointer && !self.tcx.features().arbitrary_self_types; + let mut err = self.err_ctxt().emit_inference_failure_err( + self.body_id, + span, + ty.into(), + E0282, + !raw_ptr_call, + ); + if raw_ptr_call { + err.span_label(span, "cannot call a method on a raw pointer with an unknown pointee type"); + } + err.emit() + } ty::Error(guar) => guar, _ => bug!("unexpected bad final type in method autoderef"), }; diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index 6fc65e56901a7..a03347fdc3b4e 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -153,7 +153,7 @@ fn check_error_codes_docs( if error_codes.iter().all(|e| e != err_code) { errors.push(format!( "Found valid file `{}` in error code docs directory without corresponding \ - entry in `error_code.rs`", + entry in `rustc_error_codes/src/lib.rs`", path.display() )); return; diff --git a/tests/ui/editions/edition-raw-pointer-method-2018.rs b/tests/ui/editions/edition-raw-pointer-method-2018.rs index b346953e187ee..ad47553d5b7a2 100644 --- a/tests/ui/editions/edition-raw-pointer-method-2018.rs +++ b/tests/ui/editions/edition-raw-pointer-method-2018.rs @@ -6,6 +6,6 @@ fn main() { let x = 0; let y = &x as *const _; + //~^ error: type annotations needed let _ = y.is_null(); - //~^ error: cannot call a method on a raw pointer with an unknown pointee type [E0699] } diff --git a/tests/ui/editions/edition-raw-pointer-method-2018.stderr b/tests/ui/editions/edition-raw-pointer-method-2018.stderr index 663843ad7bc78..2792d1e740056 100644 --- a/tests/ui/editions/edition-raw-pointer-method-2018.stderr +++ b/tests/ui/editions/edition-raw-pointer-method-2018.stderr @@ -1,9 +1,17 @@ -error[E0699]: cannot call a method on a raw pointer with an unknown pointee type - --> $DIR/edition-raw-pointer-method-2018.rs:9:15 +error[E0282]: type annotations needed for `*const _` + --> $DIR/edition-raw-pointer-method-2018.rs:8:9 | +LL | let y = &x as *const _; + | ^ +LL | LL | let _ = y.is_null(); - | ^^^^^^^ + | ------- cannot call a method on a raw pointer with an unknown pointee type + | +help: consider giving `y` an explicit type, where the placeholders `_` are specified + | +LL | let y: *const _ = &x as *const _; + | ++++++++++ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0699`. +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/methods/call_method_unknown_pointee.rs b/tests/ui/methods/call_method_unknown_pointee.rs index 1643b6bfa1813..a144e855ae3cb 100644 --- a/tests/ui/methods/call_method_unknown_pointee.rs +++ b/tests/ui/methods/call_method_unknown_pointee.rs @@ -8,10 +8,10 @@ fn main() { let ptr = &val as *const u32; unsafe { let _a: i32 = (ptr as *const _).read(); - //~^ ERROR cannot call a method on a raw pointer with an unknown pointee type [E0699] + //~^ ERROR type annotations needed let b = ptr as *const _; + //~^ ERROR type annotations needed let _b: u8 = b.read(); - //~^ ERROR cannot call a method on a raw pointer with an unknown pointee type [E0699] let _c = (ptr as *const u8).read(); // we know the type here } @@ -19,10 +19,10 @@ fn main() { let ptr = &mut val as *mut u32; unsafe { let _a: i32 = (ptr as *mut _).read(); - //~^ ERROR cannot call a method on a raw pointer with an unknown pointee type [E0699] + //~^ ERROR type annotations needed let b = ptr as *mut _; + //~^ ERROR type annotations needed b.write(10); - //~^ ERROR cannot call a method on a raw pointer with an unknown pointee type [E0699] (ptr as *mut i32).write(1000); // we know the type here } } diff --git a/tests/ui/methods/call_method_unknown_pointee.stderr b/tests/ui/methods/call_method_unknown_pointee.stderr index 84ecf046e7ac2..9d0f38cf6b5c1 100644 --- a/tests/ui/methods/call_method_unknown_pointee.stderr +++ b/tests/ui/methods/call_method_unknown_pointee.stderr @@ -1,27 +1,49 @@ -error[E0699]: cannot call a method on a raw pointer with an unknown pointee type +error[E0282]: type annotations needed --> $DIR/call_method_unknown_pointee.rs:10:41 | LL | let _a: i32 = (ptr as *const _).read(); | ^^^^ + | | + | cannot infer type + | cannot call a method on a raw pointer with an unknown pointee type -error[E0699]: cannot call a method on a raw pointer with an unknown pointee type - --> $DIR/call_method_unknown_pointee.rs:13:24 +error[E0282]: type annotations needed for `*const _` + --> $DIR/call_method_unknown_pointee.rs:12:13 | +LL | let b = ptr as *const _; + | ^ +LL | LL | let _b: u8 = b.read(); - | ^^^^ + | ---- cannot call a method on a raw pointer with an unknown pointee type + | +help: consider giving `b` an explicit type, where the placeholders `_` are specified + | +LL | let b: *const _ = ptr as *const _; + | ++++++++++ -error[E0699]: cannot call a method on a raw pointer with an unknown pointee type +error[E0282]: type annotations needed --> $DIR/call_method_unknown_pointee.rs:21:39 | LL | let _a: i32 = (ptr as *mut _).read(); | ^^^^ + | | + | cannot infer type + | cannot call a method on a raw pointer with an unknown pointee type -error[E0699]: cannot call a method on a raw pointer with an unknown pointee type - --> $DIR/call_method_unknown_pointee.rs:24:11 +error[E0282]: type annotations needed for `*mut _` + --> $DIR/call_method_unknown_pointee.rs:23:13 | +LL | let b = ptr as *mut _; + | ^ +LL | LL | b.write(10); - | ^^^^^ + | ----- cannot call a method on a raw pointer with an unknown pointee type + | +help: consider giving `b` an explicit type, where the placeholders `_` are specified + | +LL | let b: *mut _ = ptr as *mut _; + | ++++++++ error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0699`. +For more information about this error, try `rustc --explain E0282`. From 7f9a4af0eb498bd0b1bcd7b6124ed90a1f7fac7b Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 20 Mar 2024 11:09:17 +0000 Subject: [PATCH 2/2] Make tidy error code parsing robust against comments --- src/tools/tidy/src/error_codes.rs | 43 +++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index a03347fdc3b4e..39f7e70b69393 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -71,10 +71,12 @@ fn extract_error_codes(root_path: &Path, errors: &mut Vec) -> Vec) -> Vec