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.
Erroneous code example:
```compile_fail,edition2018,E0699
```compile_fail,edition2018
# #![deny(warnings)]
# fn main() {
let foo = &1;

View File

@ -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,

View File

@ -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 ->

View File

@ -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 {

View File

@ -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,13 +432,13 @@ 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,
@ -447,7 +446,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
"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"),
};

View File

@ -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;

View File

@ -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]
}

View File

@ -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`.

View File

@ -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
}
}

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
|
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`.