Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Work around invalid spans in imported FileMaps #23489

Merged
merged 2 commits into from
Mar 20, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,12 +235,27 @@ impl<'a, 'b, 'tcx> DecodeContext<'a, 'b, 'tcx> {
pub fn tr_span(&self, span: Span) -> Span {
let imported_filemaps = &self.cdata.codemap_import_info[..];

let span = if span.lo > span.hi {
// Currently macro expansion sometimes produces invalid Span values
// where lo > hi. In order not to crash the compiler when trying to
// translate these values, let's transform them into something we
// can handle (and which will produce useful debug locations at
// least some of the time).
// This workaround is only necessary as long as macro expansion is
// not fixed. FIXME(#23480)
codemap::mk_sp(span.lo, span.lo)
} else {
span
};

let filemap_index = {
// Optimize for the case that most spans within a translated item
// originate from the same filemap.
let last_filemap_index = self.last_filemap_index.get();

if span.lo >= imported_filemaps[last_filemap_index].original_start_pos &&
span.lo <= imported_filemaps[last_filemap_index].original_end_pos &&
span.hi >= imported_filemaps[last_filemap_index].original_start_pos &&
span.hi <= imported_filemaps[last_filemap_index].original_end_pos {
last_filemap_index
} else {
Expand Down
30 changes: 30 additions & 0 deletions src/test/auxiliary/crate_with_invalid_spans.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![crate_type = "rlib"]
// no-prefer-dynamic

// compile-flags: -g

#[macro_use]
mod crate_with_invalid_spans_macros;

pub fn exported_generic<T>(x: T, y: u32) -> (T, u32) {
// Using the add1 macro will produce an invalid span, because the `y` passed
// to the macro will have a span from this file, but the rest of the code
// generated from the macro will have spans from the macro-defining file.
// The AST node for the (1 + y) expression generated by the macro will then
// take it's `lo` span bound from the `1` literal in the macro-defining file
// and it's `hi` bound from `y` in this file, which should be lower than the
// `lo` and even lower than the lower bound of the FileMap it is supposedly
// contained in because the FileMap for this file was allocated earlier than
// the FileMap of the macro-defining file.
return (x, add1!(y));
}
17 changes: 17 additions & 0 deletions src/test/auxiliary/crate_with_invalid_spans_macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

macro_rules! add1 {
($e:expr) => ({
let a = 1 + $e;
let b = $e + 1;
a + b - 1
})
}
20 changes: 20 additions & 0 deletions src/test/run-pass/import-crate-with-invalid-spans.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// aux-build:crate_with_invalid_spans.rs

extern crate crate_with_invalid_spans;

fn main() {
// The AST of `exported_generic` stored in crate_with_invalid_spans's
// metadata should contain an invalid span where span.lo > span.hi.
// Let's make sure the compiler doesn't crash when encountering this.
let _ = crate_with_invalid_spans::exported_generic(32u32, 7u32);
}