Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 486699f

Browse files
ehussJayflux
authored andcommittedJan 6, 2018
Update messages for changes in 1.21, 1.22, 1.23 (beta), and 1.24 (nightly) (#228)
* Update message handling for Rust 1.21, 1.22, 1.23, and 1.24 (nightly). - Refactoring of suggested replacements in 1.23 and 1.24 has changed the JSON output, so stop using the `rendered` suggestion which is no longer available. - Fix some duplicate messages being displayed. - Update tests for minor wording changes in some diagnostics. - Update tests to handle debug files being produced in 1.21. * Support multi-span messages added in 1.21. * Fix comment.
1 parent 30445d4 commit 486699f

File tree

15 files changed

+156
-75
lines changed

15 files changed

+156
-75
lines changed
 

‎rust/messages.py

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import os
1010
import re
1111
import webbrowser
12-
from pprint import pprint
1312

1413
from . import util
1514

@@ -27,7 +26,8 @@
2726
# - `is_main`: If True, this is a top-level message. False is used for
2827
# attached detailed diagnostic information, child notes, etc.
2928
# - `path`: Absolute path to the file.
30-
# - `text`: The raw text of the message without any minihtml markup.
29+
# - `text`: The raw text of the message without any minihtml markup. May be
30+
# None if the content is raw markup.
3131
# - `minihtml_text`: The string used for showing phantoms that includes the
3232
# minihtml markup.
3333
# - `output_panel_region`: Optional Sublime Region object that indicates the
@@ -107,7 +107,8 @@ def add_message(window, path, span, level, is_main, text, minihtml_text, msg_cb)
107107
:param level: The Rust message level ('error', 'note', etc.).
108108
:param is_main: If True, this is a top-level message. False is used for
109109
attached detailed diagnostic information, child notes, etc.
110-
:param text: The raw text of the message without any minihtml markup.
110+
:param text: The raw text of the message without any minihtml markup. May
111+
be None if there is no text (such as when adding pure markup).
111112
:param minihtml_text: The message to display with minihtml markup.
112113
:param msg_cb: Callback that will be given the message. May be None.
113114
"""
@@ -147,10 +148,11 @@ def add_message(window, path, span, level, is_main, text, minihtml_text, msg_cb)
147148

148149

149150
def _is_duplicate(to_add, messages):
150-
# Primarily to avoid comparing the `output_panel_region` key.
151+
# Ignore 'minihtml_text' and 'output_panel_region' keys.
152+
keys = ('path', 'span', 'is_main', 'level', 'text')
151153
for message in messages:
152-
for key, value in to_add.items():
153-
if message[key] != value:
154+
for key in keys:
155+
if to_add[key] != message[key]:
154156
break
155157
else:
156158
return True
@@ -681,6 +683,7 @@ def add_rust_messages(window, cwd, info, target_path, msg_cb):
681683
main_message = {}
682684
# List of message dictionaries, belonging to the main message.
683685
additional_messages = []
686+
684687
_collect_rust_messages(window, cwd, info, target_path, msg_cb, {},
685688
main_message, additional_messages)
686689

@@ -712,18 +715,25 @@ def escape_and_link(i_txt):
712715
if i % 2:
713716
return '<a href="%s">%s</a>' % (txt, txt)
714717
else:
715-
return html.escape(txt, quote=False).\
718+
# Call strip() because sometimes rust includes newlines at the
719+
# end of the message, which we don't want.
720+
return html.escape(txt.strip(), quote=False).\
716721
replace('\n', '<br>' + indent)
717-
parts = re.split(LINK_PATTERN, message['text'])
718-
escaped_text = ''.join(map(escape_and_link, enumerate(parts)))
719-
720-
content = content_template.format(
721-
cls=cls,
722-
level=level_text,
723-
msg=escaped_text,
724-
help_link=message.get('help_link', ''),
725-
back_link=message.get('back_link', ''),
726-
)
722+
723+
if message['text']:
724+
parts = re.split(LINK_PATTERN, message['text'])
725+
escaped_text = ''.join(map(escape_and_link, enumerate(parts)))
726+
727+
content = content_template.format(
728+
cls=cls,
729+
level=level_text,
730+
msg=escaped_text,
731+
help_link=message.get('help_link', ''),
732+
back_link=message.get('back_link', ''),
733+
)
734+
else:
735+
content = None
736+
727737
add_message(window, message['span_path'], message['span_region'],
728738
level, message['is_main'], message['text'], content,
729739
msg_cb)
@@ -797,10 +807,14 @@ def _collect_rust_messages(window, cwd, info, target_path,
797807
- 'children': List of attached diagnostic messages (following this
798808
same format) of associated information. AFAIK, these are never
799809
nested.
800-
- 'rendered': Optional string (may be None). Currently only used by
801-
suggested replacements. If a child has a span with
802-
'suggested_replacement' set, then this a suggestion of how the line
803-
should be written.
810+
- 'rendered': Optional string (may be None).
811+
812+
Before 1.23: Used by suggested replacements. If
813+
'suggested_replacement' is set, then this is rendering of how the
814+
line should be written.
815+
816+
After 1.23: This contains the ASCII-art rendering of the message as
817+
displayed by rustc's normal console output.
804818
805819
- `parent_info`: Dictionary used for tracking "children" messages.
806820
Currently only has 'span' key, the span of the parent to display the
@@ -953,14 +967,17 @@ def find_span_r(span, expansion=None):
953967
# to happen when the span is_primary.
954968
#
955969
# This can also happen for macro expansions.
956-
if label:
970+
#
971+
# Label with an empty string can happen for messages that have
972+
# multiple spans (starting in 1.21).
973+
if label != None:
957974
# Display the label for this Span.
958975
add_additional(span, label, info['level'])
959976
if span['suggested_replacement']:
960977
# The "suggested_replacement" contains the code that
961978
# should replace the span. However, it can be easier to
962979
# read if you repeat the entire line (from "rendered").
963-
add_additional(span, info['rendered'], 'help')
980+
add_additional(span, span['suggested_replacement'], 'help')
964981

965982
# Recurse into children (which typically hold notes).
966983
for child in info['children']:

‎tests/error-tests/benches/bench_err.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33

44
#[asdf]
55
// ^^^^^^^ERR The attribute `asdf` is currently unknown
6-
// ^^^^^^^HELP(>=1.21.0-nightly) add #![feature(custom_attribute)]
6+
// ^^^^^^^HELP(nightly) add #![feature(custom_attribute)]
77
fn f() {}

‎tests/error-tests/examples/no_main_mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
/*BEGIN*/fn main() {
2+
// ^^^^^^^^^WARN(no-trans) function is never used
3+
// ^^^^^^^^^NOTE(no-trans) #[warn(dead_code)]
4+
// 1.24 nightly has changed how these no-trans messages are displayed (instead
5+
// of encompassing the entire function).
26
}/*END*/
37
// ~NOTE(check) here is a function named 'main'
4-
// ~NOTE(no-trans) function is never used
5-
// ~NOTE(no-trans) #[warn(dead_code)]

‎tests/error-tests/tests/cast-to-unsized-trait-object-suggestion.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ fn main() {
1212
&1 as Send;
1313
// ^^^^^^^^^^ERR cast to unsized type
1414
// ^^^^HELP try casting to
15-
// ^^^^HELP &1 as &Send
15+
// ^^^^HELP &Send
1616
Box::new(1) as Send;
1717
// ^^^^^^^^^^^^^^^^^^^ERR cast to unsized type
1818
// ^^^^HELP try casting to a `Box` instead
19-
// ^^^^HELP Box::new(1) as Box<Send>;
19+
// ^^^^HELP Box<Send>
2020
}

‎tests/error-tests/tests/macro-backtrace-println.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ macro_rules! myprint {
2222

2323
macro_rules! myprintln {
2424
($fmt:expr) => (myprint!(concat!($fmt, "\n")));
25-
// ^^^^^^^^^^^^^^^^^^^ERR invalid reference
25+
// ^^^^^^^^^^^^^^^^^^^ERR(<1.23.0-beta) invalid reference
26+
// ^^^^^^^^^^^^^^^^^^^ERR(>=1.23.0-beta) 1 positional argument
27+
// ^^^^^^^^^^^^^^^^^^^MSG Note: ↓:31
2628
}
2729

2830
fn main() {

‎tests/error-tests/tests/macro-expansion-outside-1.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ extern crate dcrate;
77
// at the bottom of the "root" source file.
88

99
/*BEGIN*/example_bad_syntax!{}/*END*/
10-
// ~ERR(>=1.20.0-beta) /expected one of .*, found `:`/
11-
// ~ERR(>=1.20.0-beta) this error originates in a macro outside of the current crate
12-
// ~ERR(>=1.20.0-beta) /expected one of .* here/
13-
// ~ERR(>=1.20.0-beta) unexpected token
14-
// ~ERR(>=1.20.0-beta) /expected one of .*, found `:`/
15-
// ~ERR(>=1.20.0-beta) expected one of 7 possible tokens here
10+
// ~ERR(>=1.20.0) /expected one of .*, found `:`/
11+
// ~ERR(>=1.20.0) this error originates in a macro outside of the current crate
12+
// ~ERR(>=1.20.0) /expected one of .* here/
13+
// ~ERR(>=1.20.0,<1.24.0-nightly) unexpected token
14+
// ~ERR(>=1.20.0) /expected one of .*, found `:`/
15+
// ~ERR(>=1.20.0) expected one of
1616
// end-msg: ERR(check,>=1.19.0,<1.20.0-beta) /expected one of .*, found `:`/
1717
// end-msg: ERR(check,>=1.19.0,<1.20.0-beta) Errors occurred in macro <example_bad_syntax macros> from external crate
1818
// end-msg: ERR(check,>=1.19.0,<1.20.0-beta) Macro text: ( ) => { enum E { Kind ( x : u32 ) } }

‎tests/error-tests/tests/macro_expansion_inside_mod1.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ macro_rules! example_bad_syntax {
55
Kind(x: u32)
66
// ^ERR /expected one of .*, found `:`/
77
// ^ERR(>=1.18.0) /expected one of .* here/
8-
// ^MSG(>=1.20.0-beta) Note: macro-expansion-inside-1.rs:6
8+
// ^MSG(>=1.20.0) Note: macro-expansion-inside-1.rs:6
99
// ^ERR /expected one of .*, found `:`/
10-
// ^ERR(>=1.18.0) expected one of 7 possible tokens here
10+
// ^ERR(>=1.18.0) expected one of
1111
}
1212
}
1313
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// 1.21 added new support for messages with multiple spans.
2+
/*BEGIN*/fn foo(x: &mut Vec<&u32>, y: &u32) {
3+
// ^^^^ERR(>=1.21.0)
4+
// ^^^^ERR(>=1.21.0) these two types
5+
x.push(y);
6+
// ^ERR(>=1.21.0) lifetime mismatch
7+
// ^ERR(>=1.21.0) ...but data from
8+
// ^ERR(<1.21.0) lifetime of reference outlives
9+
}/*END*/
10+
// ~NOTE(<1.21.0) ...the reference is valid
11+
// ~NOTE(<1.21.0) ...but the borrowed content

‎tests/error-tests/tests/test_unicode.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ fn main() {
44
let foo = "❤";
55
// ^^^WARN unused variable
66
// ^^^NOTE(>=1.17.0) #[warn(unused_variables)]
7-
// ^^^NOTE(>=1.22.0-nightly) to disable this warning
7+
// ^^^NOTE(>=1.21.0,<1.22.0) to disable this warning
8+
// ^^^NOTE(>=1.22.0) to avoid this warning
89
}

‎tests/multi-targets/src/altmain.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ fn main() {
33
}
44

55
/*BEGIN*/fn warning_example() {
6+
// ^^^^^^^^^^^^^^^^^^^^WARN(>=1.22.0) function is never used
7+
// ^^^^^^^^^^^^^^^^^^^^NOTE(>=1.22.0) #[warn(dead_code)]
68
}/*END*/
7-
// ~WARN function is never used
8-
// ~NOTE(>=1.17.0) #[warn(dead_code)]
9+
// ~WARN(<1.22.0) function is never used
10+
// ~NOTE(<1.22.0,>=1.17.0) #[warn(dead_code)]

‎tests/multi-targets/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ pub fn libf1() {
55
}
66

77
/*BEGIN*/fn unused() {
8+
// ^^^^^^^^^^^WARN(>=1.22.0) function is never used
9+
// ^^^^^^^^^^^NOTE(>=1.22.0) #[warn(dead_code)]
810
}/*END*/
9-
// ~WARN function is never used
10-
// ~NOTE(>=1.17.0) #[warn(dead_code)]
11+
// ~WARN(<1.22.0) function is never used
12+
// ~NOTE(<1.22.0,>=1.17.0) #[warn(dead_code)]
Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
// Example of a module shared among test code.
22

33
/*BEGIN*/pub fn helper() {
4-
4+
// ^^^^^^^^^^^^^^^WARN(>=1.22.0) function is never used
5+
// ^^^^^^^^^^^^^^^NOTE(>=1.22.0) #[warn(dead_code)]
56
}/*END*/
6-
// ~WARN function is never used
7-
// ~NOTE(>=1.17.0) #[warn(dead_code)]
7+
// ~WARN(<1.22.0) function is never used
8+
// ~NOTE(<1.22.0,>=1.17.0) #[warn(dead_code)]
89

910
/*BEGIN*/pub fn unused() {
10-
11+
// ^^^^^^^^^^^^^^^WARN(>=1.22.0) function is never used
12+
// ^^^^^^^^^^^^^^^NOTE(<1.24.0-nightly) #[warn(dead_code)]
1113
}/*END*/
12-
// ~WARN function is never used
13-
// ~NOTE(>=1.17.0) #[warn(dead_code)]
14+
// ~WARN(<1.22.0) function is never used
15+
// ~NOTE(<1.22.0,>=1.17.0) #[warn(dead_code)]

‎tests/test_cargo_build.py

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,21 @@
1212

1313

1414
def exe(s):
15-
return s
16-
17-
if sys.platform == 'win32':
18-
def exe(s):
15+
"""Wrapper around a filename to add .exe extension on windows."""
16+
if sys.platform == 'win32':
1917
return s + '.exe'
18+
else:
19+
return s
20+
21+
22+
def version(filename, check_version):
23+
"""Wrapper around a filename to make it optional based on the rustc version."""
24+
rustc_version = util.get_rustc_version(sublime.active_window(),
25+
plugin_path)
26+
if semver.match(rustc_version, check_version):
27+
return filename
28+
else:
29+
return None
2030

2131

2232
class TestCargoBuild(TestBase):
@@ -42,19 +52,40 @@ def test_build_with_target(self):
4252

4353
def _test_build_with_target(self, view):
4454
targets = [
45-
('--bin bin1', [exe('bin1'), 'libmulti_targets.rlib']),
46-
('--bin bin2', [exe('bin2'), 'libmulti_targets.rlib']),
47-
('--bin otherbin', [exe('otherbin'), 'libmulti_targets.rlib']),
48-
('--bin multi-targets', [exe('multi-targets'),
49-
'libmulti_targets.rlib']),
50-
('--lib', ['libmulti_targets.rlib']),
55+
('--bin bin1', [
56+
exe('bin1'),
57+
version('bin1.d', '>=1.21.0'),
58+
'libmulti_targets.rlib']),
59+
('--bin bin2', [
60+
exe('bin2'),
61+
version('bin2.d', '>=1.21.0'),
62+
'libmulti_targets.rlib']),
63+
('--bin otherbin', [
64+
exe('otherbin'),
65+
version('otherbin.d', '>=1.21.0'),
66+
'libmulti_targets.rlib']),
67+
('--bin multi-targets', [
68+
exe('multi-targets'),
69+
version('multi-targets.d', '>=1.21.0'),
70+
'libmulti_targets.rlib']),
71+
('--lib', [
72+
'libmulti_targets.rlib',
73+
version('libmulti_targets.d', '>=1.21.0')]),
5174
# Not clear to me why it produces ex1-* files.
52-
('--example ex1', [exe('examples/ex1'), exe('examples/ex1-*'),
53-
'libmulti_targets.rlib']),
54-
# I'm actually uncertain why Cargo builds all bins here.
55-
('--test test1', [exe('bin1'), exe('bin2'), exe('multi-targets'),
56-
exe('otherbin'), exe('feats'), exe('penv'),
57-
'libmulti_targets.rlib', 'test1-*']),
75+
('--example ex1', [
76+
exe('examples/ex1'),
77+
exe('examples/ex1-*'),
78+
version('examples/ex1.d', '>=1.21.0'),
79+
'libmulti_targets.rlib']),
80+
('--test test1', [
81+
exe('bin1'),
82+
exe('bin2'),
83+
exe('multi-targets'),
84+
exe('otherbin'),
85+
exe('feats'),
86+
exe('penv'),
87+
'libmulti_targets.rlib',
88+
'test1-*']),
5889
# bench requires nightly
5990
]
6091
window = view.window()
@@ -72,6 +103,8 @@ def _test_build_with_target(self, view):
72103
not x.startswith('.') and
73104
not x.endswith('.pdb')]
74105
files.sort()
106+
# Remove any option (None) entries.
107+
expected_files = list(filter(None, expected_files))
75108
expected_files.sort()
76109
for file, expected_file in zip(files, expected_files):
77110
if not fnmatch.fnmatch(file, expected_file):
@@ -201,8 +234,8 @@ def _test_test(self, view):
201234
window = view.window()
202235
self._run_build_wait('test')
203236
output = self._get_build_output(window)
204-
self.assertRegex(output, '(?m)^test sample_test1 \.\.\. ok$')
205-
self.assertRegex(output, '(?m)^test sample_test2 \.\.\. ok$')
237+
self.assertRegex(output, r'(?m)^test sample_test1 \.\.\. ok$')
238+
self.assertRegex(output, r'(?m)^test sample_test2 \.\.\. ok$')
206239

207240
def test_test_with_args(self):
208241
"""Test "Test (with args) variant."""
@@ -214,14 +247,14 @@ def _test_test_with_args(self, view):
214247
self._run_build_wait('test',
215248
settings={'extra_run_args': 'sample_test2'})
216249
output = self._get_build_output(window)
217-
self.assertNotRegex(output, '(?m)^test sample_test1 \.\.\. ')
218-
self.assertRegex(output, '(?m)^test sample_test2 \.\.\. ok')
250+
self.assertNotRegex(output, r'(?m)^test sample_test1 \.\.\. ')
251+
self.assertRegex(output, r'(?m)^test sample_test2 \.\.\. ok')
219252

220253
def test_check(self):
221254
"""Test "Check" variant."""
222255
rustc_version = util.get_rustc_version(sublime.active_window(),
223256
plugin_path)
224-
if plugin.rust.semver.match(rustc_version, '<1.16.0'):
257+
if semver.match(rustc_version, '<1.16.0'):
225258
print('Skipping "Check" test, need rustc >= 1.16')
226259
return
227260
self._with_open_file('tests/error-tests/examples/err_ex.rs',
@@ -246,8 +279,8 @@ def _test_bench(self, view):
246279
'toolchain': 'nightly'})
247280
self._run_build_wait('bench')
248281
output = self._get_build_output(window)
249-
self.assertRegex(output, '(?m)^test example1 \.\.\. bench:')
250-
self.assertRegex(output, '(?m)^test example2 \.\.\. bench:')
282+
self.assertRegex(output, r'(?m)^test example1 \.\.\. bench:')
283+
self.assertRegex(output, r'(?m)^test example2 \.\.\. bench:')
251284

252285
def test_clean(self):
253286
"""Test "Clean" variant."""

‎tests/test_syntax_check.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ def test_messages(self):
104104
('error-tests/tests/macro-expansion-inside-2.rs', 'error-tests/tests/macro_expansion_inside_mod2.rs'),
105105
('error-tests/tests/error_across_mod.rs', 'error-tests/tests/error_across_mod_f.rs'),
106106
'error-tests/tests/derive-error.rs',
107+
'error-tests/tests/test_new_lifetime_message.rs',
107108
# Workspace tests.
108109
'workspace/workspace1/src/lib.rs',
109110
'workspace/workspace1/src/anothermod/mod.rs',
@@ -223,6 +224,9 @@ def restriction_check(restrictions):
223224
# This message only shows up in no-trans.
224225
if method != 'no-trans':
225226
return False
227+
elif check == 'nightly':
228+
# This message only shows on nightly.
229+
return 'nightly' in self.rustc_version
226230
else:
227231
if not semver.match(self.rustc_version, check):
228232
return False
@@ -232,6 +236,9 @@ def restriction_check(restrictions):
232236

233237
# Check phantoms.
234238
for emsg_info in expected_messages:
239+
if not emsg_info['message']:
240+
# This is a region-only highlight.
241+
continue
235242
if restriction_check(emsg_info['restrictions']):
236243
for i, (region, content) in enumerate(phantoms):
237244
content = unescape(content)
@@ -254,8 +261,8 @@ def restriction_check(restrictions):
254261
view.file_name(), method, phantoms))
255262
del phantoms[i]
256263
if len(phantoms):
257-
raise AssertionError('Got extra phantoms for %r (method=%s): %r' % (
258-
view.file_name(), method, phantoms))
264+
raise AssertionError('Got extra phantoms for %r (method=%s, version=%s): %r' % (
265+
view.file_name(), method, self.rustc_version, phantoms))
259266

260267
# Check regions.
261268
found_regions = set()
@@ -328,7 +335,7 @@ def _collect_expected_regions(self, view):
328335
# Single-line spans.
329336
last_line = None
330337
last_line_offset = 1
331-
pattern = r'//( *)(\^+)(WARN|ERR|HELP|NOTE|MSG)(\([^)]+\))? (.+)'
338+
pattern = r'//( *)(\^+)(WARN|ERR|HELP|NOTE|MSG)(\([^)]+\))?(?: (.+))?'
332339
regions = view.find_all(pattern)
333340
for region in regions:
334341
text = view.substr(region)

‎tests/workspace/workspace2/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,7 @@ pub fn f() {
99
// ^ERR mismatched types
1010
// ^NOTE expected type `&Trait`
1111
// ^NOTE(<1.16.0) found type
12-
// ^HELP(>=1.18.0) try with `&x`
12+
// ^HELP(>=1.18.0,<1.24.0-nightly) try with `&x`
13+
// ^HELP(>=1.24.0-nightly) consider borrowing here
14+
// ^HELP(>=1.24.0-nightly) &x
1315
}

0 commit comments

Comments
 (0)
Please sign in to comment.