1
Fork 0

Use the more informative generic type inference failure error on method calls on raw pointers

This commit is contained in:
Oli Scherer 2024-03-20 10:25:13 +00:00
parent 200e3f7995
commit 958a02247a
10 changed files with 79 additions and 48 deletions

View file

@ -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. A method was called on a raw pointer whose inner type wasn't completely known.
Erroneous code example: Erroneous code example:
```compile_fail,edition2018,E0699 ```compile_fail,edition2018
# #![deny(warnings)] # #![deny(warnings)]
# fn main() { # fn main() {
let foo = &1; let foo = &1;

View file

@ -441,7 +441,7 @@ E0695: 0695,
E0696: 0696, E0696: 0696,
E0697: 0697, E0697: 0697,
E0698: 0698, E0698: 0698,
E0699: 0699, E0699: 0699, // REMOVED: merged into generic inference var error
E0700: 0700, E0700: 0700,
E0701: 0701, E0701: 0701,
E0703: 0703, E0703: 0703,

View file

@ -93,9 +93,6 @@ hir_typeck_lossy_provenance_ptr2int =
.suggestion = use `.addr()` to obtain the address of a pointer .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 .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_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 -> hir_typeck_no_associated_item = no {$item_kind} named `{$item_name}` found for {$ty_prefix} `{$ty_str}`{$trait_missing_method ->

View file

@ -76,13 +76,6 @@ pub struct StructExprNonExhaustive {
pub what: &'static str, 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)] #[derive(Diagnostic)]
#[diag(hir_typeck_functional_record_update_on_non_struct, code = E0436)] #[diag(hir_typeck_functional_record_update_on_non_struct, code = E0436)]
pub struct FunctionalRecordUpdateOnNonStruct { pub struct FunctionalRecordUpdateOnNonStruct {

View file

@ -3,7 +3,6 @@ use super::CandidateSource;
use super::MethodError; use super::MethodError;
use super::NoMatchData; use super::NoMatchData;
use crate::errors::MethodCallOnUnknownRawPointee;
use crate::FnCtxt; use crate::FnCtxt;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability; use rustc_errors::Applicability;
@ -433,13 +432,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if is_suggestion.0 { if is_suggestion.0 {
// Ambiguity was encountered during a suggestion. Just keep going. // Ambiguity was encountered during a suggestion. Just keep going.
debug!("ProbeContext: encountered ambiguity in suggestion"); 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, // this case used to be allowed by the compiler,
// so we do a future-compat lint here for the 2015 edition // so we do a future-compat lint here for the 2015 edition
// (see https://github.com/rust-lang/rust/issues/46906) // (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( self.tcx.node_span_lint(
lint::builtin::TYVAR_BEHIND_RAW_POINTER, lint::builtin::TYVAR_BEHIND_RAW_POINTER,
scope_expr_id, scope_expr_id,
@ -447,7 +446,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
"type annotations needed", "type annotations needed",
|_| {}, |_| {},
); );
}
} else { } else {
// Ended up encountering a type variable when doing autoderef, // Ended up encountering a type variable when doing autoderef,
// but it may not be a type variable after processing obligations // 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)); .unwrap_or_else(|_| span_bug!(span, "instantiating {:?} failed?", ty));
let ty = self.resolve_vars_if_possible(ty.value); let ty = self.resolve_vars_if_possible(ty.value);
let guar = match *ty.kind() { let guar = match *ty.kind() {
ty::Infer(ty::TyVar(_)) => self ty::Infer(ty::TyVar(_)) => {
.err_ctxt() let raw_ptr_call =
.emit_inference_failure_err(self.body_id, span, ty.into(), E0282, true) bad_ty.reached_raw_pointer && !self.tcx.features().arbitrary_self_types;
.emit(), 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, ty::Error(guar) => guar,
_ => bug!("unexpected bad final type in method autoderef"), _ => bug!("unexpected bad final type in method autoderef"),
}; };

View file

@ -153,7 +153,7 @@ fn check_error_codes_docs(
if error_codes.iter().all(|e| e != err_code) { if error_codes.iter().all(|e| e != err_code) {
errors.push(format!( errors.push(format!(
"Found valid file `{}` in error code docs directory without corresponding \ "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() path.display()
)); ));
return; return;

View file

@ -6,6 +6,6 @@
fn main() { fn main() {
let x = 0; let x = 0;
let y = &x as *const _; let y = &x as *const _;
//~^ error: type annotations needed
let _ = y.is_null(); let _ = y.is_null();
//~^ error: cannot call a method on a raw pointer with an unknown pointee type [E0699]
} }

View file

@ -1,9 +1,17 @@
error[E0699]: cannot call a method on a raw pointer with an unknown pointee type error[E0282]: type annotations needed for `*const _`
--> $DIR/edition-raw-pointer-method-2018.rs:9:15 --> $DIR/edition-raw-pointer-method-2018.rs:8:9
| |
LL | let y = &x as *const _;
| ^
LL |
LL | let _ = y.is_null(); 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 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`.

View file

@ -8,10 +8,10 @@ fn main() {
let ptr = &val as *const u32; let ptr = &val as *const u32;
unsafe { unsafe {
let _a: i32 = (ptr as *const _).read(); 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 _; let b = ptr as *const _;
//~^ ERROR type annotations needed
let _b: u8 = b.read(); 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 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; let ptr = &mut val as *mut u32;
unsafe { unsafe {
let _a: i32 = (ptr as *mut _).read(); 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 _; let b = ptr as *mut _;
//~^ ERROR type annotations needed
b.write(10); 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 (ptr as *mut i32).write(1000); // we know the type here
} }
} }

View file

@ -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 --> $DIR/call_method_unknown_pointee.rs:10:41
| |
LL | let _a: i32 = (ptr as *const _).read(); 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 error[E0282]: type annotations needed for `*const _`
--> $DIR/call_method_unknown_pointee.rs:13:24 --> $DIR/call_method_unknown_pointee.rs:12:13
| |
LL | let b = ptr as *const _;
| ^
LL |
LL | let _b: u8 = b.read(); 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 --> $DIR/call_method_unknown_pointee.rs:21:39
| |
LL | let _a: i32 = (ptr as *mut _).read(); 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 error[E0282]: type annotations needed for `*mut _`
--> $DIR/call_method_unknown_pointee.rs:24:11 --> $DIR/call_method_unknown_pointee.rs:23:13
| |
LL | let b = ptr as *mut _;
| ^
LL |
LL | b.write(10); 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 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`.