|
1 | 1 | use rustc_ast::ptr::P; |
2 | | -use rustc_ast::{token, Attribute, Item}; |
| 2 | +use rustc_ast::{token, Attribute, Inline, Item}; |
3 | 3 | use rustc_errors::{struct_span_err, PResult}; |
4 | 4 | use rustc_parse::new_parser_from_file; |
5 | 5 | use rustc_session::parse::ParseSess; |
@@ -103,25 +103,47 @@ crate fn push_directory( |
103 | 103 | id: Ident, |
104 | 104 | attrs: &[Attribute], |
105 | 105 | Directory { mut ownership, mut path }: Directory, |
| 106 | + inline: Inline, |
| 107 | + inner_span: Span, |
| 108 | + span: Span, // The span to blame on errors. |
106 | 109 | ) -> Directory { |
107 | | - if let Some(filename) = sess.first_attr_value_str_by_name(attrs, sym::path) { |
108 | | - path.push(&*filename.as_str()); |
109 | | - ownership = DirectoryOwnership::Owned { relative: None }; |
110 | | - } else { |
111 | | - // We have to push on the current module name in the case of relative |
112 | | - // paths in order to ensure that any additional module paths from inline |
113 | | - // `mod x { ... }` come after the relative extension. |
114 | | - // |
115 | | - // For example, a `mod z { ... }` inside `x/y.rs` should set the current |
116 | | - // directory path to `/x/y/z`, not `/x/z` with a relative offset of `y`. |
117 | | - if let DirectoryOwnership::Owned { relative } = &mut ownership { |
118 | | - if let Some(ident) = relative.take() { |
119 | | - // Remove the relative offset. |
120 | | - path.push(&*ident.as_str()); |
| 110 | + match inline { |
| 111 | + Inline::Yes => { |
| 112 | + if let Some(filename) = sess.first_attr_value_str_by_name(attrs, sym::path) { |
| 113 | + path.push(&*filename.as_str()); |
| 114 | + ownership = DirectoryOwnership::Owned { relative: None }; |
| 115 | + } else { |
| 116 | + // We have to push on the current module name in the case of relative |
| 117 | + // paths in order to ensure that any additional module paths from inline |
| 118 | + // `mod x { ... }` come after the relative extension. |
| 119 | + // |
| 120 | + // For example, a `mod z { ... }` inside `x/y.rs` should set the current |
| 121 | + // directory path to `/x/y/z`, not `/x/z` with a relative offset of `y`. |
| 122 | + if let DirectoryOwnership::Owned { relative } = &mut ownership { |
| 123 | + if let Some(ident) = relative.take() { |
| 124 | + // Remove the relative offset. |
| 125 | + path.push(&*ident.as_str()); |
| 126 | + } |
| 127 | + } |
| 128 | + path.push(&*id.as_str()); |
| 129 | + } |
| 130 | + } |
| 131 | + Inline::No => { |
| 132 | + // FIXME: This is a subset of `parse_external_mod` without actual parsing, |
| 133 | + // check whether the logic for unloaded, loaded and inline modules can be unified. |
| 134 | + if let Ok(mp) = submod_path(sess, id, span, &attrs, ownership, &path) { |
| 135 | + ownership = mp.ownership; |
121 | 136 | } |
| 137 | + |
| 138 | + // Extract the directory path for submodules of the module. |
| 139 | + path = match sess.source_map().span_to_unmapped_path(inner_span) { |
| 140 | + FileName::Real(name) => name.into_local_path(), |
| 141 | + other => PathBuf::from(other.to_string()), |
| 142 | + }; |
| 143 | + path.pop(); |
122 | 144 | } |
123 | | - path.push(&*id.as_str()); |
124 | 145 | } |
| 146 | + |
125 | 147 | Directory { ownership, path } |
126 | 148 | } |
127 | 149 |
|
|
0 commit comments