Skip to content

Commit 1a3cdd3

Browse files
committed
Auto merge of rust-lang#147377 - karolzwolak:dont-create-empty-ident-issue-147365, r=nnethercote
don't make empty ident when printing `'` ident from `extern "'"` Fixes rust-lang#147365. r? `@nnethercote`
2 parents 828c2a9 + 5234d36 commit 1a3cdd3

File tree

3 files changed

+40
-7
lines changed

3 files changed

+40
-7
lines changed

compiler/rustc_span/src/symbol.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2464,9 +2464,10 @@ pub const STDLIB_STABLE_CRATES: &[Symbol] = &[sym::std, sym::core, sym::alloc, s
24642464

24652465
#[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
24662466
pub struct Ident {
2467-
// `name` should never be the empty symbol. If you are considering that,
2468-
// you are probably conflating "empty identifier with "no identifier" and
2469-
// you should use `Option<Ident>` instead.
2467+
/// `name` should never be the empty symbol. If you are considering that,
2468+
/// you are probably conflating "empty identifier with "no identifier" and
2469+
/// you should use `Option<Ident>` instead.
2470+
/// Trying to construct an `Ident` with an empty name will trigger debug assertions.
24702471
pub name: Symbol,
24712472
pub span: Span,
24722473
}
@@ -2509,6 +2510,8 @@ impl Ident {
25092510
Ident::new(self.name, span.with_ctxt(self.span.ctxt()))
25102511
}
25112512

2513+
/// Creates a new ident with the same span and name with leading quote removed, if any.
2514+
/// If called on an empty ident, or with name just a single quote, returns an empty ident which is invalid.
25122515
pub fn without_first_quote(self) -> Ident {
25132516
Ident::new(Symbol::intern(self.as_str().trim_start_matches('\'')), self.span)
25142517
}
@@ -3096,10 +3099,15 @@ impl Ident {
30963099
}
30973100

30983101
pub fn is_raw_lifetime_guess(self) -> bool {
3099-
let name_without_apostrophe = self.without_first_quote();
3100-
name_without_apostrophe.name != self.name
3101-
&& name_without_apostrophe.name.can_be_raw()
3102-
&& name_without_apostrophe.is_reserved_lifetime()
3102+
// Check that the name isn't just a single quote.
3103+
// `self.without_first_quote()` would return empty ident, which triggers debug assert.
3104+
if self.name.as_str() == "'" {
3105+
return false;
3106+
}
3107+
let ident_without_apostrophe = self.without_first_quote();
3108+
ident_without_apostrophe.name != self.name
3109+
&& ident_without_apostrophe.name.can_be_raw()
3110+
&& ident_without_apostrophe.is_reserved_lifetime()
31033111
}
31043112

31053113
pub fn guess_print_mode(self) -> IdentPrintMode {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//@ needs-rustc-debug-assertions
2+
3+
// https://github.com/rust-lang/rust/issues/147365
4+
// Ensures we don't trigger debug assert by creating an empty Ident when determining whether
5+
// the single quote is a raw lifetime.
6+
7+
extern "'" {} //~ ERROR invalid ABI: found `'`
8+
9+
fn main() {}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0703]: invalid ABI: found `'`
2+
--> $DIR/extern-single-quote-issue-147365.rs:7:8
3+
|
4+
LL | extern "'" {}
5+
| ^^^ invalid ABI
6+
|
7+
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
8+
help: there's a similarly named valid ABI `C`
9+
|
10+
LL - extern "'" {}
11+
LL + extern "C" {}
12+
|
13+
14+
error: aborting due to 1 previous error
15+
16+
For more information about this error, try `rustc --explain E0703`.

0 commit comments

Comments
 (0)