Skip to content

Commit 643dee7

Browse files
authored
Rollup merge of rust-lang#122768 - oli-obk:why_is_E0699_so_bad, r=WaffleLapkin
Use the more informative generic type inference failure error on method calls on raw pointers
2 parents 59c808f + 7f9a4af commit 643dee7

File tree

10 files changed

+109
-61
lines changed

10 files changed

+109
-61
lines changed

compiler/rustc_error_codes/src/error_codes/E0699.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
#### Note: this error code is no longer emitted by the compiler.
2+
13
A method was called on a raw pointer whose inner type wasn't completely known.
24

35
Erroneous code example:
46

5-
```compile_fail,edition2018,E0699
7+
```compile_fail,edition2018
68
# #![deny(warnings)]
79
# fn main() {
810
let foo = &1;

compiler/rustc_error_codes/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ E0695: 0695,
441441
E0696: 0696,
442442
E0697: 0697,
443443
E0698: 0698,
444-
E0699: 0699,
444+
E0699: 0699, // REMOVED: merged into generic inference var error
445445
E0700: 0700,
446446
E0701: 0701,
447447
E0703: 0703,

compiler/rustc_hir_typeck/messages.ftl

-3
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,6 @@ hir_typeck_lossy_provenance_ptr2int =
9393
.suggestion = use `.addr()` to obtain the address of a pointer
9494
.help = if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
9595
96-
hir_typeck_method_call_on_unknown_raw_pointee =
97-
cannot call a method on a raw pointer with an unknown pointee type
98-
9996
hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}`
10097
10198
hir_typeck_no_associated_item = no {$item_kind} named `{$item_name}` found for {$ty_prefix} `{$ty_str}`{$trait_missing_method ->

compiler/rustc_hir_typeck/src/errors.rs

-7
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,6 @@ pub struct StructExprNonExhaustive {
7676
pub what: &'static str,
7777
}
7878

79-
#[derive(Diagnostic)]
80-
#[diag(hir_typeck_method_call_on_unknown_raw_pointee, code = E0699)]
81-
pub struct MethodCallOnUnknownRawPointee {
82-
#[primary_span]
83-
pub span: Span,
84-
}
85-
8679
#[derive(Diagnostic)]
8780
#[diag(hir_typeck_functional_record_update_on_non_struct, code = E0436)]
8881
pub struct FunctionalRecordUpdateOnNonStruct {

compiler/rustc_hir_typeck/src/method/probe.rs

+26-17
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use super::CandidateSource;
33
use super::MethodError;
44
use super::NoMatchData;
55

6-
use crate::errors::MethodCallOnUnknownRawPointee;
76
use crate::FnCtxt;
87
use rustc_data_structures::fx::FxHashSet;
98
use rustc_errors::Applicability;
@@ -430,21 +429,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
430429
if is_suggestion.0 {
431430
// Ambiguity was encountered during a suggestion. Just keep going.
432431
debug!("ProbeContext: encountered ambiguity in suggestion");
433-
} else if bad_ty.reached_raw_pointer && !self.tcx.features().arbitrary_self_types {
432+
} else if bad_ty.reached_raw_pointer
433+
&& !self.tcx.features().arbitrary_self_types
434+
&& !self.tcx.sess.at_least_rust_2018()
435+
{
434436
// this case used to be allowed by the compiler,
435437
// so we do a future-compat lint here for the 2015 edition
436438
// (see https://github.com/rust-lang/rust/issues/46906)
437-
if self.tcx.sess.at_least_rust_2018() {
438-
self.dcx().emit_err(MethodCallOnUnknownRawPointee { span });
439-
} else {
440-
self.tcx.node_span_lint(
441-
lint::builtin::TYVAR_BEHIND_RAW_POINTER,
442-
scope_expr_id,
443-
span,
444-
"type annotations needed",
445-
|_| {},
446-
);
447-
}
439+
self.tcx.node_span_lint(
440+
lint::builtin::TYVAR_BEHIND_RAW_POINTER,
441+
scope_expr_id,
442+
span,
443+
"type annotations needed",
444+
|_| {},
445+
);
448446
} else {
449447
// Ended up encountering a type variable when doing autoderef,
450448
// but it may not be a type variable after processing obligations
@@ -455,10 +453,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
455453
.unwrap_or_else(|_| span_bug!(span, "instantiating {:?} failed?", ty));
456454
let ty = self.resolve_vars_if_possible(ty.value);
457455
let guar = match *ty.kind() {
458-
ty::Infer(ty::TyVar(_)) => self
459-
.err_ctxt()
460-
.emit_inference_failure_err(self.body_id, span, ty.into(), E0282, true)
461-
.emit(),
456+
ty::Infer(ty::TyVar(_)) => {
457+
let raw_ptr_call =
458+
bad_ty.reached_raw_pointer && !self.tcx.features().arbitrary_self_types;
459+
let mut err = self.err_ctxt().emit_inference_failure_err(
460+
self.body_id,
461+
span,
462+
ty.into(),
463+
E0282,
464+
!raw_ptr_call,
465+
);
466+
if raw_ptr_call {
467+
err.span_label(span, "cannot call a method on a raw pointer with an unknown pointee type");
468+
}
469+
err.emit()
470+
}
462471
ty::Error(guar) => guar,
463472
_ => bug!("unexpected bad final type in method autoderef"),
464473
};

src/tools/tidy/src/error_codes.rs

+31-14
Original file line numberDiff line numberDiff line change
@@ -71,50 +71,67 @@ fn extract_error_codes(root_path: &Path, errors: &mut Vec<String>) -> Vec<String
7171
let path = root_path.join(Path::new(ERROR_CODES_PATH));
7272
let file =
7373
fs::read_to_string(&path).unwrap_or_else(|e| panic!("failed to read `{path:?}`: {e}"));
74+
let path = path.display();
7475

7576
let mut error_codes = Vec::new();
7677

77-
for line in file.lines() {
78+
for (line_index, line) in file.lines().enumerate() {
79+
let line_index = line_index + 1;
7880
let line = line.trim();
7981

8082
if line.starts_with('E') {
8183
let split_line = line.split_once(':');
8284

8385
// Extract the error code from the line. Emit a fatal error if it is not in the correct
8486
// format.
85-
let err_code = if let Some(err_code) = split_line {
86-
err_code.0.to_owned()
87-
} else {
87+
let Some(split_line) = split_line else {
8888
errors.push(format!(
89-
"Expected a line with the format `Eabcd: abcd, \
89+
"{path}:{line_index}: Expected a line with the format `Eabcd: abcd, \
9090
but got \"{}\" without a `:` delimiter",
9191
line,
9292
));
9393
continue;
9494
};
9595

96+
let err_code = split_line.0.to_owned();
97+
9698
// If this is a duplicate of another error code, emit a fatal error.
9799
if error_codes.contains(&err_code) {
98-
errors.push(format!("Found duplicate error code: `{}`", err_code));
100+
errors.push(format!(
101+
"{path}:{line_index}: Found duplicate error code: `{}`",
102+
err_code
103+
));
99104
continue;
100105
}
101106

102107
let mut chars = err_code.chars();
103-
chars.next();
108+
assert_eq!(chars.next(), Some('E'));
104109
let error_num_as_str = chars.as_str();
105110

106111
// Ensure that the line references the correct markdown file.
107-
let expected_filename = format!(" {},", error_num_as_str);
108-
if expected_filename != split_line.unwrap().1 {
112+
let rest = split_line.1.split_once(',');
113+
let Some(rest) = rest else {
114+
errors.push(format!(
115+
"{path}:{line_index}: Expected a line with the format `Eabcd: abcd, \
116+
but got \"{}\" without a `,` delimiter",
117+
line,
118+
));
119+
continue;
120+
};
121+
if error_num_as_str != rest.0.trim() {
109122
errors.push(format!(
110-
"`{}:` should be followed by `{}` but instead found `{}` in \
123+
"{path}:{line_index}: `{}:` should be followed by `{},` but instead found `{}` in \
111124
`compiler/rustc_error_codes/src/lib.rs`",
112125
err_code,
113-
expected_filename,
114-
split_line.unwrap().1,
126+
error_num_as_str,
127+
split_line.1,
115128
));
116129
continue;
117130
}
131+
if !rest.1.trim().is_empty() && !rest.1.trim().starts_with("//") {
132+
errors.push(format!("{path}:{line_index}: should only have one error per line"));
133+
continue;
134+
}
118135

119136
error_codes.push(err_code);
120137
}
@@ -146,14 +163,14 @@ fn check_error_codes_docs(
146163
return;
147164
}
148165

149-
// Make sure that the file is referenced in `error_codes.rs`
166+
// Make sure that the file is referenced in `rustc_error_codes/src/lib.rs`
150167
let filename = path.file_name().unwrap().to_str().unwrap().split_once('.');
151168
let err_code = filename.unwrap().0; // `unwrap` is ok because we know the filename is in the correct format.
152169

153170
if error_codes.iter().all(|e| e != err_code) {
154171
errors.push(format!(
155172
"Found valid file `{}` in error code docs directory without corresponding \
156-
entry in `error_code.rs`",
173+
entry in `rustc_error_codes/src/lib.rs`",
157174
path.display()
158175
));
159176
return;

tests/ui/editions/edition-raw-pointer-method-2018.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66
fn main() {
77
let x = 0;
88
let y = &x as *const _;
9+
//~^ error: type annotations needed
910
let _ = y.is_null();
10-
//~^ error: cannot call a method on a raw pointer with an unknown pointee type [E0699]
1111
}
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
1-
error[E0699]: cannot call a method on a raw pointer with an unknown pointee type
2-
--> $DIR/edition-raw-pointer-method-2018.rs:9:15
1+
error[E0282]: type annotations needed for `*const _`
2+
--> $DIR/edition-raw-pointer-method-2018.rs:8:9
33
|
4+
LL | let y = &x as *const _;
5+
| ^
6+
LL |
47
LL | let _ = y.is_null();
5-
| ^^^^^^^
8+
| ------- cannot call a method on a raw pointer with an unknown pointee type
9+
|
10+
help: consider giving `y` an explicit type, where the placeholders `_` are specified
11+
|
12+
LL | let y: *const _ = &x as *const _;
13+
| ++++++++++
614

715
error: aborting due to 1 previous error
816

9-
For more information about this error, try `rustc --explain E0699`.
17+
For more information about this error, try `rustc --explain E0282`.

tests/ui/methods/call_method_unknown_pointee.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,21 @@ fn main() {
88
let ptr = &val as *const u32;
99
unsafe {
1010
let _a: i32 = (ptr as *const _).read();
11-
//~^ ERROR cannot call a method on a raw pointer with an unknown pointee type [E0699]
11+
//~^ ERROR type annotations needed
1212
let b = ptr as *const _;
13+
//~^ ERROR type annotations needed
1314
let _b: u8 = b.read();
14-
//~^ ERROR cannot call a method on a raw pointer with an unknown pointee type [E0699]
1515
let _c = (ptr as *const u8).read(); // we know the type here
1616
}
1717

1818
let mut val = 2_u32;
1919
let ptr = &mut val as *mut u32;
2020
unsafe {
2121
let _a: i32 = (ptr as *mut _).read();
22-
//~^ ERROR cannot call a method on a raw pointer with an unknown pointee type [E0699]
22+
//~^ ERROR type annotations needed
2323
let b = ptr as *mut _;
24+
//~^ ERROR type annotations needed
2425
b.write(10);
25-
//~^ ERROR cannot call a method on a raw pointer with an unknown pointee type [E0699]
2626
(ptr as *mut i32).write(1000); // we know the type here
2727
}
2828
}
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,49 @@
1-
error[E0699]: cannot call a method on a raw pointer with an unknown pointee type
1+
error[E0282]: type annotations needed
22
--> $DIR/call_method_unknown_pointee.rs:10:41
33
|
44
LL | let _a: i32 = (ptr as *const _).read();
55
| ^^^^
6+
| |
7+
| cannot infer type
8+
| cannot call a method on a raw pointer with an unknown pointee type
69

7-
error[E0699]: cannot call a method on a raw pointer with an unknown pointee type
8-
--> $DIR/call_method_unknown_pointee.rs:13:24
10+
error[E0282]: type annotations needed for `*const _`
11+
--> $DIR/call_method_unknown_pointee.rs:12:13
912
|
13+
LL | let b = ptr as *const _;
14+
| ^
15+
LL |
1016
LL | let _b: u8 = b.read();
11-
| ^^^^
17+
| ---- cannot call a method on a raw pointer with an unknown pointee type
18+
|
19+
help: consider giving `b` an explicit type, where the placeholders `_` are specified
20+
|
21+
LL | let b: *const _ = ptr as *const _;
22+
| ++++++++++
1223

13-
error[E0699]: cannot call a method on a raw pointer with an unknown pointee type
24+
error[E0282]: type annotations needed
1425
--> $DIR/call_method_unknown_pointee.rs:21:39
1526
|
1627
LL | let _a: i32 = (ptr as *mut _).read();
1728
| ^^^^
29+
| |
30+
| cannot infer type
31+
| cannot call a method on a raw pointer with an unknown pointee type
1832

19-
error[E0699]: cannot call a method on a raw pointer with an unknown pointee type
20-
--> $DIR/call_method_unknown_pointee.rs:24:11
33+
error[E0282]: type annotations needed for `*mut _`
34+
--> $DIR/call_method_unknown_pointee.rs:23:13
2135
|
36+
LL | let b = ptr as *mut _;
37+
| ^
38+
LL |
2239
LL | b.write(10);
23-
| ^^^^^
40+
| ----- cannot call a method on a raw pointer with an unknown pointee type
41+
|
42+
help: consider giving `b` an explicit type, where the placeholders `_` are specified
43+
|
44+
LL | let b: *mut _ = ptr as *mut _;
45+
| ++++++++
2446

2547
error: aborting due to 4 previous errors
2648

27-
For more information about this error, try `rustc --explain E0699`.
49+
For more information about this error, try `rustc --explain E0282`.

0 commit comments

Comments
 (0)