Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: One error occurs from the missing semicolon. Instead, this happened: An additional unexpected error occurs when when I obviously do not want to invoke a closure. Also note that the semicolon error is after the supposed closure invocation, when I would expect it to be after the . Occurs on latest stable and nightly. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
label A-diagnostics D-newcomer-roadblock D-terse
The compiler would consider the case the same as I think it's hard to determine if the user wants invoke a closure or not by writing the "()" to the next line. Rust allows syntax like this(actually a lot of languages allow this type of syntax)
We should definitely be able to look at the spans of the callee and the argument list, determine if they are on separate lines (via the ) & don't originate from a macro expansion and if so at least add a note to the diagnostic suggesting to add a semicolon. Of course, there will always be false positives.
The case should be handled in both the parser and the call error. In the parser we can't be certain that the call expression is incorrect, except for maybe literals, but if you had we are back to ambiguity, so that should be handled in E0618 and suggest a semicolon there as well. You could also have which would parse successfully but fail only in the call.
claim
When adding a nice parser error you have to make sure that you never emit a parser error for valid rust syntax. So for the example Esteban described above handling it in the parser is fine since the statement is missing a semicolon, making it invalid syntax. But you have to make sure that something like doesn't give a parser error but only errors during type checking. This is because of macros, which may transform code that is valid syntax but invalid semantically into something entirely valid.
At the very least, these cases should be handled
I guess I should also be clear that the suggestion currently provided by rustc could never be correct: function (and closure) names can't start with integer
The diagnostics currently emitted by the compiler are absolutely correct: An integer cannot be called and the let-statement must be followed by a semicolon. Indeed, identifiers (“function (and closure) names”) cannot start with a digit. However, this is not relevant here: Syntactically speaking, the callee (the thing being called) in a call expression can be an arbitrary expression. Consider (this might even be well-typed depending on the definition of and its s). So is syntactically well-formed but semantically it is not (according to the trait solver) as there is no primitive integer type (e.g. ) that implements or friends. Technically speaking, could very well add a implementation for that makes semantically well-formed, too. This is the reason why you see the error messages you posted. Edit: I hope it's already clear from context but I'd like to emphasize that I am not saying that the diagnostics as emitted today should stay the way they are (we should definitely suggest to add a as mentioned above), I am just trying to clarify the semantics and disputing the quoted statement.
Ahh right, I forget briefly that function calls could be on values, I was thinking of the integer literal being seen as an identifier only (and of course integer identifiers don't exist). Silly me!
the point you're making is why we can proactively catch the "literal followed by ()" case in the parser, and avoid the second, unnecessary "invalid call" error. But for the general case, where the parser doesn't have enough context (a, b and c in my examples), we would have to emit two errors, or delay the parse error until resolve.
According to the discussion, the current diagnostics emitted by the compiler are correct. Can we close the issue now?
the compiler errors are correct, but they are misleading, so we'll put some effort to improve the output to make it clear what is happening to everyone, regardless of expertise level, at a glance.
ok. So we still let the compiler emit 2 diagnostics, one is from the parser, another one is error[E0618]. How about the output being like this? Which won't be misleading the user to program code like ;
Hmm, I haven't really been keeping up to date with this so this might not be ideal/possible but: This parser error is, IMO, wrong. It should say "expected , found ". We shouldn't leave out the here.
Disclaimer: I might be biased by the phrasing of existing diagnostics. The error message expected , found looks like it's describing a syntax error, even though it's not (it's a type error) as I've previously mentioned. The wording expected / found [token] is exclusively used by the parser as far as I know. If I see that message I assume that annotating the container with or adding the CLI flag would not make the error go away. Because of this, I caution against using such phrasing. I expect it to look similar to:
Sorry, I should have been more clear: doesn't really make sense to me, it leaves out the which is obviously important in this context. EDIT: AFAIK, it still remains in the parser, and it definitely is still a syntax error. As for your suggested diagnostic, the proposed suggestion doesn't seem quite right in terms of wording. Adding a semicolon does not fix the error; it does not provide a function, but rather makes the error go away by removing the expectation of a function in the first place. This has to be explained to the user, otherwise it just looks even more confusing.

self.typeck_results.borrow().qpath_res(qpath, callee_expr.hir_id) } hir::ExprKind::Call(ref inner_callee, _) => { <del> // If the call spans more than one line and the callee kind is // itself another `ExprCall`, that's a clue that we might just be // missing a semicolon (Issue #51055) let call_is_multiline = self.tcx.sess.source_map().is_multiline(call_expr.span); if call_is_multiline { err.span_suggestion( callee_expr.span.shrink_to_hi(), "consider using a semicolon here", ";", Applicability::MaybeIncorrect, ); } </del> if let hir::ExprKind::Path(ref inner_qpath) = inner_callee.kind { inner_callee_path = Some(inner_qpath); self.typeck_results.borrow().qpath_res(inner_qpath, inner_callee.hir_id)


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: One error occurs from the missing semicolon. Instead, this happened: An additional unexpected error occurs when when I obviously do not want to invoke a closure. Also note that the semicolon error is after the supposed closure invocation, when I would expect it to be after the . Occurs on latest stable and nightly. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
label A-diagnostics D-newcomer-roadblock D-terse
The compiler would consider the case the same as I think it's hard to determine if the user wants invoke a closure or not by writing the "()" to the next line. Rust allows syntax like this(actually a lot of languages allow this type of syntax)
We should definitely be able to look at the spans of the callee and the argument list, determine if they are on separate lines (via the ) & don't originate from a macro expansion and if so at least add a note to the diagnostic suggesting to add a semicolon. Of course, there will always be false positives.
The case should be handled in both the parser and the call error. In the parser we can't be certain that the call expression is incorrect, except for maybe literals, but if you had we are back to ambiguity, so that should be handled in E0618 and suggest a semicolon there as well. You could also have which would parse successfully but fail only in the call.
claim
When adding a nice parser error you have to make sure that you never emit a parser error for valid rust syntax. So for the example Esteban described above handling it in the parser is fine since the statement is missing a semicolon, making it invalid syntax. But you have to make sure that something like doesn't give a parser error but only errors during type checking. This is because of macros, which may transform code that is valid syntax but invalid semantically into something entirely valid.
At the very least, these cases should be handled
I guess I should also be clear that the suggestion currently provided by rustc could never be correct: function (and closure) names can't start with integer
The diagnostics currently emitted by the compiler are absolutely correct: An integer cannot be called and the let-statement must be followed by a semicolon. Indeed, identifiers (“function (and closure) names”) cannot start with a digit. However, this is not relevant here: Syntactically speaking, the callee (the thing being called) in a call expression can be an arbitrary expression. Consider (this might even be well-typed depending on the definition of and its s). So is syntactically well-formed but semantically it is not (according to the trait solver) as there is no primitive integer type (e.g. ) that implements or friends. Technically speaking, could very well add a implementation for that makes semantically well-formed, too. This is the reason why you see the error messages you posted. Edit: I hope it's already clear from context but I'd like to emphasize that I am not saying that the diagnostics as emitted today should stay the way they are (we should definitely suggest to add a as mentioned above), I am just trying to clarify the semantics and disputing the quoted statement.
Ahh right, I forget briefly that function calls could be on values, I was thinking of the integer literal being seen as an identifier only (and of course integer identifiers don't exist). Silly me!
the point you're making is why we can proactively catch the "literal followed by ()" case in the parser, and avoid the second, unnecessary "invalid call" error. But for the general case, where the parser doesn't have enough context (a, b and c in my examples), we would have to emit two errors, or delay the parse error until resolve.
According to the discussion, the current diagnostics emitted by the compiler are correct. Can we close the issue now?
the compiler errors are correct, but they are misleading, so we'll put some effort to improve the output to make it clear what is happening to everyone, regardless of expertise level, at a glance.
ok. So we still let the compiler emit 2 diagnostics, one is from the parser, another one is error[E0618]. How about the output being like this? Which won't be misleading the user to program code like ;
Hmm, I haven't really been keeping up to date with this so this might not be ideal/possible but: This parser error is, IMO, wrong. It should say "expected , found ". We shouldn't leave out the here.
Disclaimer: I might be biased by the phrasing of existing diagnostics. The error message expected , found looks like it's describing a syntax error, even though it's not (it's a type error) as I've previously mentioned. The wording expected / found [token] is exclusively used by the parser as far as I know. If I see that message I assume that annotating the container with or adding the CLI flag would not make the error go away. Because of this, I caution against using such phrasing. I expect it to look similar to:
Sorry, I should have been more clear: doesn't really make sense to me, it leaves out the which is obviously important in this context. EDIT: AFAIK, it still remains in the parser, and it definitely is still a syntax error. As for your suggested diagnostic, the proposed suggestion doesn't seem quite right in terms of wording. Adding a semicolon does not fix the error; it does not provide a function, but rather makes the error go away by removing the expectation of a function in the first place. This has to be explained to the user, otherwise it just looks even more confusing.

}; if !self.maybe_suggest_bad_array_definition(&mut err, call_expr, callee_expr) { <ins> // If the call spans more than one line and the callee kind is // itself another `ExprCall`, that's a clue that we might just be // missing a semicolon (#51055, #106515). let call_is_multiline = self .tcx .sess .source_map() .is_multiline(call_expr.span.with_lo(callee_expr.span.hi())) && call_expr.span.ctxt() == callee_expr.span.ctxt(); if call_is_multiline { err.span_suggestion( callee_expr.span.shrink_to_hi(), "consider using a semicolon here to finish the statement", ";", Applicability::MaybeIncorrect, ); } </ins> if let Some((maybe_def, output_ty, _)) = self.extract_callable_info(callee_ty) && !self.type_is_sized_modulo_regions(self.param_env, output_ty) {


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: One error occurs from the missing semicolon. Instead, this happened: An additional unexpected error occurs when when I obviously do not want to invoke a closure. Also note that the semicolon error is after the supposed closure invocation, when I would expect it to be after the . Occurs on latest stable and nightly. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
label A-diagnostics D-newcomer-roadblock D-terse
The compiler would consider the case the same as I think it's hard to determine if the user wants invoke a closure or not by writing the "()" to the next line. Rust allows syntax like this(actually a lot of languages allow this type of syntax)
We should definitely be able to look at the spans of the callee and the argument list, determine if they are on separate lines (via the ) & don't originate from a macro expansion and if so at least add a note to the diagnostic suggesting to add a semicolon. Of course, there will always be false positives.
The case should be handled in both the parser and the call error. In the parser we can't be certain that the call expression is incorrect, except for maybe literals, but if you had we are back to ambiguity, so that should be handled in E0618 and suggest a semicolon there as well. You could also have which would parse successfully but fail only in the call.
claim
When adding a nice parser error you have to make sure that you never emit a parser error for valid rust syntax. So for the example Esteban described above handling it in the parser is fine since the statement is missing a semicolon, making it invalid syntax. But you have to make sure that something like doesn't give a parser error but only errors during type checking. This is because of macros, which may transform code that is valid syntax but invalid semantically into something entirely valid.
At the very least, these cases should be handled
I guess I should also be clear that the suggestion currently provided by rustc could never be correct: function (and closure) names can't start with integer
The diagnostics currently emitted by the compiler are absolutely correct: An integer cannot be called and the let-statement must be followed by a semicolon. Indeed, identifiers (“function (and closure) names”) cannot start with a digit. However, this is not relevant here: Syntactically speaking, the callee (the thing being called) in a call expression can be an arbitrary expression. Consider (this might even be well-typed depending on the definition of and its s). So is syntactically well-formed but semantically it is not (according to the trait solver) as there is no primitive integer type (e.g. ) that implements or friends. Technically speaking, could very well add a implementation for that makes semantically well-formed, too. This is the reason why you see the error messages you posted. Edit: I hope it's already clear from context but I'd like to emphasize that I am not saying that the diagnostics as emitted today should stay the way they are (we should definitely suggest to add a as mentioned above), I am just trying to clarify the semantics and disputing the quoted statement.
Ahh right, I forget briefly that function calls could be on values, I was thinking of the integer literal being seen as an identifier only (and of course integer identifiers don't exist). Silly me!
the point you're making is why we can proactively catch the "literal followed by ()" case in the parser, and avoid the second, unnecessary "invalid call" error. But for the general case, where the parser doesn't have enough context (a, b and c in my examples), we would have to emit two errors, or delay the parse error until resolve.
According to the discussion, the current diagnostics emitted by the compiler are correct. Can we close the issue now?
the compiler errors are correct, but they are misleading, so we'll put some effort to improve the output to make it clear what is happening to everyone, regardless of expertise level, at a glance.
ok. So we still let the compiler emit 2 diagnostics, one is from the parser, another one is error[E0618]. How about the output being like this? Which won't be misleading the user to program code like ;
Hmm, I haven't really been keeping up to date with this so this might not be ideal/possible but: This parser error is, IMO, wrong. It should say "expected , found ". We shouldn't leave out the here.
Disclaimer: I might be biased by the phrasing of existing diagnostics. The error message expected , found looks like it's describing a syntax error, even though it's not (it's a type error) as I've previously mentioned. The wording expected / found [token] is exclusively used by the parser as far as I know. If I see that message I assume that annotating the container with or adding the CLI flag would not make the error go away. Because of this, I caution against using such phrasing. I expect it to look similar to:
Sorry, I should have been more clear: doesn't really make sense to me, it leaves out the which is obviously important in this context. EDIT: AFAIK, it still remains in the parser, and it definitely is still a syntax error. As for your suggested diagnostic, the proposed suggestion doesn't seem quite right in terms of wording. Adding a semicolon does not fix the error; it does not provide a function, but rather makes the error go away by removing the expectation of a function in the first place. This has to be explained to the user, otherwise it just looks even more confusing.

|   ----------------------- `vindictive` defined here returns `bool` ... LL |       vindictive() <del> |       -^^^^^^^^^^^- help: consider using a semicolon here: `;` </del> <ins> |       -^^^^^^^^^^^- help: consider using a semicolon here to finish the statement: `;` </ins> |  _____| | | LL | |     (1, 2)


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: One error occurs from the missing semicolon. Instead, this happened: An additional unexpected error occurs when when I obviously do not want to invoke a closure. Also note that the semicolon error is after the supposed closure invocation, when I would expect it to be after the . Occurs on latest stable and nightly. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
label A-diagnostics D-newcomer-roadblock D-terse
The compiler would consider the case the same as I think it's hard to determine if the user wants invoke a closure or not by writing the "()" to the next line. Rust allows syntax like this(actually a lot of languages allow this type of syntax)
We should definitely be able to look at the spans of the callee and the argument list, determine if they are on separate lines (via the ) & don't originate from a macro expansion and if so at least add a note to the diagnostic suggesting to add a semicolon. Of course, there will always be false positives.
The case should be handled in both the parser and the call error. In the parser we can't be certain that the call expression is incorrect, except for maybe literals, but if you had we are back to ambiguity, so that should be handled in E0618 and suggest a semicolon there as well. You could also have which would parse successfully but fail only in the call.
claim
When adding a nice parser error you have to make sure that you never emit a parser error for valid rust syntax. So for the example Esteban described above handling it in the parser is fine since the statement is missing a semicolon, making it invalid syntax. But you have to make sure that something like doesn't give a parser error but only errors during type checking. This is because of macros, which may transform code that is valid syntax but invalid semantically into something entirely valid.
At the very least, these cases should be handled
I guess I should also be clear that the suggestion currently provided by rustc could never be correct: function (and closure) names can't start with integer
The diagnostics currently emitted by the compiler are absolutely correct: An integer cannot be called and the let-statement must be followed by a semicolon. Indeed, identifiers (“function (and closure) names”) cannot start with a digit. However, this is not relevant here: Syntactically speaking, the callee (the thing being called) in a call expression can be an arbitrary expression. Consider (this might even be well-typed depending on the definition of and its s). So is syntactically well-formed but semantically it is not (according to the trait solver) as there is no primitive integer type (e.g. ) that implements or friends. Technically speaking, could very well add a implementation for that makes semantically well-formed, too. This is the reason why you see the error messages you posted. Edit: I hope it's already clear from context but I'd like to emphasize that I am not saying that the diagnostics as emitted today should stay the way they are (we should definitely suggest to add a as mentioned above), I am just trying to clarify the semantics and disputing the quoted statement.
Ahh right, I forget briefly that function calls could be on values, I was thinking of the integer literal being seen as an identifier only (and of course integer identifiers don't exist). Silly me!
the point you're making is why we can proactively catch the "literal followed by ()" case in the parser, and avoid the second, unnecessary "invalid call" error. But for the general case, where the parser doesn't have enough context (a, b and c in my examples), we would have to emit two errors, or delay the parse error until resolve.
According to the discussion, the current diagnostics emitted by the compiler are correct. Can we close the issue now?
the compiler errors are correct, but they are misleading, so we'll put some effort to improve the output to make it clear what is happening to everyone, regardless of expertise level, at a glance.
ok. So we still let the compiler emit 2 diagnostics, one is from the parser, another one is error[E0618]. How about the output being like this? Which won't be misleading the user to program code like ;
Hmm, I haven't really been keeping up to date with this so this might not be ideal/possible but: This parser error is, IMO, wrong. It should say "expected , found ". We shouldn't leave out the here.
Disclaimer: I might be biased by the phrasing of existing diagnostics. The error message expected , found looks like it's describing a syntax error, even though it's not (it's a type error) as I've previously mentioned. The wording expected / found [token] is exclusively used by the parser as far as I know. If I see that message I assume that annotating the container with or adding the CLI flag would not make the error go away. Because of this, I caution against using such phrasing. I expect it to look similar to:
Sorry, I should have been more clear: doesn't really make sense to me, it leaves out the which is obviously important in this context. EDIT: AFAIK, it still remains in the parser, and it definitely is still a syntax error. As for your suggested diagnostic, the proposed suggestion doesn't seem quite right in terms of wording. Adding a semicolon does not fix the error; it does not provide a function, but rather makes the error go away by removing the expectation of a function in the first place. This has to be explained to the user, otherwise it just looks even more confusing.

<ins> // run-rustfix #![allow(dead_code, unused_variables, path_statements)] fn a() { let x = 5; let y = x; //~ ERROR expected function (); //~ ERROR expected `;`, found `}` } fn b() { let x = 5; let y = x; //~ ERROR expected function (); } fn c() { let x = 5; x; //~ ERROR expected function () } fn d() { // ok let x = || (); x () } fn e() { // ok let x = || (); x (); } fn f() { let y = 5; //~ ERROR expected function (); //~ ERROR expected `;`, found `}` } fn g() { 5; //~ ERROR expected function (); } fn main() {} </ins>


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: One error occurs from the missing semicolon. Instead, this happened: An additional unexpected error occurs when when I obviously do not want to invoke a closure. Also note that the semicolon error is after the supposed closure invocation, when I would expect it to be after the . Occurs on latest stable and nightly. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
label A-diagnostics D-newcomer-roadblock D-terse
The compiler would consider the case the same as I think it's hard to determine if the user wants invoke a closure or not by writing the "()" to the next line. Rust allows syntax like this(actually a lot of languages allow this type of syntax)
We should definitely be able to look at the spans of the callee and the argument list, determine if they are on separate lines (via the ) & don't originate from a macro expansion and if so at least add a note to the diagnostic suggesting to add a semicolon. Of course, there will always be false positives.
The case should be handled in both the parser and the call error. In the parser we can't be certain that the call expression is incorrect, except for maybe literals, but if you had we are back to ambiguity, so that should be handled in E0618 and suggest a semicolon there as well. You could also have which would parse successfully but fail only in the call.
claim
When adding a nice parser error you have to make sure that you never emit a parser error for valid rust syntax. So for the example Esteban described above handling it in the parser is fine since the statement is missing a semicolon, making it invalid syntax. But you have to make sure that something like doesn't give a parser error but only errors during type checking. This is because of macros, which may transform code that is valid syntax but invalid semantically into something entirely valid.
At the very least, these cases should be handled
I guess I should also be clear that the suggestion currently provided by rustc could never be correct: function (and closure) names can't start with integer
The diagnostics currently emitted by the compiler are absolutely correct: An integer cannot be called and the let-statement must be followed by a semicolon. Indeed, identifiers (“function (and closure) names”) cannot start with a digit. However, this is not relevant here: Syntactically speaking, the callee (the thing being called) in a call expression can be an arbitrary expression. Consider (this might even be well-typed depending on the definition of and its s). So is syntactically well-formed but semantically it is not (according to the trait solver) as there is no primitive integer type (e.g. ) that implements or friends. Technically speaking, could very well add a implementation for that makes semantically well-formed, too. This is the reason why you see the error messages you posted. Edit: I hope it's already clear from context but I'd like to emphasize that I am not saying that the diagnostics as emitted today should stay the way they are (we should definitely suggest to add a as mentioned above), I am just trying to clarify the semantics and disputing the quoted statement.
Ahh right, I forget briefly that function calls could be on values, I was thinking of the integer literal being seen as an identifier only (and of course integer identifiers don't exist). Silly me!
the point you're making is why we can proactively catch the "literal followed by ()" case in the parser, and avoid the second, unnecessary "invalid call" error. But for the general case, where the parser doesn't have enough context (a, b and c in my examples), we would have to emit two errors, or delay the parse error until resolve.
According to the discussion, the current diagnostics emitted by the compiler are correct. Can we close the issue now?
the compiler errors are correct, but they are misleading, so we'll put some effort to improve the output to make it clear what is happening to everyone, regardless of expertise level, at a glance.
ok. So we still let the compiler emit 2 diagnostics, one is from the parser, another one is error[E0618]. How about the output being like this? Which won't be misleading the user to program code like ;
Hmm, I haven't really been keeping up to date with this so this might not be ideal/possible but: This parser error is, IMO, wrong. It should say "expected , found ". We shouldn't leave out the here.
Disclaimer: I might be biased by the phrasing of existing diagnostics. The error message expected , found looks like it's describing a syntax error, even though it's not (it's a type error) as I've previously mentioned. The wording expected / found [token] is exclusively used by the parser as far as I know. If I see that message I assume that annotating the container with or adding the CLI flag would not make the error go away. Because of this, I caution against using such phrasing. I expect it to look similar to:
Sorry, I should have been more clear: doesn't really make sense to me, it leaves out the which is obviously important in this context. EDIT: AFAIK, it still remains in the parser, and it definitely is still a syntax error. As for your suggested diagnostic, the proposed suggestion doesn't seem quite right in terms of wording. Adding a semicolon does not fix the error; it does not provide a function, but rather makes the error go away by removing the expectation of a function in the first place. This has to be explained to the user, otherwise it just looks even more confusing.

<ins> // run-rustfix #![allow(dead_code, unused_variables, path_statements)] fn a() { let x = 5; let y = x //~ ERROR expected function () //~ ERROR expected `;`, found `}` } fn b() { let x = 5; let y = x //~ ERROR expected function (); } fn c() { let x = 5; x //~ ERROR expected function () } fn d() { // ok let x = || (); x () } fn e() { // ok let x = || (); x (); } fn f() { let y = 5 //~ ERROR expected function () //~ ERROR expected `;`, found `}` } fn g() { 5 //~ ERROR expected function (); } fn main() {} </ins>


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: One error occurs from the missing semicolon. Instead, this happened: An additional unexpected error occurs when when I obviously do not want to invoke a closure. Also note that the semicolon error is after the supposed closure invocation, when I would expect it to be after the . Occurs on latest stable and nightly. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
label A-diagnostics D-newcomer-roadblock D-terse
The compiler would consider the case the same as I think it's hard to determine if the user wants invoke a closure or not by writing the "()" to the next line. Rust allows syntax like this(actually a lot of languages allow this type of syntax)
We should definitely be able to look at the spans of the callee and the argument list, determine if they are on separate lines (via the ) & don't originate from a macro expansion and if so at least add a note to the diagnostic suggesting to add a semicolon. Of course, there will always be false positives.
The case should be handled in both the parser and the call error. In the parser we can't be certain that the call expression is incorrect, except for maybe literals, but if you had we are back to ambiguity, so that should be handled in E0618 and suggest a semicolon there as well. You could also have which would parse successfully but fail only in the call.
claim
When adding a nice parser error you have to make sure that you never emit a parser error for valid rust syntax. So for the example Esteban described above handling it in the parser is fine since the statement is missing a semicolon, making it invalid syntax. But you have to make sure that something like doesn't give a parser error but only errors during type checking. This is because of macros, which may transform code that is valid syntax but invalid semantically into something entirely valid.
At the very least, these cases should be handled
I guess I should also be clear that the suggestion currently provided by rustc could never be correct: function (and closure) names can't start with integer
The diagnostics currently emitted by the compiler are absolutely correct: An integer cannot be called and the let-statement must be followed by a semicolon. Indeed, identifiers (“function (and closure) names”) cannot start with a digit. However, this is not relevant here: Syntactically speaking, the callee (the thing being called) in a call expression can be an arbitrary expression. Consider (this might even be well-typed depending on the definition of and its s). So is syntactically well-formed but semantically it is not (according to the trait solver) as there is no primitive integer type (e.g. ) that implements or friends. Technically speaking, could very well add a implementation for that makes semantically well-formed, too. This is the reason why you see the error messages you posted. Edit: I hope it's already clear from context but I'd like to emphasize that I am not saying that the diagnostics as emitted today should stay the way they are (we should definitely suggest to add a as mentioned above), I am just trying to clarify the semantics and disputing the quoted statement.
Ahh right, I forget briefly that function calls could be on values, I was thinking of the integer literal being seen as an identifier only (and of course integer identifiers don't exist). Silly me!
the point you're making is why we can proactively catch the "literal followed by ()" case in the parser, and avoid the second, unnecessary "invalid call" error. But for the general case, where the parser doesn't have enough context (a, b and c in my examples), we would have to emit two errors, or delay the parse error until resolve.
According to the discussion, the current diagnostics emitted by the compiler are correct. Can we close the issue now?
the compiler errors are correct, but they are misleading, so we'll put some effort to improve the output to make it clear what is happening to everyone, regardless of expertise level, at a glance.
ok. So we still let the compiler emit 2 diagnostics, one is from the parser, another one is error[E0618]. How about the output being like this? Which won't be misleading the user to program code like ;
Hmm, I haven't really been keeping up to date with this so this might not be ideal/possible but: This parser error is, IMO, wrong. It should say "expected , found ". We shouldn't leave out the here.
Disclaimer: I might be biased by the phrasing of existing diagnostics. The error message expected , found looks like it's describing a syntax error, even though it's not (it's a type error) as I've previously mentioned. The wording expected / found [token] is exclusively used by the parser as far as I know. If I see that message I assume that annotating the container with or adding the CLI flag would not make the error go away. Because of this, I caution against using such phrasing. I expect it to look similar to:
Sorry, I should have been more clear: doesn't really make sense to me, it leaves out the which is obviously important in this context. EDIT: AFAIK, it still remains in the parser, and it definitely is still a syntax error. As for your suggested diagnostic, the proposed suggestion doesn't seem quite right in terms of wording. Adding a semicolon does not fix the error; it does not provide a function, but rather makes the error go away by removing the expectation of a function in the first place. This has to be explained to the user, otherwise it just looks even more confusing.

<ins> error: expected `;`, found `}` --> $DIR/missing-semicolon.rs:6:7 | LL |     () |       ^ help: add `;` here LL | } | - unexpected token error: expected `;`, found `}` --> $DIR/missing-semicolon.rs:32:7 | LL |     () |       ^ help: add `;` here LL | } | - unexpected token error[E0618]: expected function, found `{integer}` --> $DIR/missing-semicolon.rs:5:13 | LL |       let x = 5; |           - `x` has type `{integer}` LL |       let y = x |               ^- help: consider using a semicolon here to finish the statement: `;` |  _____________| | | LL | |     () | |______- call expression requires function error[E0618]: expected function, found `{integer}` --> $DIR/missing-semicolon.rs:11:13 | LL |       let x = 5; |           - `x` has type `{integer}` LL |       let y = x |               ^- help: consider using a semicolon here to finish the statement: `;` |  _____________| | | LL | |     (); | |______- call expression requires function error[E0618]: expected function, found `{integer}` --> $DIR/missing-semicolon.rs:16:5 | LL |       let x = 5; |           - `x` has type `{integer}` LL |       x |       ^- help: consider using a semicolon here to finish the statement: `;` |  _____| | | LL | |     () | |______- call expression requires function error[E0618]: expected function, found `{integer}` --> $DIR/missing-semicolon.rs:31:13 | LL |       let y = 5 |               ^- help: consider using a semicolon here to finish the statement: `;` |  _____________| | | LL | |     () | |______- call expression requires function error[E0618]: expected function, found `{integer}` --> $DIR/missing-semicolon.rs:35:5 | LL |       5 |       ^- help: consider using a semicolon here to finish the statement: `;` |  _____| | | LL | |     (); | |______- call expression requires function error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0618`. </ins>


Question:
rust version: Do you think it would be useful to add a hint here? Something in the lines of <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
i was hoping this to be my first PR to the compiler, if accepted as necessary. :D I need some guidance as to where this code might be though...
claim
hups sorry
I was testing the bot feature
The 'is not an iterator' message comes from the attribute. One solution would be to add a new case to that attribute which detects literals of the form (where both sides are numeric) and suggests the iterator syntax.
thanks!
is this in the right direction?

note = "if you want to iterate between `start` until a value `end`, use the exclusive range  syntax `start..end` or the inclusive range syntax `start..=end`" ), <ins> on( _Self = "{float}", note = "if you want to iterate between `start` until a value `end`, use the exclusive range  syntax `start..end` or the inclusive range syntax `start..=end`" ), </ins> label = "`{Self}` is not an iterator", message = "`{Self}` is not an iterator" )]


Question:
rust version: Do you think it would be useful to add a hint here? Something in the lines of <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
i was hoping this to be my first PR to the compiler, if accepted as necessary. :D I need some guidance as to where this code might be though...
claim
hups sorry
I was testing the bot feature
The 'is not an iterator' message comes from the attribute. One solution would be to add a new case to that attribute which detects literals of the form (where both sides are numeric) and suggests the iterator syntax.
thanks!
is this in the right direction?

<ins> // #106728 fn main() { for i in 0.2 { //~^ ERROR `{float}` is not an iterator //~| `{float}` is not an iterator //~| NOTE in this expansion of desugaring of `for` loop //~| NOTE in this expansion of desugaring of `for` loop //~| NOTE in this expansion of desugaring of `for` loop //~| NOTE in this expansion of desugaring of `for` loop //~| NOTE if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` //~| NOTE required for `{float}` to implement `IntoIterator` println!(); } } </ins>


Question:
rust version: Do you think it would be useful to add a hint here? Something in the lines of <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
i was hoping this to be my first PR to the compiler, if accepted as necessary. :D I need some guidance as to where this code might be though...
claim
hups sorry
I was testing the bot feature
The 'is not an iterator' message comes from the attribute. One solution would be to add a new case to that attribute which detects literals of the form (where both sides are numeric) and suggests the iterator syntax.
thanks!
is this in the right direction?

<ins> error[E0277]: `{float}` is not an iterator --> $DIR/float_iterator_hint.rs:4:14 | LL |     for i in 0.2 { |              ^^^ `{float}` is not an iterator | = help: the trait `Iterator` is not implemented for `{float}` = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` = note: required for `{float}` to implement `IntoIterator` error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. </ins>


Question:
rust version: Do you think it would be useful to add a hint here? Something in the lines of <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
i was hoping this to be my first PR to the compiler, if accepted as necessary. :D I need some guidance as to where this code might be though...
claim
hups sorry
I was testing the bot feature
The 'is not an iterator' message comes from the attribute. One solution would be to add a new case to that attribute which detects literals of the form (where both sides are numeric) and suggests the iterator syntax.
thanks!
is this in the right direction?

|              ^^^^ `{float}` is not an iterator | = help: the trait `Iterator` is not implemented for `{float}` <ins> = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` </ins> = note: required for `{float}` to implement `IntoIterator` error: aborting due to 12 previous errors


Question:
Today I synchronized my local version of the rust repo, made a few changes and formatted. This prints: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
This is a known issue, it means that you have a remote to the rust-lang repo that is outdated. The 35k lines likely means that it is at least behind the test move. Does running (replace with the remote name if different) fixes it ?
Maybe we should remove these logs?
There is the same problem if you created lots of file in the formatted directories, but did not track them in git: It will print the name of all of these.
I think we should avoid printing the names of the files if there are more than 10 (or whatever number). That would avoid all similar issues.
claim
Hi! May I know if you're still working on this issue?

if !check && paths.is_empty() { match get_modified_rs_files(build) { Ok(Some(files)) => { <ins> if files.len() <= 10 { for file in &files { println!("formatting modified file {file}"); } } else { println!("formatting {} modified files", files.len()); } </ins> for file in files { <del> println!("formatting modified file {file}"); </del> ignore_fmt.add(&format!("/{file}")).expect(&file); } }


Question:
The problem is that the configure script assumes that all keys are in a section and there are no top-level keys. This forces people to use instead: We should make it possible to set top-level keys through , both and . We should also update the line in the readme linked above to suggest instead of printf. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Mentoring instructions: look around I think the fix would be something like .
In the , from where exactly do we get the top-level keys? from the set function?
I'm not sure off the top of my head. How could you find out that information?
Hi are you still working on this?
do you think it's okay to unassign ? This issue is blocking as well.
Since there's no response from the assignee, I think you can take the issue. Are you still keen on working on this issue?
Yup I am interested! claim
Hi and thanks for mentoring! Assuming I run , I think will be 2. So I am not sure if this path would work. It seems like the first blocker is that does not contain or as keys. Should the approach be to expand with those keys? Or should we just allow / as special cases? I am guessing it's closer to the latter, since that might affect the definition of which searches for . Finally, I am a little confused what top-level keys mean - do they exclusively refer to [, ] ? Are there more?
I am able to expand when parsing to include and but I realise I may either have to make changes to or write a new method. Before I do that, I would like to understand how the configure script is commonly used. Could you give me some sample commands, say if I want to modify the field of llvm?
Shall we refactor the 2 top level keys under a section? this makes the parsing logic more consistent and unwieldy lol
you can take a look at for a complete example of what a configuration could look like. I think that would resolve most, if not all of your queries(: Hope this helps!
try running
Got it, thanks I put up a PR. This is kinda my first PR so would appreciate all the tips and advice!

sections[None] = [] section_order = [None] targets = {} <ins> top_level_keys = [] </ins> for line in open(rust_dir + '/config.toml.example').read().split("n"): <ins> if cur_section == None: if line.count('=') == 1: top_level_key = line.split('=')[0] top_level_key = top_level_key.strip(' #') top_level_keys.append(top_level_key) </ins> if line.startswith('['): cur_section = line[1:-1] if cur_section.startswith('target'):


Question:
The problem is that the configure script assumes that all keys are in a section and there are no top-level keys. This forces people to use instead: We should make it possible to set top-level keys through , both and . We should also update the line in the readme linked above to suggest instead of printf. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Mentoring instructions: look around I think the fix would be something like .
In the , from where exactly do we get the top-level keys? from the set function?
I'm not sure off the top of my head. How could you find out that information?
Hi are you still working on this?
do you think it's okay to unassign ? This issue is blocking as well.
Since there's no response from the assignee, I think you can take the issue. Are you still keen on working on this issue?
Yup I am interested! claim
Hi and thanks for mentoring! Assuming I run , I think will be 2. So I am not sure if this path would work. It seems like the first blocker is that does not contain or as keys. Should the approach be to expand with those keys? Or should we just allow / as special cases? I am guessing it's closer to the latter, since that might affect the definition of which searches for . Finally, I am a little confused what top-level keys mean - do they exclusively refer to [, ] ? Are there more?
I am able to expand when parsing to include and but I realise I may either have to make changes to or write a new method. Before I do that, I would like to understand how the configure script is commonly used. Could you give me some sample commands, say if I want to modify the field of llvm?
Shall we refactor the 2 top level keys under a section? this makes the parsing logic more consistent and unwieldy lol
you can take a look at for a complete example of what a configuration could look like. I think that would resolve most, if not all of your queries(: Hope this helps!
try running
Got it, thanks I put up a PR. This is kinda my first PR so would appreciate all the tips and advice!

raise RuntimeError("failed to find config line for {}".format(key)) <del> for section_key in config: section_config = config[section_key] if section_key not in sections: raise RuntimeError("config key {} not in sections".format(section_key)) </del> <ins> def configure_top_level_key(lines, top_level_key, value): for i, line in enumerate(lines): if line.startswith('#' + top_level_key + ' = ') or line.startswith(top_level_key + ' = '): lines[i] = "{} = {}".format(top_level_key, value) return </ins> <del> if section_key == 'target': </del> <ins> raise RuntimeError("failed to find config line for {}".format(top_level_key)) for section_key, section_config in config.items(): if section_key not in sections and section_key not in top_level_keys: raise RuntimeError("config key {} not in sections or top_level_keys".format(section_key)) if section_key in top_level_keys: configure_top_level_key(sections[None], section_key, section_config) elif  section_key == 'target': </ins> for target in section_config: configure_section(targets[target], section_config[target]) else:


Question:
(and similarly, should call ) Windows provides these nice functions which performantly implement utf-8 <-utf-16 conversions. We should probably call them in the standard library when possible.
Do we get measurable performance wins that make calling more unsafe C APIs worth it? Especially with the inlining barrier across languages. And I would assume console printing is bottlenecked on the console rendering part anyway, not on string conversions.
Do we have any good benchmarks for console I/O perf?
A simple main writing 100MB worth of lines to stdout and measuring the time it takes should do?
For sure. I was just wondering if we had something already. I mean, we'd probably want to be testing a few different languages as well to make sure we're not just optimizing for ASCII only.
I don't think we do because most benchmarks suppress console output.
I did do a benchmark, and interestingly, ASCII text was about twice as fast with as with rust-native code; however, Chinese text was slightly slower. Given that most of the actual cost of printing to the screen is in the actual printing, I no longer think it's a good idea to do this. See benchmarks at [strega-nil/rust-bench-cvt-utf8-utf16][]. [strega-nil/rust-bench-cvt-utf8-utf16]: Run on M1 chip: someone may want to check on an x64 chip, since that might be faster.
Just to check my understanding: The utf16 conversion only happens when one writes to an actually rendered console. There isn't some stuff like virtual consoles that act more like NUL where speeding up the conversion could help because the data will be discarded by the OS. And output to files is binary anyway.
There are now (since Windows 10, 1809) which are consoles without the rendering part. Though the intent would be for the rendering to be implemented by another program, it would also be possible to skip or delay (e.g. by writing a log) rendering.
In that case a speedup may be useful, but is the optimization potential of the built-in conversion already squeezed dry?
yeah, I think it's unlikely that the complexity is worth it given what the benchmarks show; I would really appreciate if someone ran the benchmark on x64, since it may be that Windows implements faster algorithms on that platform.
I don't think anyone has worked on optimizing this so I'm sure there's plenty of optimization potential. The results from I got from an AMD Ryzen 5 3600 machine are:
Mmh, thanks I'll also push some benchmarks for testing other cases later, since there are plenty of other cases than just "bulk-converting a bunch of text". Thanks! Nicole

all(target_vendor = "fortanix", target_env = "sgx"), feature(slice_index_methods, coerce_unsized, sgx_platform) )] <ins> #![cfg_attr(windows, feature(round_char_boundary))] </ins> // // Language features: #![feature(alloc_error_handler)]


Question:
(and similarly, should call ) Windows provides these nice functions which performantly implement utf-8 <-utf-16 conversions. We should probably call them in the standard library when possible.
Do we get measurable performance wins that make calling more unsafe C APIs worth it? Especially with the inlining barrier across languages. And I would assume console printing is bottlenecked on the console rendering part anyway, not on string conversions.
Do we have any good benchmarks for console I/O perf?
A simple main writing 100MB worth of lines to stdout and measuring the time it takes should do?
For sure. I was just wondering if we had something already. I mean, we'd probably want to be testing a few different languages as well to make sure we're not just optimizing for ASCII only.
I don't think we do because most benchmarks suppress console output.
I did do a benchmark, and interestingly, ASCII text was about twice as fast with as with rust-native code; however, Chinese text was slightly slower. Given that most of the actual cost of printing to the screen is in the actual printing, I no longer think it's a good idea to do this. See benchmarks at [strega-nil/rust-bench-cvt-utf8-utf16][]. [strega-nil/rust-bench-cvt-utf8-utf16]: Run on M1 chip: someone may want to check on an x64 chip, since that might be faster.
Just to check my understanding: The utf16 conversion only happens when one writes to an actually rendered console. There isn't some stuff like virtual consoles that act more like NUL where speeding up the conversion could help because the data will be discarded by the OS. And output to files is binary anyway.
There are now (since Windows 10, 1809) which are consoles without the rendering part. Though the intent would be for the rendering to be implemented by another program, it would also be possible to skip or delay (e.g. by writing a log) rendering.
In that case a speedup may be useful, but is the optimization potential of the built-in conversion already squeezed dry?
yeah, I think it's unlikely that the complexity is worth it given what the benchmarks show; I would really appreciate if someone ran the benchmark on x64, since it may be that Windows implements faster algorithms on that platform.
I don't think anyone has worked on optimizing this so I'm sure there's plenty of optimization potential. The results from I got from an AMD Ryzen 5 3600 machine are:
Mmh, thanks I'll also push some benchmarks for testing other cases later, since there are plenty of other cases than just "bulk-converting a bunch of text". Thanks! Nicole

use crate::ffi::CStr; use crate::mem; <del> use crate::os::raw::{c_char, c_int, c_long, c_longlong, c_uint, c_ulong, c_ushort}; </del> <ins> use crate::os::raw::{c_char, c_long, c_longlong, c_uint, c_ulong, c_ushort}; </ins> use crate::os::windows::io::{BorrowedHandle, HandleOrInvalid, HandleOrNull}; use crate::ptr; use core::ffi::NonZero_c_ulong; use libc::{c_void, size_t, wchar_t}; <ins> pub use crate::os::raw::c_int; </ins> #[path = "c/errors.rs"] // c.rs is included from two places so we need to specify this mod errors; pub use errors::*;


Question:
(and similarly, should call ) Windows provides these nice functions which performantly implement utf-8 <-utf-16 conversions. We should probably call them in the standard library when possible.
Do we get measurable performance wins that make calling more unsafe C APIs worth it? Especially with the inlining barrier across languages. And I would assume console printing is bottlenecked on the console rendering part anyway, not on string conversions.
Do we have any good benchmarks for console I/O perf?
A simple main writing 100MB worth of lines to stdout and measuring the time it takes should do?
For sure. I was just wondering if we had something already. I mean, we'd probably want to be testing a few different languages as well to make sure we're not just optimizing for ASCII only.
I don't think we do because most benchmarks suppress console output.
I did do a benchmark, and interestingly, ASCII text was about twice as fast with as with rust-native code; however, Chinese text was slightly slower. Given that most of the actual cost of printing to the screen is in the actual printing, I no longer think it's a good idea to do this. See benchmarks at [strega-nil/rust-bench-cvt-utf8-utf16][]. [strega-nil/rust-bench-cvt-utf8-utf16]: Run on M1 chip: someone may want to check on an x64 chip, since that might be faster.
Just to check my understanding: The utf16 conversion only happens when one writes to an actually rendered console. There isn't some stuff like virtual consoles that act more like NUL where speeding up the conversion could help because the data will be discarded by the OS. And output to files is binary anyway.
There are now (since Windows 10, 1809) which are consoles without the rendering part. Though the intent would be for the rendering to be implemented by another program, it would also be possible to skip or delay (e.g. by writing a log) rendering.
In that case a speedup may be useful, but is the optimization potential of the built-in conversion already squeezed dry?
yeah, I think it's unlikely that the complexity is worth it given what the benchmarks show; I would really appreciate if someone ran the benchmark on x64, since it may be that Windows implements faster algorithms on that platform.
I don't think anyone has worked on optimizing this so I'm sure there's plenty of optimization potential. The results from I got from an AMD Ryzen 5 3600 machine are:
Mmh, thanks I'll also push some benchmarks for testing other cases later, since there are plenty of other cases than just "bulk-converting a bunch of text". Thanks! Nicole

pub type LPBOOL = *mut BOOL; pub type LPBYTE = *mut BYTE; <ins> pub type LPCCH = *const CHAR; </ins> pub type LPCSTR = *const CHAR; <ins> pub type LPCWCH = *const WCHAR; </ins> pub type LPCWSTR = *const WCHAR; <ins> pub type LPCVOID = *const c_void; </ins> pub type LPDWORD = *mut DWORD; pub type LPHANDLE = *mut HANDLE; pub type LPOVERLAPPED = *mut OVERLAPPED; pub type LPPROCESS_INFORMATION = *mut PROCESS_INFORMATION; pub type LPSECURITY_ATTRIBUTES = *mut SECURITY_ATTRIBUTES; pub type LPSTARTUPINFO = *mut STARTUPINFO; <ins> pub type LPSTR = *mut CHAR; </ins> pub type LPVOID = *mut c_void; <del> pub type LPCVOID = *const c_void; </del> pub type LPWCH = *mut WCHAR; pub type LPWIN32_FIND_DATAW = *mut WIN32_FIND_DATAW; pub type LPWSADATA = *mut WSADATA;


Question:
(and similarly, should call ) Windows provides these nice functions which performantly implement utf-8 <-utf-16 conversions. We should probably call them in the standard library when possible.
Do we get measurable performance wins that make calling more unsafe C APIs worth it? Especially with the inlining barrier across languages. And I would assume console printing is bottlenecked on the console rendering part anyway, not on string conversions.
Do we have any good benchmarks for console I/O perf?
A simple main writing 100MB worth of lines to stdout and measuring the time it takes should do?
For sure. I was just wondering if we had something already. I mean, we'd probably want to be testing a few different languages as well to make sure we're not just optimizing for ASCII only.
I don't think we do because most benchmarks suppress console output.
I did do a benchmark, and interestingly, ASCII text was about twice as fast with as with rust-native code; however, Chinese text was slightly slower. Given that most of the actual cost of printing to the screen is in the actual printing, I no longer think it's a good idea to do this. See benchmarks at [strega-nil/rust-bench-cvt-utf8-utf16][]. [strega-nil/rust-bench-cvt-utf8-utf16]: Run on M1 chip: someone may want to check on an x64 chip, since that might be faster.
Just to check my understanding: The utf16 conversion only happens when one writes to an actually rendered console. There isn't some stuff like virtual consoles that act more like NUL where speeding up the conversion could help because the data will be discarded by the OS. And output to files is binary anyway.
There are now (since Windows 10, 1809) which are consoles without the rendering part. Though the intent would be for the rendering to be implemented by another program, it would also be possible to skip or delay (e.g. by writing a log) rendering.
In that case a speedup may be useful, but is the optimization potential of the built-in conversion already squeezed dry?
yeah, I think it's unlikely that the complexity is worth it given what the benchmarks show; I would really appreciate if someone ran the benchmark on x64, since it may be that Windows implements faster algorithms on that platform.
I don't think anyone has worked on optimizing this so I'm sure there's plenty of optimization potential. The results from I got from an AMD Ryzen 5 3600 machine are:
Mmh, thanks I'll also push some benchmarks for testing other cases later, since there are plenty of other cases than just "bulk-converting a bunch of text". Thanks! Nicole

pub const FILE_TYPE_PIPE: u32 = 3; <ins> pub const CP_UTF8: DWORD = 65001; pub const MB_ERR_INVALID_CHARS: DWORD = 0x08; pub const WC_ERR_INVALID_CHARS: DWORD = 0x80; </ins> #[repr(C)] #[derive(Copy)] pub struct WIN32_FIND_DATAW {


Question:
(and similarly, should call ) Windows provides these nice functions which performantly implement utf-8 <-utf-16 conversions. We should probably call them in the standard library when possible.
Do we get measurable performance wins that make calling more unsafe C APIs worth it? Especially with the inlining barrier across languages. And I would assume console printing is bottlenecked on the console rendering part anyway, not on string conversions.
Do we have any good benchmarks for console I/O perf?
A simple main writing 100MB worth of lines to stdout and measuring the time it takes should do?
For sure. I was just wondering if we had something already. I mean, we'd probably want to be testing a few different languages as well to make sure we're not just optimizing for ASCII only.
I don't think we do because most benchmarks suppress console output.
I did do a benchmark, and interestingly, ASCII text was about twice as fast with as with rust-native code; however, Chinese text was slightly slower. Given that most of the actual cost of printing to the screen is in the actual printing, I no longer think it's a good idea to do this. See benchmarks at [strega-nil/rust-bench-cvt-utf8-utf16][]. [strega-nil/rust-bench-cvt-utf8-utf16]: Run on M1 chip: someone may want to check on an x64 chip, since that might be faster.
Just to check my understanding: The utf16 conversion only happens when one writes to an actually rendered console. There isn't some stuff like virtual consoles that act more like NUL where speeding up the conversion could help because the data will be discarded by the OS. And output to files is binary anyway.
There are now (since Windows 10, 1809) which are consoles without the rendering part. Though the intent would be for the rendering to be implemented by another program, it would also be possible to skip or delay (e.g. by writing a log) rendering.
In that case a speedup may be useful, but is the optimization potential of the built-in conversion already squeezed dry?
yeah, I think it's unlikely that the complexity is worth it given what the benchmarks show; I would really appreciate if someone ran the benchmark on x64, since it may be that Windows implements faster algorithms on that platform.
I don't think anyone has worked on optimizing this so I'm sure there's plenty of optimization potential. The results from I got from an AMD Ryzen 5 3600 machine are:
Mmh, thanks I'll also push some benchmarks for testing other cases later, since there are plenty of other cases than just "bulk-converting a bunch of text". Thanks! Nicole

lpFilePart: *mut LPWSTR, ) -> DWORD; pub fn GetFileAttributesW(lpFileName: LPCWSTR) -> DWORD; <ins> pub fn MultiByteToWideChar( CodePage: UINT, dwFlags: DWORD, lpMultiByteStr: LPCCH, cbMultiByte: c_int, lpWideCharStr: LPWSTR, cchWideChar: c_int, ) -> c_int; pub fn WideCharToMultiByte( CodePage: UINT, dwFlags: DWORD, lpWideCharStr: LPCWCH, cchWideChar: c_int, lpMultiByteStr: LPSTR, cbMultiByte: c_int, lpDefaultChar: LPCCH, lpUsedDefaultChar: LPBOOL, ) -> c_int; </ins> } #[link(name = "ws2_32")]


Question:
(and similarly, should call ) Windows provides these nice functions which performantly implement utf-8 <-utf-16 conversions. We should probably call them in the standard library when possible.
Do we get measurable performance wins that make calling more unsafe C APIs worth it? Especially with the inlining barrier across languages. And I would assume console printing is bottlenecked on the console rendering part anyway, not on string conversions.
Do we have any good benchmarks for console I/O perf?
A simple main writing 100MB worth of lines to stdout and measuring the time it takes should do?
For sure. I was just wondering if we had something already. I mean, we'd probably want to be testing a few different languages as well to make sure we're not just optimizing for ASCII only.
I don't think we do because most benchmarks suppress console output.
I did do a benchmark, and interestingly, ASCII text was about twice as fast with as with rust-native code; however, Chinese text was slightly slower. Given that most of the actual cost of printing to the screen is in the actual printing, I no longer think it's a good idea to do this. See benchmarks at [strega-nil/rust-bench-cvt-utf8-utf16][]. [strega-nil/rust-bench-cvt-utf8-utf16]: Run on M1 chip: someone may want to check on an x64 chip, since that might be faster.
Just to check my understanding: The utf16 conversion only happens when one writes to an actually rendered console. There isn't some stuff like virtual consoles that act more like NUL where speeding up the conversion could help because the data will be discarded by the OS. And output to files is binary anyway.
There are now (since Windows 10, 1809) which are consoles without the rendering part. Though the intent would be for the rendering to be implemented by another program, it would also be possible to skip or delay (e.g. by writing a log) rendering.
In that case a speedup may be useful, but is the optimization potential of the built-in conversion already squeezed dry?
yeah, I think it's unlikely that the complexity is worth it given what the benchmarks show; I would really appreciate if someone ran the benchmark on x64, since it may be that Windows implements faster algorithms on that platform.
I don't think anyone has worked on optimizing this so I'm sure there's plenty of optimization potential. The results from I got from an AMD Ryzen 5 3600 machine are:
Mmh, thanks I'll also push some benchmarks for testing other cases later, since there are plenty of other cases than just "bulk-converting a bunch of text". Thanks! Nicole

} fn write_valid_utf8_to_console(handle: c::HANDLE, utf8: &str) -> io::Result<usize> { <ins> debug_assert!(!utf8.is_empty()); </ins> let mut utf16 = [MaybeUninit::<u16>::uninit(); MAX_BUFFER_SIZE / 2]; <del> let mut len_utf16 = 0; for (chr, dest) in utf8.encode_utf16().zip(utf16.iter_mut()) { *dest = MaybeUninit::new(chr); len_utf16 += 1; } // Safety: We've initialized `len_utf16` values. let utf16: &[u16] = unsafe { MaybeUninit::slice_assume_init_ref(&utf16[..len_utf16]) }; </del> <ins> let utf8 = &utf8[..utf8.floor_char_boundary(utf16.len())]; let utf16: &[u16] = unsafe { // Note that this theoretically checks validity twice in the (most common) case // where the underlying byte sequence is valid utf-8 (given the check in `write()`). let result = c::MultiByteToWideChar( c::CP_UTF8,                      // CodePage c::MB_ERR_INVALID_CHARS,         // dwFlags utf8.as_ptr() as c::LPCCH,       // lpMultiByteStr utf8.len() as c::c_int,          // cbMultiByte utf16.as_mut_ptr() as c::LPWSTR, // lpWideCharStr utf16.len() as c::c_int,         // cchWideChar ); assert!(result != 0, "Unexpected error in MultiByteToWideChar"); // Safety: MultiByteToWideChar initializes `result` values. MaybeUninit::slice_assume_init_ref(&utf16[..result as usize]) }; </ins> let mut written = write_u16s(handle, &utf16)?;


Question:
(and similarly, should call ) Windows provides these nice functions which performantly implement utf-8 <-utf-16 conversions. We should probably call them in the standard library when possible.
Do we get measurable performance wins that make calling more unsafe C APIs worth it? Especially with the inlining barrier across languages. And I would assume console printing is bottlenecked on the console rendering part anyway, not on string conversions.
Do we have any good benchmarks for console I/O perf?
A simple main writing 100MB worth of lines to stdout and measuring the time it takes should do?
For sure. I was just wondering if we had something already. I mean, we'd probably want to be testing a few different languages as well to make sure we're not just optimizing for ASCII only.
I don't think we do because most benchmarks suppress console output.
I did do a benchmark, and interestingly, ASCII text was about twice as fast with as with rust-native code; however, Chinese text was slightly slower. Given that most of the actual cost of printing to the screen is in the actual printing, I no longer think it's a good idea to do this. See benchmarks at [strega-nil/rust-bench-cvt-utf8-utf16][]. [strega-nil/rust-bench-cvt-utf8-utf16]: Run on M1 chip: someone may want to check on an x64 chip, since that might be faster.
Just to check my understanding: The utf16 conversion only happens when one writes to an actually rendered console. There isn't some stuff like virtual consoles that act more like NUL where speeding up the conversion could help because the data will be discarded by the OS. And output to files is binary anyway.
There are now (since Windows 10, 1809) which are consoles without the rendering part. Though the intent would be for the rendering to be implemented by another program, it would also be possible to skip or delay (e.g. by writing a log) rendering.
In that case a speedup may be useful, but is the optimization potential of the built-in conversion already squeezed dry?
yeah, I think it's unlikely that the complexity is worth it given what the benchmarks show; I would really appreciate if someone ran the benchmark on x64, since it may be that Windows implements faster algorithms on that platform.
I don't think anyone has worked on optimizing this so I'm sure there's plenty of optimization potential. The results from I got from an AMD Ryzen 5 3600 machine are:
Mmh, thanks I'll also push some benchmarks for testing other cases later, since there are plenty of other cases than just "bulk-converting a bunch of text". Thanks! Nicole

// a missing surrogate can be produced (and also because of the UTF-8 validation above), // write the missing surrogate out now. // Buffering it would mean we have to lie about the number of bytes written. <del> let first_char_remaining = utf16[written]; if first_char_remaining >= 0xDCEE && first_char_remaining <= 0xDFFF { </del> <ins> let first_code_unit_remaining = utf16[written]; if first_code_unit_remaining >= 0xDCEE && first_code_unit_remaining <= 0xDFFF { </ins> // low surrogate // We just hope this works, and give up otherwise let _ = write_u16s(handle, &utf16[written..written + 1]);


Question:
(and similarly, should call ) Windows provides these nice functions which performantly implement utf-8 <-utf-16 conversions. We should probably call them in the standard library when possible.
Do we get measurable performance wins that make calling more unsafe C APIs worth it? Especially with the inlining barrier across languages. And I would assume console printing is bottlenecked on the console rendering part anyway, not on string conversions.
Do we have any good benchmarks for console I/O perf?
A simple main writing 100MB worth of lines to stdout and measuring the time it takes should do?
For sure. I was just wondering if we had something already. I mean, we'd probably want to be testing a few different languages as well to make sure we're not just optimizing for ASCII only.
I don't think we do because most benchmarks suppress console output.
I did do a benchmark, and interestingly, ASCII text was about twice as fast with as with rust-native code; however, Chinese text was slightly slower. Given that most of the actual cost of printing to the screen is in the actual printing, I no longer think it's a good idea to do this. See benchmarks at [strega-nil/rust-bench-cvt-utf8-utf16][]. [strega-nil/rust-bench-cvt-utf8-utf16]: Run on M1 chip: someone may want to check on an x64 chip, since that might be faster.
Just to check my understanding: The utf16 conversion only happens when one writes to an actually rendered console. There isn't some stuff like virtual consoles that act more like NUL where speeding up the conversion could help because the data will be discarded by the OS. And output to files is binary anyway.
There are now (since Windows 10, 1809) which are consoles without the rendering part. Though the intent would be for the rendering to be implemented by another program, it would also be possible to skip or delay (e.g. by writing a log) rendering.
In that case a speedup may be useful, but is the optimization potential of the built-in conversion already squeezed dry?
yeah, I think it's unlikely that the complexity is worth it given what the benchmarks show; I would really appreciate if someone ran the benchmark on x64, since it may be that Windows implements faster algorithms on that platform.
I don't think anyone has worked on optimizing this so I'm sure there's plenty of optimization potential. The results from I got from an AMD Ryzen 5 3600 machine are:
Mmh, thanks I'll also push some benchmarks for testing other cases later, since there are plenty of other cases than just "bulk-converting a bunch of text". Thanks! Nicole

} fn write_u16s(handle: c::HANDLE, data: &[u16]) -> io::Result<usize> { <ins> debug_assert!(data.len() < u32::MAX as usize); </ins> let mut written = 0; cvt(unsafe { c::WriteConsoleW(


Question:
(and similarly, should call ) Windows provides these nice functions which performantly implement utf-8 <-utf-16 conversions. We should probably call them in the standard library when possible.
Do we get measurable performance wins that make calling more unsafe C APIs worth it? Especially with the inlining barrier across languages. And I would assume console printing is bottlenecked on the console rendering part anyway, not on string conversions.
Do we have any good benchmarks for console I/O perf?
A simple main writing 100MB worth of lines to stdout and measuring the time it takes should do?
For sure. I was just wondering if we had something already. I mean, we'd probably want to be testing a few different languages as well to make sure we're not just optimizing for ASCII only.
I don't think we do because most benchmarks suppress console output.
I did do a benchmark, and interestingly, ASCII text was about twice as fast with as with rust-native code; however, Chinese text was slightly slower. Given that most of the actual cost of printing to the screen is in the actual printing, I no longer think it's a good idea to do this. See benchmarks at [strega-nil/rust-bench-cvt-utf8-utf16][]. [strega-nil/rust-bench-cvt-utf8-utf16]: Run on M1 chip: someone may want to check on an x64 chip, since that might be faster.
Just to check my understanding: The utf16 conversion only happens when one writes to an actually rendered console. There isn't some stuff like virtual consoles that act more like NUL where speeding up the conversion could help because the data will be discarded by the OS. And output to files is binary anyway.
There are now (since Windows 10, 1809) which are consoles without the rendering part. Though the intent would be for the rendering to be implemented by another program, it would also be possible to skip or delay (e.g. by writing a log) rendering.
In that case a speedup may be useful, but is the optimization potential of the built-in conversion already squeezed dry?
yeah, I think it's unlikely that the complexity is worth it given what the benchmarks show; I would really appreciate if someone ran the benchmark on x64, since it may be that Windows implements faster algorithms on that platform.
I don't think anyone has worked on optimizing this so I'm sure there's plenty of optimization potential. The results from I got from an AMD Ryzen 5 3600 machine are:
Mmh, thanks I'll also push some benchmarks for testing other cases later, since there are plenty of other cases than just "bulk-converting a bunch of text". Thanks! Nicole

Ok(amount as usize) } <del> #[allow(unused)] </del> fn utf16_to_utf8(utf16: &[u16], utf8: &mut [u8]) -> io::Result<usize> { <del> let mut written = 0; for chr in char::decode_utf16(utf16.iter().cloned()) { match chr { Ok(chr) => { chr.encode_utf8(&mut utf8[written..]); written += chr.len_utf8(); } Err(_) => { // We can't really do any better than forget all data and return an error. return Err(io::const_io_error!( io::ErrorKind::InvalidData, "Windows stdin in console mode does not support non-UTF-16 input;  encountered unpaired surrogate", )); } } </del> <ins> debug_assert!(utf16.len() <= c::c_int::MAX as usize); debug_assert!(utf8.len() <= c::c_int::MAX as usize); let result = unsafe { c::WideCharToMultiByte( c::CP_UTF8,                    // CodePage c::WC_ERR_INVALID_CHARS,       // dwFlags utf16.as_ptr(),                // lpWideCharStr utf16.len() as c::c_int,       // cchWideChar utf8.as_mut_ptr() as c::LPSTR, // lpMultiByteStr utf8.len() as c::c_int,        // cbMultiByte ptr::null(),                   // lpDefaultChar ptr::null_mut(),               // lpUsedDefaultChar ) }; if result == 0 { // We can't really do any better than forget all data and return an error. Err(io::const_io_error!( io::ErrorKind::InvalidData, "Windows stdin in console mode does not support non-UTF-16 input;  encountered unpaired surrogate", )) } else { Ok(result as usize) </ins> } <del> Ok(written) </del> } impl IncompleteUtf8 {


Question:
This occurs with binary crate that is able to target macOS and is most visible when cross compiling. is sufficient. The command produces the error on Linux machines, with or without . [ ] Previous Stable [X] Current Stable [X] Current Beta [X] Current Nightly I encountered this when cross compiling from Linux to macOS. Setting to some path that does exist but isn't a valid macOS SDK gives the expected linker errors of not-found libraries and undefined symbols. <details<summaryThe correct linker errors, which occur with (or any other path that exists) </summaryerror: linking with failed: exit status: 1 | = note: "" "-flavor" "darwin" "-arch" "x8664" "-platformversion" "macos" "10.7" "10.7" "/tmp/rustcmRdv6R/symbols.o" "/home/qyriad/code/hello/target/x8664-apple-darwin/debug/deps/hello-" "/home/qyriad/code/hello/target/x8664-apple-darwin/debug/deps/hello-" "/home/qyriad/code/hello/target/x8664-apple-darwin/debug/deps/hello-" "/home/qyriad/code/hello/target/x8664-apple-darwin/debug/deps/hello-" "/home/qyriad/code/hello/target/x8664-apple-darwin/debug/deps/hello-" "/home/qyriad/code/hello/target/x8664-apple-darwin/debug/deps/hello-" "/home/qyriad/code/hello/target/x8664-apple-darwin/debug/deps/hello-" "-L" "/home/qyriad/code/hello/target/x8664-apple-darwin/debug/deps" "-L" "/home/qyriad/code/hello/target/debug/deps" "-L" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "-lSystem" "-lc" "-lm" "-syslibroot" "/usr" "-L" "" "-o" "/home/qyriad/code/hello/target/x8664-apple-darwin/debug/deps/hello-" "-deadstrip" = note: error: library not found for -lSystem error: library not found for -lc error: library not found for -lm error: undefined symbol: UnwindResume referenced by () /home/qyriad/code/hello/target/x8664-apple-darwin/debug/deps/hello-(symbol ZN4core3ops8function6FnOnce9callonce17hf4bc1fd436eb6a1eE+0x1f) referenced by () (std-):(symbol ZN4core3ops8function6FnOnce40callonceu7bu7d$17hb84e30cb55012ce5E+0x80) referenced by () (std-):(symbol ZN4core3ptr104dropinplaceLTusizeRPGT$17hed3f267c6b45955bE+0xd1) referenced 89 more times error: undefined symbol: memcpy referenced by () (std-):(symbol ZN4core3fmt5Write10writechar17hdfc69d6746a59f51E+0xd4) referenced by () (std-):(symbol ZN50RFu20u20u2010writechar17h93a4c2621e683652E+0xe5) referenced by () (std-):(symbol ZN50RFu20u20u209writestr17h37febf5394bdf526E+0x38) referenced 82 more times error: undefined symbol: UnwindGetTextRelBase referenced by () (std-):(symbol ZN4core3ops8function6FnOnce40callonceu7bu7d$17h8d16de3fdc0c0a05E+0xc) referenced by () (std-):(symbol ZN3std11personality3gcc14findehaction28u7bu7d17hebef1726d888f975E+0xc) error: undefined symbol: UnwindGetDataRelBase referenced by () (std-):(symbol ZN4core3ops8function6FnOnce40callonceu7bu7d$17hb69dca3e57cf94bbE+0xc) referenced by () (std-):(symbol ZN3std11personality3gcc14findehaction28u7bu7d17hbca95bb609e12226E+0xc) error: undefined symbol: pthreadmutexunlock referenced by () (std-):(symbol ZN4core3ptr175dropinplacestd..syscommon..remutex..ReentrantMutexGuardLTGTGT17h7737580f0f37fcd6E+0x2e) referenced by () (std-):(symbol ZN4core3ptr175dropinplacestd..syscommon..remutex..ReentrantMutexGuardLTGTGT17h7737580f0f37fcd6E+0x20) referenced by () (std-):(symbol ZN4core3ptr46dropinplaceGT$17hf0f24132fd49ff9eE+0x43) referenced 7 more times error: undefined symbol: munmap referenced by () (std-):(symbol ZN4core3ptr65dropinplaceGT$17hf85f5ce9a3e31452E+0xce) referenced by () (std-):(symbol ZN4core3ptr65dropinplaceGT$17hf85f5ce9a3e31452E+0x31) referenced by () (std-):(symbol ZN4core3ptr68dropinplaceGT$17hc7e97f0fcf430b3cE+0x6) referenced 6 more times error: undefined symbol: pthreadrwlockunlock referenced by () (std-):(symbol ZN4core3ptr71dropinplaceLTRPGT$17hd1e2d6a084e6fddbE+0x33) referenced by () (std-):(symbol ZN4core3ptr71dropinplaceLTRPGT$17hd1e2d6a084e6fddbE+0x1a) referenced by () (std-):(symbol ZN3std3env7varos17h3777805ff41a36e7E+0xab) referenced 3 more times error: undefined symbol: pthreadmutexdestroy referenced by () (std-):(symbol ZN4core3ptr73dropinplaceGT$17hd8239a4ac87360b9E+0x6) referenced by () (std-):(symbol ZN4core3ptr98dropinplaceLTGT$17hb027e78f6c4c6db8E+0xd) referenced by () (std-):(symbol ZN5alloc4sync12ArcT9dropslow17h1dfce2778cdf5d36E+0x6f) referenced 1 more times error: undefined symbol: pthreadmutexattrdestroy referenced by () (std-):(symbol ZN4core3ptr75dropinplaceGT$17hca493304f47198a7E+0x6) referenced by () (std-):(symbol ZN108u20u20GT$4init17ha3b0898f5c42f4f6E+0xdc) error: undefined symbol: pthreadrwlockdestroy referenced by () (std-):(symbol ZN4core3ptr75dropinplaceGT$17h7c423d2bc244a6ffE+0x6) referenced by () (std-):(symbol ZN3std10syscommon8lazybox16LazyBoxT10initialize17h760b822df99198c6E+0x70) error: undefined symbol: memmove referenced by () (std-):(symbol ZN4core3ptr90dropinplaceLTGTGT$17hcdc9da9cacd190baE+0x36) referenced by () (std-):(symbol ZN9addr2line16ContextR11findframes17he44479834bec168fE+0x269f) referenced by () (std-):(symbol ZN9addr2line16ContextR11findframes17he44479834bec168fE+0x1223) referenced 18 more times error: undefined symbol: memcmp referenced by () (std-):(symbol ZN4core5slice4sort12choosepivot28u7bu7d17h1db2e1cfbb6463b0E+0x13e) referenced by () (std-):(symbol ZN4core5slice4sort12choosepivot28u7bu7d17h1db2e1cfbb6463b0E+0xda) referenced by () (std-):(symbol ZN4core5slice4sort12choosepivot28u7bu7d17h1db2e1cfbb6463b0E+0x5a) referenced 31 more times error: undefined symbol: pthreadmutextrylock referenced by () (std-):(symbol ZN5alloc4sync12ArcT9dropslow17h1dfce2778cdf5d36E+0x17) referenced by () (std-):(symbol ZN3std4sync4once4Once9callonce28u7bu7d17h9c07188eab35bf0eE+0x1c2) referenced by () (std-):(symbol ZN3std4sync4once4Once9callonce28u7bu7d17h9c07188eab35bf0eE+0x7f) error: undefined symbol: dispatchrelease referenced by () (std-):(symbol ZN5alloc4sync12ArcT9dropslow17ha7ab73c110de5a07E+0x31) error: undefined symbol: abort referenced by () (std-):(symbol ZN3std2rt19langstartinternal17hd56d2fa7efb2dd60E+0x570) referenced by () (std-):(symbol ZN3std3sys4unix14abortinternal17ha17a3eb079646e02E+0x5) error: undefined symbol: error referenced by () (std-):(symbol ZN3std2rt19langstartinternal17hd56d2fa7efb2dd60E+0x3a3) referenced by () (std-):(symbol ZN3std2rt19langstartinternal17hd56d2fa7efb2dd60E+0x334) referenced by () (std-):(symbol ZN3std2rt19langstartinternal17hd56d2fa7efb2dd60E+0xb5) referenced 19 more times error: undefined symbol: mprotect referenced by () (std-):(symbol ZN3std2rt19langstartinternal17hd56d2fa7efb2dd60E+0x256) referenced by () (std-):(symbol ZN3std3sys4unix14stackoverflow3imp12makehandler17h50336235e5e30f96E+0x85) error: too many errors emitted, stopping now (use --error-limit=0 to see all errors) </detailsOn Rust 1.66.0, it simply emits the (non-internal) error: , which makes sense. I imagine this would also happen on non-cross builds targeting macOS if isn't available and isn't set. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
label regression-from-stable-to-stable O-macos A-cross A-linkage
This is an issue with a buggy translation message: This should be , not .
This is fixed as part of
assign

invalid monomorphization of `{$name}` intrinsic: unsupported {$name} from `{$in_ty}` with element `{$elem_ty}` to `{$ret_ty}` codegen_gcc_invalid_monomorphization_invalid_bitmask = <del> invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]` </del> <ins> invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{$ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]` </ins> codegen_gcc_invalid_monomorphization_simd_shuffle = invalid monomorphization of `{$name}` intrinsic: simd_shuffle index must be an array of `u32`, got `{$ty}`


Question:
This occurs with binary crate that is able to target macOS and is most visible when cross compiling. is sufficient. The command produces the error on Linux machines, with or without . [ ] Previous Stable [X] Current Stable [X] Current Beta [X] Current Nightly I encountered this when cross compiling from Linux to macOS. Setting to some path that does exist but isn't a valid macOS SDK gives the expected linker errors of not-found libraries and undefined symbols. <details<summaryThe correct linker errors, which occur with (or any other path that exists) </summaryerror: linking with failed: exit status: 1 | = note: "" "-flavor" "darwin" "-arch" "x8664" "-platformversion" "macos" "10.7" "10.7" "/tmp/rustcmRdv6R/symbols.o" "/home/qyriad/code/hello/target/x8664-apple-darwin/debug/deps/hello-" "/home/qyriad/code/hello/target/x8664-apple-darwin/debug/deps/hello-" "/home/qyriad/code/hello/target/x8664-apple-darwin/debug/deps/hello-" "/home/qyriad/code/hello/target/x8664-apple-darwin/debug/deps/hello-" "/home/qyriad/code/hello/target/x8664-apple-darwin/debug/deps/hello-" "/home/qyriad/code/hello/target/x8664-apple-darwin/debug/deps/hello-" "/home/qyriad/code/hello/target/x8664-apple-darwin/debug/deps/hello-" "-L" "/home/qyriad/code/hello/target/x8664-apple-darwin/debug/deps" "-L" "/home/qyriad/code/hello/target/debug/deps" "-L" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "-lSystem" "-lc" "-lm" "-syslibroot" "/usr" "-L" "" "-o" "/home/qyriad/code/hello/target/x8664-apple-darwin/debug/deps/hello-" "-deadstrip" = note: error: library not found for -lSystem error: library not found for -lc error: library not found for -lm error: undefined symbol: UnwindResume referenced by () /home/qyriad/code/hello/target/x8664-apple-darwin/debug/deps/hello-(symbol ZN4core3ops8function6FnOnce9callonce17hf4bc1fd436eb6a1eE+0x1f) referenced by () (std-):(symbol ZN4core3ops8function6FnOnce40callonceu7bu7d$17hb84e30cb55012ce5E+0x80) referenced by () (std-):(symbol ZN4core3ptr104dropinplaceLTusizeRPGT$17hed3f267c6b45955bE+0xd1) referenced 89 more times error: undefined symbol: memcpy referenced by () (std-):(symbol ZN4core3fmt5Write10writechar17hdfc69d6746a59f51E+0xd4) referenced by () (std-):(symbol ZN50RFu20u20u2010writechar17h93a4c2621e683652E+0xe5) referenced by () (std-):(symbol ZN50RFu20u20u209writestr17h37febf5394bdf526E+0x38) referenced 82 more times error: undefined symbol: UnwindGetTextRelBase referenced by () (std-):(symbol ZN4core3ops8function6FnOnce40callonceu7bu7d$17h8d16de3fdc0c0a05E+0xc) referenced by () (std-):(symbol ZN3std11personality3gcc14findehaction28u7bu7d17hebef1726d888f975E+0xc) error: undefined symbol: UnwindGetDataRelBase referenced by () (std-):(symbol ZN4core3ops8function6FnOnce40callonceu7bu7d$17hb69dca3e57cf94bbE+0xc) referenced by () (std-):(symbol ZN3std11personality3gcc14findehaction28u7bu7d17hbca95bb609e12226E+0xc) error: undefined symbol: pthreadmutexunlock referenced by () (std-):(symbol ZN4core3ptr175dropinplacestd..syscommon..remutex..ReentrantMutexGuardLTGTGT17h7737580f0f37fcd6E+0x2e) referenced by () (std-):(symbol ZN4core3ptr175dropinplacestd..syscommon..remutex..ReentrantMutexGuardLTGTGT17h7737580f0f37fcd6E+0x20) referenced by () (std-):(symbol ZN4core3ptr46dropinplaceGT$17hf0f24132fd49ff9eE+0x43) referenced 7 more times error: undefined symbol: munmap referenced by () (std-):(symbol ZN4core3ptr65dropinplaceGT$17hf85f5ce9a3e31452E+0xce) referenced by () (std-):(symbol ZN4core3ptr65dropinplaceGT$17hf85f5ce9a3e31452E+0x31) referenced by () (std-):(symbol ZN4core3ptr68dropinplaceGT$17hc7e97f0fcf430b3cE+0x6) referenced 6 more times error: undefined symbol: pthreadrwlockunlock referenced by () (std-):(symbol ZN4core3ptr71dropinplaceLTRPGT$17hd1e2d6a084e6fddbE+0x33) referenced by () (std-):(symbol ZN4core3ptr71dropinplaceLTRPGT$17hd1e2d6a084e6fddbE+0x1a) referenced by () (std-):(symbol ZN3std3env7varos17h3777805ff41a36e7E+0xab) referenced 3 more times error: undefined symbol: pthreadmutexdestroy referenced by () (std-):(symbol ZN4core3ptr73dropinplaceGT$17hd8239a4ac87360b9E+0x6) referenced by () (std-):(symbol ZN4core3ptr98dropinplaceLTGT$17hb027e78f6c4c6db8E+0xd) referenced by () (std-):(symbol ZN5alloc4sync12ArcT9dropslow17h1dfce2778cdf5d36E+0x6f) referenced 1 more times error: undefined symbol: pthreadmutexattrdestroy referenced by () (std-):(symbol ZN4core3ptr75dropinplaceGT$17hca493304f47198a7E+0x6) referenced by () (std-):(symbol ZN108u20u20GT$4init17ha3b0898f5c42f4f6E+0xdc) error: undefined symbol: pthreadrwlockdestroy referenced by () (std-):(symbol ZN4core3ptr75dropinplaceGT$17h7c423d2bc244a6ffE+0x6) referenced by () (std-):(symbol ZN3std10syscommon8lazybox16LazyBoxT10initialize17h760b822df99198c6E+0x70) error: undefined symbol: memmove referenced by () (std-):(symbol ZN4core3ptr90dropinplaceLTGTGT$17hcdc9da9cacd190baE+0x36) referenced by () (std-):(symbol ZN9addr2line16ContextR11findframes17he44479834bec168fE+0x269f) referenced by () (std-):(symbol ZN9addr2line16ContextR11findframes17he44479834bec168fE+0x1223) referenced 18 more times error: undefined symbol: memcmp referenced by () (std-):(symbol ZN4core5slice4sort12choosepivot28u7bu7d17h1db2e1cfbb6463b0E+0x13e) referenced by () (std-):(symbol ZN4core5slice4sort12choosepivot28u7bu7d17h1db2e1cfbb6463b0E+0xda) referenced by () (std-):(symbol ZN4core5slice4sort12choosepivot28u7bu7d17h1db2e1cfbb6463b0E+0x5a) referenced 31 more times error: undefined symbol: pthreadmutextrylock referenced by () (std-):(symbol ZN5alloc4sync12ArcT9dropslow17h1dfce2778cdf5d36E+0x17) referenced by () (std-):(symbol ZN3std4sync4once4Once9callonce28u7bu7d17h9c07188eab35bf0eE+0x1c2) referenced by () (std-):(symbol ZN3std4sync4once4Once9callonce28u7bu7d17h9c07188eab35bf0eE+0x7f) error: undefined symbol: dispatchrelease referenced by () (std-):(symbol ZN5alloc4sync12ArcT9dropslow17ha7ab73c110de5a07E+0x31) error: undefined symbol: abort referenced by () (std-):(symbol ZN3std2rt19langstartinternal17hd56d2fa7efb2dd60E+0x570) referenced by () (std-):(symbol ZN3std3sys4unix14abortinternal17ha17a3eb079646e02E+0x5) error: undefined symbol: error referenced by () (std-):(symbol ZN3std2rt19langstartinternal17hd56d2fa7efb2dd60E+0x3a3) referenced by () (std-):(symbol ZN3std2rt19langstartinternal17hd56d2fa7efb2dd60E+0x334) referenced by () (std-):(symbol ZN3std2rt19langstartinternal17hd56d2fa7efb2dd60E+0xb5) referenced 19 more times error: undefined symbol: mprotect referenced by () (std-):(symbol ZN3std2rt19langstartinternal17hd56d2fa7efb2dd60E+0x256) referenced by () (std-):(symbol ZN3std3sys4unix14stackoverflow3imp12makehandler17h50336235e5e30f96E+0x85) error: too many errors emitted, stopping now (use --error-limit=0 to see all errors) </detailsOn Rust 1.66.0, it simply emits the (non-internal) error: , which makes sense. I imagine this would also happen on non-cross builds targeting macOS if isn't available and isn't set. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
label regression-from-stable-to-stable O-macos A-cross A-linkage
This is an issue with a buggy translation message: This should be , not .
This is fixed as part of
assign

codegen_ssa_unsupported_arch = unsupported arch `{$arch}` for os `{$os}` <del> codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {error} </del> <ins> codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {$error} </ins> <del> codegen_ssa_read_file = failed to read file: {message} </del> <ins> codegen_ssa_read_file = failed to read file: {$message} </ins> codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target