diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index 98225d10400..ea27ed6b360 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -17,7 +17,7 @@
 //! within the CodeMap, which upon request can be converted to line and column
 //! information, source code snippets, etc.
 
-pub use self::MacroFormat::*;
+pub use self::ExpnFormat::*;
 
 use std::cell::RefCell;
 use std::ops::{Add, Sub};
@@ -228,17 +228,17 @@ pub struct FileMapAndBytePos { pub fm: Rc<FileMap>, pub pos: BytePos }
 
 
 // _____________________________________________________________________________
-// MacroFormat, NameAndSpan, ExpnInfo, ExpnId
+// ExpnFormat, NameAndSpan, ExpnInfo, ExpnId
 //
 
-/// The syntax with which a macro was invoked.
-#[derive(Clone, Copy, Hash, Debug)]
-pub enum MacroFormat {
+/// The source of expansion.
+#[derive(Clone, Copy, Hash, Debug, PartialEq, Eq)]
+pub enum ExpnFormat {
     /// e.g. #[derive(...)] <item>
     MacroAttribute,
     /// e.g. `format!()`
     MacroBang,
-    /// Expansion performed by the compiler (libsyntax::expand).
+    /// Syntax sugar expansion performed by the compiler (libsyntax::expand).
     CompilerExpansion,
 }
 
@@ -248,7 +248,7 @@ pub struct NameAndSpan {
     /// with this Span.
     pub name: String,
     /// The format with which the macro was invoked.
-    pub format: MacroFormat,
+    pub format: ExpnFormat,
     /// Whether the macro is allowed to use #[unstable]/feature-gated
     /// features internally without forcing the whole crate to opt-in
     /// to them.
@@ -259,11 +259,11 @@ pub struct NameAndSpan {
     pub span: Option<Span>
 }
 
-/// Extra information for tracking macro expansion of spans
+/// Extra information for tracking spans of macro and syntax sugar expansion
 #[derive(Hash, Debug)]
 pub struct ExpnInfo {
-    /// The location of the actual macro invocation, e.g. `let x =
-    /// foo!();`
+    /// The location of the actual macro invocation or syntax sugar , e.g.
+    /// `let x = foo!();` or `if let Some(y) = x {}`
     ///
     /// This may recursively refer to other macro invocations, e.g. if
     /// `foo!()` invoked `bar!()` internally, and there was an
@@ -272,12 +272,7 @@ pub struct ExpnInfo {
     /// call_site span would have its own ExpnInfo, with the call_site
     /// pointing to the `foo!` invocation.
     pub call_site: Span,
-    /// Information about the macro and its definition.
-    ///
-    /// The `callee` of the inner expression in the `call_site`
-    /// example would point to the `macro_rules! bar { ... }` and that
-    /// of the `bar!()` invocation would point to the `macro_rules!
-    /// foo { ... }`.
+    /// Information about the expansion.
     pub callee: NameAndSpan
 }
 
@@ -677,7 +672,39 @@ impl CodeMap {
 
     /// Lookup source information about a BytePos
     pub fn lookup_char_pos(&self, pos: BytePos) -> Loc {
-        self.lookup_pos(pos)
+        let FileMapAndLine {fm: f, line: a} = self.lookup_line(pos);
+        let line = a + 1; // Line numbers start at 1
+        let chpos = self.bytepos_to_file_charpos(pos);
+        let linebpos = (*f.lines.borrow())[a];
+        let linechpos = self.bytepos_to_file_charpos(linebpos);
+        debug!("byte pos {:?} is on the line at byte pos {:?}",
+               pos, linebpos);
+        debug!("char pos {:?} is on the line at char pos {:?}",
+               chpos, linechpos);
+        debug!("byte is on line: {}", line);
+        assert!(chpos >= linechpos);
+        Loc {
+            file: f,
+            line: line,
+            col: chpos - linechpos
+        }
+    }
+
+    fn lookup_line(&self, pos: BytePos) -> FileMapAndLine {
+        let idx = self.lookup_filemap_idx(pos);
+
+        let files = self.files.borrow();
+        let f = (*files)[idx].clone();
+        let mut a = 0;
+        {
+            let lines = f.lines.borrow();
+            let mut b = lines.len();
+            while b - a > 1 {
+                let m = (a + b) / 2;
+                if (*lines)[m] > pos { b = m; } else { a = m; }
+            }
+        }
+        FileMapAndLine {fm: f, line: a}
     }
 
     pub fn lookup_char_pos_adj(&self, pos: BytePos) -> LocWithOpt {
@@ -877,42 +904,6 @@ impl CodeMap {
         return a;
     }
 
-    fn lookup_line(&self, pos: BytePos) -> FileMapAndLine {
-        let idx = self.lookup_filemap_idx(pos);
-
-        let files = self.files.borrow();
-        let f = (*files)[idx].clone();
-        let mut a = 0;
-        {
-            let lines = f.lines.borrow();
-            let mut b = lines.len();
-            while b - a > 1 {
-                let m = (a + b) / 2;
-                if (*lines)[m] > pos { b = m; } else { a = m; }
-            }
-        }
-        FileMapAndLine {fm: f, line: a}
-    }
-
-    fn lookup_pos(&self, pos: BytePos) -> Loc {
-        let FileMapAndLine {fm: f, line: a} = self.lookup_line(pos);
-        let line = a + 1; // Line numbers start at 1
-        let chpos = self.bytepos_to_file_charpos(pos);
-        let linebpos = (*f.lines.borrow())[a];
-        let linechpos = self.bytepos_to_file_charpos(linebpos);
-        debug!("byte pos {:?} is on the line at byte pos {:?}",
-               pos, linebpos);
-        debug!("char pos {:?} is on the line at char pos {:?}",
-               chpos, linechpos);
-        debug!("byte is on line: {}", line);
-        assert!(chpos >= linechpos);
-        Loc {
-            file: f,
-            line: line,
-            col: chpos - linechpos
-        }
-    }
-
     pub fn record_expansion(&self, expn_info: ExpnInfo) -> ExpnId {
         let mut expansions = self.expansions.borrow_mut();
         expansions.push(expn_info);
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index c2ed3583835..499562edc0c 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -13,7 +13,7 @@ pub use self::SyntaxExtension::*;
 use ast;
 use ast::Name;
 use codemap;
-use codemap::{CodeMap, Span, ExpnId, ExpnInfo, NO_EXPANSION};
+use codemap::{CodeMap, Span, ExpnId, ExpnInfo, NO_EXPANSION, CompilerExpansion};
 use ext;
 use ext::expand;
 use ext::tt::macro_rules;
@@ -658,6 +658,8 @@ impl<'a> ExtCtxt<'a> {
         })
     }
     pub fn backtrace(&self) -> ExpnId { self.backtrace }
+
+    /// Original span that caused the current exapnsion to happen.
     pub fn original_span(&self) -> Span {
         let mut expn_id = self.backtrace;
         let mut call_site = None;
@@ -672,26 +674,31 @@ impl<'a> ExtCtxt<'a> {
         }
         call_site.expect("missing expansion backtrace")
     }
-    pub fn original_span_in_file(&self) -> Span {
+
+    /// Returns span for the macro which originally caused the current expansion to happen.
+    ///
+    /// Stops backtracing at include! boundary.
+    pub fn expansion_cause(&self) -> Span {
         let mut expn_id = self.backtrace;
-        let mut call_site = None;
+        let mut last_macro = None;
         loop {
-            let expn_info = self.codemap().with_expn_info(expn_id, |ei| {
-                ei.map(|ei| (ei.call_site, ei.callee.name == "include"))
-            });
-            match expn_info {
-                None => break,
-                Some((cs, is_include)) => {
-                    if is_include {
-                        // Don't recurse into file using "include!".
-                        break;
+            if self.codemap().with_expn_info(expn_id, |info| {
+                info.map_or(None, |i| {
+                    if i.callee.name == "include" {
+                        // Stop going up the backtrace once include! is encountered
+                        return None;
                     }
-                    call_site = Some(cs);
-                    expn_id = cs.expn_id;
-                }
+                    expn_id = i.call_site.expn_id;
+                    if i.callee.format != CompilerExpansion {
+                        last_macro = Some(i.call_site)
+                    }
+                    return Some(());
+                })
+            }).is_none() {
+                break
             }
         }
-        call_site.expect("missing expansion backtrace")
+        last_macro.expect("missing expansion backtrace")
     }
 
     pub fn mod_push(&mut self, i: ast::Ident) { self.mod_path.push(i); }
diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs
index 08bb4ca1064..3866f5534c2 100644
--- a/src/libsyntax/ext/source_util.rs
+++ b/src/libsyntax/ext/source_util.rs
@@ -34,7 +34,7 @@ pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                    -> Box<base::MacResult+'static> {
     base::check_zero_tts(cx, sp, tts, "line!");
 
-    let topmost = cx.original_span_in_file();
+    let topmost = cx.expansion_cause();
     let loc = cx.codemap().lookup_char_pos(topmost.lo);
 
     base::MacEager::expr(cx.expr_u32(topmost, loc.line as u32))
@@ -45,7 +45,7 @@ pub fn expand_column(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                   -> Box<base::MacResult+'static> {
     base::check_zero_tts(cx, sp, tts, "column!");
 
-    let topmost = cx.original_span_in_file();
+    let topmost = cx.expansion_cause();
     let loc = cx.codemap().lookup_char_pos(topmost.lo);
 
     base::MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32))
@@ -58,7 +58,7 @@ pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                    -> Box<base::MacResult+'static> {
     base::check_zero_tts(cx, sp, tts, "file!");
 
-    let topmost = cx.original_span_in_file();
+    let topmost = cx.expansion_cause();
     let loc = cx.codemap().lookup_char_pos(topmost.lo);
     let filename = token::intern_and_get_ident(&loc.file.name);
     base::MacEager::expr(cx.expr_str(topmost, filename))
diff --git a/src/test/run-pass/issue-26322.rs b/src/test/run-pass/issue-26322.rs
new file mode 100644
index 00000000000..766d1ce25d1
--- /dev/null
+++ b/src/test/run-pass/issue-26322.rs
@@ -0,0 +1,36 @@
+// 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! columnline {
+    () => (
+        (column!(), line!())
+    )
+}
+
+macro_rules! indirectcolumnline {
+    () => (
+        (||{ columnline!() })()
+    )
+}
+
+fn main() {
+    let closure = || {
+        columnline!()
+    };
+    let iflet = if let Some(_) = Some(0) {
+        columnline!()
+    } else { (0, 0) };
+    let cl = columnline!();
+    assert_eq!(closure(), (8, 25));
+    assert_eq!(iflet, (8, 28));
+    assert_eq!(cl, (13, 30));
+    let indirect = indirectcolumnline!();
+    assert_eq!(indirect, (19, 34));
+}