@@ -294,15 +294,40 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
294294 let prefix_span = self . mk_sp ( start, ident_start) ;
295295
296296 if prefix_span. at_least_rust_2021 ( ) {
297+ // If the raw lifetime is followed by \' then treat it a normal
298+ // lifetime followed by a \', which is to interpret it as a character
299+ // literal. In this case, it's always an invalid character literal
300+ // since the literal must necessarily have >3 characters (r#...) inside
301+ // of it, which is invalid.
302+ if self . cursor . as_str ( ) . starts_with ( '\'' ) {
303+ let lit_span = self . mk_sp ( start, self . pos + BytePos ( 1 ) ) ;
304+ let contents = self . str_from_to ( start + BytePos ( 1 ) , self . pos ) ;
305+ emit_unescape_error (
306+ self . dcx ( ) ,
307+ contents,
308+ lit_span,
309+ lit_span,
310+ Mode :: Char ,
311+ 0 ..contents. len ( ) ,
312+ EscapeError :: MoreThanOneChar ,
313+ )
314+ . expect ( "expected error" ) ;
315+ }
316+
297317 let span = self . mk_sp ( start, self . pos ) ;
298318
299- let lifetime_name_without_tick = Symbol :: intern ( & self . str_from ( ident_start) ) ;
319+ let lifetime_name_without_tick =
320+ Symbol :: intern ( & self . str_from ( ident_start) ) ;
300321 if !lifetime_name_without_tick. can_be_raw ( ) {
301- self . dcx ( ) . emit_err ( errors:: CannotBeRawLifetime { span, ident : lifetime_name_without_tick } ) ;
322+ self . dcx ( ) . emit_err ( errors:: CannotBeRawLifetime {
323+ span,
324+ ident : lifetime_name_without_tick,
325+ } ) ;
302326 }
303327
304328 // Put the `'` back onto the lifetime name.
305- let mut lifetime_name = String :: with_capacity ( lifetime_name_without_tick. as_str ( ) . len ( ) + 1 ) ;
329+ let mut lifetime_name =
330+ String :: with_capacity ( lifetime_name_without_tick. as_str ( ) . len ( ) + 1 ) ;
306331 lifetime_name. push ( '\'' ) ;
307332 lifetime_name += lifetime_name_without_tick. as_str ( ) ;
308333 let sym = Symbol :: intern ( & lifetime_name) ;
@@ -358,8 +383,7 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
358383 rustc_lexer:: TokenKind :: Caret => token:: BinOp ( token:: Caret ) ,
359384 rustc_lexer:: TokenKind :: Percent => token:: BinOp ( token:: Percent ) ,
360385
361- rustc_lexer:: TokenKind :: Unknown
362- | rustc_lexer:: TokenKind :: InvalidIdent => {
386+ rustc_lexer:: TokenKind :: Unknown | rustc_lexer:: TokenKind :: InvalidIdent => {
363387 // Don't emit diagnostics for sequences of the same invalid token
364388 if swallow_next_invalid > 0 {
365389 swallow_next_invalid -= 1 ;
0 commit comments