|
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