This isn't doing what you expect: it's getting the character after the `i + 1`th byte, where `i` is the *count* of the current character (i.e. not it's byte index, and so will break on an multibyte codepoints) and similarly the `char_at` above is wrong too. I think this loop could be written correctly as:

```rust
let last_was_underscore = false;
for c in ident.chars() {
    if last_was_underscore && !"_0123456789".contains_char(c) {
        return true;
    }
    last_was_underscore = c == '_';
}
false
```
(untested)

Also, this changes the behaviour to reject `_A`, where as that was ok previously.