From 0b713ae919705bfbc2ec5bf5eea74570f7ecc19a Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 13 Aug 2019 23:54:20 +0200 Subject: [PATCH 01/35] typeck: extract ban_private_field_access --- src/librustc_typeck/check/expr.rs | 50 ++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 9680f61d6990..b4154c15d673 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -24,6 +24,7 @@ use syntax::source_map::Span; use syntax::util::lev_distance::find_best_match_for_name; use rustc::hir; use rustc::hir::{ExprKind, QPath}; +use rustc::hir::def_id::DefId; use rustc::hir::def::{CtorKind, Res, DefKind}; use rustc::hir::ptr::P; use rustc::infer; @@ -1336,23 +1337,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { autoderef.unambiguous_final_ty(self); if let Some((did, field_ty)) = private_candidate { - let struct_path = self.tcx().def_path_str(did); - let mut err = struct_span_err!(self.tcx().sess, expr.span, E0616, - "field `{}` of struct `{}` is private", - field, struct_path); - // Also check if an accessible method exists, which is often what is meant. - if self.method_exists(field, expr_t, expr.hir_id, false) - && !self.expr_in_place(expr.hir_id) - { - self.suggest_method_call( - &mut err, - &format!("a method `{}` also exists, call it with parentheses", field), - field, - expr_t, - expr.hir_id, - ); - } - err.emit(); + self.ban_private_field_access(expr, expr_t, field, did); field_ty } else if field.name == kw::Invalid { self.tcx().types.err @@ -1446,6 +1431,37 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + fn ban_private_field_access( + &self, + expr: &'tcx hir::Expr, + expr_t: Ty<'tcx>, + field: ast::Ident, + def_id: DefId, + ) { + let struct_path = self.tcx().def_path_str(def_id); + let mut err = struct_span_err!( + self.tcx().sess, + expr.span, + E0616, + "field `{}` of struct `{}` is private", + field, + struct_path + ); + // Also check if an accessible method exists, which is often what is meant. + if self.method_exists(field, expr_t, expr.hir_id, false) + && !self.expr_in_place(expr.hir_id) + { + self.suggest_method_call( + &mut err, + &format!("a method `{}` also exists, call it with parentheses", field), + field, + expr_t, + expr.hir_id, + ); + } + err.emit(); + } + fn no_such_field_err(&self, span: Span, field: T, expr_t: &ty::TyS<'_>) -> DiagnosticBuilder<'_> { type_error_struct!(self.tcx().sess, span, expr_t, E0609, From 5e019def0d8c277ef7b82d9348350ed1fc8747db Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 13 Aug 2019 23:59:22 +0200 Subject: [PATCH 02/35] typeck: extract ban_take_value_of_method --- src/librustc_typeck/check/expr.rs | 48 +++++++++++++++++++------------ 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index b4154c15d673..c25a60d065d6 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -1342,23 +1342,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else if field.name == kw::Invalid { self.tcx().types.err } else if self.method_exists(field, expr_t, expr.hir_id, true) { - let mut err = type_error_struct!(self.tcx().sess, field.span, expr_t, E0615, - "attempted to take value of method `{}` on type `{}`", - field, expr_t); - - if !self.expr_in_place(expr.hir_id) { - self.suggest_method_call( - &mut err, - "use parentheses to call the method", - field, - expr_t, - expr.hir_id - ); - } else { - err.help("methods are immutable and cannot be assigned to"); - } - - err.emit(); + self.ban_take_value_of_method(expr, expr_t, field); self.tcx().types.err } else { if !expr_t.is_primitive_ty() { @@ -1436,9 +1420,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &'tcx hir::Expr, expr_t: Ty<'tcx>, field: ast::Ident, - def_id: DefId, + base_did: DefId, ) { - let struct_path = self.tcx().def_path_str(def_id); + let struct_path = self.tcx().def_path_str(base_did); let mut err = struct_span_err!( self.tcx().sess, expr.span, @@ -1462,6 +1446,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.emit(); } + fn ban_take_value_of_method(&self, expr: &'tcx hir::Expr, expr_t: Ty<'tcx>, field: ast::Ident) { + let mut err = type_error_struct!( + self.tcx().sess, + field.span, + expr_t, + E0615, + "attempted to take value of method `{}` on type `{}`", + field, + expr_t + ); + + if !self.expr_in_place(expr.hir_id) { + self.suggest_method_call( + &mut err, + "use parentheses to call the method", + field, + expr_t, + expr.hir_id + ); + } else { + err.help("methods are immutable and cannot be assigned to"); + } + + err.emit(); + } + fn no_such_field_err(&self, span: Span, field: T, expr_t: &ty::TyS<'_>) -> DiagnosticBuilder<'_> { type_error_struct!(self.tcx().sess, span, expr_t, E0609, From 98058468815a62be36875ed0e990bbcbcd4a42b4 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 14 Aug 2019 00:30:06 +0200 Subject: [PATCH 03/35] typeck: extract maybe_suggest_array_indexing --- src/librustc_typeck/check/expr.rs | 50 ++++++++++++++++++------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index c25a60d065d6..20a47441375b 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -1370,25 +1370,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; } ty::Array(_, len) => { - if let (Some(len), Ok(user_index)) = ( - len.try_eval_usize(self.tcx, self.param_env), - field.as_str().parse::() - ) { - let base = self.tcx.sess.source_map() - .span_to_snippet(base.span) - .unwrap_or_else(|_| - self.tcx.hir().hir_to_pretty_string(base.hir_id)); - let help = "instead of using tuple indexing, use array indexing"; - let suggestion = format!("{}[{}]", base, field); - let applicability = if len < user_index { - Applicability::MachineApplicable - } else { - Applicability::MaybeIncorrect - }; - err.span_suggestion( - expr.span, help, suggestion, applicability - ); - } + self.maybe_suggest_array_indexing(&mut err, expr, base, field, len); } ty::RawPtr(..) => { let base = self.tcx.sess.source_map() @@ -1417,7 +1399,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn ban_private_field_access( &self, - expr: &'tcx hir::Expr, + expr: &hir::Expr, expr_t: Ty<'tcx>, field: ast::Ident, base_did: DefId, @@ -1446,7 +1428,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.emit(); } - fn ban_take_value_of_method(&self, expr: &'tcx hir::Expr, expr_t: Ty<'tcx>, field: ast::Ident) { + fn ban_take_value_of_method(&self, expr: &hir::Expr, expr_t: Ty<'tcx>, field: ast::Ident) { let mut err = type_error_struct!( self.tcx().sess, field.span, @@ -1472,6 +1454,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.emit(); } + fn maybe_suggest_array_indexing( + &self, + err: &mut DiagnosticBuilder<'_>, + expr: &hir::Expr, + base: &hir::Expr, + field: ast::Ident, + len: &ty::Const<'tcx>, + ) { + if let (Some(len), Ok(user_index)) = ( + len.try_eval_usize(self.tcx, self.param_env), + field.as_str().parse::() + ) { + let base = self.tcx.sess.source_map() + .span_to_snippet(base.span) + .unwrap_or_else(|_| self.tcx.hir().hir_to_pretty_string(base.hir_id)); + let help = "instead of using tuple indexing, use array indexing"; + let suggestion = format!("{}[{}]", base, field); + let applicability = if len < user_index { + Applicability::MachineApplicable + } else { + Applicability::MaybeIncorrect + }; + err.span_suggestion(expr.span, help, suggestion, applicability); + } + } + fn no_such_field_err(&self, span: Span, field: T, expr_t: &ty::TyS<'_>) -> DiagnosticBuilder<'_> { type_error_struct!(self.tcx().sess, span, expr_t, E0609, From 039c78932564c38c79f08745ab6e02bceb1eb468 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 14 Aug 2019 00:31:08 +0200 Subject: [PATCH 04/35] typeck: extract suggest_first_deref_field --- src/librustc_typeck/check/expr.rs | 32 ++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 20a47441375b..2b696613c8b5 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -1373,17 +1373,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.maybe_suggest_array_indexing(&mut err, expr, base, field, len); } ty::RawPtr(..) => { - let base = self.tcx.sess.source_map() - .span_to_snippet(base.span) - .unwrap_or_else(|_| self.tcx.hir().hir_to_pretty_string(base.hir_id)); - let msg = format!("`{}` is a raw pointer; try dereferencing it", base); - let suggestion = format!("(*{}).{}", base, field); - err.span_suggestion( - expr.span, - &msg, - suggestion, - Applicability::MaybeIncorrect, - ); + self.suggest_first_deref_field(&mut err, expr, base, field); } _ => {} } @@ -1480,6 +1470,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + fn suggest_first_deref_field( + &self, + err: &mut DiagnosticBuilder<'_>, + expr: &hir::Expr, + base: &hir::Expr, + field: ast::Ident, + ) { + let base = self.tcx.sess.source_map() + .span_to_snippet(base.span) + .unwrap_or_else(|_| self.tcx.hir().hir_to_pretty_string(base.hir_id)); + let msg = format!("`{}` is a raw pointer; try dereferencing it", base); + let suggestion = format!("(*{}).{}", base, field); + err.span_suggestion( + expr.span, + &msg, + suggestion, + Applicability::MaybeIncorrect, + ); + } + fn no_such_field_err(&self, span: Span, field: T, expr_t: &ty::TyS<'_>) -> DiagnosticBuilder<'_> { type_error_struct!(self.tcx().sess, span, expr_t, E0609, From 01e96dc5832b85f87acb1a651e33d12ac9b37cc5 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 14 Aug 2019 00:40:44 +0200 Subject: [PATCH 05/35] typeck: extract suggest_fields_on_recordish --- src/librustc_typeck/check/expr.rs | 45 ++++++++++++++++++------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 2b696613c8b5..e4582424d0fc 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -1350,24 +1350,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match expr_t.sty { ty::Adt(def, _) if !def.is_enum() => { - if let Some(suggested_field_name) = - Self::suggest_field_name(def.non_enum_variant(), - &field.as_str(), vec![]) { - err.span_suggestion( - field.span, - "a field with a similar name exists", - suggested_field_name.to_string(), - Applicability::MaybeIncorrect, - ); - } else { - err.span_label(field.span, "unknown field"); - let struct_variant_def = def.non_enum_variant(); - let field_names = self.available_field_names(struct_variant_def); - if !field_names.is_empty() { - err.note(&format!("available fields are: {}", - self.name_series_display(field_names))); - } - }; + self.suggest_fields_on_recordish(&mut err, def, field); } ty::Array(_, len) => { self.maybe_suggest_array_indexing(&mut err, expr, base, field, len); @@ -1444,6 +1427,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.emit(); } + fn suggest_fields_on_recordish( + &self, + err: &mut DiagnosticBuilder<'_>, + def: &'tcx ty::AdtDef, + field: ast::Ident, + ) { + if let Some(suggested_field_name) = + Self::suggest_field_name(def.non_enum_variant(), &field.as_str(), vec![]) + { + err.span_suggestion( + field.span, + "a field with a similar name exists", + suggested_field_name.to_string(), + Applicability::MaybeIncorrect, + ); + } else { + err.span_label(field.span, "unknown field"); + let struct_variant_def = def.non_enum_variant(); + let field_names = self.available_field_names(struct_variant_def); + if !field_names.is_empty() { + err.note(&format!("available fields are: {}", + self.name_series_display(field_names))); + } + } + } + fn maybe_suggest_array_indexing( &self, err: &mut DiagnosticBuilder<'_>, From 07414417c58cf9e1ad1d75730007c683bd7dfae7 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 14 Aug 2019 00:50:39 +0200 Subject: [PATCH 06/35] typeck: restructure check_field a bit --- src/librustc_typeck/check/expr.rs | 56 +++++++++++++++++-------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index e4582424d0fc..57e82714150e 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -1338,36 +1338,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some((did, field_ty)) = private_candidate { self.ban_private_field_access(expr, expr_t, field, did); - field_ty - } else if field.name == kw::Invalid { - self.tcx().types.err + return field_ty; + } + + if field.name == kw::Invalid { } else if self.method_exists(field, expr_t, expr.hir_id, true) { self.ban_take_value_of_method(expr, expr_t, field); - self.tcx().types.err - } else { - if !expr_t.is_primitive_ty() { - let mut err = self.no_such_field_err(field.span, field, expr_t); + } else if !expr_t.is_primitive_ty() { + let mut err = self.no_such_field_err(field.span, field, expr_t); - match expr_t.sty { - ty::Adt(def, _) if !def.is_enum() => { - self.suggest_fields_on_recordish(&mut err, def, field); - } - ty::Array(_, len) => { - self.maybe_suggest_array_indexing(&mut err, expr, base, field, len); - } - ty::RawPtr(..) => { - self.suggest_first_deref_field(&mut err, expr, base, field); - } - _ => {} + match expr_t.sty { + ty::Adt(def, _) if !def.is_enum() => { + self.suggest_fields_on_recordish(&mut err, def, field); } - err - } else { - type_error_struct!(self.tcx().sess, field.span, expr_t, E0610, - "`{}` is a primitive type and therefore doesn't have fields", - expr_t) - }.emit(); - self.tcx().types.err + ty::Array(_, len) => { + self.maybe_suggest_array_indexing(&mut err, expr, base, field, len); + } + ty::RawPtr(..) => { + self.suggest_first_deref_field(&mut err, expr, base, field); + } + _ => {} + } + + err.emit(); + } else { + type_error_struct!( + self.tcx().sess, + field.span, + expr_t, + E0610, + "`{}` is a primitive type and therefore doesn't have fields", + expr_t + ) + .emit(); } + + self.tcx().types.err } fn ban_private_field_access( From 88398a429c04ac915fbd314da22c6dc813c275c9 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 14 Aug 2019 01:51:41 +0200 Subject: [PATCH 07/35] typeck: on wrong .await suggest -> 2018 --- src/librustc_typeck/check/expr.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 57e82714150e..d139cd4264c8 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -1360,6 +1360,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => {} } + if field.name == kw::Await { + // We know by construction that `.await` is either on Rust 2015 + // or results in `ExprKind::Await`. Suggest switching the edition to 2018. + err.note("to `.await` a `Future`, switch to Rust 2018"); + err.help("set `edition = \"2018\"` in `Cargo.toml`"); + err.note("for more on editions, read https://doc.rust-lang.org/edition-guide"); + } + err.emit(); } else { type_error_struct!( From 9287eb647f7168a65950965044bd5e22d1b05faf Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 14 Aug 2019 01:52:16 +0200 Subject: [PATCH 08/35] typeck: add tests for suggesting -> 2018 on wrong .await --- .../suggest-switching-edition-on-await.rs | 45 +++++++++++++++++++ .../suggest-switching-edition-on-await.stderr | 43 ++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 src/test/ui/async-await/suggest-switching-edition-on-await.rs create mode 100644 src/test/ui/async-await/suggest-switching-edition-on-await.stderr diff --git a/src/test/ui/async-await/suggest-switching-edition-on-await.rs b/src/test/ui/async-await/suggest-switching-edition-on-await.rs new file mode 100644 index 000000000000..1402f1ca92ba --- /dev/null +++ b/src/test/ui/async-await/suggest-switching-edition-on-await.rs @@ -0,0 +1,45 @@ +use std::pin::Pin; +use std::future::Future; + +fn main() {} + +fn await_on_struct_missing() { + struct S; + let x = S; + x.await; + //~^ ERROR no field `await` on type + //~| NOTE unknown field + //~| NOTE to `.await` a `Future`, switch to Rust 2018 + //~| HELP set `edition = "2018"` in `Cargo.toml` + //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide +} + +fn await_on_struct_similar() { + struct S { + awai: u8, + } + let x = S { awai: 42 }; + x.await; + //~^ ERROR no field `await` on type + //~| HELP a field with a similar name exists + //~| NOTE to `.await` a `Future`, switch to Rust 2018 + //~| HELP set `edition = "2018"` in `Cargo.toml` + //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide +} + +fn await_on_63533(x: Pin<&mut dyn Future>) { + x.await; + //~^ ERROR no field `await` on type + //~| NOTE unknown field + //~| NOTE to `.await` a `Future`, switch to Rust 2018 + //~| HELP set `edition = "2018"` in `Cargo.toml` + //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide +} + +fn await_on_apit(x: impl Future) { + x.await; + //~^ ERROR no field `await` on type + //~| NOTE to `.await` a `Future`, switch to Rust 2018 + //~| HELP set `edition = "2018"` in `Cargo.toml` + //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide +} diff --git a/src/test/ui/async-await/suggest-switching-edition-on-await.stderr b/src/test/ui/async-await/suggest-switching-edition-on-await.stderr new file mode 100644 index 000000000000..f623511c0eb2 --- /dev/null +++ b/src/test/ui/async-await/suggest-switching-edition-on-await.stderr @@ -0,0 +1,43 @@ +error[E0609]: no field `await` on type `await_on_struct_missing::S` + --> $DIR/suggest-switching-edition-on-await.rs:9:7 + | +LL | x.await; + | ^^^^^ unknown field + | + = note: to `.await` a `Future`, switch to Rust 2018 + = help: set `edition = "2018"` in `Cargo.toml` + = note: for more on editions, read https://doc.rust-lang.org/edition-guide + +error[E0609]: no field `await` on type `await_on_struct_similar::S` + --> $DIR/suggest-switching-edition-on-await.rs:22:7 + | +LL | x.await; + | ^^^^^ help: a field with a similar name exists: `awai` + | + = note: to `.await` a `Future`, switch to Rust 2018 + = help: set `edition = "2018"` in `Cargo.toml` + = note: for more on editions, read https://doc.rust-lang.org/edition-guide + +error[E0609]: no field `await` on type `std::pin::Pin<&mut dyn std::future::Future>` + --> $DIR/suggest-switching-edition-on-await.rs:31:7 + | +LL | x.await; + | ^^^^^ unknown field + | + = note: to `.await` a `Future`, switch to Rust 2018 + = help: set `edition = "2018"` in `Cargo.toml` + = note: for more on editions, read https://doc.rust-lang.org/edition-guide + +error[E0609]: no field `await` on type `impl Future` + --> $DIR/suggest-switching-edition-on-await.rs:40:7 + | +LL | x.await; + | ^^^^^ + | + = note: to `.await` a `Future`, switch to Rust 2018 + = help: set `edition = "2018"` in `Cargo.toml` + = note: for more on editions, read https://doc.rust-lang.org/edition-guide + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0609`. From f54503c908413ef54ac9dc8ccf47915fa07a3286 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 15 Aug 2019 09:59:25 +0200 Subject: [PATCH 09/35] libcore: more cleanups using associated_type_bounds --- src/libcore/iter/adapters/flatten.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/libcore/iter/adapters/flatten.rs b/src/libcore/iter/adapters/flatten.rs index d8d41a2a31ef..d812da26580b 100644 --- a/src/libcore/iter/adapters/flatten.rs +++ b/src/libcore/iter/adapters/flatten.rs @@ -72,8 +72,7 @@ impl Iterator for FlatMap impl DoubleEndedIterator for FlatMap where F: FnMut(I::Item) -> U, - U: IntoIterator, - U::IntoIter: DoubleEndedIterator, + U: IntoIterator, { #[inline] fn next_back(&mut self) -> Option { self.inner.next_back() } @@ -107,10 +106,7 @@ impl FusedIterator for FlatMap /// [`Iterator`]: trait.Iterator.html #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "iterator_flatten", since = "1.29.0")] -pub struct Flatten -where - I::Item: IntoIterator, -{ +pub struct Flatten> { inner: FlattenCompat::IntoIter>, } From f036faeb3581c1079516667d43a77e2d23963c0a Mon Sep 17 00:00:00 2001 From: Kevin Per Date: Thu, 15 Aug 2019 11:37:19 +0200 Subject: [PATCH 10/35] Grouping ABI test #62401 --- .../run-pass/abi/abi-sysv64-arg-passing.rs | 366 ++++++++++++++++++ .../run-pass/abi/abi-sysv64-register-usage.rs | 95 +++++ src/test/run-pass/abi/abort-on-c-abi.rs | 36 ++ src/test/run-pass/abi/anon-extern-mod.rs | 17 + .../anon-extern-mod-cross-crate-1.rs | 9 + .../run-pass/abi/auxiliary/foreign_lib.rs | 38 ++ src/test/run-pass/abi/c-stack-as-value.rs | 17 + src/test/run-pass/abi/cabi-int-widening.rs | 14 + .../anon-extern-mod-cross-crate-1.rs | 9 + .../anon-extern-mod-cross-crate-1.rs | 9 + .../auxiliary/extern-crosscrate-source.rs | 31 ++ .../run-pass/abi/extern/extern-call-deep.rs | 39 ++ .../run-pass/abi/extern/extern-call-deep2.rs | 44 +++ .../abi/extern/extern-call-indirect.rs | 38 ++ .../run-pass/abi/extern/extern-call-scrub.rs | 48 +++ .../abi/extern/extern-pass-TwoU16s.rs | 25 ++ .../run-pass/abi/extern/extern-pass-TwoU8s.rs | 25 ++ .../run-pass/abi/extern/extern-pass-char.rs | 16 + .../run-pass/abi/extern/extern-pass-double.rs | 13 + .../run-pass/abi/extern/extern-pass-empty.rs | 55 +++ .../abi/extern/extern-return-TwoU16s.rs | 21 + .../abi/extern/extern-return-TwoU32s.rs | 21 + .../abi/extern/extern-return-TwoU64s.rs | 21 + .../abi/extern/extern-return-TwoU8s.rs | 21 + .../abi/foreign/auxiliary/foreign_lib.rs | 38 ++ .../abi/foreign/foreign-call-no-runtime.rs | 55 +++ .../abi/foreign/foreign-fn-with-byval.rs | 32 ++ .../run-pass/abi/foreign/foreign-no-abi.rs | 22 ++ .../abi/issues/auxiliary/issue-25185-1.rs | 8 + src/test/run-pass/abi/issues/issue-28676.rs | 35 ++ src/test/run-pass/abi/lib-defaults.rs | 16 + .../run-pass/abi/macros/macros-in-extern.rs | 30 ++ .../abi/mir/mir_codegen_calls_variadic.rs | 22 ++ .../abi/numbers-arithmetic/i128-ffi.rs | 31 ++ .../abi/proc_macro/macros-in-extern.rs | 24 ++ .../abi/rfcs/rfc1717/library-override.rs | 14 + .../run-pass/abi/segfault-no-out-of-stack.rs | 48 +++ src/test/run-pass/abi/stack-probes.rs | 67 ++++ .../abi/statics/static-mut-foreign.rs | 41 ++ .../abi/structs-enums/struct-return.rs | 64 +++ .../run-pass/abi/union/union-c-interop.rs | 37 ++ src/test/run-pass/abi/variadic-ffi.rs | 83 ++++ 42 files changed, 1695 insertions(+) create mode 100644 src/test/run-pass/abi/abi-sysv64-arg-passing.rs create mode 100644 src/test/run-pass/abi/abi-sysv64-register-usage.rs create mode 100644 src/test/run-pass/abi/abort-on-c-abi.rs create mode 100644 src/test/run-pass/abi/anon-extern-mod.rs create mode 100644 src/test/run-pass/abi/auxiliary/anon-extern-mod-cross-crate-1.rs create mode 100644 src/test/run-pass/abi/auxiliary/foreign_lib.rs create mode 100644 src/test/run-pass/abi/c-stack-as-value.rs create mode 100644 src/test/run-pass/abi/cabi-int-widening.rs create mode 100644 src/test/run-pass/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs create mode 100644 src/test/run-pass/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs create mode 100644 src/test/run-pass/abi/extern/auxiliary/extern-crosscrate-source.rs create mode 100644 src/test/run-pass/abi/extern/extern-call-deep.rs create mode 100644 src/test/run-pass/abi/extern/extern-call-deep2.rs create mode 100644 src/test/run-pass/abi/extern/extern-call-indirect.rs create mode 100644 src/test/run-pass/abi/extern/extern-call-scrub.rs create mode 100644 src/test/run-pass/abi/extern/extern-pass-TwoU16s.rs create mode 100644 src/test/run-pass/abi/extern/extern-pass-TwoU8s.rs create mode 100644 src/test/run-pass/abi/extern/extern-pass-char.rs create mode 100644 src/test/run-pass/abi/extern/extern-pass-double.rs create mode 100644 src/test/run-pass/abi/extern/extern-pass-empty.rs create mode 100644 src/test/run-pass/abi/extern/extern-return-TwoU16s.rs create mode 100644 src/test/run-pass/abi/extern/extern-return-TwoU32s.rs create mode 100644 src/test/run-pass/abi/extern/extern-return-TwoU64s.rs create mode 100644 src/test/run-pass/abi/extern/extern-return-TwoU8s.rs create mode 100644 src/test/run-pass/abi/foreign/auxiliary/foreign_lib.rs create mode 100644 src/test/run-pass/abi/foreign/foreign-call-no-runtime.rs create mode 100644 src/test/run-pass/abi/foreign/foreign-fn-with-byval.rs create mode 100644 src/test/run-pass/abi/foreign/foreign-no-abi.rs create mode 100644 src/test/run-pass/abi/issues/auxiliary/issue-25185-1.rs create mode 100644 src/test/run-pass/abi/issues/issue-28676.rs create mode 100644 src/test/run-pass/abi/lib-defaults.rs create mode 100644 src/test/run-pass/abi/macros/macros-in-extern.rs create mode 100644 src/test/run-pass/abi/mir/mir_codegen_calls_variadic.rs create mode 100644 src/test/run-pass/abi/numbers-arithmetic/i128-ffi.rs create mode 100644 src/test/run-pass/abi/proc_macro/macros-in-extern.rs create mode 100644 src/test/run-pass/abi/rfcs/rfc1717/library-override.rs create mode 100644 src/test/run-pass/abi/segfault-no-out-of-stack.rs create mode 100644 src/test/run-pass/abi/stack-probes.rs create mode 100644 src/test/run-pass/abi/statics/static-mut-foreign.rs create mode 100644 src/test/run-pass/abi/structs-enums/struct-return.rs create mode 100644 src/test/run-pass/abi/union/union-c-interop.rs create mode 100644 src/test/run-pass/abi/variadic-ffi.rs diff --git a/src/test/run-pass/abi/abi-sysv64-arg-passing.rs b/src/test/run-pass/abi/abi-sysv64-arg-passing.rs new file mode 100644 index 000000000000..fdf0573b5e3e --- /dev/null +++ b/src/test/run-pass/abi/abi-sysv64-arg-passing.rs @@ -0,0 +1,366 @@ +// Checks if the "sysv64" calling convention behaves the same as the +// "C" calling convention on platforms where both should be the same + +// This file contains versions of the following run-pass tests with +// the calling convention changed to "sysv64" + +// cabi-int-widening +// extern-pass-char +// extern-pass-u32 +// extern-pass-u64 +// extern-pass-double +// extern-pass-empty +// extern-pass-TwoU8s +// extern-pass-TwoU16s +// extern-pass-TwoU32s +// extern-pass-TwoU64s +// extern-return-TwoU8s +// extern-return-TwoU16s +// extern-return-TwoU32s +// extern-return-TwoU64s +// foreign-fn-with-byval +// issue-28676 +// issue-62350-sysv-neg-reg-counts +// struct-return + +// ignore-android +// ignore-arm +// ignore-aarch64 +// ignore-windows + +// note: windows is ignored as rust_test_helpers does not have the sysv64 abi on windows + +#[allow(dead_code)] +#[allow(improper_ctypes)] + +#[cfg(target_arch = "x86_64")] +mod tests { + #[repr(C)] + #[derive(Copy, Clone, PartialEq, Debug)] + pub struct TwoU8s { + one: u8, two: u8 + } + + #[repr(C)] + #[derive(Copy, Clone, PartialEq, Debug)] + pub struct TwoU16s { + one: u16, two: u16 + } + + #[repr(C)] + #[derive(Copy, Clone, PartialEq, Debug)] + pub struct TwoU32s { + one: u32, two: u32 + } + + #[repr(C)] + #[derive(Copy, Clone, PartialEq, Debug)] + pub struct TwoU64s { + one: u64, two: u64 + } + + #[repr(C)] + pub struct ManyInts { + arg1: i8, + arg2: i16, + arg3: i32, + arg4: i16, + arg5: i8, + arg6: TwoU8s, + } + + #[repr(C)] + pub struct Empty; + + #[repr(C)] + #[derive(Copy, Clone)] + pub struct S { + x: u64, + y: u64, + z: u64, + } + + #[repr(C)] + #[derive(Copy, Clone)] + pub struct Quad { a: u64, b: u64, c: u64, d: u64 } + + #[derive(Copy, Clone)] + pub struct QuadFloats { a: f32, b: f32, c: f32, d: f32 } + + #[repr(C)] + #[derive(Copy, Clone)] + pub struct Floats { a: f64, b: u8, c: f64 } + + #[link(name = "rust_test_helpers", kind = "static")] + extern "sysv64" { + pub fn rust_int8_to_int32(_: i8) -> i32; + pub fn rust_dbg_extern_identity_u8(v: u8) -> u8; + pub fn rust_dbg_extern_identity_u32(v: u32) -> u32; + pub fn rust_dbg_extern_identity_u64(v: u64) -> u64; + pub fn rust_dbg_extern_identity_double(v: f64) -> f64; + pub fn rust_dbg_extern_empty_struct(v1: ManyInts, e: Empty, v2: ManyInts); + pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s; + pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s; + pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s; + pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s; + pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s; + pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s; + pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s; + pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s; + pub fn get_x(x: S) -> u64; + pub fn get_y(x: S) -> u64; + pub fn get_z(x: S) -> u64; + pub fn get_c_many_params(_: *const (), _: *const (), + _: *const (), _: *const (), f: Quad) -> u64; + pub fn get_c_exhaust_sysv64_ints( + _: *const (), + _: *const (), + _: *const (), + _: *const (), + _: *const (), + _: *const (), + _: *const (), + h: QuadFloats, + ) -> f32; + pub fn rust_dbg_abi_1(q: Quad) -> Quad; + pub fn rust_dbg_abi_2(f: Floats) -> Floats; + } + + pub fn cabi_int_widening() { + let x = unsafe { + rust_int8_to_int32(-1) + }; + + assert!(x == -1); + } + + pub fn extern_pass_char() { + unsafe { + assert_eq!(22, rust_dbg_extern_identity_u8(22)); + } + } + + pub fn extern_pass_u32() { + unsafe { + assert_eq!(22, rust_dbg_extern_identity_u32(22)); + } + } + + pub fn extern_pass_u64() { + unsafe { + assert_eq!(22, rust_dbg_extern_identity_u64(22)); + } + } + + pub fn extern_pass_double() { + unsafe { + assert_eq!(22.0_f64, rust_dbg_extern_identity_double(22.0_f64)); + } + } + + pub fn extern_pass_empty() { + unsafe { + let x = ManyInts { + arg1: 2, + arg2: 3, + arg3: 4, + arg4: 5, + arg5: 6, + arg6: TwoU8s { one: 7, two: 8, } + }; + let y = ManyInts { + arg1: 1, + arg2: 2, + arg3: 3, + arg4: 4, + arg5: 5, + arg6: TwoU8s { one: 6, two: 7, } + }; + let empty = Empty; + rust_dbg_extern_empty_struct(x, empty, y); + } + } + + pub fn extern_pass_twou8s() { + unsafe { + let x = TwoU8s {one: 22, two: 23}; + let y = rust_dbg_extern_identity_TwoU8s(x); + assert_eq!(x, y); + } + } + + pub fn extern_pass_twou16s() { + unsafe { + let x = TwoU16s {one: 22, two: 23}; + let y = rust_dbg_extern_identity_TwoU16s(x); + assert_eq!(x, y); + } + } + + pub fn extern_pass_twou32s() { + unsafe { + let x = TwoU32s {one: 22, two: 23}; + let y = rust_dbg_extern_identity_TwoU32s(x); + assert_eq!(x, y); + } + } + + pub fn extern_pass_twou64s() { + unsafe { + let x = TwoU64s {one: 22, two: 23}; + let y = rust_dbg_extern_identity_TwoU64s(x); + assert_eq!(x, y); + } + } + + pub fn extern_return_twou8s() { + unsafe { + let y = rust_dbg_extern_return_TwoU8s(); + assert_eq!(y.one, 10); + assert_eq!(y.two, 20); + } + } + + pub fn extern_return_twou16s() { + unsafe { + let y = rust_dbg_extern_return_TwoU16s(); + assert_eq!(y.one, 10); + assert_eq!(y.two, 20); + } + } + + pub fn extern_return_twou32s() { + unsafe { + let y = rust_dbg_extern_return_TwoU32s(); + assert_eq!(y.one, 10); + assert_eq!(y.two, 20); + } + } + + pub fn extern_return_twou64s() { + unsafe { + let y = rust_dbg_extern_return_TwoU64s(); + assert_eq!(y.one, 10); + assert_eq!(y.two, 20); + } + } + + #[inline(never)] + fn indirect_call(func: unsafe extern "sysv64" fn(s: S) -> u64, s: S) -> u64 { + unsafe { + func(s) + } + } + + pub fn foreign_fn_with_byval() { + let s = S { x: 1, y: 2, z: 3 }; + assert_eq!(s.x, indirect_call(get_x, s)); + assert_eq!(s.y, indirect_call(get_y, s)); + assert_eq!(s.z, indirect_call(get_z, s)); + } + + fn test() { + use std::ptr; + unsafe { + let null = ptr::null(); + let q = Quad { + a: 1, + b: 2, + c: 3, + d: 4 + }; + assert_eq!(get_c_many_params(null, null, null, null, q), q.c); + } + } + + pub fn issue_28676() { + test(); + } + + fn test_62350() { + use std::ptr; + unsafe { + let null = ptr::null(); + let q = QuadFloats { + a: 10.2, + b: 20.3, + c: 30.4, + d: 40.5 + }; + assert_eq!( + get_c_exhaust_sysv64_ints(null, null, null, null, null, null, null, q), + q.c, + ); + } + } + + pub fn issue_62350() { + test_62350(); + } + + fn test1() { + unsafe { + let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa, + b: 0xbbbb_bbbb_bbbb_bbbb, + c: 0xcccc_cccc_cccc_cccc, + d: 0xdddd_dddd_dddd_dddd }; + let qq = rust_dbg_abi_1(q); + println!("a: {:x}", qq.a as usize); + println!("b: {:x}", qq.b as usize); + println!("c: {:x}", qq.c as usize); + println!("d: {:x}", qq.d as usize); + assert_eq!(qq.a, q.c + 1); + assert_eq!(qq.b, q.d - 1); + assert_eq!(qq.c, q.a + 1); + assert_eq!(qq.d, q.b - 1); + } + } + + fn test2() { + unsafe { + let f = Floats { a: 1.234567890e-15_f64, + b: 0b_1010_1010, + c: 1.0987654321e-15_f64 }; + let ff = rust_dbg_abi_2(f); + println!("a: {}", ff.a as f64); + println!("b: {}", ff.b as usize); + println!("c: {}", ff.c as f64); + assert_eq!(ff.a, f.c + 1.0f64); + assert_eq!(ff.b, 0xff); + assert_eq!(ff.c, f.a - 1.0f64); + } + } + + pub fn struct_return() { + test1(); + test2(); + } +} + +#[cfg(target_arch = "x86_64")] +fn main() { + use tests::*; + cabi_int_widening(); + extern_pass_char(); + extern_pass_u32(); + extern_pass_u64(); + extern_pass_double(); + extern_pass_empty(); + extern_pass_twou8s(); + extern_pass_twou16s(); + extern_pass_twou32s(); + extern_pass_twou64s(); + extern_return_twou8s(); + extern_return_twou16s(); + extern_return_twou32s(); + extern_return_twou64s(); + foreign_fn_with_byval(); + issue_28676(); + issue_62350(); + struct_return(); +} + +#[cfg(not(target_arch = "x86_64"))] +fn main() { + +} diff --git a/src/test/run-pass/abi/abi-sysv64-register-usage.rs b/src/test/run-pass/abi/abi-sysv64-register-usage.rs new file mode 100644 index 000000000000..a0d6e968252a --- /dev/null +++ b/src/test/run-pass/abi/abi-sysv64-register-usage.rs @@ -0,0 +1,95 @@ +// Checks if the correct registers are being used to pass arguments +// when the sysv64 ABI is specified. + +// ignore-android +// ignore-arm +// ignore-aarch64 + +#![feature(asm)] + +#[cfg(target_arch = "x86_64")] +pub extern "sysv64" fn all_the_registers(rdi: i64, rsi: i64, rdx: i64, + rcx: i64, r8 : i64, r9 : i64, + xmm0: f32, xmm1: f32, xmm2: f32, + xmm3: f32, xmm4: f32, xmm5: f32, + xmm6: f32, xmm7: f32) -> i64 { + assert_eq!(rdi, 1); + assert_eq!(rsi, 2); + assert_eq!(rdx, 3); + assert_eq!(rcx, 4); + assert_eq!(r8, 5); + assert_eq!(r9, 6); + assert_eq!(xmm0, 1.0f32); + assert_eq!(xmm1, 2.0f32); + assert_eq!(xmm2, 4.0f32); + assert_eq!(xmm3, 8.0f32); + assert_eq!(xmm4, 16.0f32); + assert_eq!(xmm5, 32.0f32); + assert_eq!(xmm6, 64.0f32); + assert_eq!(xmm7, 128.0f32); + 42 +} + +// this struct contains 8 i64's, while only 6 can be passed in registers. +#[cfg(target_arch = "x86_64")] +#[derive(PartialEq, Eq, Debug)] +pub struct LargeStruct(i64, i64, i64, i64, i64, i64, i64, i64); + +#[cfg(target_arch = "x86_64")] +#[inline(never)] +pub extern "sysv64" fn large_struct_by_val(mut foo: LargeStruct) -> LargeStruct { + foo.0 *= 1; + foo.1 *= 2; + foo.2 *= 3; + foo.3 *= 4; + foo.4 *= 5; + foo.5 *= 6; + foo.6 *= 7; + foo.7 *= 8; + foo +} + +#[cfg(target_arch = "x86_64")] +pub fn main() { + let result: i64; + unsafe { + asm!("mov rdi, 1; + mov rsi, 2; + mov rdx, 3; + mov rcx, 4; + mov r8, 5; + mov r9, 6; + mov eax, 0x3F800000; + movd xmm0, eax; + mov eax, 0x40000000; + movd xmm1, eax; + mov eax, 0x40800000; + movd xmm2, eax; + mov eax, 0x41000000; + movd xmm3, eax; + mov eax, 0x41800000; + movd xmm4, eax; + mov eax, 0x42000000; + movd xmm5, eax; + mov eax, 0x42800000; + movd xmm6, eax; + mov eax, 0x43000000; + movd xmm7, eax; + call r10 + " + : "={rax}"(result) + : "{r10}"(all_the_registers as usize) + : "rdi", "rsi", "rdx", "rcx", "r8", "r9", "r11", "cc", "memory" + : "intel", "alignstack" + ) + } + assert_eq!(result, 42); + + assert_eq!( + large_struct_by_val(LargeStruct(1, 2, 3, 4, 5, 6, 7, 8)), + LargeStruct(1, 4, 9, 16, 25, 36, 49, 64) + ); +} + +#[cfg(not(target_arch = "x86_64"))] +pub fn main() {} diff --git a/src/test/run-pass/abi/abort-on-c-abi.rs b/src/test/run-pass/abi/abort-on-c-abi.rs new file mode 100644 index 000000000000..110f3eee1ef8 --- /dev/null +++ b/src/test/run-pass/abi/abort-on-c-abi.rs @@ -0,0 +1,36 @@ +#![allow(unused_must_use)] +// Since we mark some ABIs as "nounwind" to LLVM, we must make sure that +// we never unwind through them. + +// ignore-cloudabi no env and process +// ignore-emscripten no processes +// ignore-sgx no processes + +use std::{env, panic}; +use std::io::prelude::*; +use std::io; +use std::process::{Command, Stdio}; + +extern "C" fn panic_in_ffi() { + panic!("Test"); +} + +fn test() { + let _ = panic::catch_unwind(|| { panic_in_ffi(); }); + // The process should have aborted by now. + io::stdout().write(b"This should never be printed.\n"); + let _ = io::stdout().flush(); +} + +fn main() { + let args: Vec = env::args().collect(); + if args.len() > 1 && args[1] == "test" { + return test(); + } + + let mut p = Command::new(&args[0]) + .stdout(Stdio::piped()) + .stdin(Stdio::piped()) + .arg("test").spawn().unwrap(); + assert!(!p.wait().unwrap().success()); +} diff --git a/src/test/run-pass/abi/anon-extern-mod.rs b/src/test/run-pass/abi/anon-extern-mod.rs new file mode 100644 index 000000000000..6d7e3f3cd5c1 --- /dev/null +++ b/src/test/run-pass/abi/anon-extern-mod.rs @@ -0,0 +1,17 @@ +// pretty-expanded FIXME #23616 +// ignore-wasm32-bare no libc to test ffi with + +#![feature(rustc_private)] + +extern crate libc; + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + fn rust_get_test_int() -> libc::intptr_t; +} + +pub fn main() { + unsafe { + let _ = rust_get_test_int(); + } +} diff --git a/src/test/run-pass/abi/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/run-pass/abi/auxiliary/anon-extern-mod-cross-crate-1.rs new file mode 100644 index 000000000000..948b5e688ebc --- /dev/null +++ b/src/test/run-pass/abi/auxiliary/anon-extern-mod-cross-crate-1.rs @@ -0,0 +1,9 @@ +#![crate_name="anonexternmod"] +#![feature(rustc_private)] + +extern crate libc; + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_get_test_int() -> libc::intptr_t; +} diff --git a/src/test/run-pass/abi/auxiliary/foreign_lib.rs b/src/test/run-pass/abi/auxiliary/foreign_lib.rs new file mode 100644 index 000000000000..de6b0e2118a5 --- /dev/null +++ b/src/test/run-pass/abi/auxiliary/foreign_lib.rs @@ -0,0 +1,38 @@ +#![crate_name="foreign_lib"] + +#![feature(rustc_private)] + +pub mod rustrt { + extern crate libc; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn rust_get_test_int() -> libc::intptr_t; + } +} + +pub mod rustrt2 { + extern crate libc; + + extern { + pub fn rust_get_test_int() -> libc::intptr_t; + } +} + +pub mod rustrt3 { + // Different type, but same ABI (on all supported platforms). + // Ensures that we don't ICE or trigger LLVM asserts when + // importing the same symbol under different types. + // See https://github.com/rust-lang/rust/issues/32740. + extern { + pub fn rust_get_test_int() -> *const u8; + } +} + +pub fn local_uses() { + unsafe { + let x = rustrt::rust_get_test_int(); + assert_eq!(x, rustrt2::rust_get_test_int()); + assert_eq!(x as *const _, rustrt3::rust_get_test_int()); + } +} diff --git a/src/test/run-pass/abi/c-stack-as-value.rs b/src/test/run-pass/abi/c-stack-as-value.rs new file mode 100644 index 000000000000..3b997295c122 --- /dev/null +++ b/src/test/run-pass/abi/c-stack-as-value.rs @@ -0,0 +1,17 @@ +// pretty-expanded FIXME #23616 +// ignore-wasm32-bare no libc to test ffi with + +#![feature(rustc_private)] + +mod rustrt { + extern crate libc; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn rust_get_test_int() -> libc::intptr_t; + } +} + +pub fn main() { + let _foo = rustrt::rust_get_test_int; +} diff --git a/src/test/run-pass/abi/cabi-int-widening.rs b/src/test/run-pass/abi/cabi-int-widening.rs new file mode 100644 index 000000000000..f6524c6a3d90 --- /dev/null +++ b/src/test/run-pass/abi/cabi-int-widening.rs @@ -0,0 +1,14 @@ +// ignore-wasm32-bare no libc to test ffi with + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + fn rust_int8_to_int32(_: i8) -> i32; +} + +fn main() { + let x = unsafe { + rust_int8_to_int32(-1) + }; + + assert!(x == -1); +} diff --git a/src/test/run-pass/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/run-pass/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs new file mode 100644 index 000000000000..948b5e688ebc --- /dev/null +++ b/src/test/run-pass/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs @@ -0,0 +1,9 @@ +#![crate_name="anonexternmod"] +#![feature(rustc_private)] + +extern crate libc; + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_get_test_int() -> libc::intptr_t; +} diff --git a/src/test/run-pass/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/run-pass/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs new file mode 100644 index 000000000000..948b5e688ebc --- /dev/null +++ b/src/test/run-pass/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs @@ -0,0 +1,9 @@ +#![crate_name="anonexternmod"] +#![feature(rustc_private)] + +extern crate libc; + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_get_test_int() -> libc::intptr_t; +} diff --git a/src/test/run-pass/abi/extern/auxiliary/extern-crosscrate-source.rs b/src/test/run-pass/abi/extern/auxiliary/extern-crosscrate-source.rs new file mode 100644 index 000000000000..d4568d38e25c --- /dev/null +++ b/src/test/run-pass/abi/extern/auxiliary/extern-crosscrate-source.rs @@ -0,0 +1,31 @@ +#![crate_name="externcallback"] +#![crate_type = "lib"] +#![feature(rustc_private)] + +extern crate libc; + +pub mod rustrt { + extern crate libc; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, + data: libc::uintptr_t) + -> libc::uintptr_t; + } +} + +pub fn fact(n: libc::uintptr_t) -> libc::uintptr_t { + unsafe { + println!("n = {}", n); + rustrt::rust_dbg_call(cb, n) + } +} + +pub extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { + if data == 1 { + data + } else { + fact(data - 1) * data + } +} diff --git a/src/test/run-pass/abi/extern/extern-call-deep.rs b/src/test/run-pass/abi/extern/extern-call-deep.rs new file mode 100644 index 000000000000..81f884dada9b --- /dev/null +++ b/src/test/run-pass/abi/extern/extern-call-deep.rs @@ -0,0 +1,39 @@ +// run-pass +// ignore-wasm32-bare no libc to test ffi with +// ignore-emscripten blows the JS stack + +#![feature(rustc_private)] + +extern crate libc; + +mod rustrt { + extern crate libc; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, + data: libc::uintptr_t) + -> libc::uintptr_t; + } +} + +extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { + if data == 1 { + data + } else { + count(data - 1) + 1 + } +} + +fn count(n: libc::uintptr_t) -> libc::uintptr_t { + unsafe { + println!("n = {}", n); + rustrt::rust_dbg_call(cb, n) + } +} + +pub fn main() { + let result = count(1000); + println!("result = {}", result); + assert_eq!(result, 1000); +} diff --git a/src/test/run-pass/abi/extern/extern-call-deep2.rs b/src/test/run-pass/abi/extern/extern-call-deep2.rs new file mode 100644 index 000000000000..b31489b1e10c --- /dev/null +++ b/src/test/run-pass/abi/extern/extern-call-deep2.rs @@ -0,0 +1,44 @@ +// run-pass +#![allow(unused_must_use)] +// ignore-emscripten no threads support + +#![feature(rustc_private)] + +extern crate libc; +use std::thread; + +mod rustrt { + extern crate libc; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, + data: libc::uintptr_t) + -> libc::uintptr_t; + } +} + +extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { + if data == 1 { + data + } else { + count(data - 1) + 1 + } +} + +fn count(n: libc::uintptr_t) -> libc::uintptr_t { + unsafe { + println!("n = {}", n); + rustrt::rust_dbg_call(cb, n) + } +} + +pub fn main() { + // Make sure we're on a thread with small Rust stacks (main currently + // has a large stack) + thread::spawn(move|| { + let result = count(1000); + println!("result = {}", result); + assert_eq!(result, 1000); + }).join(); +} diff --git a/src/test/run-pass/abi/extern/extern-call-indirect.rs b/src/test/run-pass/abi/extern/extern-call-indirect.rs new file mode 100644 index 000000000000..158b54e4b8cd --- /dev/null +++ b/src/test/run-pass/abi/extern/extern-call-indirect.rs @@ -0,0 +1,38 @@ +// run-pass +// ignore-wasm32-bare no libc to test ffi with + +#![feature(rustc_private)] + +extern crate libc; + +mod rustrt { + extern crate libc; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, + data: libc::uintptr_t) + -> libc::uintptr_t; + } +} + +extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { + if data == 1 { + data + } else { + fact(data - 1) * data + } +} + +fn fact(n: libc::uintptr_t) -> libc::uintptr_t { + unsafe { + println!("n = {}", n); + rustrt::rust_dbg_call(cb, n) + } +} + +pub fn main() { + let result = fact(10); + println!("result = {}", result); + assert_eq!(result, 3628800); +} diff --git a/src/test/run-pass/abi/extern/extern-call-scrub.rs b/src/test/run-pass/abi/extern/extern-call-scrub.rs new file mode 100644 index 000000000000..a7b1065c9e1f --- /dev/null +++ b/src/test/run-pass/abi/extern/extern-call-scrub.rs @@ -0,0 +1,48 @@ +// run-pass +#![allow(unused_must_use)] +// This time we're testing repeatedly going up and down both stacks to +// make sure the stack pointers are maintained properly in both +// directions + +// ignore-emscripten no threads support + +#![feature(rustc_private)] + +extern crate libc; +use std::thread; + +mod rustrt { + extern crate libc; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, + data: libc::uintptr_t) + -> libc::uintptr_t; + } +} + +extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { + if data == 1 { + data + } else { + count(data - 1) + count(data - 1) + } +} + +fn count(n: libc::uintptr_t) -> libc::uintptr_t { + unsafe { + println!("n = {}", n); + rustrt::rust_dbg_call(cb, n) + } +} + +pub fn main() { + // Make sure we're on a thread with small Rust stacks (main currently + // has a large stack) + thread::spawn(move|| { + let result = count(12); + println!("result = {}", result); + assert_eq!(result, 2048); + }).join(); +} diff --git a/src/test/run-pass/abi/extern/extern-pass-TwoU16s.rs b/src/test/run-pass/abi/extern/extern-pass-TwoU16s.rs new file mode 100644 index 000000000000..285bce2e19c3 --- /dev/null +++ b/src/test/run-pass/abi/extern/extern-pass-TwoU16s.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc for ffi testing + +// Test a foreign function that accepts and returns a struct +// by value. + +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct TwoU16s { + one: u16, two: u16 +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s; +} + +pub fn main() { + unsafe { + let x = TwoU16s {one: 22, two: 23}; + let y = rust_dbg_extern_identity_TwoU16s(x); + assert_eq!(x, y); + } +} diff --git a/src/test/run-pass/abi/extern/extern-pass-TwoU8s.rs b/src/test/run-pass/abi/extern/extern-pass-TwoU8s.rs new file mode 100644 index 000000000000..53a6a0f29f8a --- /dev/null +++ b/src/test/run-pass/abi/extern/extern-pass-TwoU8s.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc for ffi testing + +// Test a foreign function that accepts and returns a struct +// by value. + +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct TwoU8s { + one: u8, two: u8 +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s; +} + +pub fn main() { + unsafe { + let x = TwoU8s {one: 22, two: 23}; + let y = rust_dbg_extern_identity_TwoU8s(x); + assert_eq!(x, y); + } +} diff --git a/src/test/run-pass/abi/extern/extern-pass-char.rs b/src/test/run-pass/abi/extern/extern-pass-char.rs new file mode 100644 index 000000000000..22f841b45527 --- /dev/null +++ b/src/test/run-pass/abi/extern/extern-pass-char.rs @@ -0,0 +1,16 @@ +// run-pass +// ignore-wasm32-bare no libc for ffi testing + +// Test a function that takes/returns a u8. + + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_identity_u8(v: u8) -> u8; +} + +pub fn main() { + unsafe { + assert_eq!(22, rust_dbg_extern_identity_u8(22)); + } +} diff --git a/src/test/run-pass/abi/extern/extern-pass-double.rs b/src/test/run-pass/abi/extern/extern-pass-double.rs new file mode 100644 index 000000000000..dbd0a2dfa488 --- /dev/null +++ b/src/test/run-pass/abi/extern/extern-pass-double.rs @@ -0,0 +1,13 @@ +// run-pass +// ignore-wasm32-bare no libc for ffi testing + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_identity_double(v: f64) -> f64; +} + +pub fn main() { + unsafe { + assert_eq!(22.0_f64, rust_dbg_extern_identity_double(22.0_f64)); + } +} diff --git a/src/test/run-pass/abi/extern/extern-pass-empty.rs b/src/test/run-pass/abi/extern/extern-pass-empty.rs new file mode 100644 index 000000000000..07099a242048 --- /dev/null +++ b/src/test/run-pass/abi/extern/extern-pass-empty.rs @@ -0,0 +1,55 @@ +// run-pass +#![allow(improper_ctypes)] // FIXME: this test is inherently not FFI-safe. + +// Test a foreign function that accepts empty struct. + +// pretty-expanded FIXME #23616 +// ignore-msvc +// ignore-emscripten emcc asserts on an empty struct as an argument + +#[repr(C)] +struct TwoU8s { + one: u8, + two: u8, +} + +#[repr(C)] +struct ManyInts { + arg1: i8, + arg2: i16, + arg3: i32, + arg4: i16, + arg5: i8, + arg6: TwoU8s, +} + +#[repr(C)] +struct Empty; + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + fn rust_dbg_extern_empty_struct(v1: ManyInts, e: Empty, v2: ManyInts); +} + +pub fn main() { + unsafe { + let x = ManyInts { + arg1: 2, + arg2: 3, + arg3: 4, + arg4: 5, + arg5: 6, + arg6: TwoU8s { one: 7, two: 8, } + }; + let y = ManyInts { + arg1: 1, + arg2: 2, + arg3: 3, + arg4: 4, + arg5: 5, + arg6: TwoU8s { one: 6, two: 7, } + }; + let empty = Empty; + rust_dbg_extern_empty_struct(x, empty, y); + } +} diff --git a/src/test/run-pass/abi/extern/extern-return-TwoU16s.rs b/src/test/run-pass/abi/extern/extern-return-TwoU16s.rs new file mode 100644 index 000000000000..dd884ee77fe7 --- /dev/null +++ b/src/test/run-pass/abi/extern/extern-return-TwoU16s.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc to test ffi with + +pub struct TwoU16s { + one: u16, two: u16 +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s; +} + +pub fn main() { + unsafe { + let y = rust_dbg_extern_return_TwoU16s(); + assert_eq!(y.one, 10); + assert_eq!(y.two, 20); + } +} diff --git a/src/test/run-pass/abi/extern/extern-return-TwoU32s.rs b/src/test/run-pass/abi/extern/extern-return-TwoU32s.rs new file mode 100644 index 000000000000..d6aaf5c9eaf1 --- /dev/null +++ b/src/test/run-pass/abi/extern/extern-return-TwoU32s.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc to test ffi with + +pub struct TwoU32s { + one: u32, two: u32 +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s; +} + +pub fn main() { + unsafe { + let y = rust_dbg_extern_return_TwoU32s(); + assert_eq!(y.one, 10); + assert_eq!(y.two, 20); + } +} diff --git a/src/test/run-pass/abi/extern/extern-return-TwoU64s.rs b/src/test/run-pass/abi/extern/extern-return-TwoU64s.rs new file mode 100644 index 000000000000..c5e4ebadc182 --- /dev/null +++ b/src/test/run-pass/abi/extern/extern-return-TwoU64s.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc to test ffi with + +pub struct TwoU64s { + one: u64, two: u64 +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s; +} + +pub fn main() { + unsafe { + let y = rust_dbg_extern_return_TwoU64s(); + assert_eq!(y.one, 10); + assert_eq!(y.two, 20); + } +} diff --git a/src/test/run-pass/abi/extern/extern-return-TwoU8s.rs b/src/test/run-pass/abi/extern/extern-return-TwoU8s.rs new file mode 100644 index 000000000000..a7cd21b20735 --- /dev/null +++ b/src/test/run-pass/abi/extern/extern-return-TwoU8s.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc to test ffi with + +pub struct TwoU8s { + one: u8, two: u8 +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s; +} + +pub fn main() { + unsafe { + let y = rust_dbg_extern_return_TwoU8s(); + assert_eq!(y.one, 10); + assert_eq!(y.two, 20); + } +} diff --git a/src/test/run-pass/abi/foreign/auxiliary/foreign_lib.rs b/src/test/run-pass/abi/foreign/auxiliary/foreign_lib.rs new file mode 100644 index 000000000000..de6b0e2118a5 --- /dev/null +++ b/src/test/run-pass/abi/foreign/auxiliary/foreign_lib.rs @@ -0,0 +1,38 @@ +#![crate_name="foreign_lib"] + +#![feature(rustc_private)] + +pub mod rustrt { + extern crate libc; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn rust_get_test_int() -> libc::intptr_t; + } +} + +pub mod rustrt2 { + extern crate libc; + + extern { + pub fn rust_get_test_int() -> libc::intptr_t; + } +} + +pub mod rustrt3 { + // Different type, but same ABI (on all supported platforms). + // Ensures that we don't ICE or trigger LLVM asserts when + // importing the same symbol under different types. + // See https://github.com/rust-lang/rust/issues/32740. + extern { + pub fn rust_get_test_int() -> *const u8; + } +} + +pub fn local_uses() { + unsafe { + let x = rustrt::rust_get_test_int(); + assert_eq!(x, rustrt2::rust_get_test_int()); + assert_eq!(x as *const _, rustrt3::rust_get_test_int()); + } +} diff --git a/src/test/run-pass/abi/foreign/foreign-call-no-runtime.rs b/src/test/run-pass/abi/foreign/foreign-call-no-runtime.rs new file mode 100644 index 000000000000..c6afa07ad050 --- /dev/null +++ b/src/test/run-pass/abi/foreign/foreign-call-no-runtime.rs @@ -0,0 +1,55 @@ +// run-pass +// ignore-emscripten no threads support + +#![feature(rustc_private)] + +extern crate libc; + +use std::mem; +use std::thread; + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t), + data: libc::uintptr_t) -> libc::uintptr_t; +} + +pub fn main() { + unsafe { + thread::spawn(move|| { + let i: isize = 100; + rust_dbg_call(callback_isize, mem::transmute(&i)); + }).join().unwrap(); + + thread::spawn(move|| { + let i: i32 = 100; + rust_dbg_call(callback_i32, mem::transmute(&i)); + }).join().unwrap(); + + thread::spawn(move|| { + let i: i64 = 100; + rust_dbg_call(callback_i64, mem::transmute(&i)); + }).join().unwrap(); + } +} + +extern fn callback_isize(data: libc::uintptr_t) { + unsafe { + let data: *const isize = mem::transmute(data); + assert_eq!(*data, 100); + } +} + +extern fn callback_i64(data: libc::uintptr_t) { + unsafe { + let data: *const i64 = mem::transmute(data); + assert_eq!(*data, 100); + } +} + +extern fn callback_i32(data: libc::uintptr_t) { + unsafe { + let data: *const i32 = mem::transmute(data); + assert_eq!(*data, 100); + } +} diff --git a/src/test/run-pass/abi/foreign/foreign-fn-with-byval.rs b/src/test/run-pass/abi/foreign/foreign-fn-with-byval.rs new file mode 100644 index 000000000000..3a35599aa573 --- /dev/null +++ b/src/test/run-pass/abi/foreign/foreign-fn-with-byval.rs @@ -0,0 +1,32 @@ +// run-pass +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc to test ffi with + +#[derive(Copy, Clone)] +pub struct S { + x: u64, + y: u64, + z: u64, +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn get_x(x: S) -> u64; + pub fn get_y(x: S) -> u64; + pub fn get_z(x: S) -> u64; +} + +#[inline(never)] +fn indirect_call(func: unsafe extern fn(s: S) -> u64, s: S) -> u64 { + unsafe { + func(s) + } +} + +fn main() { + let s = S { x: 1, y: 2, z: 3 }; + assert_eq!(s.x, indirect_call(get_x, s)); + assert_eq!(s.y, indirect_call(get_y, s)); + assert_eq!(s.z, indirect_call(get_z, s)); +} diff --git a/src/test/run-pass/abi/foreign/foreign-no-abi.rs b/src/test/run-pass/abi/foreign/foreign-no-abi.rs new file mode 100644 index 000000000000..2f33fb476569 --- /dev/null +++ b/src/test/run-pass/abi/foreign/foreign-no-abi.rs @@ -0,0 +1,22 @@ +// run-pass +// ABI is cdecl by default + +// ignore-wasm32-bare no libc to test ffi with +// pretty-expanded FIXME #23616 + +#![feature(rustc_private)] + +mod rustrt { + extern crate libc; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn rust_get_test_int() -> libc::intptr_t; + } +} + +pub fn main() { + unsafe { + rustrt::rust_get_test_int(); + } +} diff --git a/src/test/run-pass/abi/issues/auxiliary/issue-25185-1.rs b/src/test/run-pass/abi/issues/auxiliary/issue-25185-1.rs new file mode 100644 index 000000000000..77a4787ba943 --- /dev/null +++ b/src/test/run-pass/abi/issues/auxiliary/issue-25185-1.rs @@ -0,0 +1,8 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_identity_u32(u: u32) -> u32; +} diff --git a/src/test/run-pass/abi/issues/issue-28676.rs b/src/test/run-pass/abi/issues/issue-28676.rs new file mode 100644 index 000000000000..2b83478ca611 --- /dev/null +++ b/src/test/run-pass/abi/issues/issue-28676.rs @@ -0,0 +1,35 @@ +// run-pass +#![allow(dead_code)] +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc to test ffi with + +#[derive(Copy, Clone)] +pub struct Quad { a: u64, b: u64, c: u64, d: u64 } + +mod rustrt { + use super::Quad; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn get_c_many_params(_: *const (), _: *const (), + _: *const (), _: *const (), f: Quad) -> u64; + } +} + +fn test() { + unsafe { + let null = std::ptr::null(); + let q = Quad { + a: 1, + b: 2, + c: 3, + d: 4 + }; + assert_eq!(rustrt::get_c_many_params(null, null, null, null, q), q.c); + } +} + +pub fn main() { + test(); +} diff --git a/src/test/run-pass/abi/lib-defaults.rs b/src/test/run-pass/abi/lib-defaults.rs new file mode 100644 index 000000000000..dcf537866c50 --- /dev/null +++ b/src/test/run-pass/abi/lib-defaults.rs @@ -0,0 +1,16 @@ +// dont-check-compiler-stderr (rust-lang/rust#54222) + +// ignore-wasm32-bare no libc to test ffi with + +// compile-flags: -lrust_test_helpers + +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + pub fn rust_dbg_extern_identity_u32(x: u32) -> u32; +} + +fn main() { + unsafe { + rust_dbg_extern_identity_u32(42); + } +} diff --git a/src/test/run-pass/abi/macros/macros-in-extern.rs b/src/test/run-pass/abi/macros/macros-in-extern.rs new file mode 100644 index 000000000000..28abef5cf4ed --- /dev/null +++ b/src/test/run-pass/abi/macros/macros-in-extern.rs @@ -0,0 +1,30 @@ +// run-pass +// ignore-wasm32 + +#![feature(decl_macro, macros_in_extern)] + +macro_rules! returns_isize( + ($ident:ident) => ( + fn $ident() -> isize; + ) +); + +macro takes_u32_returns_u32($ident:ident) { + fn $ident (arg: u32) -> u32; +} + +macro_rules! emits_nothing( + () => () +); + +fn main() { + assert_eq!(unsafe { rust_get_test_int() }, 1isize); + assert_eq!(unsafe { rust_dbg_extern_identity_u32(0xDEADBEEF) }, 0xDEADBEEFu32); +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + returns_isize!(rust_get_test_int); + takes_u32_returns_u32!(rust_dbg_extern_identity_u32); + emits_nothing!(); +} diff --git a/src/test/run-pass/abi/mir/mir_codegen_calls_variadic.rs b/src/test/run-pass/abi/mir/mir_codegen_calls_variadic.rs new file mode 100644 index 000000000000..dc9fee03b776 --- /dev/null +++ b/src/test/run-pass/abi/mir/mir_codegen_calls_variadic.rs @@ -0,0 +1,22 @@ +// run-pass +// ignore-wasm32-bare no libc to test ffi with + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + fn rust_interesting_average(_: i64, ...) -> f64; +} + +fn test(a: i64, b: i64, c: i64, d: i64, e: i64, f: T, g: U) -> i64 { + unsafe { + rust_interesting_average(6, a, a as f64, + b, b as f64, + c, c as f64, + d, d as f64, + e, e as f64, + f, g) as i64 + } +} + +fn main(){ + assert_eq!(test(10, 20, 30, 40, 50, 60_i64, 60.0_f64), 70); +} diff --git a/src/test/run-pass/abi/numbers-arithmetic/i128-ffi.rs b/src/test/run-pass/abi/numbers-arithmetic/i128-ffi.rs new file mode 100644 index 000000000000..19edf9779f35 --- /dev/null +++ b/src/test/run-pass/abi/numbers-arithmetic/i128-ffi.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(improper_ctypes)] + +// MSVC doesn't support 128 bit integers, and other Windows +// C compilers have very inconsistent views on how the ABI +// should look like. + +// ignore-windows +// ignore-32bit + +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + fn identity(f: u128) -> u128; + fn square(f: i128) -> i128; + fn sub(f: i128, f: i128) -> i128; +} + +fn main() { + unsafe { + let a = 0x734C_C2F2_A521; + let b = 0x33EE_0E2A_54E2_59DA_A0E7_8E41; + let b_out = identity(b); + assert_eq!(b, b_out); + let a_square = square(a); + assert_eq!(b, a_square as u128); + let k = 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210; + let k_d = 0x2468_ACF1_3579_BDFF_DB97_530E_CA86_420; + let k_out = sub(k_d, k); + assert_eq!(k, k_out); + } +} diff --git a/src/test/run-pass/abi/proc_macro/macros-in-extern.rs b/src/test/run-pass/abi/proc_macro/macros-in-extern.rs new file mode 100644 index 000000000000..99e3f7d14fd1 --- /dev/null +++ b/src/test/run-pass/abi/proc_macro/macros-in-extern.rs @@ -0,0 +1,24 @@ +// aux-build:test-macros.rs +// ignore-wasm32 + +#![feature(macros_in_extern)] + +extern crate test_macros; + +use test_macros::{nop_attr, no_output, emit_input}; + +fn main() { + assert_eq!(unsafe { rust_get_test_int() }, 1isize); + assert_eq!(unsafe { rust_dbg_extern_identity_u32(0xDEADBEEF) }, 0xDEADBEEF); +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + #[no_output] + fn some_definitely_unknown_symbol_which_should_be_removed(); + + #[nop_attr] + fn rust_get_test_int() -> isize; + + emit_input!(fn rust_dbg_extern_identity_u32(arg: u32) -> u32;); +} diff --git a/src/test/run-pass/abi/rfcs/rfc1717/library-override.rs b/src/test/run-pass/abi/rfcs/rfc1717/library-override.rs new file mode 100644 index 000000000000..014ccac31b7a --- /dev/null +++ b/src/test/run-pass/abi/rfcs/rfc1717/library-override.rs @@ -0,0 +1,14 @@ +// run-pass +// ignore-wasm32-bare no libc to test ffi with +// compile-flags: -lstatic=wronglibrary:rust_test_helpers + +#[link(name = "wronglibrary", kind = "dylib")] +extern "C" { + pub fn rust_dbg_extern_identity_u32(x: u32) -> u32; +} + +fn main() { + unsafe { + rust_dbg_extern_identity_u32(42); + } +} diff --git a/src/test/run-pass/abi/segfault-no-out-of-stack.rs b/src/test/run-pass/abi/segfault-no-out-of-stack.rs new file mode 100644 index 000000000000..e90efface687 --- /dev/null +++ b/src/test/run-pass/abi/segfault-no-out-of-stack.rs @@ -0,0 +1,48 @@ +#![allow(unused_imports)] +// ignore-cloudabi can't run commands +// ignore-emscripten can't run commands +// ignore-sgx no processes + +#![feature(rustc_private)] + +extern crate libc; + +use std::process::{Command, ExitStatus}; +use std::env; + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + fn rust_get_null_ptr() -> *mut ::libc::c_char; +} + +#[cfg(unix)] +fn check_status(status: std::process::ExitStatus) +{ + use libc; + use std::os::unix::process::ExitStatusExt; + + assert!(status.signal() == Some(libc::SIGSEGV) + || status.signal() == Some(libc::SIGBUS)); +} + +#[cfg(not(unix))] +fn check_status(status: std::process::ExitStatus) +{ + assert!(!status.success()); +} + +fn main() { + let args: Vec = env::args().collect(); + if args.len() > 1 && args[1] == "segfault" { + unsafe { *rust_get_null_ptr() = 1; }; // trigger a segfault + } else { + let segfault = Command::new(&args[0]).arg("segfault").output().unwrap(); + let stderr = String::from_utf8_lossy(&segfault.stderr); + let stdout = String::from_utf8_lossy(&segfault.stdout); + println!("stdout: {}", stdout); + println!("stderr: {}", stderr); + println!("status: {}", segfault.status); + check_status(segfault.status); + assert!(!stderr.contains("has overflowed its stack")); + } +} diff --git a/src/test/run-pass/abi/stack-probes.rs b/src/test/run-pass/abi/stack-probes.rs new file mode 100644 index 000000000000..773d0ace90ed --- /dev/null +++ b/src/test/run-pass/abi/stack-probes.rs @@ -0,0 +1,67 @@ +// ignore-arm +// ignore-aarch64 +// ignore-mips +// ignore-mips64 +// ignore-powerpc +// ignore-s390x +// ignore-sparc +// ignore-sparc64 +// ignore-wasm +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes +// ignore-musl FIXME #31506 + +use std::mem; +use std::process::Command; +use std::thread; +use std::env; + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + #[link_name = "rust_dbg_extern_identity_u64"] + fn black_box(u: u64); +} + +fn main() { + let args = env::args().skip(1).collect::>(); + if args.len() > 0 { + match &args[0][..] { + "main-thread" => recurse(&[]), + "child-thread" => thread::spawn(|| recurse(&[])).join().unwrap(), + _ => panic!(), + } + return + } + + let me = env::current_exe().unwrap(); + + // The linux kernel has some different behavior for the main thread because + // the main thread's stack can typically grow. We can't always guarantee + // that we report stack overflow on the main thread, see #43052 for some + // details + if cfg!(not(target_os = "linux")) { + assert_overflow(Command::new(&me).arg("main-thread")); + } + assert_overflow(Command::new(&me).arg("child-thread")); +} + +#[allow(unconditional_recursion)] +fn recurse(array: &[u64]) { + unsafe { black_box(array.as_ptr() as u64); } + #[allow(deprecated)] + let local: [_; 1024] = unsafe { mem::uninitialized() }; + recurse(&local); +} + +fn assert_overflow(cmd: &mut Command) { + let output = cmd.output().unwrap(); + assert!(!output.status.success()); + let stdout = String::from_utf8_lossy(&output.stdout); + let stderr = String::from_utf8_lossy(&output.stderr); + println!("status: {}", output.status); + println!("stdout: {}", stdout); + println!("stderr: {}", stderr); + assert!(stdout.is_empty()); + assert!(stderr.contains("has overflowed its stack\n")); +} diff --git a/src/test/run-pass/abi/statics/static-mut-foreign.rs b/src/test/run-pass/abi/statics/static-mut-foreign.rs new file mode 100644 index 000000000000..5d6fa416b989 --- /dev/null +++ b/src/test/run-pass/abi/statics/static-mut-foreign.rs @@ -0,0 +1,41 @@ +// run-pass +// Constants (static variables) can be used to match in patterns, but mutable +// statics cannot. This ensures that there's some form of error if this is +// attempted. + +// ignore-wasm32-bare no libc to test ffi with + +#![feature(rustc_private)] + +extern crate libc; + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + static mut rust_dbg_static_mut: libc::c_int; + pub fn rust_dbg_static_mut_check_four(); +} + +unsafe fn static_bound(_: &'static libc::c_int) {} + +fn static_bound_set(a: &'static mut libc::c_int) { + *a = 3; +} + +unsafe fn run() { + assert_eq!(rust_dbg_static_mut, 3); + rust_dbg_static_mut = 4; + assert_eq!(rust_dbg_static_mut, 4); + rust_dbg_static_mut_check_four(); + rust_dbg_static_mut += 1; + assert_eq!(rust_dbg_static_mut, 5); + rust_dbg_static_mut *= 3; + assert_eq!(rust_dbg_static_mut, 15); + rust_dbg_static_mut = -3; + assert_eq!(rust_dbg_static_mut, -3); + static_bound(&rust_dbg_static_mut); + static_bound_set(&mut rust_dbg_static_mut); +} + +pub fn main() { + unsafe { run() } +} diff --git a/src/test/run-pass/abi/structs-enums/struct-return.rs b/src/test/run-pass/abi/structs-enums/struct-return.rs new file mode 100644 index 000000000000..5930fc4acbbe --- /dev/null +++ b/src/test/run-pass/abi/structs-enums/struct-return.rs @@ -0,0 +1,64 @@ +// run-pass +#![allow(dead_code)] +// ignore-wasm32-bare no libc to test ffi with + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct Quad { a: u64, b: u64, c: u64, d: u64 } + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct Floats { a: f64, b: u8, c: f64 } + +mod rustrt { + use super::{Floats, Quad}; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn rust_dbg_abi_1(q: Quad) -> Quad; + pub fn rust_dbg_abi_2(f: Floats) -> Floats; + } +} + +fn test1() { + unsafe { + let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa, + b: 0xbbbb_bbbb_bbbb_bbbb, + c: 0xcccc_cccc_cccc_cccc, + d: 0xdddd_dddd_dddd_dddd }; + let qq = rustrt::rust_dbg_abi_1(q); + println!("a: {:x}", qq.a as usize); + println!("b: {:x}", qq.b as usize); + println!("c: {:x}", qq.c as usize); + println!("d: {:x}", qq.d as usize); + assert_eq!(qq.a, q.c + 1); + assert_eq!(qq.b, q.d - 1); + assert_eq!(qq.c, q.a + 1); + assert_eq!(qq.d, q.b - 1); + } +} + +#[cfg(target_pointer_width = "64")] +fn test2() { + unsafe { + let f = Floats { a: 1.234567890e-15_f64, + b: 0b_1010_1010, + c: 1.0987654321e-15_f64 }; + let ff = rustrt::rust_dbg_abi_2(f); + println!("a: {}", ff.a as f64); + println!("b: {}", ff.b as usize); + println!("c: {}", ff.c as f64); + assert_eq!(ff.a, f.c + 1.0f64); + assert_eq!(ff.b, 0xff); + assert_eq!(ff.c, f.a - 1.0f64); + } +} + +#[cfg(target_pointer_width = "32")] +fn test2() { +} + +pub fn main() { + test1(); + test2(); +} diff --git a/src/test/run-pass/abi/union/union-c-interop.rs b/src/test/run-pass/abi/union/union-c-interop.rs new file mode 100644 index 000000000000..00f04d5b7ff3 --- /dev/null +++ b/src/test/run-pass/abi/union/union-c-interop.rs @@ -0,0 +1,37 @@ +// run-pass +#![allow(non_snake_case)] + +// ignore-wasm32-bare no libc to test ffi with + +#[derive(Clone, Copy)] +#[repr(C)] +struct LARGE_INTEGER_U { + LowPart: u32, + HighPart: u32, +} + +#[derive(Clone, Copy)] +#[repr(C)] +union LARGE_INTEGER { + __unnamed__: LARGE_INTEGER_U, + u: LARGE_INTEGER_U, + QuadPart: u64, +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + fn increment_all_parts(_: LARGE_INTEGER) -> LARGE_INTEGER; +} + +fn main() { + unsafe { + let mut li = LARGE_INTEGER { QuadPart: 0 }; + let li_c = increment_all_parts(li); + li.__unnamed__.LowPart += 1; + li.__unnamed__.HighPart += 1; + li.u.LowPart += 1; + li.u.HighPart += 1; + li.QuadPart += 1; + assert_eq!(li.QuadPart, li_c.QuadPart); + } +} diff --git a/src/test/run-pass/abi/variadic-ffi.rs b/src/test/run-pass/abi/variadic-ffi.rs new file mode 100644 index 000000000000..d6fbb1773b29 --- /dev/null +++ b/src/test/run-pass/abi/variadic-ffi.rs @@ -0,0 +1,83 @@ +// ignore-wasm32-bare no libc to test ffi with +#![feature(c_variadic)] + +use std::ffi::VaList; + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + fn rust_interesting_average(_: u64, ...) -> f64; + + // FIXME: we need to disable this lint for `VaList`, + // since it contains a `MaybeUninit` on the asmjs target, + // and this type isn't FFI-safe. This is OK for now, + // since the type is layout-compatible with `i32`. + #[cfg_attr(target_arch = "asmjs", allow(improper_ctypes))] + fn rust_valist_interesting_average(_: u64, _: VaList) -> f64; +} + +pub unsafe extern "C" fn test_valist_forward(n: u64, mut ap: ...) -> f64 { + rust_valist_interesting_average(n, ap.as_va_list()) +} + +pub unsafe extern "C" fn test_va_copy(_: u64, mut ap: ...) { + let mut ap2 = ap.clone(); + assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 30); + + // Advance one pair in the copy before checking + let mut ap2 = ap.clone(); + let _ = ap2.arg::(); + let _ = ap2.arg::(); + assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 50); + + // Advance one pair in the original + let _ = ap.arg::(); + let _ = ap.arg::(); + + let mut ap2 = ap.clone(); + assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 50); + + let mut ap2 = ap.clone(); + let _ = ap2.arg::(); + let _ = ap2.arg::(); + assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 70); +} + +pub fn main() { + // Call without variadic arguments + unsafe { + assert!(rust_interesting_average(0).is_nan()); + } + + // Call with direct arguments + unsafe { + assert_eq!(rust_interesting_average(1, 10i64, 10.0f64) as i64, 20); + } + + // Call with named arguments, variable number of them + let (x1, x2, x3, x4) = (10i64, 10.0f64, 20i64, 20.0f64); + unsafe { + assert_eq!(rust_interesting_average(2, x1, x2, x3, x4) as i64, 30); + } + + // A function that takes a function pointer + unsafe fn call(fp: unsafe extern fn(u64, ...) -> f64) { + let (x1, x2, x3, x4) = (10i64, 10.0f64, 20i64, 20.0f64); + assert_eq!(fp(2, x1, x2, x3, x4) as i64, 30); + } + + unsafe { + call(rust_interesting_average); + + // Make a function pointer, pass indirectly + let x: unsafe extern fn(u64, ...) -> f64 = rust_interesting_average; + call(x); + } + + unsafe { + assert_eq!(test_valist_forward(2, 10i64, 10f64, 20i64, 20f64) as i64, 30); + } + + unsafe { + test_va_copy(4, 10i64, 10f64, 20i64, 20f64, 30i64, 30f64, 40i64, 40f64); + } +} From 98325eb592f537e87100199c0c67682306df3fa4 Mon Sep 17 00:00:00 2001 From: Kevin Per Date: Tue, 9 Jul 2019 09:05:45 +0200 Subject: [PATCH 11/35] Grouping ABI tests (2) #62401 --- .../abi/extern/extern-pass-TwoU32s.rs | 25 +++++++++++++++++++ .../abi/extern/extern-pass-TwoU64s.rs | 25 +++++++++++++++++++ .../run-pass/abi/extern/extern-pass-u32.rs | 16 ++++++++++++ .../run-pass/abi/extern/extern-pass-u64.rs | 16 ++++++++++++ 4 files changed, 82 insertions(+) create mode 100644 src/test/run-pass/abi/extern/extern-pass-TwoU32s.rs create mode 100644 src/test/run-pass/abi/extern/extern-pass-TwoU64s.rs create mode 100644 src/test/run-pass/abi/extern/extern-pass-u32.rs create mode 100644 src/test/run-pass/abi/extern/extern-pass-u64.rs diff --git a/src/test/run-pass/abi/extern/extern-pass-TwoU32s.rs b/src/test/run-pass/abi/extern/extern-pass-TwoU32s.rs new file mode 100644 index 000000000000..fb18aa8d22fd --- /dev/null +++ b/src/test/run-pass/abi/extern/extern-pass-TwoU32s.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc for ffi testing + +// Test a foreign function that accepts and returns a struct +// by value. + +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct TwoU32s { + one: u32, two: u32 +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s; +} + +pub fn main() { + unsafe { + let x = TwoU32s {one: 22, two: 23}; + let y = rust_dbg_extern_identity_TwoU32s(x); + assert_eq!(x, y); + } +} diff --git a/src/test/run-pass/abi/extern/extern-pass-TwoU64s.rs b/src/test/run-pass/abi/extern/extern-pass-TwoU64s.rs new file mode 100644 index 000000000000..419648263aa9 --- /dev/null +++ b/src/test/run-pass/abi/extern/extern-pass-TwoU64s.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc for ffi testing + +// Test a foreign function that accepts and returns a struct +// by value. + +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct TwoU64s { + one: u64, two: u64 +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s; +} + +pub fn main() { + unsafe { + let x = TwoU64s {one: 22, two: 23}; + let y = rust_dbg_extern_identity_TwoU64s(x); + assert_eq!(x, y); + } +} diff --git a/src/test/run-pass/abi/extern/extern-pass-u32.rs b/src/test/run-pass/abi/extern/extern-pass-u32.rs new file mode 100644 index 000000000000..f2efdb7d3664 --- /dev/null +++ b/src/test/run-pass/abi/extern/extern-pass-u32.rs @@ -0,0 +1,16 @@ +// run-pass +// ignore-wasm32-bare no libc for ffi testing + +// Test a function that takes/returns a u32. + + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_identity_u32(v: u32) -> u32; +} + +pub fn main() { + unsafe { + assert_eq!(22, rust_dbg_extern_identity_u32(22)); + } +} diff --git a/src/test/run-pass/abi/extern/extern-pass-u64.rs b/src/test/run-pass/abi/extern/extern-pass-u64.rs new file mode 100644 index 000000000000..975446d430c2 --- /dev/null +++ b/src/test/run-pass/abi/extern/extern-pass-u64.rs @@ -0,0 +1,16 @@ +// run-pass +// ignore-wasm32-bare no libc for ffi testing + +// Test a call to a function that takes/returns a u64. + + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_identity_u64(v: u64) -> u64; +} + +pub fn main() { + unsafe { + assert_eq!(22, rust_dbg_extern_identity_u64(22)); + } +} From cac53fe3f24f9862d7faa85296f348e17c729bc4 Mon Sep 17 00:00:00 2001 From: Kevin Per Date: Thu, 11 Jul 2019 19:40:09 +0200 Subject: [PATCH 12/35] Fixing broken tests #62401 The grouping led to a lot of `mv`. Therefore, some relative paths were wrong. In this commit the dependent files were also moved so that the paths work again. --- .../anon-extern-mod-cross-crate-2.rs | 14 ++++++++++ .../run-pass/abi/duplicated-external-mods.rs | 8 ++++++ .../run-pass/abi/extern/extern-crosscrate.rs | 21 +++++++++++++++ src/test/run-pass/abi/foreign/foreign-dupe.rs | 17 ++++++++++++ .../run-pass/abi/invoke-external-foreign.rs | 16 ++++++++++++ .../abi/issues/auxiliary/issue-25185-2.rs | 3 +++ src/test/run-pass/abi/issues/issue-25185.rs | 13 ++++++++++ .../abi/proc_macro/auxiliary/test-macros.rs | 26 +++++++++++++++++++ src/test/run-pass/abi/stack-probes-lto.rs | 18 +++++++++++++ 9 files changed, 136 insertions(+) create mode 100644 src/test/run-pass/abi/cross-crate/anon-extern-mod-cross-crate-2.rs create mode 100644 src/test/run-pass/abi/duplicated-external-mods.rs create mode 100644 src/test/run-pass/abi/extern/extern-crosscrate.rs create mode 100644 src/test/run-pass/abi/foreign/foreign-dupe.rs create mode 100644 src/test/run-pass/abi/invoke-external-foreign.rs create mode 100644 src/test/run-pass/abi/issues/auxiliary/issue-25185-2.rs create mode 100644 src/test/run-pass/abi/issues/issue-25185.rs create mode 100644 src/test/run-pass/abi/proc_macro/auxiliary/test-macros.rs create mode 100644 src/test/run-pass/abi/stack-probes-lto.rs diff --git a/src/test/run-pass/abi/cross-crate/anon-extern-mod-cross-crate-2.rs b/src/test/run-pass/abi/cross-crate/anon-extern-mod-cross-crate-2.rs new file mode 100644 index 000000000000..77168be5374b --- /dev/null +++ b/src/test/run-pass/abi/cross-crate/anon-extern-mod-cross-crate-2.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:anon-extern-mod-cross-crate-1.rs +// pretty-expanded FIXME #23616 +// ignore-wasm32-bare no libc to test ffi with + +extern crate anonexternmod; + +use anonexternmod::rust_get_test_int; + +pub fn main() { + unsafe { + rust_get_test_int(); + } +} diff --git a/src/test/run-pass/abi/duplicated-external-mods.rs b/src/test/run-pass/abi/duplicated-external-mods.rs new file mode 100644 index 000000000000..f2c1e1f65401 --- /dev/null +++ b/src/test/run-pass/abi/duplicated-external-mods.rs @@ -0,0 +1,8 @@ +// aux-build:anon-extern-mod-cross-crate-1.rs +// aux-build:anon-extern-mod-cross-crate-1.rs +// pretty-expanded FIXME #23616 +// ignore-wasm32-bare no libc to test ffi with + +extern crate anonexternmod; + +pub fn main() { } diff --git a/src/test/run-pass/abi/extern/extern-crosscrate.rs b/src/test/run-pass/abi/extern/extern-crosscrate.rs new file mode 100644 index 000000000000..123ce20ca262 --- /dev/null +++ b/src/test/run-pass/abi/extern/extern-crosscrate.rs @@ -0,0 +1,21 @@ +// run-pass +// aux-build:extern-crosscrate-source.rs +// ignore-wasm32-bare no libc to test ffi with + +#![feature(rustc_private)] + +extern crate externcallback; +extern crate libc; + +fn fact(n: libc::uintptr_t) -> libc::uintptr_t { + unsafe { + println!("n = {}", n); + externcallback::rustrt::rust_dbg_call(externcallback::cb, n) + } +} + +pub fn main() { + let result = fact(10); + println!("result = {}", result); + assert_eq!(result, 3628800); +} diff --git a/src/test/run-pass/abi/foreign/foreign-dupe.rs b/src/test/run-pass/abi/foreign/foreign-dupe.rs new file mode 100644 index 000000000000..3c9f0f583d48 --- /dev/null +++ b/src/test/run-pass/abi/foreign/foreign-dupe.rs @@ -0,0 +1,17 @@ +// run-pass +// aux-build:foreign_lib.rs +// ignore-wasm32-bare no libc to test ffi with + +// Check that we can still call duplicated extern (imported) functions +// which were declared in another crate. See issues #32740 and #32783. + + +extern crate foreign_lib; + +pub fn main() { + unsafe { + let x = foreign_lib::rustrt::rust_get_test_int(); + assert_eq!(x, foreign_lib::rustrt2::rust_get_test_int()); + assert_eq!(x as *const _, foreign_lib::rustrt3::rust_get_test_int()); + } +} diff --git a/src/test/run-pass/abi/invoke-external-foreign.rs b/src/test/run-pass/abi/invoke-external-foreign.rs new file mode 100644 index 000000000000..d34933cde424 --- /dev/null +++ b/src/test/run-pass/abi/invoke-external-foreign.rs @@ -0,0 +1,16 @@ +// aux-build:foreign_lib.rs +// ignore-wasm32-bare no libc to test ffi with + +// The purpose of this test is to check that we can +// successfully (and safely) invoke external, cdecl +// functions from outside the crate. + +// pretty-expanded FIXME #23616 + +extern crate foreign_lib; + +pub fn main() { + unsafe { + let _foo = foreign_lib::rustrt::rust_get_test_int(); + } +} diff --git a/src/test/run-pass/abi/issues/auxiliary/issue-25185-2.rs b/src/test/run-pass/abi/issues/auxiliary/issue-25185-2.rs new file mode 100644 index 000000000000..7ce3df255a33 --- /dev/null +++ b/src/test/run-pass/abi/issues/auxiliary/issue-25185-2.rs @@ -0,0 +1,3 @@ +extern crate issue_25185_1; + +pub use issue_25185_1::rust_dbg_extern_identity_u32; diff --git a/src/test/run-pass/abi/issues/issue-25185.rs b/src/test/run-pass/abi/issues/issue-25185.rs new file mode 100644 index 000000000000..383c9a1e9c4a --- /dev/null +++ b/src/test/run-pass/abi/issues/issue-25185.rs @@ -0,0 +1,13 @@ +// run-pass +// aux-build:issue-25185-1.rs +// aux-build:issue-25185-2.rs +// ignore-wasm32-bare no libc for ffi testing + +extern crate issue_25185_2; + +fn main() { + let x = unsafe { + issue_25185_2::rust_dbg_extern_identity_u32(1) + }; + assert_eq!(x, 1); +} diff --git a/src/test/run-pass/abi/proc_macro/auxiliary/test-macros.rs b/src/test/run-pass/abi/proc_macro/auxiliary/test-macros.rs new file mode 100644 index 000000000000..15fe3804f9b4 --- /dev/null +++ b/src/test/run-pass/abi/proc_macro/auxiliary/test-macros.rs @@ -0,0 +1,26 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn nop_attr(_attr: TokenStream, input: TokenStream) -> TokenStream { + assert!(_attr.to_string().is_empty()); + input +} + +#[proc_macro_attribute] +pub fn no_output(_attr: TokenStream, _input: TokenStream) -> TokenStream { + assert!(_attr.to_string().is_empty()); + assert!(!_input.to_string().is_empty()); + "".parse().unwrap() +} + +#[proc_macro] +pub fn emit_input(input: TokenStream) -> TokenStream { + input +} diff --git a/src/test/run-pass/abi/stack-probes-lto.rs b/src/test/run-pass/abi/stack-probes-lto.rs new file mode 100644 index 000000000000..1274f032a3e2 --- /dev/null +++ b/src/test/run-pass/abi/stack-probes-lto.rs @@ -0,0 +1,18 @@ +// ignore-arm +// ignore-aarch64 +// ignore-mips +// ignore-mips64 +// ignore-powerpc +// ignore-s390x +// ignore-sparc +// ignore-sparc64 +// ignore-wasm +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes +// ignore-musl FIXME #31506 +// ignore-pretty +// compile-flags: -C lto +// no-prefer-dynamic + +include!("stack-probes.rs"); From 5941acd80faaf9043cb48737c47d0b94023eddc3 Mon Sep 17 00:00:00 2001 From: Marco A L Barbosa Date: Tue, 30 Jul 2019 16:31:26 -0300 Subject: [PATCH 13/35] Use libunwind from llvm-project submodule for musl targets --- src/bootstrap/sanity.rs | 4 ---- src/ci/docker/scripts/musl-toolchain.sh | 26 ------------------------- src/ci/docker/scripts/musl.sh | 26 ++----------------------- src/libunwind/Cargo.toml | 4 ++-- src/libunwind/build.rs | 16 +++++++++++---- 5 files changed, 16 insertions(+), 60 deletions(-) diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index 4e3930c8da7f..bffe748f37cc 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -202,10 +202,6 @@ pub fn check(build: &mut Build) { panic!("couldn't find libc.a in musl dir: {}", root.join("lib").display()); } - if fs::metadata(root.join("lib/libunwind.a")).is_err() { - panic!("couldn't find libunwind.a in musl dir: {}", - root.join("lib").display()); - } } None => { panic!("when targeting MUSL either the rust.musl-root \ diff --git a/src/ci/docker/scripts/musl-toolchain.sh b/src/ci/docker/scripts/musl-toolchain.sh index 55899fa6c3e6..74ba2f0eadb2 100644 --- a/src/ci/docker/scripts/musl-toolchain.sh +++ b/src/ci/docker/scripts/musl-toolchain.sh @@ -54,29 +54,3 @@ if [ "$REPLACE_CC" = "1" ]; then ln -s $TARGET-g++ /usr/local/bin/$exec done fi - -export CC=$TARGET-gcc -export CXX=$TARGET-g++ - -LLVM=70 - -# may have been downloaded in a previous run -if [ ! -d libunwind-release_$LLVM ]; then - curl -L https://github.com/llvm-mirror/llvm/archive/release_$LLVM.tar.gz | tar xzf - - curl -L https://github.com/llvm-mirror/libunwind/archive/release_$LLVM.tar.gz | tar xzf - -fi - -# fixme(mati865): Replace it with https://github.com/rust-lang/rust/pull/59089 -mkdir libunwind-build -cd libunwind-build -cmake ../libunwind-release_$LLVM \ - -DLLVM_PATH=/build/llvm-release_$LLVM \ - -DLIBUNWIND_ENABLE_SHARED=0 \ - -DCMAKE_C_COMPILER=$CC \ - -DCMAKE_CXX_COMPILER=$CXX \ - -DCMAKE_C_FLAGS="$CFLAGS" \ - -DCMAKE_CXX_FLAGS="$CXXFLAGS" - -hide_output make -j$(nproc) -cp lib/libunwind.a $OUTPUT/$TARGET/lib -cd - && rm -rf libunwind-build diff --git a/src/ci/docker/scripts/musl.sh b/src/ci/docker/scripts/musl.sh index c2cf77d56cb3..d847c407aba6 100644 --- a/src/ci/docker/scripts/musl.sh +++ b/src/ci/docker/scripts/musl.sh @@ -20,6 +20,8 @@ exit 1 TAG=$1 shift +# Ancient binutils versions don't understand debug symbols produced by more recent tools. +# Apparently applying `-fPIC` everywhere allows them to link successfully. export CFLAGS="-fPIC $CFLAGS" MUSL=musl-1.1.22 @@ -38,27 +40,3 @@ else fi hide_output make install hide_output make clean - -cd .. - -LLVM=70 - -# may have been downloaded in a previous run -if [ ! -d libunwind-release_$LLVM ]; then - curl -L https://github.com/llvm-mirror/llvm/archive/release_$LLVM.tar.gz | tar xzf - - curl -L https://github.com/llvm-mirror/libunwind/archive/release_$LLVM.tar.gz | tar xzf - -fi - -mkdir libunwind-build -cd libunwind-build -cmake ../libunwind-release_$LLVM \ - -DLLVM_PATH=/build/llvm-release_$LLVM \ - -DLIBUNWIND_ENABLE_SHARED=0 \ - -DCMAKE_C_COMPILER=$CC \ - -DCMAKE_CXX_COMPILER=$CXX \ - -DCMAKE_C_FLAGS="$CFLAGS" \ - -DCMAKE_CXX_FLAGS="$CXXFLAGS" - -hide_output make -j$(nproc) -cp lib/libunwind.a /musl-$TAG/lib -cd ../ && rm -rf libunwind-build diff --git a/src/libunwind/Cargo.toml b/src/libunwind/Cargo.toml index f0f1bab425d7..f10df8c85ba0 100644 --- a/src/libunwind/Cargo.toml +++ b/src/libunwind/Cargo.toml @@ -22,7 +22,7 @@ compiler_builtins = "0.1.0" cfg-if = "0.1.8" [build-dependencies] -cc = { optional = true, version = "1.0.1" } +cc = { version = "1.0.1" } [features] -llvm-libunwind = ["cc"] +llvm-libunwind = [] diff --git a/src/libunwind/build.rs b/src/libunwind/build.rs index c1b0dbc0881d..a266407c6029 100644 --- a/src/libunwind/build.rs +++ b/src/libunwind/build.rs @@ -5,14 +5,14 @@ fn main() { let target = env::var("TARGET").expect("TARGET was not set"); if cfg!(feature = "llvm-libunwind") && - (target.contains("linux") || + ((target.contains("linux") && !target.contains("musl")) || target.contains("fuchsia")) { // Build the unwinding from libunwind C/C++ source code. - #[cfg(feature = "llvm-libunwind")] llvm_libunwind::compile(); } else if target.contains("linux") { if target.contains("musl") { - // musl is handled in lib.rs + // linking for musl is handled in lib.rs + llvm_libunwind::compile(); } else if !target.contains("android") { println!("cargo:rustc-link-lib=gcc_s"); } @@ -44,7 +44,6 @@ fn main() { } } -#[cfg(feature = "llvm-libunwind")] mod llvm_libunwind { use std::env; use std::path::Path; @@ -96,6 +95,15 @@ mod llvm_libunwind { cfg.file(root.join("src").join(src)); } + if target_env == "musl" { + // use the same C compiler command to compile C++ code so we do not need to setup the + // C++ compiler env variables on the builders + cfg.cpp(false); + // linking for musl is handled in lib.rs + cfg.cargo_metadata(false); + println!("cargo:rustc-link-search=native={}", env::var("OUT_DIR").unwrap()); + } + cfg.compile("unwind"); } } From df713dd39709bfdc34f364cd78d345a29d7b9d8a Mon Sep 17 00:00:00 2001 From: Kevin Per Date: Thu, 15 Aug 2019 16:00:54 +0200 Subject: [PATCH 14/35] Group all ui tests and move to abi #62593 --- src/test/ui/{ => abi}/abi-sysv64-arg-passing.rs | 0 src/test/ui/{ => abi}/abi-sysv64-register-usage.rs | 0 src/test/ui/{ => abi}/abort-on-c-abi.rs | 0 src/test/ui/{ => abi}/anon-extern-mod.rs | 0 src/test/ui/{ => abi}/auxiliary/anon-extern-mod-cross-crate-1.rs | 0 src/test/ui/{ => abi}/auxiliary/foreign_lib.rs | 0 src/test/ui/{ => abi}/c-stack-as-value.rs | 0 src/test/ui/{ => abi}/cabi-int-widening.rs | 0 .../{ => abi}/consts/auxiliary/anon-extern-mod-cross-crate-1.rs | 0 .../ui/{ => abi}/cross-crate/anon-extern-mod-cross-crate-2.rs | 0 .../cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs | 0 src/test/ui/{ => abi}/duplicated-external-mods.rs | 0 .../ui/{ => abi}/extern/auxiliary/extern-crosscrate-source.rs | 0 src/test/ui/{ => abi}/extern/extern-call-deep.rs | 0 src/test/ui/{ => abi}/extern/extern-call-deep2.rs | 0 src/test/ui/{ => abi}/extern/extern-call-direct.rs | 0 src/test/ui/{ => abi}/extern/extern-call-indirect.rs | 0 src/test/ui/{ => abi}/extern/extern-call-scrub.rs | 0 src/test/ui/{ => abi}/extern/extern-crosscrate.rs | 0 src/test/ui/{ => abi}/extern/extern-pass-TwoU16s.rs | 0 src/test/ui/{ => abi}/extern/extern-pass-TwoU32s.rs | 0 src/test/ui/{ => abi}/extern/extern-pass-TwoU64s.rs | 0 src/test/ui/{ => abi}/extern/extern-pass-TwoU8s.rs | 0 src/test/ui/{ => abi}/extern/extern-pass-char.rs | 0 src/test/ui/{ => abi}/extern/extern-pass-double.rs | 0 src/test/ui/{ => abi}/extern/extern-pass-empty.rs | 0 src/test/ui/{ => abi}/extern/extern-pass-u32.rs | 0 src/test/ui/{ => abi}/extern/extern-pass-u64.rs | 0 src/test/ui/{ => abi}/extern/extern-return-TwoU16s.rs | 0 src/test/ui/{ => abi}/extern/extern-return-TwoU32s.rs | 0 src/test/ui/{ => abi}/extern/extern-return-TwoU64s.rs | 0 src/test/ui/{ => abi}/extern/extern-return-TwoU8s.rs | 0 src/test/ui/{ => abi}/foreign/auxiliary/foreign_lib.rs | 0 src/test/ui/{ => abi}/foreign/foreign-call-no-runtime.rs | 0 src/test/ui/{ => abi}/foreign/foreign-dupe.rs | 0 src/test/ui/{ => abi}/foreign/foreign-fn-with-byval.rs | 0 src/test/ui/{ => abi}/foreign/foreign-no-abi.rs | 0 src/test/ui/{ => abi}/invoke-external-foreign.rs | 0 src/test/ui/{ => abi}/lib-defaults.rs | 0 src/test/ui/{ => abi}/macros/macros-in-extern.rs | 0 src/test/ui/{ => abi}/macros/macros-in-extern.stderr | 0 src/test/ui/{ => abi}/mir/mir_codegen_calls_variadic.rs | 0 src/test/ui/{ => abi}/numbers-arithmetic/i128-ffi.rs | 0 src/test/ui/{ => abi}/proc-macro/auxiliary/test-macros.rs | 0 src/test/ui/{ => abi}/proc-macro/macros-in-extern.rs | 0 src/test/ui/{ => abi}/proc-macro/macros-in-extern.stderr | 0 src/test/ui/{ => abi}/segfault-no-out-of-stack.rs | 0 src/test/ui/{ => abi}/stack-probes-lto.rs | 0 src/test/ui/{ => abi}/stack-probes.rs | 0 src/test/ui/{ => abi}/statics/static-mut-foreign.rs | 0 src/test/ui/{structs-enums => abi/struct-enums}/struct-return.rs | 0 src/test/ui/{ => abi}/union/union-c-interop.rs | 0 src/test/ui/{ => abi}/variadic-ffi.rs | 0 53 files changed, 0 insertions(+), 0 deletions(-) rename src/test/ui/{ => abi}/abi-sysv64-arg-passing.rs (100%) rename src/test/ui/{ => abi}/abi-sysv64-register-usage.rs (100%) rename src/test/ui/{ => abi}/abort-on-c-abi.rs (100%) rename src/test/ui/{ => abi}/anon-extern-mod.rs (100%) rename src/test/ui/{ => abi}/auxiliary/anon-extern-mod-cross-crate-1.rs (100%) rename src/test/ui/{ => abi}/auxiliary/foreign_lib.rs (100%) rename src/test/ui/{ => abi}/c-stack-as-value.rs (100%) rename src/test/ui/{ => abi}/cabi-int-widening.rs (100%) rename src/test/ui/{ => abi}/consts/auxiliary/anon-extern-mod-cross-crate-1.rs (100%) rename src/test/ui/{ => abi}/cross-crate/anon-extern-mod-cross-crate-2.rs (100%) rename src/test/ui/{ => abi}/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs (100%) rename src/test/ui/{ => abi}/duplicated-external-mods.rs (100%) rename src/test/ui/{ => abi}/extern/auxiliary/extern-crosscrate-source.rs (100%) rename src/test/ui/{ => abi}/extern/extern-call-deep.rs (100%) rename src/test/ui/{ => abi}/extern/extern-call-deep2.rs (100%) rename src/test/ui/{ => abi}/extern/extern-call-direct.rs (100%) rename src/test/ui/{ => abi}/extern/extern-call-indirect.rs (100%) rename src/test/ui/{ => abi}/extern/extern-call-scrub.rs (100%) rename src/test/ui/{ => abi}/extern/extern-crosscrate.rs (100%) rename src/test/ui/{ => abi}/extern/extern-pass-TwoU16s.rs (100%) rename src/test/ui/{ => abi}/extern/extern-pass-TwoU32s.rs (100%) rename src/test/ui/{ => abi}/extern/extern-pass-TwoU64s.rs (100%) rename src/test/ui/{ => abi}/extern/extern-pass-TwoU8s.rs (100%) rename src/test/ui/{ => abi}/extern/extern-pass-char.rs (100%) rename src/test/ui/{ => abi}/extern/extern-pass-double.rs (100%) rename src/test/ui/{ => abi}/extern/extern-pass-empty.rs (100%) rename src/test/ui/{ => abi}/extern/extern-pass-u32.rs (100%) rename src/test/ui/{ => abi}/extern/extern-pass-u64.rs (100%) rename src/test/ui/{ => abi}/extern/extern-return-TwoU16s.rs (100%) rename src/test/ui/{ => abi}/extern/extern-return-TwoU32s.rs (100%) rename src/test/ui/{ => abi}/extern/extern-return-TwoU64s.rs (100%) rename src/test/ui/{ => abi}/extern/extern-return-TwoU8s.rs (100%) rename src/test/ui/{ => abi}/foreign/auxiliary/foreign_lib.rs (100%) rename src/test/ui/{ => abi}/foreign/foreign-call-no-runtime.rs (100%) rename src/test/ui/{ => abi}/foreign/foreign-dupe.rs (100%) rename src/test/ui/{ => abi}/foreign/foreign-fn-with-byval.rs (100%) rename src/test/ui/{ => abi}/foreign/foreign-no-abi.rs (100%) rename src/test/ui/{ => abi}/invoke-external-foreign.rs (100%) rename src/test/ui/{ => abi}/lib-defaults.rs (100%) rename src/test/ui/{ => abi}/macros/macros-in-extern.rs (100%) rename src/test/ui/{ => abi}/macros/macros-in-extern.stderr (100%) rename src/test/ui/{ => abi}/mir/mir_codegen_calls_variadic.rs (100%) rename src/test/ui/{ => abi}/numbers-arithmetic/i128-ffi.rs (100%) rename src/test/ui/{ => abi}/proc-macro/auxiliary/test-macros.rs (100%) rename src/test/ui/{ => abi}/proc-macro/macros-in-extern.rs (100%) rename src/test/ui/{ => abi}/proc-macro/macros-in-extern.stderr (100%) rename src/test/ui/{ => abi}/segfault-no-out-of-stack.rs (100%) rename src/test/ui/{ => abi}/stack-probes-lto.rs (100%) rename src/test/ui/{ => abi}/stack-probes.rs (100%) rename src/test/ui/{ => abi}/statics/static-mut-foreign.rs (100%) rename src/test/ui/{structs-enums => abi/struct-enums}/struct-return.rs (100%) rename src/test/ui/{ => abi}/union/union-c-interop.rs (100%) rename src/test/ui/{ => abi}/variadic-ffi.rs (100%) diff --git a/src/test/ui/abi-sysv64-arg-passing.rs b/src/test/ui/abi/abi-sysv64-arg-passing.rs similarity index 100% rename from src/test/ui/abi-sysv64-arg-passing.rs rename to src/test/ui/abi/abi-sysv64-arg-passing.rs diff --git a/src/test/ui/abi-sysv64-register-usage.rs b/src/test/ui/abi/abi-sysv64-register-usage.rs similarity index 100% rename from src/test/ui/abi-sysv64-register-usage.rs rename to src/test/ui/abi/abi-sysv64-register-usage.rs diff --git a/src/test/ui/abort-on-c-abi.rs b/src/test/ui/abi/abort-on-c-abi.rs similarity index 100% rename from src/test/ui/abort-on-c-abi.rs rename to src/test/ui/abi/abort-on-c-abi.rs diff --git a/src/test/ui/anon-extern-mod.rs b/src/test/ui/abi/anon-extern-mod.rs similarity index 100% rename from src/test/ui/anon-extern-mod.rs rename to src/test/ui/abi/anon-extern-mod.rs diff --git a/src/test/ui/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/ui/abi/auxiliary/anon-extern-mod-cross-crate-1.rs similarity index 100% rename from src/test/ui/auxiliary/anon-extern-mod-cross-crate-1.rs rename to src/test/ui/abi/auxiliary/anon-extern-mod-cross-crate-1.rs diff --git a/src/test/ui/auxiliary/foreign_lib.rs b/src/test/ui/abi/auxiliary/foreign_lib.rs similarity index 100% rename from src/test/ui/auxiliary/foreign_lib.rs rename to src/test/ui/abi/auxiliary/foreign_lib.rs diff --git a/src/test/ui/c-stack-as-value.rs b/src/test/ui/abi/c-stack-as-value.rs similarity index 100% rename from src/test/ui/c-stack-as-value.rs rename to src/test/ui/abi/c-stack-as-value.rs diff --git a/src/test/ui/cabi-int-widening.rs b/src/test/ui/abi/cabi-int-widening.rs similarity index 100% rename from src/test/ui/cabi-int-widening.rs rename to src/test/ui/abi/cabi-int-widening.rs diff --git a/src/test/ui/consts/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/ui/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs similarity index 100% rename from src/test/ui/consts/auxiliary/anon-extern-mod-cross-crate-1.rs rename to src/test/ui/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs diff --git a/src/test/ui/cross-crate/anon-extern-mod-cross-crate-2.rs b/src/test/ui/abi/cross-crate/anon-extern-mod-cross-crate-2.rs similarity index 100% rename from src/test/ui/cross-crate/anon-extern-mod-cross-crate-2.rs rename to src/test/ui/abi/cross-crate/anon-extern-mod-cross-crate-2.rs diff --git a/src/test/ui/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/ui/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs similarity index 100% rename from src/test/ui/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs rename to src/test/ui/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs diff --git a/src/test/ui/duplicated-external-mods.rs b/src/test/ui/abi/duplicated-external-mods.rs similarity index 100% rename from src/test/ui/duplicated-external-mods.rs rename to src/test/ui/abi/duplicated-external-mods.rs diff --git a/src/test/ui/extern/auxiliary/extern-crosscrate-source.rs b/src/test/ui/abi/extern/auxiliary/extern-crosscrate-source.rs similarity index 100% rename from src/test/ui/extern/auxiliary/extern-crosscrate-source.rs rename to src/test/ui/abi/extern/auxiliary/extern-crosscrate-source.rs diff --git a/src/test/ui/extern/extern-call-deep.rs b/src/test/ui/abi/extern/extern-call-deep.rs similarity index 100% rename from src/test/ui/extern/extern-call-deep.rs rename to src/test/ui/abi/extern/extern-call-deep.rs diff --git a/src/test/ui/extern/extern-call-deep2.rs b/src/test/ui/abi/extern/extern-call-deep2.rs similarity index 100% rename from src/test/ui/extern/extern-call-deep2.rs rename to src/test/ui/abi/extern/extern-call-deep2.rs diff --git a/src/test/ui/extern/extern-call-direct.rs b/src/test/ui/abi/extern/extern-call-direct.rs similarity index 100% rename from src/test/ui/extern/extern-call-direct.rs rename to src/test/ui/abi/extern/extern-call-direct.rs diff --git a/src/test/ui/extern/extern-call-indirect.rs b/src/test/ui/abi/extern/extern-call-indirect.rs similarity index 100% rename from src/test/ui/extern/extern-call-indirect.rs rename to src/test/ui/abi/extern/extern-call-indirect.rs diff --git a/src/test/ui/extern/extern-call-scrub.rs b/src/test/ui/abi/extern/extern-call-scrub.rs similarity index 100% rename from src/test/ui/extern/extern-call-scrub.rs rename to src/test/ui/abi/extern/extern-call-scrub.rs diff --git a/src/test/ui/extern/extern-crosscrate.rs b/src/test/ui/abi/extern/extern-crosscrate.rs similarity index 100% rename from src/test/ui/extern/extern-crosscrate.rs rename to src/test/ui/abi/extern/extern-crosscrate.rs diff --git a/src/test/ui/extern/extern-pass-TwoU16s.rs b/src/test/ui/abi/extern/extern-pass-TwoU16s.rs similarity index 100% rename from src/test/ui/extern/extern-pass-TwoU16s.rs rename to src/test/ui/abi/extern/extern-pass-TwoU16s.rs diff --git a/src/test/ui/extern/extern-pass-TwoU32s.rs b/src/test/ui/abi/extern/extern-pass-TwoU32s.rs similarity index 100% rename from src/test/ui/extern/extern-pass-TwoU32s.rs rename to src/test/ui/abi/extern/extern-pass-TwoU32s.rs diff --git a/src/test/ui/extern/extern-pass-TwoU64s.rs b/src/test/ui/abi/extern/extern-pass-TwoU64s.rs similarity index 100% rename from src/test/ui/extern/extern-pass-TwoU64s.rs rename to src/test/ui/abi/extern/extern-pass-TwoU64s.rs diff --git a/src/test/ui/extern/extern-pass-TwoU8s.rs b/src/test/ui/abi/extern/extern-pass-TwoU8s.rs similarity index 100% rename from src/test/ui/extern/extern-pass-TwoU8s.rs rename to src/test/ui/abi/extern/extern-pass-TwoU8s.rs diff --git a/src/test/ui/extern/extern-pass-char.rs b/src/test/ui/abi/extern/extern-pass-char.rs similarity index 100% rename from src/test/ui/extern/extern-pass-char.rs rename to src/test/ui/abi/extern/extern-pass-char.rs diff --git a/src/test/ui/extern/extern-pass-double.rs b/src/test/ui/abi/extern/extern-pass-double.rs similarity index 100% rename from src/test/ui/extern/extern-pass-double.rs rename to src/test/ui/abi/extern/extern-pass-double.rs diff --git a/src/test/ui/extern/extern-pass-empty.rs b/src/test/ui/abi/extern/extern-pass-empty.rs similarity index 100% rename from src/test/ui/extern/extern-pass-empty.rs rename to src/test/ui/abi/extern/extern-pass-empty.rs diff --git a/src/test/ui/extern/extern-pass-u32.rs b/src/test/ui/abi/extern/extern-pass-u32.rs similarity index 100% rename from src/test/ui/extern/extern-pass-u32.rs rename to src/test/ui/abi/extern/extern-pass-u32.rs diff --git a/src/test/ui/extern/extern-pass-u64.rs b/src/test/ui/abi/extern/extern-pass-u64.rs similarity index 100% rename from src/test/ui/extern/extern-pass-u64.rs rename to src/test/ui/abi/extern/extern-pass-u64.rs diff --git a/src/test/ui/extern/extern-return-TwoU16s.rs b/src/test/ui/abi/extern/extern-return-TwoU16s.rs similarity index 100% rename from src/test/ui/extern/extern-return-TwoU16s.rs rename to src/test/ui/abi/extern/extern-return-TwoU16s.rs diff --git a/src/test/ui/extern/extern-return-TwoU32s.rs b/src/test/ui/abi/extern/extern-return-TwoU32s.rs similarity index 100% rename from src/test/ui/extern/extern-return-TwoU32s.rs rename to src/test/ui/abi/extern/extern-return-TwoU32s.rs diff --git a/src/test/ui/extern/extern-return-TwoU64s.rs b/src/test/ui/abi/extern/extern-return-TwoU64s.rs similarity index 100% rename from src/test/ui/extern/extern-return-TwoU64s.rs rename to src/test/ui/abi/extern/extern-return-TwoU64s.rs diff --git a/src/test/ui/extern/extern-return-TwoU8s.rs b/src/test/ui/abi/extern/extern-return-TwoU8s.rs similarity index 100% rename from src/test/ui/extern/extern-return-TwoU8s.rs rename to src/test/ui/abi/extern/extern-return-TwoU8s.rs diff --git a/src/test/ui/foreign/auxiliary/foreign_lib.rs b/src/test/ui/abi/foreign/auxiliary/foreign_lib.rs similarity index 100% rename from src/test/ui/foreign/auxiliary/foreign_lib.rs rename to src/test/ui/abi/foreign/auxiliary/foreign_lib.rs diff --git a/src/test/ui/foreign/foreign-call-no-runtime.rs b/src/test/ui/abi/foreign/foreign-call-no-runtime.rs similarity index 100% rename from src/test/ui/foreign/foreign-call-no-runtime.rs rename to src/test/ui/abi/foreign/foreign-call-no-runtime.rs diff --git a/src/test/ui/foreign/foreign-dupe.rs b/src/test/ui/abi/foreign/foreign-dupe.rs similarity index 100% rename from src/test/ui/foreign/foreign-dupe.rs rename to src/test/ui/abi/foreign/foreign-dupe.rs diff --git a/src/test/ui/foreign/foreign-fn-with-byval.rs b/src/test/ui/abi/foreign/foreign-fn-with-byval.rs similarity index 100% rename from src/test/ui/foreign/foreign-fn-with-byval.rs rename to src/test/ui/abi/foreign/foreign-fn-with-byval.rs diff --git a/src/test/ui/foreign/foreign-no-abi.rs b/src/test/ui/abi/foreign/foreign-no-abi.rs similarity index 100% rename from src/test/ui/foreign/foreign-no-abi.rs rename to src/test/ui/abi/foreign/foreign-no-abi.rs diff --git a/src/test/ui/invoke-external-foreign.rs b/src/test/ui/abi/invoke-external-foreign.rs similarity index 100% rename from src/test/ui/invoke-external-foreign.rs rename to src/test/ui/abi/invoke-external-foreign.rs diff --git a/src/test/ui/lib-defaults.rs b/src/test/ui/abi/lib-defaults.rs similarity index 100% rename from src/test/ui/lib-defaults.rs rename to src/test/ui/abi/lib-defaults.rs diff --git a/src/test/ui/macros/macros-in-extern.rs b/src/test/ui/abi/macros/macros-in-extern.rs similarity index 100% rename from src/test/ui/macros/macros-in-extern.rs rename to src/test/ui/abi/macros/macros-in-extern.rs diff --git a/src/test/ui/macros/macros-in-extern.stderr b/src/test/ui/abi/macros/macros-in-extern.stderr similarity index 100% rename from src/test/ui/macros/macros-in-extern.stderr rename to src/test/ui/abi/macros/macros-in-extern.stderr diff --git a/src/test/ui/mir/mir_codegen_calls_variadic.rs b/src/test/ui/abi/mir/mir_codegen_calls_variadic.rs similarity index 100% rename from src/test/ui/mir/mir_codegen_calls_variadic.rs rename to src/test/ui/abi/mir/mir_codegen_calls_variadic.rs diff --git a/src/test/ui/numbers-arithmetic/i128-ffi.rs b/src/test/ui/abi/numbers-arithmetic/i128-ffi.rs similarity index 100% rename from src/test/ui/numbers-arithmetic/i128-ffi.rs rename to src/test/ui/abi/numbers-arithmetic/i128-ffi.rs diff --git a/src/test/ui/proc-macro/auxiliary/test-macros.rs b/src/test/ui/abi/proc-macro/auxiliary/test-macros.rs similarity index 100% rename from src/test/ui/proc-macro/auxiliary/test-macros.rs rename to src/test/ui/abi/proc-macro/auxiliary/test-macros.rs diff --git a/src/test/ui/proc-macro/macros-in-extern.rs b/src/test/ui/abi/proc-macro/macros-in-extern.rs similarity index 100% rename from src/test/ui/proc-macro/macros-in-extern.rs rename to src/test/ui/abi/proc-macro/macros-in-extern.rs diff --git a/src/test/ui/proc-macro/macros-in-extern.stderr b/src/test/ui/abi/proc-macro/macros-in-extern.stderr similarity index 100% rename from src/test/ui/proc-macro/macros-in-extern.stderr rename to src/test/ui/abi/proc-macro/macros-in-extern.stderr diff --git a/src/test/ui/segfault-no-out-of-stack.rs b/src/test/ui/abi/segfault-no-out-of-stack.rs similarity index 100% rename from src/test/ui/segfault-no-out-of-stack.rs rename to src/test/ui/abi/segfault-no-out-of-stack.rs diff --git a/src/test/ui/stack-probes-lto.rs b/src/test/ui/abi/stack-probes-lto.rs similarity index 100% rename from src/test/ui/stack-probes-lto.rs rename to src/test/ui/abi/stack-probes-lto.rs diff --git a/src/test/ui/stack-probes.rs b/src/test/ui/abi/stack-probes.rs similarity index 100% rename from src/test/ui/stack-probes.rs rename to src/test/ui/abi/stack-probes.rs diff --git a/src/test/ui/statics/static-mut-foreign.rs b/src/test/ui/abi/statics/static-mut-foreign.rs similarity index 100% rename from src/test/ui/statics/static-mut-foreign.rs rename to src/test/ui/abi/statics/static-mut-foreign.rs diff --git a/src/test/ui/structs-enums/struct-return.rs b/src/test/ui/abi/struct-enums/struct-return.rs similarity index 100% rename from src/test/ui/structs-enums/struct-return.rs rename to src/test/ui/abi/struct-enums/struct-return.rs diff --git a/src/test/ui/union/union-c-interop.rs b/src/test/ui/abi/union/union-c-interop.rs similarity index 100% rename from src/test/ui/union/union-c-interop.rs rename to src/test/ui/abi/union/union-c-interop.rs diff --git a/src/test/ui/variadic-ffi.rs b/src/test/ui/abi/variadic-ffi.rs similarity index 100% rename from src/test/ui/variadic-ffi.rs rename to src/test/ui/abi/variadic-ffi.rs From a90d0876d17c8ce3cb903c867acd70cb8379de60 Mon Sep 17 00:00:00 2001 From: Kevin Per Date: Thu, 15 Aug 2019 17:05:49 +0200 Subject: [PATCH 15/35] Move `test-macros.rs` back to `ui` to fix tests #62593 --- src/test/ui/{abi => }/proc-macro/auxiliary/test-macros.rs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/test/ui/{abi => }/proc-macro/auxiliary/test-macros.rs (100%) diff --git a/src/test/ui/abi/proc-macro/auxiliary/test-macros.rs b/src/test/ui/proc-macro/auxiliary/test-macros.rs similarity index 100% rename from src/test/ui/abi/proc-macro/auxiliary/test-macros.rs rename to src/test/ui/proc-macro/auxiliary/test-macros.rs From 4a8ff5bb7c31c90a5be3e4d6a2e7e7211b4c8745 Mon Sep 17 00:00:00 2001 From: Kevin Per Date: Thu, 15 Aug 2019 17:07:38 +0200 Subject: [PATCH 16/35] Remove `run-pass` directory #62593 --- .../run-pass/abi/abi-sysv64-arg-passing.rs | 366 ------------------ .../run-pass/abi/abi-sysv64-register-usage.rs | 95 ----- src/test/run-pass/abi/abort-on-c-abi.rs | 36 -- src/test/run-pass/abi/anon-extern-mod.rs | 17 - .../anon-extern-mod-cross-crate-1.rs | 9 - .../run-pass/abi/auxiliary/foreign_lib.rs | 38 -- src/test/run-pass/abi/c-stack-as-value.rs | 17 - src/test/run-pass/abi/cabi-int-widening.rs | 14 - .../anon-extern-mod-cross-crate-1.rs | 9 - .../anon-extern-mod-cross-crate-2.rs | 14 - .../anon-extern-mod-cross-crate-1.rs | 9 - .../run-pass/abi/duplicated-external-mods.rs | 8 - .../auxiliary/extern-crosscrate-source.rs | 31 -- .../run-pass/abi/extern/extern-call-deep.rs | 39 -- .../run-pass/abi/extern/extern-call-deep2.rs | 44 --- .../abi/extern/extern-call-indirect.rs | 38 -- .../run-pass/abi/extern/extern-call-scrub.rs | 48 --- .../run-pass/abi/extern/extern-crosscrate.rs | 21 - .../abi/extern/extern-pass-TwoU16s.rs | 25 -- .../abi/extern/extern-pass-TwoU32s.rs | 25 -- .../abi/extern/extern-pass-TwoU64s.rs | 25 -- .../run-pass/abi/extern/extern-pass-TwoU8s.rs | 25 -- .../run-pass/abi/extern/extern-pass-char.rs | 16 - .../run-pass/abi/extern/extern-pass-double.rs | 13 - .../run-pass/abi/extern/extern-pass-empty.rs | 55 --- .../run-pass/abi/extern/extern-pass-u32.rs | 16 - .../run-pass/abi/extern/extern-pass-u64.rs | 16 - .../abi/extern/extern-return-TwoU16s.rs | 21 - .../abi/extern/extern-return-TwoU32s.rs | 21 - .../abi/extern/extern-return-TwoU64s.rs | 21 - .../abi/extern/extern-return-TwoU8s.rs | 21 - .../abi/foreign/auxiliary/foreign_lib.rs | 38 -- .../abi/foreign/foreign-call-no-runtime.rs | 55 --- src/test/run-pass/abi/foreign/foreign-dupe.rs | 17 - .../abi/foreign/foreign-fn-with-byval.rs | 32 -- .../run-pass/abi/foreign/foreign-no-abi.rs | 22 -- .../run-pass/abi/invoke-external-foreign.rs | 16 - .../abi/issues/auxiliary/issue-25185-1.rs | 8 - .../abi/issues/auxiliary/issue-25185-2.rs | 3 - src/test/run-pass/abi/issues/issue-25185.rs | 13 - src/test/run-pass/abi/issues/issue-28676.rs | 35 -- src/test/run-pass/abi/lib-defaults.rs | 16 - .../run-pass/abi/macros/macros-in-extern.rs | 30 -- .../abi/mir/mir_codegen_calls_variadic.rs | 22 -- .../abi/numbers-arithmetic/i128-ffi.rs | 31 -- .../abi/proc_macro/auxiliary/test-macros.rs | 26 -- .../abi/proc_macro/macros-in-extern.rs | 24 -- .../abi/rfcs/rfc1717/library-override.rs | 14 - .../run-pass/abi/segfault-no-out-of-stack.rs | 48 --- src/test/run-pass/abi/stack-probes-lto.rs | 18 - src/test/run-pass/abi/stack-probes.rs | 67 ---- .../abi/statics/static-mut-foreign.rs | 41 -- .../abi/structs-enums/struct-return.rs | 64 --- .../run-pass/abi/union/union-c-interop.rs | 37 -- src/test/run-pass/abi/variadic-ffi.rs | 83 ---- 55 files changed, 1913 deletions(-) delete mode 100644 src/test/run-pass/abi/abi-sysv64-arg-passing.rs delete mode 100644 src/test/run-pass/abi/abi-sysv64-register-usage.rs delete mode 100644 src/test/run-pass/abi/abort-on-c-abi.rs delete mode 100644 src/test/run-pass/abi/anon-extern-mod.rs delete mode 100644 src/test/run-pass/abi/auxiliary/anon-extern-mod-cross-crate-1.rs delete mode 100644 src/test/run-pass/abi/auxiliary/foreign_lib.rs delete mode 100644 src/test/run-pass/abi/c-stack-as-value.rs delete mode 100644 src/test/run-pass/abi/cabi-int-widening.rs delete mode 100644 src/test/run-pass/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs delete mode 100644 src/test/run-pass/abi/cross-crate/anon-extern-mod-cross-crate-2.rs delete mode 100644 src/test/run-pass/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs delete mode 100644 src/test/run-pass/abi/duplicated-external-mods.rs delete mode 100644 src/test/run-pass/abi/extern/auxiliary/extern-crosscrate-source.rs delete mode 100644 src/test/run-pass/abi/extern/extern-call-deep.rs delete mode 100644 src/test/run-pass/abi/extern/extern-call-deep2.rs delete mode 100644 src/test/run-pass/abi/extern/extern-call-indirect.rs delete mode 100644 src/test/run-pass/abi/extern/extern-call-scrub.rs delete mode 100644 src/test/run-pass/abi/extern/extern-crosscrate.rs delete mode 100644 src/test/run-pass/abi/extern/extern-pass-TwoU16s.rs delete mode 100644 src/test/run-pass/abi/extern/extern-pass-TwoU32s.rs delete mode 100644 src/test/run-pass/abi/extern/extern-pass-TwoU64s.rs delete mode 100644 src/test/run-pass/abi/extern/extern-pass-TwoU8s.rs delete mode 100644 src/test/run-pass/abi/extern/extern-pass-char.rs delete mode 100644 src/test/run-pass/abi/extern/extern-pass-double.rs delete mode 100644 src/test/run-pass/abi/extern/extern-pass-empty.rs delete mode 100644 src/test/run-pass/abi/extern/extern-pass-u32.rs delete mode 100644 src/test/run-pass/abi/extern/extern-pass-u64.rs delete mode 100644 src/test/run-pass/abi/extern/extern-return-TwoU16s.rs delete mode 100644 src/test/run-pass/abi/extern/extern-return-TwoU32s.rs delete mode 100644 src/test/run-pass/abi/extern/extern-return-TwoU64s.rs delete mode 100644 src/test/run-pass/abi/extern/extern-return-TwoU8s.rs delete mode 100644 src/test/run-pass/abi/foreign/auxiliary/foreign_lib.rs delete mode 100644 src/test/run-pass/abi/foreign/foreign-call-no-runtime.rs delete mode 100644 src/test/run-pass/abi/foreign/foreign-dupe.rs delete mode 100644 src/test/run-pass/abi/foreign/foreign-fn-with-byval.rs delete mode 100644 src/test/run-pass/abi/foreign/foreign-no-abi.rs delete mode 100644 src/test/run-pass/abi/invoke-external-foreign.rs delete mode 100644 src/test/run-pass/abi/issues/auxiliary/issue-25185-1.rs delete mode 100644 src/test/run-pass/abi/issues/auxiliary/issue-25185-2.rs delete mode 100644 src/test/run-pass/abi/issues/issue-25185.rs delete mode 100644 src/test/run-pass/abi/issues/issue-28676.rs delete mode 100644 src/test/run-pass/abi/lib-defaults.rs delete mode 100644 src/test/run-pass/abi/macros/macros-in-extern.rs delete mode 100644 src/test/run-pass/abi/mir/mir_codegen_calls_variadic.rs delete mode 100644 src/test/run-pass/abi/numbers-arithmetic/i128-ffi.rs delete mode 100644 src/test/run-pass/abi/proc_macro/auxiliary/test-macros.rs delete mode 100644 src/test/run-pass/abi/proc_macro/macros-in-extern.rs delete mode 100644 src/test/run-pass/abi/rfcs/rfc1717/library-override.rs delete mode 100644 src/test/run-pass/abi/segfault-no-out-of-stack.rs delete mode 100644 src/test/run-pass/abi/stack-probes-lto.rs delete mode 100644 src/test/run-pass/abi/stack-probes.rs delete mode 100644 src/test/run-pass/abi/statics/static-mut-foreign.rs delete mode 100644 src/test/run-pass/abi/structs-enums/struct-return.rs delete mode 100644 src/test/run-pass/abi/union/union-c-interop.rs delete mode 100644 src/test/run-pass/abi/variadic-ffi.rs diff --git a/src/test/run-pass/abi/abi-sysv64-arg-passing.rs b/src/test/run-pass/abi/abi-sysv64-arg-passing.rs deleted file mode 100644 index fdf0573b5e3e..000000000000 --- a/src/test/run-pass/abi/abi-sysv64-arg-passing.rs +++ /dev/null @@ -1,366 +0,0 @@ -// Checks if the "sysv64" calling convention behaves the same as the -// "C" calling convention on platforms where both should be the same - -// This file contains versions of the following run-pass tests with -// the calling convention changed to "sysv64" - -// cabi-int-widening -// extern-pass-char -// extern-pass-u32 -// extern-pass-u64 -// extern-pass-double -// extern-pass-empty -// extern-pass-TwoU8s -// extern-pass-TwoU16s -// extern-pass-TwoU32s -// extern-pass-TwoU64s -// extern-return-TwoU8s -// extern-return-TwoU16s -// extern-return-TwoU32s -// extern-return-TwoU64s -// foreign-fn-with-byval -// issue-28676 -// issue-62350-sysv-neg-reg-counts -// struct-return - -// ignore-android -// ignore-arm -// ignore-aarch64 -// ignore-windows - -// note: windows is ignored as rust_test_helpers does not have the sysv64 abi on windows - -#[allow(dead_code)] -#[allow(improper_ctypes)] - -#[cfg(target_arch = "x86_64")] -mod tests { - #[repr(C)] - #[derive(Copy, Clone, PartialEq, Debug)] - pub struct TwoU8s { - one: u8, two: u8 - } - - #[repr(C)] - #[derive(Copy, Clone, PartialEq, Debug)] - pub struct TwoU16s { - one: u16, two: u16 - } - - #[repr(C)] - #[derive(Copy, Clone, PartialEq, Debug)] - pub struct TwoU32s { - one: u32, two: u32 - } - - #[repr(C)] - #[derive(Copy, Clone, PartialEq, Debug)] - pub struct TwoU64s { - one: u64, two: u64 - } - - #[repr(C)] - pub struct ManyInts { - arg1: i8, - arg2: i16, - arg3: i32, - arg4: i16, - arg5: i8, - arg6: TwoU8s, - } - - #[repr(C)] - pub struct Empty; - - #[repr(C)] - #[derive(Copy, Clone)] - pub struct S { - x: u64, - y: u64, - z: u64, - } - - #[repr(C)] - #[derive(Copy, Clone)] - pub struct Quad { a: u64, b: u64, c: u64, d: u64 } - - #[derive(Copy, Clone)] - pub struct QuadFloats { a: f32, b: f32, c: f32, d: f32 } - - #[repr(C)] - #[derive(Copy, Clone)] - pub struct Floats { a: f64, b: u8, c: f64 } - - #[link(name = "rust_test_helpers", kind = "static")] - extern "sysv64" { - pub fn rust_int8_to_int32(_: i8) -> i32; - pub fn rust_dbg_extern_identity_u8(v: u8) -> u8; - pub fn rust_dbg_extern_identity_u32(v: u32) -> u32; - pub fn rust_dbg_extern_identity_u64(v: u64) -> u64; - pub fn rust_dbg_extern_identity_double(v: f64) -> f64; - pub fn rust_dbg_extern_empty_struct(v1: ManyInts, e: Empty, v2: ManyInts); - pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s; - pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s; - pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s; - pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s; - pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s; - pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s; - pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s; - pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s; - pub fn get_x(x: S) -> u64; - pub fn get_y(x: S) -> u64; - pub fn get_z(x: S) -> u64; - pub fn get_c_many_params(_: *const (), _: *const (), - _: *const (), _: *const (), f: Quad) -> u64; - pub fn get_c_exhaust_sysv64_ints( - _: *const (), - _: *const (), - _: *const (), - _: *const (), - _: *const (), - _: *const (), - _: *const (), - h: QuadFloats, - ) -> f32; - pub fn rust_dbg_abi_1(q: Quad) -> Quad; - pub fn rust_dbg_abi_2(f: Floats) -> Floats; - } - - pub fn cabi_int_widening() { - let x = unsafe { - rust_int8_to_int32(-1) - }; - - assert!(x == -1); - } - - pub fn extern_pass_char() { - unsafe { - assert_eq!(22, rust_dbg_extern_identity_u8(22)); - } - } - - pub fn extern_pass_u32() { - unsafe { - assert_eq!(22, rust_dbg_extern_identity_u32(22)); - } - } - - pub fn extern_pass_u64() { - unsafe { - assert_eq!(22, rust_dbg_extern_identity_u64(22)); - } - } - - pub fn extern_pass_double() { - unsafe { - assert_eq!(22.0_f64, rust_dbg_extern_identity_double(22.0_f64)); - } - } - - pub fn extern_pass_empty() { - unsafe { - let x = ManyInts { - arg1: 2, - arg2: 3, - arg3: 4, - arg4: 5, - arg5: 6, - arg6: TwoU8s { one: 7, two: 8, } - }; - let y = ManyInts { - arg1: 1, - arg2: 2, - arg3: 3, - arg4: 4, - arg5: 5, - arg6: TwoU8s { one: 6, two: 7, } - }; - let empty = Empty; - rust_dbg_extern_empty_struct(x, empty, y); - } - } - - pub fn extern_pass_twou8s() { - unsafe { - let x = TwoU8s {one: 22, two: 23}; - let y = rust_dbg_extern_identity_TwoU8s(x); - assert_eq!(x, y); - } - } - - pub fn extern_pass_twou16s() { - unsafe { - let x = TwoU16s {one: 22, two: 23}; - let y = rust_dbg_extern_identity_TwoU16s(x); - assert_eq!(x, y); - } - } - - pub fn extern_pass_twou32s() { - unsafe { - let x = TwoU32s {one: 22, two: 23}; - let y = rust_dbg_extern_identity_TwoU32s(x); - assert_eq!(x, y); - } - } - - pub fn extern_pass_twou64s() { - unsafe { - let x = TwoU64s {one: 22, two: 23}; - let y = rust_dbg_extern_identity_TwoU64s(x); - assert_eq!(x, y); - } - } - - pub fn extern_return_twou8s() { - unsafe { - let y = rust_dbg_extern_return_TwoU8s(); - assert_eq!(y.one, 10); - assert_eq!(y.two, 20); - } - } - - pub fn extern_return_twou16s() { - unsafe { - let y = rust_dbg_extern_return_TwoU16s(); - assert_eq!(y.one, 10); - assert_eq!(y.two, 20); - } - } - - pub fn extern_return_twou32s() { - unsafe { - let y = rust_dbg_extern_return_TwoU32s(); - assert_eq!(y.one, 10); - assert_eq!(y.two, 20); - } - } - - pub fn extern_return_twou64s() { - unsafe { - let y = rust_dbg_extern_return_TwoU64s(); - assert_eq!(y.one, 10); - assert_eq!(y.two, 20); - } - } - - #[inline(never)] - fn indirect_call(func: unsafe extern "sysv64" fn(s: S) -> u64, s: S) -> u64 { - unsafe { - func(s) - } - } - - pub fn foreign_fn_with_byval() { - let s = S { x: 1, y: 2, z: 3 }; - assert_eq!(s.x, indirect_call(get_x, s)); - assert_eq!(s.y, indirect_call(get_y, s)); - assert_eq!(s.z, indirect_call(get_z, s)); - } - - fn test() { - use std::ptr; - unsafe { - let null = ptr::null(); - let q = Quad { - a: 1, - b: 2, - c: 3, - d: 4 - }; - assert_eq!(get_c_many_params(null, null, null, null, q), q.c); - } - } - - pub fn issue_28676() { - test(); - } - - fn test_62350() { - use std::ptr; - unsafe { - let null = ptr::null(); - let q = QuadFloats { - a: 10.2, - b: 20.3, - c: 30.4, - d: 40.5 - }; - assert_eq!( - get_c_exhaust_sysv64_ints(null, null, null, null, null, null, null, q), - q.c, - ); - } - } - - pub fn issue_62350() { - test_62350(); - } - - fn test1() { - unsafe { - let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa, - b: 0xbbbb_bbbb_bbbb_bbbb, - c: 0xcccc_cccc_cccc_cccc, - d: 0xdddd_dddd_dddd_dddd }; - let qq = rust_dbg_abi_1(q); - println!("a: {:x}", qq.a as usize); - println!("b: {:x}", qq.b as usize); - println!("c: {:x}", qq.c as usize); - println!("d: {:x}", qq.d as usize); - assert_eq!(qq.a, q.c + 1); - assert_eq!(qq.b, q.d - 1); - assert_eq!(qq.c, q.a + 1); - assert_eq!(qq.d, q.b - 1); - } - } - - fn test2() { - unsafe { - let f = Floats { a: 1.234567890e-15_f64, - b: 0b_1010_1010, - c: 1.0987654321e-15_f64 }; - let ff = rust_dbg_abi_2(f); - println!("a: {}", ff.a as f64); - println!("b: {}", ff.b as usize); - println!("c: {}", ff.c as f64); - assert_eq!(ff.a, f.c + 1.0f64); - assert_eq!(ff.b, 0xff); - assert_eq!(ff.c, f.a - 1.0f64); - } - } - - pub fn struct_return() { - test1(); - test2(); - } -} - -#[cfg(target_arch = "x86_64")] -fn main() { - use tests::*; - cabi_int_widening(); - extern_pass_char(); - extern_pass_u32(); - extern_pass_u64(); - extern_pass_double(); - extern_pass_empty(); - extern_pass_twou8s(); - extern_pass_twou16s(); - extern_pass_twou32s(); - extern_pass_twou64s(); - extern_return_twou8s(); - extern_return_twou16s(); - extern_return_twou32s(); - extern_return_twou64s(); - foreign_fn_with_byval(); - issue_28676(); - issue_62350(); - struct_return(); -} - -#[cfg(not(target_arch = "x86_64"))] -fn main() { - -} diff --git a/src/test/run-pass/abi/abi-sysv64-register-usage.rs b/src/test/run-pass/abi/abi-sysv64-register-usage.rs deleted file mode 100644 index a0d6e968252a..000000000000 --- a/src/test/run-pass/abi/abi-sysv64-register-usage.rs +++ /dev/null @@ -1,95 +0,0 @@ -// Checks if the correct registers are being used to pass arguments -// when the sysv64 ABI is specified. - -// ignore-android -// ignore-arm -// ignore-aarch64 - -#![feature(asm)] - -#[cfg(target_arch = "x86_64")] -pub extern "sysv64" fn all_the_registers(rdi: i64, rsi: i64, rdx: i64, - rcx: i64, r8 : i64, r9 : i64, - xmm0: f32, xmm1: f32, xmm2: f32, - xmm3: f32, xmm4: f32, xmm5: f32, - xmm6: f32, xmm7: f32) -> i64 { - assert_eq!(rdi, 1); - assert_eq!(rsi, 2); - assert_eq!(rdx, 3); - assert_eq!(rcx, 4); - assert_eq!(r8, 5); - assert_eq!(r9, 6); - assert_eq!(xmm0, 1.0f32); - assert_eq!(xmm1, 2.0f32); - assert_eq!(xmm2, 4.0f32); - assert_eq!(xmm3, 8.0f32); - assert_eq!(xmm4, 16.0f32); - assert_eq!(xmm5, 32.0f32); - assert_eq!(xmm6, 64.0f32); - assert_eq!(xmm7, 128.0f32); - 42 -} - -// this struct contains 8 i64's, while only 6 can be passed in registers. -#[cfg(target_arch = "x86_64")] -#[derive(PartialEq, Eq, Debug)] -pub struct LargeStruct(i64, i64, i64, i64, i64, i64, i64, i64); - -#[cfg(target_arch = "x86_64")] -#[inline(never)] -pub extern "sysv64" fn large_struct_by_val(mut foo: LargeStruct) -> LargeStruct { - foo.0 *= 1; - foo.1 *= 2; - foo.2 *= 3; - foo.3 *= 4; - foo.4 *= 5; - foo.5 *= 6; - foo.6 *= 7; - foo.7 *= 8; - foo -} - -#[cfg(target_arch = "x86_64")] -pub fn main() { - let result: i64; - unsafe { - asm!("mov rdi, 1; - mov rsi, 2; - mov rdx, 3; - mov rcx, 4; - mov r8, 5; - mov r9, 6; - mov eax, 0x3F800000; - movd xmm0, eax; - mov eax, 0x40000000; - movd xmm1, eax; - mov eax, 0x40800000; - movd xmm2, eax; - mov eax, 0x41000000; - movd xmm3, eax; - mov eax, 0x41800000; - movd xmm4, eax; - mov eax, 0x42000000; - movd xmm5, eax; - mov eax, 0x42800000; - movd xmm6, eax; - mov eax, 0x43000000; - movd xmm7, eax; - call r10 - " - : "={rax}"(result) - : "{r10}"(all_the_registers as usize) - : "rdi", "rsi", "rdx", "rcx", "r8", "r9", "r11", "cc", "memory" - : "intel", "alignstack" - ) - } - assert_eq!(result, 42); - - assert_eq!( - large_struct_by_val(LargeStruct(1, 2, 3, 4, 5, 6, 7, 8)), - LargeStruct(1, 4, 9, 16, 25, 36, 49, 64) - ); -} - -#[cfg(not(target_arch = "x86_64"))] -pub fn main() {} diff --git a/src/test/run-pass/abi/abort-on-c-abi.rs b/src/test/run-pass/abi/abort-on-c-abi.rs deleted file mode 100644 index 110f3eee1ef8..000000000000 --- a/src/test/run-pass/abi/abort-on-c-abi.rs +++ /dev/null @@ -1,36 +0,0 @@ -#![allow(unused_must_use)] -// Since we mark some ABIs as "nounwind" to LLVM, we must make sure that -// we never unwind through them. - -// ignore-cloudabi no env and process -// ignore-emscripten no processes -// ignore-sgx no processes - -use std::{env, panic}; -use std::io::prelude::*; -use std::io; -use std::process::{Command, Stdio}; - -extern "C" fn panic_in_ffi() { - panic!("Test"); -} - -fn test() { - let _ = panic::catch_unwind(|| { panic_in_ffi(); }); - // The process should have aborted by now. - io::stdout().write(b"This should never be printed.\n"); - let _ = io::stdout().flush(); -} - -fn main() { - let args: Vec = env::args().collect(); - if args.len() > 1 && args[1] == "test" { - return test(); - } - - let mut p = Command::new(&args[0]) - .stdout(Stdio::piped()) - .stdin(Stdio::piped()) - .arg("test").spawn().unwrap(); - assert!(!p.wait().unwrap().success()); -} diff --git a/src/test/run-pass/abi/anon-extern-mod.rs b/src/test/run-pass/abi/anon-extern-mod.rs deleted file mode 100644 index 6d7e3f3cd5c1..000000000000 --- a/src/test/run-pass/abi/anon-extern-mod.rs +++ /dev/null @@ -1,17 +0,0 @@ -// pretty-expanded FIXME #23616 -// ignore-wasm32-bare no libc to test ffi with - -#![feature(rustc_private)] - -extern crate libc; - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - fn rust_get_test_int() -> libc::intptr_t; -} - -pub fn main() { - unsafe { - let _ = rust_get_test_int(); - } -} diff --git a/src/test/run-pass/abi/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/run-pass/abi/auxiliary/anon-extern-mod-cross-crate-1.rs deleted file mode 100644 index 948b5e688ebc..000000000000 --- a/src/test/run-pass/abi/auxiliary/anon-extern-mod-cross-crate-1.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![crate_name="anonexternmod"] -#![feature(rustc_private)] - -extern crate libc; - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - pub fn rust_get_test_int() -> libc::intptr_t; -} diff --git a/src/test/run-pass/abi/auxiliary/foreign_lib.rs b/src/test/run-pass/abi/auxiliary/foreign_lib.rs deleted file mode 100644 index de6b0e2118a5..000000000000 --- a/src/test/run-pass/abi/auxiliary/foreign_lib.rs +++ /dev/null @@ -1,38 +0,0 @@ -#![crate_name="foreign_lib"] - -#![feature(rustc_private)] - -pub mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers", kind = "static")] - extern { - pub fn rust_get_test_int() -> libc::intptr_t; - } -} - -pub mod rustrt2 { - extern crate libc; - - extern { - pub fn rust_get_test_int() -> libc::intptr_t; - } -} - -pub mod rustrt3 { - // Different type, but same ABI (on all supported platforms). - // Ensures that we don't ICE or trigger LLVM asserts when - // importing the same symbol under different types. - // See https://github.com/rust-lang/rust/issues/32740. - extern { - pub fn rust_get_test_int() -> *const u8; - } -} - -pub fn local_uses() { - unsafe { - let x = rustrt::rust_get_test_int(); - assert_eq!(x, rustrt2::rust_get_test_int()); - assert_eq!(x as *const _, rustrt3::rust_get_test_int()); - } -} diff --git a/src/test/run-pass/abi/c-stack-as-value.rs b/src/test/run-pass/abi/c-stack-as-value.rs deleted file mode 100644 index 3b997295c122..000000000000 --- a/src/test/run-pass/abi/c-stack-as-value.rs +++ /dev/null @@ -1,17 +0,0 @@ -// pretty-expanded FIXME #23616 -// ignore-wasm32-bare no libc to test ffi with - -#![feature(rustc_private)] - -mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers", kind = "static")] - extern { - pub fn rust_get_test_int() -> libc::intptr_t; - } -} - -pub fn main() { - let _foo = rustrt::rust_get_test_int; -} diff --git a/src/test/run-pass/abi/cabi-int-widening.rs b/src/test/run-pass/abi/cabi-int-widening.rs deleted file mode 100644 index f6524c6a3d90..000000000000 --- a/src/test/run-pass/abi/cabi-int-widening.rs +++ /dev/null @@ -1,14 +0,0 @@ -// ignore-wasm32-bare no libc to test ffi with - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - fn rust_int8_to_int32(_: i8) -> i32; -} - -fn main() { - let x = unsafe { - rust_int8_to_int32(-1) - }; - - assert!(x == -1); -} diff --git a/src/test/run-pass/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/run-pass/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs deleted file mode 100644 index 948b5e688ebc..000000000000 --- a/src/test/run-pass/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![crate_name="anonexternmod"] -#![feature(rustc_private)] - -extern crate libc; - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - pub fn rust_get_test_int() -> libc::intptr_t; -} diff --git a/src/test/run-pass/abi/cross-crate/anon-extern-mod-cross-crate-2.rs b/src/test/run-pass/abi/cross-crate/anon-extern-mod-cross-crate-2.rs deleted file mode 100644 index 77168be5374b..000000000000 --- a/src/test/run-pass/abi/cross-crate/anon-extern-mod-cross-crate-2.rs +++ /dev/null @@ -1,14 +0,0 @@ -// run-pass -// aux-build:anon-extern-mod-cross-crate-1.rs -// pretty-expanded FIXME #23616 -// ignore-wasm32-bare no libc to test ffi with - -extern crate anonexternmod; - -use anonexternmod::rust_get_test_int; - -pub fn main() { - unsafe { - rust_get_test_int(); - } -} diff --git a/src/test/run-pass/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/run-pass/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs deleted file mode 100644 index 948b5e688ebc..000000000000 --- a/src/test/run-pass/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![crate_name="anonexternmod"] -#![feature(rustc_private)] - -extern crate libc; - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - pub fn rust_get_test_int() -> libc::intptr_t; -} diff --git a/src/test/run-pass/abi/duplicated-external-mods.rs b/src/test/run-pass/abi/duplicated-external-mods.rs deleted file mode 100644 index f2c1e1f65401..000000000000 --- a/src/test/run-pass/abi/duplicated-external-mods.rs +++ /dev/null @@ -1,8 +0,0 @@ -// aux-build:anon-extern-mod-cross-crate-1.rs -// aux-build:anon-extern-mod-cross-crate-1.rs -// pretty-expanded FIXME #23616 -// ignore-wasm32-bare no libc to test ffi with - -extern crate anonexternmod; - -pub fn main() { } diff --git a/src/test/run-pass/abi/extern/auxiliary/extern-crosscrate-source.rs b/src/test/run-pass/abi/extern/auxiliary/extern-crosscrate-source.rs deleted file mode 100644 index d4568d38e25c..000000000000 --- a/src/test/run-pass/abi/extern/auxiliary/extern-crosscrate-source.rs +++ /dev/null @@ -1,31 +0,0 @@ -#![crate_name="externcallback"] -#![crate_type = "lib"] -#![feature(rustc_private)] - -extern crate libc; - -pub mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers", kind = "static")] - extern { - pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, - data: libc::uintptr_t) - -> libc::uintptr_t; - } -} - -pub fn fact(n: libc::uintptr_t) -> libc::uintptr_t { - unsafe { - println!("n = {}", n); - rustrt::rust_dbg_call(cb, n) - } -} - -pub extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { - if data == 1 { - data - } else { - fact(data - 1) * data - } -} diff --git a/src/test/run-pass/abi/extern/extern-call-deep.rs b/src/test/run-pass/abi/extern/extern-call-deep.rs deleted file mode 100644 index 81f884dada9b..000000000000 --- a/src/test/run-pass/abi/extern/extern-call-deep.rs +++ /dev/null @@ -1,39 +0,0 @@ -// run-pass -// ignore-wasm32-bare no libc to test ffi with -// ignore-emscripten blows the JS stack - -#![feature(rustc_private)] - -extern crate libc; - -mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers", kind = "static")] - extern { - pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, - data: libc::uintptr_t) - -> libc::uintptr_t; - } -} - -extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { - if data == 1 { - data - } else { - count(data - 1) + 1 - } -} - -fn count(n: libc::uintptr_t) -> libc::uintptr_t { - unsafe { - println!("n = {}", n); - rustrt::rust_dbg_call(cb, n) - } -} - -pub fn main() { - let result = count(1000); - println!("result = {}", result); - assert_eq!(result, 1000); -} diff --git a/src/test/run-pass/abi/extern/extern-call-deep2.rs b/src/test/run-pass/abi/extern/extern-call-deep2.rs deleted file mode 100644 index b31489b1e10c..000000000000 --- a/src/test/run-pass/abi/extern/extern-call-deep2.rs +++ /dev/null @@ -1,44 +0,0 @@ -// run-pass -#![allow(unused_must_use)] -// ignore-emscripten no threads support - -#![feature(rustc_private)] - -extern crate libc; -use std::thread; - -mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers", kind = "static")] - extern { - pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, - data: libc::uintptr_t) - -> libc::uintptr_t; - } -} - -extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { - if data == 1 { - data - } else { - count(data - 1) + 1 - } -} - -fn count(n: libc::uintptr_t) -> libc::uintptr_t { - unsafe { - println!("n = {}", n); - rustrt::rust_dbg_call(cb, n) - } -} - -pub fn main() { - // Make sure we're on a thread with small Rust stacks (main currently - // has a large stack) - thread::spawn(move|| { - let result = count(1000); - println!("result = {}", result); - assert_eq!(result, 1000); - }).join(); -} diff --git a/src/test/run-pass/abi/extern/extern-call-indirect.rs b/src/test/run-pass/abi/extern/extern-call-indirect.rs deleted file mode 100644 index 158b54e4b8cd..000000000000 --- a/src/test/run-pass/abi/extern/extern-call-indirect.rs +++ /dev/null @@ -1,38 +0,0 @@ -// run-pass -// ignore-wasm32-bare no libc to test ffi with - -#![feature(rustc_private)] - -extern crate libc; - -mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers", kind = "static")] - extern { - pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, - data: libc::uintptr_t) - -> libc::uintptr_t; - } -} - -extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { - if data == 1 { - data - } else { - fact(data - 1) * data - } -} - -fn fact(n: libc::uintptr_t) -> libc::uintptr_t { - unsafe { - println!("n = {}", n); - rustrt::rust_dbg_call(cb, n) - } -} - -pub fn main() { - let result = fact(10); - println!("result = {}", result); - assert_eq!(result, 3628800); -} diff --git a/src/test/run-pass/abi/extern/extern-call-scrub.rs b/src/test/run-pass/abi/extern/extern-call-scrub.rs deleted file mode 100644 index a7b1065c9e1f..000000000000 --- a/src/test/run-pass/abi/extern/extern-call-scrub.rs +++ /dev/null @@ -1,48 +0,0 @@ -// run-pass -#![allow(unused_must_use)] -// This time we're testing repeatedly going up and down both stacks to -// make sure the stack pointers are maintained properly in both -// directions - -// ignore-emscripten no threads support - -#![feature(rustc_private)] - -extern crate libc; -use std::thread; - -mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers", kind = "static")] - extern { - pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, - data: libc::uintptr_t) - -> libc::uintptr_t; - } -} - -extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { - if data == 1 { - data - } else { - count(data - 1) + count(data - 1) - } -} - -fn count(n: libc::uintptr_t) -> libc::uintptr_t { - unsafe { - println!("n = {}", n); - rustrt::rust_dbg_call(cb, n) - } -} - -pub fn main() { - // Make sure we're on a thread with small Rust stacks (main currently - // has a large stack) - thread::spawn(move|| { - let result = count(12); - println!("result = {}", result); - assert_eq!(result, 2048); - }).join(); -} diff --git a/src/test/run-pass/abi/extern/extern-crosscrate.rs b/src/test/run-pass/abi/extern/extern-crosscrate.rs deleted file mode 100644 index 123ce20ca262..000000000000 --- a/src/test/run-pass/abi/extern/extern-crosscrate.rs +++ /dev/null @@ -1,21 +0,0 @@ -// run-pass -// aux-build:extern-crosscrate-source.rs -// ignore-wasm32-bare no libc to test ffi with - -#![feature(rustc_private)] - -extern crate externcallback; -extern crate libc; - -fn fact(n: libc::uintptr_t) -> libc::uintptr_t { - unsafe { - println!("n = {}", n); - externcallback::rustrt::rust_dbg_call(externcallback::cb, n) - } -} - -pub fn main() { - let result = fact(10); - println!("result = {}", result); - assert_eq!(result, 3628800); -} diff --git a/src/test/run-pass/abi/extern/extern-pass-TwoU16s.rs b/src/test/run-pass/abi/extern/extern-pass-TwoU16s.rs deleted file mode 100644 index 285bce2e19c3..000000000000 --- a/src/test/run-pass/abi/extern/extern-pass-TwoU16s.rs +++ /dev/null @@ -1,25 +0,0 @@ -// run-pass -#![allow(improper_ctypes)] - -// ignore-wasm32-bare no libc for ffi testing - -// Test a foreign function that accepts and returns a struct -// by value. - -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct TwoU16s { - one: u16, two: u16 -} - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s; -} - -pub fn main() { - unsafe { - let x = TwoU16s {one: 22, two: 23}; - let y = rust_dbg_extern_identity_TwoU16s(x); - assert_eq!(x, y); - } -} diff --git a/src/test/run-pass/abi/extern/extern-pass-TwoU32s.rs b/src/test/run-pass/abi/extern/extern-pass-TwoU32s.rs deleted file mode 100644 index fb18aa8d22fd..000000000000 --- a/src/test/run-pass/abi/extern/extern-pass-TwoU32s.rs +++ /dev/null @@ -1,25 +0,0 @@ -// run-pass -#![allow(improper_ctypes)] - -// ignore-wasm32-bare no libc for ffi testing - -// Test a foreign function that accepts and returns a struct -// by value. - -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct TwoU32s { - one: u32, two: u32 -} - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s; -} - -pub fn main() { - unsafe { - let x = TwoU32s {one: 22, two: 23}; - let y = rust_dbg_extern_identity_TwoU32s(x); - assert_eq!(x, y); - } -} diff --git a/src/test/run-pass/abi/extern/extern-pass-TwoU64s.rs b/src/test/run-pass/abi/extern/extern-pass-TwoU64s.rs deleted file mode 100644 index 419648263aa9..000000000000 --- a/src/test/run-pass/abi/extern/extern-pass-TwoU64s.rs +++ /dev/null @@ -1,25 +0,0 @@ -// run-pass -#![allow(improper_ctypes)] - -// ignore-wasm32-bare no libc for ffi testing - -// Test a foreign function that accepts and returns a struct -// by value. - -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct TwoU64s { - one: u64, two: u64 -} - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s; -} - -pub fn main() { - unsafe { - let x = TwoU64s {one: 22, two: 23}; - let y = rust_dbg_extern_identity_TwoU64s(x); - assert_eq!(x, y); - } -} diff --git a/src/test/run-pass/abi/extern/extern-pass-TwoU8s.rs b/src/test/run-pass/abi/extern/extern-pass-TwoU8s.rs deleted file mode 100644 index 53a6a0f29f8a..000000000000 --- a/src/test/run-pass/abi/extern/extern-pass-TwoU8s.rs +++ /dev/null @@ -1,25 +0,0 @@ -// run-pass -#![allow(improper_ctypes)] - -// ignore-wasm32-bare no libc for ffi testing - -// Test a foreign function that accepts and returns a struct -// by value. - -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct TwoU8s { - one: u8, two: u8 -} - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s; -} - -pub fn main() { - unsafe { - let x = TwoU8s {one: 22, two: 23}; - let y = rust_dbg_extern_identity_TwoU8s(x); - assert_eq!(x, y); - } -} diff --git a/src/test/run-pass/abi/extern/extern-pass-char.rs b/src/test/run-pass/abi/extern/extern-pass-char.rs deleted file mode 100644 index 22f841b45527..000000000000 --- a/src/test/run-pass/abi/extern/extern-pass-char.rs +++ /dev/null @@ -1,16 +0,0 @@ -// run-pass -// ignore-wasm32-bare no libc for ffi testing - -// Test a function that takes/returns a u8. - - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - pub fn rust_dbg_extern_identity_u8(v: u8) -> u8; -} - -pub fn main() { - unsafe { - assert_eq!(22, rust_dbg_extern_identity_u8(22)); - } -} diff --git a/src/test/run-pass/abi/extern/extern-pass-double.rs b/src/test/run-pass/abi/extern/extern-pass-double.rs deleted file mode 100644 index dbd0a2dfa488..000000000000 --- a/src/test/run-pass/abi/extern/extern-pass-double.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass -// ignore-wasm32-bare no libc for ffi testing - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - pub fn rust_dbg_extern_identity_double(v: f64) -> f64; -} - -pub fn main() { - unsafe { - assert_eq!(22.0_f64, rust_dbg_extern_identity_double(22.0_f64)); - } -} diff --git a/src/test/run-pass/abi/extern/extern-pass-empty.rs b/src/test/run-pass/abi/extern/extern-pass-empty.rs deleted file mode 100644 index 07099a242048..000000000000 --- a/src/test/run-pass/abi/extern/extern-pass-empty.rs +++ /dev/null @@ -1,55 +0,0 @@ -// run-pass -#![allow(improper_ctypes)] // FIXME: this test is inherently not FFI-safe. - -// Test a foreign function that accepts empty struct. - -// pretty-expanded FIXME #23616 -// ignore-msvc -// ignore-emscripten emcc asserts on an empty struct as an argument - -#[repr(C)] -struct TwoU8s { - one: u8, - two: u8, -} - -#[repr(C)] -struct ManyInts { - arg1: i8, - arg2: i16, - arg3: i32, - arg4: i16, - arg5: i8, - arg6: TwoU8s, -} - -#[repr(C)] -struct Empty; - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - fn rust_dbg_extern_empty_struct(v1: ManyInts, e: Empty, v2: ManyInts); -} - -pub fn main() { - unsafe { - let x = ManyInts { - arg1: 2, - arg2: 3, - arg3: 4, - arg4: 5, - arg5: 6, - arg6: TwoU8s { one: 7, two: 8, } - }; - let y = ManyInts { - arg1: 1, - arg2: 2, - arg3: 3, - arg4: 4, - arg5: 5, - arg6: TwoU8s { one: 6, two: 7, } - }; - let empty = Empty; - rust_dbg_extern_empty_struct(x, empty, y); - } -} diff --git a/src/test/run-pass/abi/extern/extern-pass-u32.rs b/src/test/run-pass/abi/extern/extern-pass-u32.rs deleted file mode 100644 index f2efdb7d3664..000000000000 --- a/src/test/run-pass/abi/extern/extern-pass-u32.rs +++ /dev/null @@ -1,16 +0,0 @@ -// run-pass -// ignore-wasm32-bare no libc for ffi testing - -// Test a function that takes/returns a u32. - - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - pub fn rust_dbg_extern_identity_u32(v: u32) -> u32; -} - -pub fn main() { - unsafe { - assert_eq!(22, rust_dbg_extern_identity_u32(22)); - } -} diff --git a/src/test/run-pass/abi/extern/extern-pass-u64.rs b/src/test/run-pass/abi/extern/extern-pass-u64.rs deleted file mode 100644 index 975446d430c2..000000000000 --- a/src/test/run-pass/abi/extern/extern-pass-u64.rs +++ /dev/null @@ -1,16 +0,0 @@ -// run-pass -// ignore-wasm32-bare no libc for ffi testing - -// Test a call to a function that takes/returns a u64. - - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - pub fn rust_dbg_extern_identity_u64(v: u64) -> u64; -} - -pub fn main() { - unsafe { - assert_eq!(22, rust_dbg_extern_identity_u64(22)); - } -} diff --git a/src/test/run-pass/abi/extern/extern-return-TwoU16s.rs b/src/test/run-pass/abi/extern/extern-return-TwoU16s.rs deleted file mode 100644 index dd884ee77fe7..000000000000 --- a/src/test/run-pass/abi/extern/extern-return-TwoU16s.rs +++ /dev/null @@ -1,21 +0,0 @@ -// run-pass -#![allow(improper_ctypes)] - -// ignore-wasm32-bare no libc to test ffi with - -pub struct TwoU16s { - one: u16, two: u16 -} - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s; -} - -pub fn main() { - unsafe { - let y = rust_dbg_extern_return_TwoU16s(); - assert_eq!(y.one, 10); - assert_eq!(y.two, 20); - } -} diff --git a/src/test/run-pass/abi/extern/extern-return-TwoU32s.rs b/src/test/run-pass/abi/extern/extern-return-TwoU32s.rs deleted file mode 100644 index d6aaf5c9eaf1..000000000000 --- a/src/test/run-pass/abi/extern/extern-return-TwoU32s.rs +++ /dev/null @@ -1,21 +0,0 @@ -// run-pass -#![allow(improper_ctypes)] - -// ignore-wasm32-bare no libc to test ffi with - -pub struct TwoU32s { - one: u32, two: u32 -} - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s; -} - -pub fn main() { - unsafe { - let y = rust_dbg_extern_return_TwoU32s(); - assert_eq!(y.one, 10); - assert_eq!(y.two, 20); - } -} diff --git a/src/test/run-pass/abi/extern/extern-return-TwoU64s.rs b/src/test/run-pass/abi/extern/extern-return-TwoU64s.rs deleted file mode 100644 index c5e4ebadc182..000000000000 --- a/src/test/run-pass/abi/extern/extern-return-TwoU64s.rs +++ /dev/null @@ -1,21 +0,0 @@ -// run-pass -#![allow(improper_ctypes)] - -// ignore-wasm32-bare no libc to test ffi with - -pub struct TwoU64s { - one: u64, two: u64 -} - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s; -} - -pub fn main() { - unsafe { - let y = rust_dbg_extern_return_TwoU64s(); - assert_eq!(y.one, 10); - assert_eq!(y.two, 20); - } -} diff --git a/src/test/run-pass/abi/extern/extern-return-TwoU8s.rs b/src/test/run-pass/abi/extern/extern-return-TwoU8s.rs deleted file mode 100644 index a7cd21b20735..000000000000 --- a/src/test/run-pass/abi/extern/extern-return-TwoU8s.rs +++ /dev/null @@ -1,21 +0,0 @@ -// run-pass -#![allow(improper_ctypes)] - -// ignore-wasm32-bare no libc to test ffi with - -pub struct TwoU8s { - one: u8, two: u8 -} - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s; -} - -pub fn main() { - unsafe { - let y = rust_dbg_extern_return_TwoU8s(); - assert_eq!(y.one, 10); - assert_eq!(y.two, 20); - } -} diff --git a/src/test/run-pass/abi/foreign/auxiliary/foreign_lib.rs b/src/test/run-pass/abi/foreign/auxiliary/foreign_lib.rs deleted file mode 100644 index de6b0e2118a5..000000000000 --- a/src/test/run-pass/abi/foreign/auxiliary/foreign_lib.rs +++ /dev/null @@ -1,38 +0,0 @@ -#![crate_name="foreign_lib"] - -#![feature(rustc_private)] - -pub mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers", kind = "static")] - extern { - pub fn rust_get_test_int() -> libc::intptr_t; - } -} - -pub mod rustrt2 { - extern crate libc; - - extern { - pub fn rust_get_test_int() -> libc::intptr_t; - } -} - -pub mod rustrt3 { - // Different type, but same ABI (on all supported platforms). - // Ensures that we don't ICE or trigger LLVM asserts when - // importing the same symbol under different types. - // See https://github.com/rust-lang/rust/issues/32740. - extern { - pub fn rust_get_test_int() -> *const u8; - } -} - -pub fn local_uses() { - unsafe { - let x = rustrt::rust_get_test_int(); - assert_eq!(x, rustrt2::rust_get_test_int()); - assert_eq!(x as *const _, rustrt3::rust_get_test_int()); - } -} diff --git a/src/test/run-pass/abi/foreign/foreign-call-no-runtime.rs b/src/test/run-pass/abi/foreign/foreign-call-no-runtime.rs deleted file mode 100644 index c6afa07ad050..000000000000 --- a/src/test/run-pass/abi/foreign/foreign-call-no-runtime.rs +++ /dev/null @@ -1,55 +0,0 @@ -// run-pass -// ignore-emscripten no threads support - -#![feature(rustc_private)] - -extern crate libc; - -use std::mem; -use std::thread; - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t), - data: libc::uintptr_t) -> libc::uintptr_t; -} - -pub fn main() { - unsafe { - thread::spawn(move|| { - let i: isize = 100; - rust_dbg_call(callback_isize, mem::transmute(&i)); - }).join().unwrap(); - - thread::spawn(move|| { - let i: i32 = 100; - rust_dbg_call(callback_i32, mem::transmute(&i)); - }).join().unwrap(); - - thread::spawn(move|| { - let i: i64 = 100; - rust_dbg_call(callback_i64, mem::transmute(&i)); - }).join().unwrap(); - } -} - -extern fn callback_isize(data: libc::uintptr_t) { - unsafe { - let data: *const isize = mem::transmute(data); - assert_eq!(*data, 100); - } -} - -extern fn callback_i64(data: libc::uintptr_t) { - unsafe { - let data: *const i64 = mem::transmute(data); - assert_eq!(*data, 100); - } -} - -extern fn callback_i32(data: libc::uintptr_t) { - unsafe { - let data: *const i32 = mem::transmute(data); - assert_eq!(*data, 100); - } -} diff --git a/src/test/run-pass/abi/foreign/foreign-dupe.rs b/src/test/run-pass/abi/foreign/foreign-dupe.rs deleted file mode 100644 index 3c9f0f583d48..000000000000 --- a/src/test/run-pass/abi/foreign/foreign-dupe.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-pass -// aux-build:foreign_lib.rs -// ignore-wasm32-bare no libc to test ffi with - -// Check that we can still call duplicated extern (imported) functions -// which were declared in another crate. See issues #32740 and #32783. - - -extern crate foreign_lib; - -pub fn main() { - unsafe { - let x = foreign_lib::rustrt::rust_get_test_int(); - assert_eq!(x, foreign_lib::rustrt2::rust_get_test_int()); - assert_eq!(x as *const _, foreign_lib::rustrt3::rust_get_test_int()); - } -} diff --git a/src/test/run-pass/abi/foreign/foreign-fn-with-byval.rs b/src/test/run-pass/abi/foreign/foreign-fn-with-byval.rs deleted file mode 100644 index 3a35599aa573..000000000000 --- a/src/test/run-pass/abi/foreign/foreign-fn-with-byval.rs +++ /dev/null @@ -1,32 +0,0 @@ -// run-pass -#![allow(improper_ctypes)] - -// ignore-wasm32-bare no libc to test ffi with - -#[derive(Copy, Clone)] -pub struct S { - x: u64, - y: u64, - z: u64, -} - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - pub fn get_x(x: S) -> u64; - pub fn get_y(x: S) -> u64; - pub fn get_z(x: S) -> u64; -} - -#[inline(never)] -fn indirect_call(func: unsafe extern fn(s: S) -> u64, s: S) -> u64 { - unsafe { - func(s) - } -} - -fn main() { - let s = S { x: 1, y: 2, z: 3 }; - assert_eq!(s.x, indirect_call(get_x, s)); - assert_eq!(s.y, indirect_call(get_y, s)); - assert_eq!(s.z, indirect_call(get_z, s)); -} diff --git a/src/test/run-pass/abi/foreign/foreign-no-abi.rs b/src/test/run-pass/abi/foreign/foreign-no-abi.rs deleted file mode 100644 index 2f33fb476569..000000000000 --- a/src/test/run-pass/abi/foreign/foreign-no-abi.rs +++ /dev/null @@ -1,22 +0,0 @@ -// run-pass -// ABI is cdecl by default - -// ignore-wasm32-bare no libc to test ffi with -// pretty-expanded FIXME #23616 - -#![feature(rustc_private)] - -mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers", kind = "static")] - extern { - pub fn rust_get_test_int() -> libc::intptr_t; - } -} - -pub fn main() { - unsafe { - rustrt::rust_get_test_int(); - } -} diff --git a/src/test/run-pass/abi/invoke-external-foreign.rs b/src/test/run-pass/abi/invoke-external-foreign.rs deleted file mode 100644 index d34933cde424..000000000000 --- a/src/test/run-pass/abi/invoke-external-foreign.rs +++ /dev/null @@ -1,16 +0,0 @@ -// aux-build:foreign_lib.rs -// ignore-wasm32-bare no libc to test ffi with - -// The purpose of this test is to check that we can -// successfully (and safely) invoke external, cdecl -// functions from outside the crate. - -// pretty-expanded FIXME #23616 - -extern crate foreign_lib; - -pub fn main() { - unsafe { - let _foo = foreign_lib::rustrt::rust_get_test_int(); - } -} diff --git a/src/test/run-pass/abi/issues/auxiliary/issue-25185-1.rs b/src/test/run-pass/abi/issues/auxiliary/issue-25185-1.rs deleted file mode 100644 index 77a4787ba943..000000000000 --- a/src/test/run-pass/abi/issues/auxiliary/issue-25185-1.rs +++ /dev/null @@ -1,8 +0,0 @@ -// no-prefer-dynamic - -#![crate_type = "rlib"] - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - pub fn rust_dbg_extern_identity_u32(u: u32) -> u32; -} diff --git a/src/test/run-pass/abi/issues/auxiliary/issue-25185-2.rs b/src/test/run-pass/abi/issues/auxiliary/issue-25185-2.rs deleted file mode 100644 index 7ce3df255a33..000000000000 --- a/src/test/run-pass/abi/issues/auxiliary/issue-25185-2.rs +++ /dev/null @@ -1,3 +0,0 @@ -extern crate issue_25185_1; - -pub use issue_25185_1::rust_dbg_extern_identity_u32; diff --git a/src/test/run-pass/abi/issues/issue-25185.rs b/src/test/run-pass/abi/issues/issue-25185.rs deleted file mode 100644 index 383c9a1e9c4a..000000000000 --- a/src/test/run-pass/abi/issues/issue-25185.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass -// aux-build:issue-25185-1.rs -// aux-build:issue-25185-2.rs -// ignore-wasm32-bare no libc for ffi testing - -extern crate issue_25185_2; - -fn main() { - let x = unsafe { - issue_25185_2::rust_dbg_extern_identity_u32(1) - }; - assert_eq!(x, 1); -} diff --git a/src/test/run-pass/abi/issues/issue-28676.rs b/src/test/run-pass/abi/issues/issue-28676.rs deleted file mode 100644 index 2b83478ca611..000000000000 --- a/src/test/run-pass/abi/issues/issue-28676.rs +++ /dev/null @@ -1,35 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![allow(improper_ctypes)] - -// ignore-wasm32-bare no libc to test ffi with - -#[derive(Copy, Clone)] -pub struct Quad { a: u64, b: u64, c: u64, d: u64 } - -mod rustrt { - use super::Quad; - - #[link(name = "rust_test_helpers", kind = "static")] - extern { - pub fn get_c_many_params(_: *const (), _: *const (), - _: *const (), _: *const (), f: Quad) -> u64; - } -} - -fn test() { - unsafe { - let null = std::ptr::null(); - let q = Quad { - a: 1, - b: 2, - c: 3, - d: 4 - }; - assert_eq!(rustrt::get_c_many_params(null, null, null, null, q), q.c); - } -} - -pub fn main() { - test(); -} diff --git a/src/test/run-pass/abi/lib-defaults.rs b/src/test/run-pass/abi/lib-defaults.rs deleted file mode 100644 index dcf537866c50..000000000000 --- a/src/test/run-pass/abi/lib-defaults.rs +++ /dev/null @@ -1,16 +0,0 @@ -// dont-check-compiler-stderr (rust-lang/rust#54222) - -// ignore-wasm32-bare no libc to test ffi with - -// compile-flags: -lrust_test_helpers - -#[link(name = "rust_test_helpers", kind = "static")] -extern "C" { - pub fn rust_dbg_extern_identity_u32(x: u32) -> u32; -} - -fn main() { - unsafe { - rust_dbg_extern_identity_u32(42); - } -} diff --git a/src/test/run-pass/abi/macros/macros-in-extern.rs b/src/test/run-pass/abi/macros/macros-in-extern.rs deleted file mode 100644 index 28abef5cf4ed..000000000000 --- a/src/test/run-pass/abi/macros/macros-in-extern.rs +++ /dev/null @@ -1,30 +0,0 @@ -// run-pass -// ignore-wasm32 - -#![feature(decl_macro, macros_in_extern)] - -macro_rules! returns_isize( - ($ident:ident) => ( - fn $ident() -> isize; - ) -); - -macro takes_u32_returns_u32($ident:ident) { - fn $ident (arg: u32) -> u32; -} - -macro_rules! emits_nothing( - () => () -); - -fn main() { - assert_eq!(unsafe { rust_get_test_int() }, 1isize); - assert_eq!(unsafe { rust_dbg_extern_identity_u32(0xDEADBEEF) }, 0xDEADBEEFu32); -} - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - returns_isize!(rust_get_test_int); - takes_u32_returns_u32!(rust_dbg_extern_identity_u32); - emits_nothing!(); -} diff --git a/src/test/run-pass/abi/mir/mir_codegen_calls_variadic.rs b/src/test/run-pass/abi/mir/mir_codegen_calls_variadic.rs deleted file mode 100644 index dc9fee03b776..000000000000 --- a/src/test/run-pass/abi/mir/mir_codegen_calls_variadic.rs +++ /dev/null @@ -1,22 +0,0 @@ -// run-pass -// ignore-wasm32-bare no libc to test ffi with - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - fn rust_interesting_average(_: i64, ...) -> f64; -} - -fn test(a: i64, b: i64, c: i64, d: i64, e: i64, f: T, g: U) -> i64 { - unsafe { - rust_interesting_average(6, a, a as f64, - b, b as f64, - c, c as f64, - d, d as f64, - e, e as f64, - f, g) as i64 - } -} - -fn main(){ - assert_eq!(test(10, 20, 30, 40, 50, 60_i64, 60.0_f64), 70); -} diff --git a/src/test/run-pass/abi/numbers-arithmetic/i128-ffi.rs b/src/test/run-pass/abi/numbers-arithmetic/i128-ffi.rs deleted file mode 100644 index 19edf9779f35..000000000000 --- a/src/test/run-pass/abi/numbers-arithmetic/i128-ffi.rs +++ /dev/null @@ -1,31 +0,0 @@ -// run-pass -#![allow(improper_ctypes)] - -// MSVC doesn't support 128 bit integers, and other Windows -// C compilers have very inconsistent views on how the ABI -// should look like. - -// ignore-windows -// ignore-32bit - -#[link(name = "rust_test_helpers", kind = "static")] -extern "C" { - fn identity(f: u128) -> u128; - fn square(f: i128) -> i128; - fn sub(f: i128, f: i128) -> i128; -} - -fn main() { - unsafe { - let a = 0x734C_C2F2_A521; - let b = 0x33EE_0E2A_54E2_59DA_A0E7_8E41; - let b_out = identity(b); - assert_eq!(b, b_out); - let a_square = square(a); - assert_eq!(b, a_square as u128); - let k = 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210; - let k_d = 0x2468_ACF1_3579_BDFF_DB97_530E_CA86_420; - let k_out = sub(k_d, k); - assert_eq!(k, k_out); - } -} diff --git a/src/test/run-pass/abi/proc_macro/auxiliary/test-macros.rs b/src/test/run-pass/abi/proc_macro/auxiliary/test-macros.rs deleted file mode 100644 index 15fe3804f9b4..000000000000 --- a/src/test/run-pass/abi/proc_macro/auxiliary/test-macros.rs +++ /dev/null @@ -1,26 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] - -extern crate proc_macro; - -use proc_macro::TokenStream; - -#[proc_macro_attribute] -pub fn nop_attr(_attr: TokenStream, input: TokenStream) -> TokenStream { - assert!(_attr.to_string().is_empty()); - input -} - -#[proc_macro_attribute] -pub fn no_output(_attr: TokenStream, _input: TokenStream) -> TokenStream { - assert!(_attr.to_string().is_empty()); - assert!(!_input.to_string().is_empty()); - "".parse().unwrap() -} - -#[proc_macro] -pub fn emit_input(input: TokenStream) -> TokenStream { - input -} diff --git a/src/test/run-pass/abi/proc_macro/macros-in-extern.rs b/src/test/run-pass/abi/proc_macro/macros-in-extern.rs deleted file mode 100644 index 99e3f7d14fd1..000000000000 --- a/src/test/run-pass/abi/proc_macro/macros-in-extern.rs +++ /dev/null @@ -1,24 +0,0 @@ -// aux-build:test-macros.rs -// ignore-wasm32 - -#![feature(macros_in_extern)] - -extern crate test_macros; - -use test_macros::{nop_attr, no_output, emit_input}; - -fn main() { - assert_eq!(unsafe { rust_get_test_int() }, 1isize); - assert_eq!(unsafe { rust_dbg_extern_identity_u32(0xDEADBEEF) }, 0xDEADBEEF); -} - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - #[no_output] - fn some_definitely_unknown_symbol_which_should_be_removed(); - - #[nop_attr] - fn rust_get_test_int() -> isize; - - emit_input!(fn rust_dbg_extern_identity_u32(arg: u32) -> u32;); -} diff --git a/src/test/run-pass/abi/rfcs/rfc1717/library-override.rs b/src/test/run-pass/abi/rfcs/rfc1717/library-override.rs deleted file mode 100644 index 014ccac31b7a..000000000000 --- a/src/test/run-pass/abi/rfcs/rfc1717/library-override.rs +++ /dev/null @@ -1,14 +0,0 @@ -// run-pass -// ignore-wasm32-bare no libc to test ffi with -// compile-flags: -lstatic=wronglibrary:rust_test_helpers - -#[link(name = "wronglibrary", kind = "dylib")] -extern "C" { - pub fn rust_dbg_extern_identity_u32(x: u32) -> u32; -} - -fn main() { - unsafe { - rust_dbg_extern_identity_u32(42); - } -} diff --git a/src/test/run-pass/abi/segfault-no-out-of-stack.rs b/src/test/run-pass/abi/segfault-no-out-of-stack.rs deleted file mode 100644 index e90efface687..000000000000 --- a/src/test/run-pass/abi/segfault-no-out-of-stack.rs +++ /dev/null @@ -1,48 +0,0 @@ -#![allow(unused_imports)] -// ignore-cloudabi can't run commands -// ignore-emscripten can't run commands -// ignore-sgx no processes - -#![feature(rustc_private)] - -extern crate libc; - -use std::process::{Command, ExitStatus}; -use std::env; - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - fn rust_get_null_ptr() -> *mut ::libc::c_char; -} - -#[cfg(unix)] -fn check_status(status: std::process::ExitStatus) -{ - use libc; - use std::os::unix::process::ExitStatusExt; - - assert!(status.signal() == Some(libc::SIGSEGV) - || status.signal() == Some(libc::SIGBUS)); -} - -#[cfg(not(unix))] -fn check_status(status: std::process::ExitStatus) -{ - assert!(!status.success()); -} - -fn main() { - let args: Vec = env::args().collect(); - if args.len() > 1 && args[1] == "segfault" { - unsafe { *rust_get_null_ptr() = 1; }; // trigger a segfault - } else { - let segfault = Command::new(&args[0]).arg("segfault").output().unwrap(); - let stderr = String::from_utf8_lossy(&segfault.stderr); - let stdout = String::from_utf8_lossy(&segfault.stdout); - println!("stdout: {}", stdout); - println!("stderr: {}", stderr); - println!("status: {}", segfault.status); - check_status(segfault.status); - assert!(!stderr.contains("has overflowed its stack")); - } -} diff --git a/src/test/run-pass/abi/stack-probes-lto.rs b/src/test/run-pass/abi/stack-probes-lto.rs deleted file mode 100644 index 1274f032a3e2..000000000000 --- a/src/test/run-pass/abi/stack-probes-lto.rs +++ /dev/null @@ -1,18 +0,0 @@ -// ignore-arm -// ignore-aarch64 -// ignore-mips -// ignore-mips64 -// ignore-powerpc -// ignore-s390x -// ignore-sparc -// ignore-sparc64 -// ignore-wasm -// ignore-cloudabi no processes -// ignore-emscripten no processes -// ignore-sgx no processes -// ignore-musl FIXME #31506 -// ignore-pretty -// compile-flags: -C lto -// no-prefer-dynamic - -include!("stack-probes.rs"); diff --git a/src/test/run-pass/abi/stack-probes.rs b/src/test/run-pass/abi/stack-probes.rs deleted file mode 100644 index 773d0ace90ed..000000000000 --- a/src/test/run-pass/abi/stack-probes.rs +++ /dev/null @@ -1,67 +0,0 @@ -// ignore-arm -// ignore-aarch64 -// ignore-mips -// ignore-mips64 -// ignore-powerpc -// ignore-s390x -// ignore-sparc -// ignore-sparc64 -// ignore-wasm -// ignore-cloudabi no processes -// ignore-emscripten no processes -// ignore-sgx no processes -// ignore-musl FIXME #31506 - -use std::mem; -use std::process::Command; -use std::thread; -use std::env; - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - #[link_name = "rust_dbg_extern_identity_u64"] - fn black_box(u: u64); -} - -fn main() { - let args = env::args().skip(1).collect::>(); - if args.len() > 0 { - match &args[0][..] { - "main-thread" => recurse(&[]), - "child-thread" => thread::spawn(|| recurse(&[])).join().unwrap(), - _ => panic!(), - } - return - } - - let me = env::current_exe().unwrap(); - - // The linux kernel has some different behavior for the main thread because - // the main thread's stack can typically grow. We can't always guarantee - // that we report stack overflow on the main thread, see #43052 for some - // details - if cfg!(not(target_os = "linux")) { - assert_overflow(Command::new(&me).arg("main-thread")); - } - assert_overflow(Command::new(&me).arg("child-thread")); -} - -#[allow(unconditional_recursion)] -fn recurse(array: &[u64]) { - unsafe { black_box(array.as_ptr() as u64); } - #[allow(deprecated)] - let local: [_; 1024] = unsafe { mem::uninitialized() }; - recurse(&local); -} - -fn assert_overflow(cmd: &mut Command) { - let output = cmd.output().unwrap(); - assert!(!output.status.success()); - let stdout = String::from_utf8_lossy(&output.stdout); - let stderr = String::from_utf8_lossy(&output.stderr); - println!("status: {}", output.status); - println!("stdout: {}", stdout); - println!("stderr: {}", stderr); - assert!(stdout.is_empty()); - assert!(stderr.contains("has overflowed its stack\n")); -} diff --git a/src/test/run-pass/abi/statics/static-mut-foreign.rs b/src/test/run-pass/abi/statics/static-mut-foreign.rs deleted file mode 100644 index 5d6fa416b989..000000000000 --- a/src/test/run-pass/abi/statics/static-mut-foreign.rs +++ /dev/null @@ -1,41 +0,0 @@ -// run-pass -// Constants (static variables) can be used to match in patterns, but mutable -// statics cannot. This ensures that there's some form of error if this is -// attempted. - -// ignore-wasm32-bare no libc to test ffi with - -#![feature(rustc_private)] - -extern crate libc; - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - static mut rust_dbg_static_mut: libc::c_int; - pub fn rust_dbg_static_mut_check_four(); -} - -unsafe fn static_bound(_: &'static libc::c_int) {} - -fn static_bound_set(a: &'static mut libc::c_int) { - *a = 3; -} - -unsafe fn run() { - assert_eq!(rust_dbg_static_mut, 3); - rust_dbg_static_mut = 4; - assert_eq!(rust_dbg_static_mut, 4); - rust_dbg_static_mut_check_four(); - rust_dbg_static_mut += 1; - assert_eq!(rust_dbg_static_mut, 5); - rust_dbg_static_mut *= 3; - assert_eq!(rust_dbg_static_mut, 15); - rust_dbg_static_mut = -3; - assert_eq!(rust_dbg_static_mut, -3); - static_bound(&rust_dbg_static_mut); - static_bound_set(&mut rust_dbg_static_mut); -} - -pub fn main() { - unsafe { run() } -} diff --git a/src/test/run-pass/abi/structs-enums/struct-return.rs b/src/test/run-pass/abi/structs-enums/struct-return.rs deleted file mode 100644 index 5930fc4acbbe..000000000000 --- a/src/test/run-pass/abi/structs-enums/struct-return.rs +++ /dev/null @@ -1,64 +0,0 @@ -// run-pass -#![allow(dead_code)] -// ignore-wasm32-bare no libc to test ffi with - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct Quad { a: u64, b: u64, c: u64, d: u64 } - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct Floats { a: f64, b: u8, c: f64 } - -mod rustrt { - use super::{Floats, Quad}; - - #[link(name = "rust_test_helpers", kind = "static")] - extern { - pub fn rust_dbg_abi_1(q: Quad) -> Quad; - pub fn rust_dbg_abi_2(f: Floats) -> Floats; - } -} - -fn test1() { - unsafe { - let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa, - b: 0xbbbb_bbbb_bbbb_bbbb, - c: 0xcccc_cccc_cccc_cccc, - d: 0xdddd_dddd_dddd_dddd }; - let qq = rustrt::rust_dbg_abi_1(q); - println!("a: {:x}", qq.a as usize); - println!("b: {:x}", qq.b as usize); - println!("c: {:x}", qq.c as usize); - println!("d: {:x}", qq.d as usize); - assert_eq!(qq.a, q.c + 1); - assert_eq!(qq.b, q.d - 1); - assert_eq!(qq.c, q.a + 1); - assert_eq!(qq.d, q.b - 1); - } -} - -#[cfg(target_pointer_width = "64")] -fn test2() { - unsafe { - let f = Floats { a: 1.234567890e-15_f64, - b: 0b_1010_1010, - c: 1.0987654321e-15_f64 }; - let ff = rustrt::rust_dbg_abi_2(f); - println!("a: {}", ff.a as f64); - println!("b: {}", ff.b as usize); - println!("c: {}", ff.c as f64); - assert_eq!(ff.a, f.c + 1.0f64); - assert_eq!(ff.b, 0xff); - assert_eq!(ff.c, f.a - 1.0f64); - } -} - -#[cfg(target_pointer_width = "32")] -fn test2() { -} - -pub fn main() { - test1(); - test2(); -} diff --git a/src/test/run-pass/abi/union/union-c-interop.rs b/src/test/run-pass/abi/union/union-c-interop.rs deleted file mode 100644 index 00f04d5b7ff3..000000000000 --- a/src/test/run-pass/abi/union/union-c-interop.rs +++ /dev/null @@ -1,37 +0,0 @@ -// run-pass -#![allow(non_snake_case)] - -// ignore-wasm32-bare no libc to test ffi with - -#[derive(Clone, Copy)] -#[repr(C)] -struct LARGE_INTEGER_U { - LowPart: u32, - HighPart: u32, -} - -#[derive(Clone, Copy)] -#[repr(C)] -union LARGE_INTEGER { - __unnamed__: LARGE_INTEGER_U, - u: LARGE_INTEGER_U, - QuadPart: u64, -} - -#[link(name = "rust_test_helpers", kind = "static")] -extern "C" { - fn increment_all_parts(_: LARGE_INTEGER) -> LARGE_INTEGER; -} - -fn main() { - unsafe { - let mut li = LARGE_INTEGER { QuadPart: 0 }; - let li_c = increment_all_parts(li); - li.__unnamed__.LowPart += 1; - li.__unnamed__.HighPart += 1; - li.u.LowPart += 1; - li.u.HighPart += 1; - li.QuadPart += 1; - assert_eq!(li.QuadPart, li_c.QuadPart); - } -} diff --git a/src/test/run-pass/abi/variadic-ffi.rs b/src/test/run-pass/abi/variadic-ffi.rs deleted file mode 100644 index d6fbb1773b29..000000000000 --- a/src/test/run-pass/abi/variadic-ffi.rs +++ /dev/null @@ -1,83 +0,0 @@ -// ignore-wasm32-bare no libc to test ffi with -#![feature(c_variadic)] - -use std::ffi::VaList; - -#[link(name = "rust_test_helpers", kind = "static")] -extern { - fn rust_interesting_average(_: u64, ...) -> f64; - - // FIXME: we need to disable this lint for `VaList`, - // since it contains a `MaybeUninit` on the asmjs target, - // and this type isn't FFI-safe. This is OK for now, - // since the type is layout-compatible with `i32`. - #[cfg_attr(target_arch = "asmjs", allow(improper_ctypes))] - fn rust_valist_interesting_average(_: u64, _: VaList) -> f64; -} - -pub unsafe extern "C" fn test_valist_forward(n: u64, mut ap: ...) -> f64 { - rust_valist_interesting_average(n, ap.as_va_list()) -} - -pub unsafe extern "C" fn test_va_copy(_: u64, mut ap: ...) { - let mut ap2 = ap.clone(); - assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 30); - - // Advance one pair in the copy before checking - let mut ap2 = ap.clone(); - let _ = ap2.arg::(); - let _ = ap2.arg::(); - assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 50); - - // Advance one pair in the original - let _ = ap.arg::(); - let _ = ap.arg::(); - - let mut ap2 = ap.clone(); - assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 50); - - let mut ap2 = ap.clone(); - let _ = ap2.arg::(); - let _ = ap2.arg::(); - assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 70); -} - -pub fn main() { - // Call without variadic arguments - unsafe { - assert!(rust_interesting_average(0).is_nan()); - } - - // Call with direct arguments - unsafe { - assert_eq!(rust_interesting_average(1, 10i64, 10.0f64) as i64, 20); - } - - // Call with named arguments, variable number of them - let (x1, x2, x3, x4) = (10i64, 10.0f64, 20i64, 20.0f64); - unsafe { - assert_eq!(rust_interesting_average(2, x1, x2, x3, x4) as i64, 30); - } - - // A function that takes a function pointer - unsafe fn call(fp: unsafe extern fn(u64, ...) -> f64) { - let (x1, x2, x3, x4) = (10i64, 10.0f64, 20i64, 20.0f64); - assert_eq!(fp(2, x1, x2, x3, x4) as i64, 30); - } - - unsafe { - call(rust_interesting_average); - - // Make a function pointer, pass indirectly - let x: unsafe extern fn(u64, ...) -> f64 = rust_interesting_average; - call(x); - } - - unsafe { - assert_eq!(test_valist_forward(2, 10i64, 10f64, 20i64, 20f64) as i64, 30); - } - - unsafe { - test_va_copy(4, 10i64, 10f64, 20i64, 20f64, 30i64, 30f64, 40i64, 40f64); - } -} From 26ee99e5d473e8743e3faa08c6cb89d3acb29104 Mon Sep 17 00:00:00 2001 From: Kevin Per Date: Thu, 15 Aug 2019 19:26:51 +0200 Subject: [PATCH 17/35] Duplicate `test-macros.rs` to fix test #62593 --- .../abi/proc-macro/auxiliary/test-macros.rs | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 src/test/ui/abi/proc-macro/auxiliary/test-macros.rs diff --git a/src/test/ui/abi/proc-macro/auxiliary/test-macros.rs b/src/test/ui/abi/proc-macro/auxiliary/test-macros.rs new file mode 100644 index 000000000000..27efa44f9803 --- /dev/null +++ b/src/test/ui/abi/proc-macro/auxiliary/test-macros.rs @@ -0,0 +1,112 @@ +// force-host +// no-prefer-dynamic + +// Proc macros commonly used by tests. +// `panic`/`print` -> `panic_bang`/`print_bang` to avoid conflicts with standard macros. + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +// Macro that return empty token stream. + +#[proc_macro] +pub fn empty(_: TokenStream) -> TokenStream { + TokenStream::new() +} + +#[proc_macro_attribute] +pub fn empty_attr(_: TokenStream, _: TokenStream) -> TokenStream { + TokenStream::new() +} + +#[proc_macro_derive(Empty, attributes(empty_helper))] +pub fn empty_derive(_: TokenStream) -> TokenStream { + TokenStream::new() +} + +// Macro that panics. + +#[proc_macro] +pub fn panic_bang(_: TokenStream) -> TokenStream { + panic!("panic-bang"); +} + +#[proc_macro_attribute] +pub fn panic_attr(_: TokenStream, _: TokenStream) -> TokenStream { + panic!("panic-attr"); +} + +#[proc_macro_derive(Panic, attributes(panic_helper))] +pub fn panic_derive(_: TokenStream) -> TokenStream { + panic!("panic-derive"); +} + +// Macros that return the input stream. + +#[proc_macro] +pub fn identity(input: TokenStream) -> TokenStream { + input +} + +#[proc_macro_attribute] +pub fn identity_attr(_: TokenStream, input: TokenStream) -> TokenStream { + input +} + +#[proc_macro_derive(Identity, attributes(identity_helper))] +pub fn identity_derive(input: TokenStream) -> TokenStream { + input +} + +// Macros that iterate and re-collect the input stream. + +#[proc_macro] +pub fn recollect(input: TokenStream) -> TokenStream { + input.into_iter().collect() +} + +#[proc_macro_attribute] +pub fn recollect_attr(_: TokenStream, input: TokenStream) -> TokenStream { + input.into_iter().collect() +} + +#[proc_macro_derive(Recollect, attributes(recollect_helper))] +pub fn recollect_derive(input: TokenStream) -> TokenStream { + input.into_iter().collect() +} + +// Macros that print their input in the original and re-collected forms (if they differ). + +fn print_helper(input: TokenStream, kind: &str) -> TokenStream { + let input_display = format!("{}", input); + let input_debug = format!("{:#?}", input); + let recollected = input.into_iter().collect(); + let recollected_display = format!("{}", recollected); + let recollected_debug = format!("{:#?}", recollected); + println!("PRINT-{} INPUT (DISPLAY): {}", kind, input_display); + if recollected_display != input_display { + println!("PRINT-{} RE-COLLECTED (DISPLAY): {}", kind, recollected_display); + } + println!("PRINT-{} INPUT (DEBUG): {}", kind, input_debug); + if recollected_debug != input_debug { + println!("PRINT-{} RE-COLLECTED (DEBUG): {}", kind, recollected_debug); + } + recollected +} + +#[proc_macro] +pub fn print_bang(input: TokenStream) -> TokenStream { + print_helper(input, "BANG") +} + +#[proc_macro_attribute] +pub fn print_attr(_: TokenStream, input: TokenStream) -> TokenStream { + print_helper(input, "ATTR") +} + +#[proc_macro_derive(Print, attributes(print_helper))] +pub fn print_derive(input: TokenStream) -> TokenStream { + print_helper(input, "DERIVE") +} From dfcbe75900f2cb813754ef104526ebce568fd75b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 11 Aug 2019 01:08:30 +0300 Subject: [PATCH 18/35] syntax_pos: Introduce a helper for checking whether a span comes from expansion --- src/librustc/lint/internal.rs | 2 +- src/librustc_codegen_ssa/mir/mod.rs | 4 ++-- src/librustc_lint/builtin.rs | 8 ++++---- src/librustc_lint/unused.rs | 2 +- src/librustc_resolve/lib.rs | 4 ++-- src/librustc_save_analysis/lib.rs | 2 +- src/librustc_typeck/check/demand.rs | 6 +++--- src/librustc_typeck/check/method/suggest.rs | 4 ++-- src/libsyntax/parse/parser.rs | 2 +- src/libsyntax_pos/hygiene.rs | 2 +- src/libsyntax_pos/lib.rs | 6 ++++++ src/libsyntax_pos/symbol.rs | 3 +-- 12 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/librustc/lint/internal.rs b/src/librustc/lint/internal.rs index dea1cc6601b0..d9ad34a5297f 100644 --- a/src/librustc/lint/internal.rs +++ b/src/librustc/lint/internal.rs @@ -108,7 +108,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TyTyKind { .help("try using `Ty` instead") .emit(); } else { - if ty.span.ctxt().outer_expn_info().is_some() { + if ty.span.from_expansion() { return; } if let Some(t) = is_ty_or_ty_ctxt(cx, ty) { diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index e7517d699919..32bcdebc1c46 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -8,7 +8,7 @@ use crate::base; use crate::debuginfo::{self, VariableAccess, VariableKind, FunctionDebugContext}; use crate::traits::*; -use syntax_pos::{DUMMY_SP, NO_EXPANSION, BytePos, Span}; +use syntax_pos::{DUMMY_SP, BytePos, Span}; use syntax::symbol::kw; use std::iter; @@ -120,7 +120,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // In order to have a good line stepping behavior in debugger, we overwrite debug // locations of macro expansions with that of the outermost expansion site // (unless the crate is being compiled with `-Z debug-macros`). - if source_info.span.ctxt() == NO_EXPANSION || + if !source_info.span.from_expansion() || self.cx.sess().opts.debugging_opts.debug_macros { let scope = self.scope_metadata_for_loc(source_info.scope, source_info.span.lo()); (scope, source_info.span) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 47b4e7c94875..82160080a44d 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -42,7 +42,7 @@ use syntax::source_map::Spanned; use syntax::edition::Edition; use syntax::feature_gate::{self, AttributeGate, AttributeType}; use syntax::feature_gate::{Stability, deprecated_attributes}; -use syntax_pos::{BytePos, Span, SyntaxContext}; +use syntax_pos::{BytePos, Span}; use syntax::symbol::{Symbol, kw, sym}; use syntax::errors::{Applicability, DiagnosticBuilder}; use syntax::print::pprust::expr_to_string; @@ -78,7 +78,7 @@ impl EarlyLintPass for WhileTrue { if let ast::ExprKind::While(cond, ..) = &e.node { if let ast::ExprKind::Lit(ref lit) = pierce_parens(cond).node { if let ast::LitKind::Bool(true) = lit.node { - if lit.span.ctxt() == SyntaxContext::empty() { + if !lit.span.from_expansion() { let msg = "denote infinite loops with `loop { ... }`"; let condition_span = cx.sess.source_map().def_span(e.span); cx.struct_span_lint(WHILE_TRUE, condition_span, msg) @@ -167,7 +167,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonShorthandFieldPatterns { if fieldpat.is_shorthand { continue; } - if fieldpat.span.ctxt().outer_expn_info().is_some() { + if fieldpat.span.from_expansion() { // Don't lint if this is a macro expansion: macro authors // shouldn't have to worry about this kind of style issue // (Issue #49588) @@ -1012,7 +1012,7 @@ impl UnreachablePub { let mut applicability = Applicability::MachineApplicable; match vis.node { hir::VisibilityKind::Public if !cx.access_levels.is_reachable(id) => { - if span.ctxt().outer_expn_info().is_some() { + if span.from_expansion() { applicability = Applicability::MaybeIncorrect; } let def_span = cx.tcx.sess.source_map().def_span(span); diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 6a3dfdbe3168..9cad8f58d41d 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -518,7 +518,7 @@ impl EarlyLintPass for UnusedParens { // when a parenthesized token tree matched in one macro expansion is matched as // an expression in another and used as a fn/method argument (Issue #47775) if e.span.ctxt().outer_expn_info() - .map_or(false, |info| info.call_site.ctxt().outer_expn_info().is_some()) { + .map_or(false, |info| info.call_site.from_expansion()) { return; } let msg = format!("{} argument", call_kind); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 8a4a60c16b0f..f0916c2ff3e2 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -274,7 +274,7 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder { ItemKind::Use(..) => { // don't suggest placing a use before the prelude // import or other generated ones - if item.span.ctxt().outer_expn_info().is_none() { + if !item.span.from_expansion() { self.span = Some(item.span.shrink_to_lo()); self.found_use = true; return; @@ -284,7 +284,7 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder { ItemKind::ExternCrate(_) => {} // but place them before the first other item _ => if self.span.map_or(true, |span| item.span < span ) { - if item.span.ctxt().outer_expn_info().is_none() { + if !item.span.from_expansion() { // don't insert between attributes and an item if item.attrs.is_empty() { self.span = Some(item.span.shrink_to_lo()); diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 9da6cd800570..0bbbbb8249c2 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -1156,7 +1156,7 @@ fn escape(s: String) -> String { // Helper function to determine if a span came from a // macro expansion or syntax extension. fn generated_code(span: Span) -> bool { - span.ctxt() != NO_EXPANSION || span.is_dummy() + span.from_expansion() || span.is_dummy() } // DefId::index is a newtype and so the JSON serialisation is ugly. Therefore diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index ed25601208ad..c72966edc5ae 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -347,9 +347,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sp, ); - // Check the `expn_info()` to see if this is a macro; if so, it's hard to - // extract the text and make a good suggestion, so don't bother. - let is_macro = sp.ctxt().outer_expn_info().is_some(); + // If the span is from a macro, then it's hard to extract the text + // and make a good suggestion, so don't bother. + let is_macro = sp.from_expansion(); match (&expr.node, &expected.sty, &checked_ty.sty) { (_, &ty::Ref(_, exp, _), &ty::Ref(_, check, _)) => match (&exp.sty, &check.sty) { diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 4a5eba1df883..53024d97c3b1 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -985,7 +985,7 @@ impl hir::intravisit::Visitor<'tcx> for UsePlacementFinder<'tcx> { hir::ItemKind::Use(..) => { // Don't suggest placing a `use` before the prelude // import or other generated ones. - if item.span.ctxt().outer_expn_info().is_none() { + if !item.span.from_expansion() { self.span = Some(item.span.shrink_to_lo()); self.found_use = true; return; @@ -995,7 +995,7 @@ impl hir::intravisit::Visitor<'tcx> for UsePlacementFinder<'tcx> { hir::ItemKind::ExternCrate(_) => {} // ...but do place them before the first other item. _ => if self.span.map_or(true, |span| item.span < span ) { - if item.span.ctxt().outer_expn_info().is_none() { + if !item.span.from_expansion() { // Don't insert between attributes and an item. if item.attrs.is_empty() { self.span = Some(item.span.shrink_to_lo()); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 2286e74e6330..3b0af88f6510 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1101,7 +1101,7 @@ impl<'a> Parser<'a> { crate fn process_potential_macro_variable(&mut self) { self.token = match self.token.kind { - token::Dollar if self.token.span.ctxt() != SyntaxContext::empty() && + token::Dollar if self.token.span.from_expansion() && self.look_ahead(1, |t| t.is_ident()) => { self.bump(); let name = match self.token.kind { diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index f91a22915445..4132b99cf416 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -255,7 +255,7 @@ impl HygieneData { } fn walk_chain(&self, mut span: Span, to: SyntaxContext) -> Span { - while span.ctxt() != crate::NO_EXPANSION && span.ctxt() != to { + while span.from_expansion() && span.ctxt() != to { if let Some(info) = self.expn_info(self.outer_expn(span.ctxt())) { span = info.call_site; } else { diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 02a7433d9469..793710b453f2 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -288,6 +288,12 @@ impl Span { span.lo.0 == 0 && span.hi.0 == 0 } + /// Returns `true` if this span comes from a macro or desugaring. + #[inline] + pub fn from_expansion(self) -> bool { + self.ctxt() != SyntaxContext::empty() + } + /// Returns a new span representing an empty span at the beginning of this span #[inline] pub fn shrink_to_lo(self) -> Span { diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 2d9556233d15..6f5a458a874e 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -14,7 +14,6 @@ use std::fmt; use std::hash::{Hash, Hasher}; use std::str; -use crate::hygiene::SyntaxContext; use crate::{Span, DUMMY_SP, GLOBALS}; #[cfg(test)] @@ -851,7 +850,7 @@ impl fmt::Display for Ident { impl Encodable for Ident { fn encode(&self, s: &mut S) -> Result<(), S::Error> { - if self.span.ctxt().modern() == SyntaxContext::empty() { + if !self.span.modern().from_expansion() { s.emit_str(&self.as_str()) } else { // FIXME(jseyfried): intercrate hygiene let mut string = "#".to_owned(); From 67d6ce42063732d7c7b12d94f872dcafb5efb607 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 11 Aug 2019 01:44:55 +0300 Subject: [PATCH 19/35] syntax_pos: `NO_EXPANSION`/`SyntaxContext::empty()` -> `SyntaxContext::root()` For consistency with `ExpnId::root`. Also introduce a helper `Span::with_root_ctxt` for creating spans with `SyntaxContext::root()` context --- src/librustc/ich/hcx.rs | 2 +- src/librustc/ty/query/on_disk_cache.rs | 4 ++-- src/librustc_errors/lib.rs | 5 ++--- src/librustc_metadata/cstore_impl.rs | 4 ++-- src/librustc_metadata/decoder.rs | 4 ++-- src/librustc_resolve/lib.rs | 2 +- src/libsyntax/ext/base.rs | 2 +- src/libsyntax/ext/expand.rs | 2 +- src/libsyntax/ext/proc_macro_server.rs | 2 +- src/libsyntax/parse/lexer/mod.rs | 4 ++-- src/libsyntax/parse/lexer/tests.rs | 6 +++--- src/libsyntax/parse/lexer/unicode_chars.rs | 7 +++---- src/libsyntax/parse/tests.rs | 4 ++-- src/libsyntax/source_map/tests.rs | 11 +++++------ src/libsyntax/tests.rs | 4 ++-- src/libsyntax/tokenstream/tests.rs | 4 ++-- src/libsyntax_ext/global_allocator.rs | 2 +- src/libsyntax_ext/test.rs | 4 ++-- src/libsyntax_pos/hygiene.rs | 12 ++++++------ src/libsyntax_pos/lib.rs | 21 ++++++++++++--------- 20 files changed, 53 insertions(+), 53 deletions(-) diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index ae7d82c2020a..39f6b0d43444 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -350,7 +350,7 @@ impl<'a> HashStable> for Span { let line_col_len = col | line | len; std_hash::Hash::hash(&line_col_len, hasher); - if span.ctxt == SyntaxContext::empty() { + if span.ctxt == SyntaxContext::root() { TAG_NO_EXPANSION.hash_stable(hcx, hasher); } else { TAG_EXPANSION.hash_stable(hcx, hasher); diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index 00871a1cbf2a..1c5baa638c2b 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -592,7 +592,7 @@ impl<'a, 'tcx> SpecializedDecoder for CacheDecoder<'a, 'tcx> { // `SyntaxContextData::prev_ctxt` or `SyntaxContextData::opaque`. These things // don't seem to be used after HIR lowering, so everything should be fine // as long as incremental compilation does not kick in before that. - let location = || Span::new(lo, hi, SyntaxContext::empty()); + let location = || Span::with_root_ctxt(lo, hi); let recover_from_expn_info = |this: &Self, expn_info, pos| { let span = location().fresh_expansion(ExpnId::root(), expn_info); this.synthetic_expansion_infos.borrow_mut().insert(pos, span.ctxt()); @@ -816,7 +816,7 @@ where col_lo.encode(self)?; len.encode(self)?; - if span_data.ctxt == SyntaxContext::empty() { + if span_data.ctxt == SyntaxContext::root() { TAG_NO_EXPANSION_INFO.encode(self) } else { let (expn_id, expn_info) = span_data.ctxt.outer_expn_with_info(); diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index f3e524152ffa..4018a667bf26 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -43,8 +43,7 @@ use syntax_pos::{BytePos, SourceFile, FileName, MultiSpan, - Span, - NO_EXPANSION}; + Span}; /// Indicates the confidence in the correctness of a suggestion. /// @@ -189,7 +188,7 @@ impl CodeSuggestion { // Find the bounding span. let lo = substitution.parts.iter().map(|part| part.span.lo()).min().unwrap(); let hi = substitution.parts.iter().map(|part| part.span.hi()).min().unwrap(); - let bounding_span = Span::new(lo, hi, NO_EXPANSION); + let bounding_span = Span::with_root_ctxt(lo, hi); let lines = cm.span_to_lines(bounding_span).unwrap(); assert!(!lines.lines.is_empty()); diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index ee1175e798d8..b46758abb5f2 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -35,7 +35,7 @@ use syntax::ext::proc_macro::BangProcMacro; use syntax::parse::source_file_to_stream; use syntax::parse::parser::emit_unclosed_delims; use syntax::symbol::{Symbol, sym}; -use syntax_pos::{Span, NO_EXPANSION, FileName}; +use syntax_pos::{Span, FileName}; use rustc_data_structures::bit_set::BitSet; macro_rules! provide { @@ -443,7 +443,7 @@ impl cstore::CStore { let source_name = FileName::Macros(macro_full_name); let source_file = sess.parse_sess.source_map().new_source_file(source_name, def.body); - let local_span = Span::new(source_file.start_pos, source_file.end_pos, NO_EXPANSION); + let local_span = Span::with_root_ctxt(source_file.start_pos, source_file.end_pos); let (body, mut errors) = source_file_to_stream(&sess.parse_sess, source_file, None); emit_unclosed_delims(&mut errors, &sess.diagnostic()); diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 935187dd0667..3de9bf4da11e 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -32,7 +32,7 @@ use syntax::source_map; use syntax::symbol::{Symbol, sym}; use syntax::ext::base::{MacroKind, SyntaxExtension}; use syntax::ext::hygiene::ExpnId; -use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, NO_EXPANSION}; +use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP}; use log::debug; pub struct DecodeContext<'a, 'tcx> { @@ -344,7 +344,7 @@ impl<'a, 'tcx> SpecializedDecoder for DecodeContext<'a, 'tcx> { let hi = (hi + source_file.translated_source_file.start_pos) - source_file.original_start_pos; - Ok(Span::new(lo, hi, NO_EXPANSION)) + Ok(Span::with_root_ctxt(lo, hi)) } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index f0916c2ff3e2..8b2e371f0f61 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1430,7 +1430,7 @@ impl<'a> Resolver<'a> { } let (general_span, modern_span) = if ident.name == kw::SelfUpper { // FIXME(jseyfried) improve `Self` hygiene - let empty_span = ident.span.with_ctxt(SyntaxContext::empty()); + let empty_span = ident.span.with_ctxt(SyntaxContext::root()); (empty_span, empty_span) } else if ns == TypeNS { let modern_span = ident.span.modern(); diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index edeca046c7b8..d9fd31db4dd6 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -762,7 +762,7 @@ impl<'a> ExtCtxt<'a> { } } pub fn backtrace(&self) -> SyntaxContext { - SyntaxContext::empty().apply_mark(self.current_expansion.id) + SyntaxContext::root().apply_mark(self.current_expansion.id) } /// Returns span for the macro which originally caused the current expansion to happen. diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 97983944931b..aa409199afd6 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -759,7 +759,7 @@ impl<'a> Parser<'a> { let msg = format!("macro expansion ignores token `{}` and any following", self.this_token_to_string()); // Avoid emitting backtrace info twice. - let def_site_span = self.token.span.with_ctxt(SyntaxContext::empty()); + let def_site_span = self.token.span.with_ctxt(SyntaxContext::root()); let mut err = self.diagnostic().struct_span_err(def_site_span, &msg); err.span_label(span, "caused by the macro expansion here"); let msg = format!( diff --git a/src/libsyntax/ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs index 36621ce77751..fd93910004ef 100644 --- a/src/libsyntax/ext/proc_macro_server.rs +++ b/src/libsyntax/ext/proc_macro_server.rs @@ -365,7 +365,7 @@ impl<'a> Rustc<'a> { let location = cx.current_expansion.id.expn_info().unwrap().call_site; let to_span = |transparency| { location.with_ctxt( - SyntaxContext::empty() + SyntaxContext::root() .apply_mark_with_transparency(cx.current_expansion.id, transparency), ) }; diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index e86d4c7fde68..17629d392cd3 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -4,7 +4,7 @@ use crate::symbol::{sym, Symbol}; use crate::parse::unescape_error_reporting::{emit_unescape_error, push_escaped_char}; use errors::{FatalError, DiagnosticBuilder}; -use syntax_pos::{BytePos, Pos, Span, NO_EXPANSION}; +use syntax_pos::{BytePos, Pos, Span}; use rustc_lexer::Base; use rustc_lexer::unescape; @@ -84,7 +84,7 @@ impl<'a> StringReader<'a> { fn mk_sp(&self, lo: BytePos, hi: BytePos) -> Span { - self.override_span.unwrap_or_else(|| Span::new(lo, hi, NO_EXPANSION)) + self.override_span.unwrap_or_else(|| Span::with_root_ctxt(lo, hi)) } /// Returns the next token, including trivia like whitespace or comments. diff --git a/src/libsyntax/parse/lexer/tests.rs b/src/libsyntax/parse/lexer/tests.rs index fc47e4f0b185..1e4d9048b41b 100644 --- a/src/libsyntax/parse/lexer/tests.rs +++ b/src/libsyntax/parse/lexer/tests.rs @@ -9,7 +9,7 @@ use crate::diagnostics::plugin::ErrorMap; use crate::with_default_globals; use std::io; use std::path::PathBuf; -use syntax_pos::{BytePos, Span, NO_EXPANSION, edition::Edition}; +use syntax_pos::{BytePos, Span, edition::Edition}; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; use rustc_data_structures::sync::{Lock, Once}; @@ -61,7 +61,7 @@ fn t1() { let tok1 = string_reader.next_token(); let tok2 = Token::new( mk_ident("fn"), - Span::new(BytePos(21), BytePos(23), NO_EXPANSION), + Span::with_root_ctxt(BytePos(21), BytePos(23)), ); assert_eq!(tok1.kind, tok2.kind); assert_eq!(tok1.span, tok2.span); @@ -71,7 +71,7 @@ fn t1() { assert_eq!(string_reader.pos.clone(), BytePos(28)); let tok4 = Token::new( mk_ident("main"), - Span::new(BytePos(24), BytePos(28), NO_EXPANSION), + Span::with_root_ctxt(BytePos(24), BytePos(28)), ); assert_eq!(tok3.kind, tok4.kind); assert_eq!(tok3.span, tok4.span); diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/libsyntax/parse/lexer/unicode_chars.rs index eaa736c6a351..525b4215affb 100644 --- a/src/libsyntax/parse/lexer/unicode_chars.rs +++ b/src/libsyntax/parse/lexer/unicode_chars.rs @@ -3,7 +3,7 @@ use super::StringReader; use errors::{Applicability, DiagnosticBuilder}; -use syntax_pos::{BytePos, Pos, Span, NO_EXPANSION, symbol::kw}; +use syntax_pos::{BytePos, Pos, Span, symbol::kw}; use crate::parse::token; #[rustfmt::skip] // for line breaks @@ -343,7 +343,7 @@ crate fn check_for_substitution<'a>( None => return None, }; - let span = Span::new(pos, pos + Pos::from_usize(ch.len_utf8()), NO_EXPANSION); + let span = Span::with_root_ctxt(pos, pos + Pos::from_usize(ch.len_utf8())); let (ascii_name, token) = match ASCII_ARRAY.iter().find(|&&(c, _, _)| c == ascii_char) { Some((_ascii_char, ascii_name, token)) => (ascii_name, token), @@ -362,10 +362,9 @@ crate fn check_for_substitution<'a>( ascii_char, ascii_name ); err.span_suggestion( - Span::new( + Span::with_root_ctxt( pos, pos + Pos::from_usize('“'.len_utf8() + s.len() + '”'.len_utf8()), - NO_EXPANSION, ), &msg, format!("\"{}\"", s), diff --git a/src/libsyntax/parse/tests.rs b/src/libsyntax/parse/tests.rs index 9edc83a35941..6a789ef99d67 100644 --- a/src/libsyntax/parse/tests.rs +++ b/src/libsyntax/parse/tests.rs @@ -12,7 +12,7 @@ use crate::symbol::{kw, sym}; use crate::tests::{matches_codepattern, string_to_stream, with_error_checking_parse}; use crate::tokenstream::{DelimSpan, TokenTree, TokenStream}; use crate::with_default_globals; -use syntax_pos::{Span, BytePos, Pos, NO_EXPANSION}; +use syntax_pos::{Span, BytePos, Pos}; use std::path::PathBuf; @@ -27,7 +27,7 @@ fn parse_item_from_source_str(name: FileName, source: String, sess: &ParseSess) // produce a syntax_pos::span fn sp(a: u32, b: u32) -> Span { - Span::new(BytePos(a), BytePos(b), NO_EXPANSION) + Span::with_root_ctxt(BytePos(a), BytePos(b)) } /// Parse a string, return an expr diff --git a/src/libsyntax/source_map/tests.rs b/src/libsyntax/source_map/tests.rs index 427e86b56e12..c7b8332c53ef 100644 --- a/src/libsyntax/source_map/tests.rs +++ b/src/libsyntax/source_map/tests.rs @@ -91,7 +91,7 @@ fn t6() { fn t7() { // Test span_to_lines for a span ending at the end of source_file let sm = init_source_map(); - let span = Span::new(BytePos(12), BytePos(23), NO_EXPANSION); + let span = Span::with_root_ctxt(BytePos(12), BytePos(23)); let file_lines = sm.span_to_lines(span).unwrap(); assert_eq!(file_lines.file.name, PathBuf::from("blork.rs").into()); @@ -107,7 +107,7 @@ fn span_from_selection(input: &str, selection: &str) -> Span { assert_eq!(input.len(), selection.len()); let left_index = selection.find('~').unwrap() as u32; let right_index = selection.rfind('~').map(|x|x as u32).unwrap_or(left_index); - Span::new(BytePos(left_index), BytePos(right_index + 1), NO_EXPANSION) + Span::with_root_ctxt(BytePos(left_index), BytePos(right_index + 1)) } /// Tests span_to_snippet and span_to_lines for a span converting 3 @@ -137,7 +137,7 @@ fn span_to_snippet_and_lines_spanning_multiple_lines() { fn t8() { // Test span_to_snippet for a span ending at the end of source_file let sm = init_source_map(); - let span = Span::new(BytePos(12), BytePos(23), NO_EXPANSION); + let span = Span::with_root_ctxt(BytePos(12), BytePos(23)); let snippet = sm.span_to_snippet(span); assert_eq!(snippet, Ok("second line".to_string())); @@ -147,7 +147,7 @@ fn t8() { fn t9() { // Test span_to_str for a span ending at the end of source_file let sm = init_source_map(); - let span = Span::new(BytePos(12), BytePos(23), NO_EXPANSION); + let span = Span::with_root_ctxt(BytePos(12), BytePos(23)); let sstr = sm.span_to_string(span); assert_eq!(sstr, "blork.rs:2:1: 2:12"); @@ -198,10 +198,9 @@ impl SourceMapExtension for SourceMap { let lo = hi + offset; hi = lo + substring.len(); if i == n { - let span = Span::new( + let span = Span::with_root_ctxt( BytePos(lo as u32 + file.start_pos.0), BytePos(hi as u32 + file.start_pos.0), - NO_EXPANSION, ); assert_eq!(&self.span_to_snippet(span).unwrap()[..], substring); diff --git a/src/libsyntax/tests.rs b/src/libsyntax/tests.rs index cff034fdeb1e..4c0e1e3704df 100644 --- a/src/libsyntax/tests.rs +++ b/src/libsyntax/tests.rs @@ -9,7 +9,7 @@ use crate::with_default_globals; use errors::emitter::EmitterWriter; use errors::Handler; use rustc_data_structures::sync::Lrc; -use syntax_pos::{BytePos, NO_EXPANSION, Span, MultiSpan}; +use syntax_pos::{BytePos, Span, MultiSpan}; use std::io; use std::io::prelude::*; @@ -169,7 +169,7 @@ fn make_span(file_text: &str, start: &Position, end: &Position) -> Span { let start = make_pos(file_text, start); let end = make_pos(file_text, end) + end.string.len(); // just after matching thing ends assert!(start <= end); - Span::new(BytePos(start as u32), BytePos(end as u32), NO_EXPANSION) + Span::with_root_ctxt(BytePos(start as u32), BytePos(end as u32)) } fn make_pos(file_text: &str, pos: &Position) -> usize { diff --git a/src/libsyntax/tokenstream/tests.rs b/src/libsyntax/tokenstream/tests.rs index 72e22a49876e..5017e5f5424c 100644 --- a/src/libsyntax/tokenstream/tests.rs +++ b/src/libsyntax/tokenstream/tests.rs @@ -3,14 +3,14 @@ use super::*; use crate::ast::Name; use crate::with_default_globals; use crate::tests::string_to_stream; -use syntax_pos::{Span, BytePos, NO_EXPANSION}; +use syntax_pos::{Span, BytePos}; fn string_to_ts(string: &str) -> TokenStream { string_to_stream(string.to_owned()) } fn sp(a: u32, b: u32) -> Span { - Span::new(BytePos(a), BytePos(b), NO_EXPANSION) + Span::with_root_ctxt(BytePos(a), BytePos(b)) } #[test] diff --git a/src/libsyntax_ext/global_allocator.rs b/src/libsyntax_ext/global_allocator.rs index f788b5138043..b1f6f55732a9 100644 --- a/src/libsyntax_ext/global_allocator.rs +++ b/src/libsyntax_ext/global_allocator.rs @@ -29,7 +29,7 @@ pub fn expand( }; // Generate a bunch of new items using the AllocFnFactory - let span = item.span.with_ctxt(SyntaxContext::empty().apply_mark(ecx.current_expansion.id)); + let span = item.span.with_ctxt(SyntaxContext::root().apply_mark(ecx.current_expansion.id)); let f = AllocFnFactory { span, kind: AllocatorKind::Global, diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs index 993ef2575275..08582e714ccb 100644 --- a/src/libsyntax_ext/test.rs +++ b/src/libsyntax_ext/test.rs @@ -29,7 +29,7 @@ pub fn expand_test_case( if !ecx.ecfg.should_test { return vec![]; } - let sp = attr_sp.with_ctxt(SyntaxContext::empty().apply_mark(ecx.current_expansion.id)); + let sp = attr_sp.with_ctxt(SyntaxContext::root().apply_mark(ecx.current_expansion.id)); let mut item = anno_item.expect_item(); item = item.map(|mut item| { item.vis = respan(item.vis.span, ast::VisibilityKind::Public); @@ -93,7 +93,7 @@ pub fn expand_test_or_bench( return vec![Annotatable::Item(item)]; } - let ctxt = SyntaxContext::empty().apply_mark(cx.current_expansion.id); + let ctxt = SyntaxContext::root().apply_mark(cx.current_expansion.id); let (sp, attr_sp) = (item.span.with_ctxt(ctxt), attr_sp.with_ctxt(ctxt)); // Gensym "test" so we can extern crate without conflicting with any local names diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index 4132b99cf416..c832e058cdf2 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -246,7 +246,7 @@ impl HygieneData { fn marks(&self, mut ctxt: SyntaxContext) -> Vec<(ExpnId, Transparency)> { let mut marks = Vec::new(); - while ctxt != SyntaxContext::empty() { + while ctxt != SyntaxContext::root() { marks.push((self.outer_expn(ctxt), self.outer_transparency(ctxt))); ctxt = self.parent_ctxt(ctxt); } @@ -286,14 +286,14 @@ impl HygieneData { } let call_site_ctxt = - self.expn_info(expn_id).map_or(SyntaxContext::empty(), |info| info.call_site.ctxt()); + self.expn_info(expn_id).map_or(SyntaxContext::root(), |info| info.call_site.ctxt()); let mut call_site_ctxt = if transparency == Transparency::SemiTransparent { self.modern(call_site_ctxt) } else { self.modern_and_legacy(call_site_ctxt) }; - if call_site_ctxt == SyntaxContext::empty() { + if call_site_ctxt == SyntaxContext::root() { return self.apply_mark_internal(ctxt, expn_id, transparency); } @@ -400,7 +400,7 @@ pub fn update_dollar_crate_names(mut get_name: impl FnMut(SyntaxContext) -> Symb impl SyntaxContext { #[inline] - pub const fn empty() -> Self { + pub const fn root() -> Self { SyntaxContext(0) } @@ -615,7 +615,7 @@ impl Span { pub fn fresh_expansion(self, parent: ExpnId, expn_info: ExpnInfo) -> Span { HygieneData::with(|data| { let expn_id = data.fresh_expn(parent, Some(expn_info)); - self.with_ctxt(data.apply_mark(SyntaxContext::empty(), expn_id)) + self.with_ctxt(data.apply_mark(SyntaxContext::root(), expn_id)) }) } } @@ -775,6 +775,6 @@ impl Encodable for SyntaxContext { impl Decodable for SyntaxContext { fn decode(_: &mut D) -> Result { - Ok(SyntaxContext::empty()) // FIXME(jseyfried) intercrate hygiene + Ok(SyntaxContext::root()) // FIXME(jseyfried) intercrate hygiene } } diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 793710b453f2..7c8539198b96 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -291,7 +291,12 @@ impl Span { /// Returns `true` if this span comes from a macro or desugaring. #[inline] pub fn from_expansion(self) -> bool { - self.ctxt() != SyntaxContext::empty() + self.ctxt() != SyntaxContext::root() + } + + #[inline] + pub fn with_root_ctxt(lo: BytePos, hi: BytePos) -> Span { + Span::new(lo, hi, SyntaxContext::root()) } /// Returns a new span representing an empty span at the beginning of this span @@ -474,9 +479,9 @@ impl Span { // Return the macro span on its own to avoid weird diagnostic output. It is preferable to // have an incomplete span than a completely nonsensical one. if span_data.ctxt != end_data.ctxt { - if span_data.ctxt == SyntaxContext::empty() { + if span_data.ctxt == SyntaxContext::root() { return end; - } else if end_data.ctxt == SyntaxContext::empty() { + } else if end_data.ctxt == SyntaxContext::root() { return self; } // Both spans fall within a macro. @@ -485,7 +490,7 @@ impl Span { Span::new( cmp::min(span_data.lo, end_data.lo), cmp::max(span_data.hi, end_data.hi), - if span_data.ctxt == SyntaxContext::empty() { end_data.ctxt } else { span_data.ctxt }, + if span_data.ctxt == SyntaxContext::root() { end_data.ctxt } else { span_data.ctxt }, ) } @@ -496,7 +501,7 @@ impl Span { Span::new( span.hi, end.lo, - if end.ctxt == SyntaxContext::empty() { end.ctxt } else { span.ctxt }, + if end.ctxt == SyntaxContext::root() { end.ctxt } else { span.ctxt }, ) } @@ -507,7 +512,7 @@ impl Span { Span::new( span.lo, end.lo, - if end.ctxt == SyntaxContext::empty() { end.ctxt } else { span.ctxt }, + if end.ctxt == SyntaxContext::root() { end.ctxt } else { span.ctxt }, ) } @@ -617,7 +622,7 @@ impl rustc_serialize::UseSpecializedDecodable for Span { d.read_struct("Span", 2, |d| { let lo = d.read_struct_field("lo", 0, Decodable::decode)?; let hi = d.read_struct_field("hi", 1, Decodable::decode)?; - Ok(Span::new(lo, hi, NO_EXPANSION)) + Ok(Span::with_root_ctxt(lo, hi)) }) } } @@ -761,8 +766,6 @@ impl From> for MultiSpan { } } -pub const NO_EXPANSION: SyntaxContext = SyntaxContext::empty(); - /// Identifies an offset of a multi-byte character in a `SourceFile`. #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Eq, PartialEq, Debug)] pub struct MultiByteChar { From 6cb28b6617e25b74389f1cee2ec0335c2ccfb865 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 11 Aug 2019 02:20:18 +0300 Subject: [PATCH 20/35] `Ident::with_empty_ctxt` -> `Ident::with_dummy_span` `Ident` has had a full span rather than just a `SyntaxContext` for a long time now. --- src/librustc/hir/lowering.rs | 8 ++++---- src/librustc/hir/lowering/expr.rs | 14 +++++++------- src/librustc/hir/mod.rs | 6 +++--- src/librustc/hir/print.rs | 2 +- src/librustc/traits/project.rs | 2 +- src/librustc_driver/lib.rs | 2 +- src/librustc_metadata/decoder.rs | 8 ++++---- src/librustc_resolve/diagnostics.rs | 2 +- src/librustc_resolve/late.rs | 16 ++++++++-------- src/librustc_resolve/lib.rs | 14 +++++++------- src/librustc_typeck/check/mod.rs | 2 +- src/librustdoc/clean/mod.rs | 2 +- src/libsyntax/attr/mod.rs | 4 ++-- src/libsyntax/diagnostics/plugin.rs | 2 +- src/libsyntax/ext/base.rs | 2 +- src/libsyntax/ext/build.rs | 2 +- src/libsyntax/ext/expand.rs | 8 ++++---- src/libsyntax/parse/parser/module.rs | 2 +- src/libsyntax/print/pprust.rs | 6 +++--- src/libsyntax_ext/deriving/clone.rs | 2 +- src/libsyntax_ext/deriving/debug.rs | 4 ++-- src/libsyntax_ext/deriving/generic/mod.rs | 2 +- src/libsyntax_ext/env.rs | 4 ++-- src/libsyntax_ext/global_allocator.rs | 8 ++++---- src/libsyntax_ext/lib.rs | 2 +- src/libsyntax_ext/plugin_macro_defs.rs | 2 +- src/libsyntax_ext/proc_macro_harness.rs | 4 ++-- src/libsyntax_ext/standard_library_imports.rs | 6 +++--- src/libsyntax_ext/test_harness.rs | 6 +++--- src/libsyntax_pos/symbol.rs | 10 +++++----- 30 files changed, 77 insertions(+), 77 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 9e5d6378c401..f942a0fb8579 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1224,7 +1224,7 @@ impl<'a> LoweringContext<'a> { P(hir::Path { res, segments: hir_vec![hir::PathSegment::from_ident( - Ident::with_empty_ctxt(kw::SelfUpper) + Ident::with_dummy_span(kw::SelfUpper) )], span: t.span, }), @@ -1558,7 +1558,7 @@ impl<'a> LoweringContext<'a> { let (name, kind) = match name { hir::LifetimeName::Underscore => ( - hir::ParamName::Plain(Ident::with_empty_ctxt(kw::UnderscoreLifetime)), + hir::ParamName::Plain(Ident::with_dummy_span(kw::UnderscoreLifetime)), hir::LifetimeParamKind::Elided, ), hir::LifetimeName::Param(param_name) => ( @@ -2002,7 +2002,7 @@ impl<'a> LoweringContext<'a> { bindings: hir_vec![ hir::TypeBinding { hir_id: this.next_id(), - ident: Ident::with_empty_ctxt(FN_OUTPUT_NAME), + ident: Ident::with_dummy_span(FN_OUTPUT_NAME), kind: hir::TypeBindingKind::Equality { ty: output .as_ref() @@ -2394,7 +2394,7 @@ impl<'a> LoweringContext<'a> { let future_params = P(hir::GenericArgs { args: hir_vec![], bindings: hir_vec![hir::TypeBinding { - ident: Ident::with_empty_ctxt(FN_OUTPUT_NAME), + ident: Ident::with_dummy_span(FN_OUTPUT_NAME), kind: hir::TypeBindingKind::Equality { ty: output_ty, }, diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs index e3a5400942d1..4ba61e9d4fdc 100644 --- a/src/librustc/hir/lowering/expr.rs +++ b/src/librustc/hir/lowering/expr.rs @@ -552,7 +552,7 @@ impl LoweringContext<'_> { // let mut pinned = ; let expr = P(self.lower_expr(expr)); - let pinned_ident = Ident::with_empty_ctxt(sym::pinned); + let pinned_ident = Ident::with_dummy_span(sym::pinned); let (pinned_pat, pinned_pat_hid) = self.pat_ident_binding_mode( span, pinned_ident, @@ -593,7 +593,7 @@ impl LoweringContext<'_> { let loop_node_id = self.sess.next_node_id(); let loop_hir_id = self.lower_node_id(loop_node_id); let ready_arm = { - let x_ident = Ident::with_empty_ctxt(sym::result); + let x_ident = Ident::with_dummy_span(sym::result); let (x_pat, x_pat_hid) = self.pat_ident(span, x_ident); let x_expr = P(self.expr_ident(span, x_ident, x_pat_hid)); let ready_pat = self.pat_std_enum( @@ -1070,9 +1070,9 @@ impl LoweringContext<'_> { ); head.span = desugared_span; - let iter = Ident::with_empty_ctxt(sym::iter); + let iter = Ident::with_dummy_span(sym::iter); - let next_ident = Ident::with_empty_ctxt(sym::__next); + let next_ident = Ident::with_dummy_span(sym::__next); let (next_pat, next_pat_hid) = self.pat_ident_binding_mode( desugared_span, next_ident, @@ -1081,7 +1081,7 @@ impl LoweringContext<'_> { // `::std::option::Option::Some(val) => __next = val` let pat_arm = { - let val_ident = Ident::with_empty_ctxt(sym::val); + let val_ident = Ident::with_dummy_span(sym::val); let (val_pat, val_pat_hid) = self.pat_ident(pat.span, val_ident); let val_expr = P(self.expr_ident(pat.span, val_ident, val_pat_hid)); let next_expr = P(self.expr_ident(pat.span, next_ident, next_pat_hid)); @@ -1247,7 +1247,7 @@ impl LoweringContext<'_> { // `Ok(val) => #[allow(unreachable_code)] val,` let ok_arm = { - let val_ident = Ident::with_empty_ctxt(sym::val); + let val_ident = Ident::with_dummy_span(sym::val); let (val_pat, val_pat_nid) = self.pat_ident(span, val_ident); let val_expr = P(self.expr_ident_with_attrs( span, @@ -1263,7 +1263,7 @@ impl LoweringContext<'_> { // `Err(err) => #[allow(unreachable_code)] // return Try::from_error(From::from(err)),` let err_arm = { - let err_ident = Ident::with_empty_ctxt(sym::err); + let err_ident = Ident::with_dummy_span(sym::err); let (err_local, err_local_nid) = self.pat_ident(try_span, err_ident); let from_expr = { let from_path = &[sym::convert, sym::From, sym::from]; diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 7c2f9907217c..57fd0be77ecf 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -202,7 +202,7 @@ impl ParamName { match *self { ParamName::Plain(ident) => ident, ParamName::Fresh(_) | - ParamName::Error => Ident::with_empty_ctxt(kw::UnderscoreLifetime), + ParamName::Error => Ident::with_dummy_span(kw::UnderscoreLifetime), } } @@ -237,8 +237,8 @@ impl LifetimeName { pub fn ident(&self) -> Ident { match *self { LifetimeName::Implicit | LifetimeName::Error => Ident::invalid(), - LifetimeName::Underscore => Ident::with_empty_ctxt(kw::UnderscoreLifetime), - LifetimeName::Static => Ident::with_empty_ctxt(kw::StaticLifetime), + LifetimeName::Underscore => Ident::with_dummy_span(kw::UnderscoreLifetime), + LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime), LifetimeName::Param(param_name) => param_name.ident(), } } diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index caf8220bbf43..2fd683ed83c5 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1457,7 +1457,7 @@ impl<'a> State<'a> { } pub fn print_name(&mut self, name: ast::Name) { - self.print_ident(ast::Ident::with_empty_ctxt(name)) + self.print_ident(ast::Ident::with_dummy_span(name)) } pub fn print_for_decl(&mut self, loc: &hir::Local, coll: &hir::Expr) { diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 38263f26a59a..72df45df9231 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -1417,7 +1417,7 @@ fn confirm_callable_candidate<'cx, 'tcx>( projection_ty: ty::ProjectionTy::from_ref_and_name( tcx, trait_ref, - Ident::with_empty_ctxt(FN_OUTPUT_NAME), + Ident::with_dummy_span(FN_OUTPUT_NAME), ), ty: ret_type } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index e9d85a53d1e4..fdd0773b73ae 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -678,7 +678,7 @@ impl RustcDefaultCalls { let mut cfgs = sess.parse_sess.config.iter().filter_map(|&(name, ref value)| { let gated_cfg = GatedCfg::gate(&ast::MetaItem { - path: ast::Path::from_ident(ast::Ident::with_empty_ctxt(name)), + path: ast::Path::from_ident(ast::Ident::with_dummy_span(name)), node: ast::MetaItemKind::Word, span: DUMMY_SP, }); diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 3de9bf4da11e..0bec31d70765 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -569,7 +569,7 @@ impl<'a, 'tcx> CrateMetadata { ty::VariantDef::new( tcx, - Ident::with_empty_ctxt(self.item_name(index)), + Ident::with_dummy_span(self.item_name(index)), variant_did, ctor_did, data.discr, @@ -577,7 +577,7 @@ impl<'a, 'tcx> CrateMetadata { let f = self.entry(index); ty::FieldDef { did: self.local_def_id(index), - ident: Ident::with_empty_ctxt(self.item_name(index)), + ident: Ident::with_dummy_span(self.item_name(index)), vis: f.visibility.decode(self) } }).collect(), @@ -741,7 +741,7 @@ impl<'a, 'tcx> CrateMetadata { DefKind::Macro(ext.macro_kind()), self.local_def_id(DefIndex::from_proc_macro_index(id)), ); - let ident = Ident::with_empty_ctxt(name); + let ident = Ident::with_dummy_span(name); callback(def::Export { ident: ident, res: res, @@ -783,7 +783,7 @@ impl<'a, 'tcx> CrateMetadata { if let Some(kind) = self.def_kind(child_index) { callback(def::Export { res: Res::Def(kind, self.local_def_id(child_index)), - ident: Ident::with_empty_ctxt(self.item_name(child_index)), + ident: Ident::with_dummy_span(self.item_name(child_index)), vis: self.get_visibility(child_index), span: self.entry(child_index).span.decode((self, sess)), }); diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 1de67edb95c0..f824dfe8e781 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -595,7 +595,7 @@ impl<'a> Resolver<'a> { where FilterFn: Fn(Res) -> bool { let mut suggestions = self.lookup_import_candidates_from_module( - lookup_ident, namespace, self.graph_root, Ident::with_empty_ctxt(kw::Crate), &filter_fn + lookup_ident, namespace, self.graph_root, Ident::with_dummy_span(kw::Crate), &filter_fn ); if lookup_ident.span.rust_2018() { diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 358eaae11e71..8c15bff71018 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -352,7 +352,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> { self.smart_resolve_path(ty.id, qself.as_ref(), path, PathSource::Type); } TyKind::ImplicitSelf => { - let self_ty = Ident::with_empty_ctxt(kw::SelfUpper); + let self_ty = Ident::with_dummy_span(kw::SelfUpper); let res = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, Some(ty.id), ty.span) .map_or(Res::Err, |d| d.res()); self.r.record_partial_res(ty.id, PartialRes::new(res)); @@ -442,7 +442,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> { GenericParamKind::Type { ref default, .. } => { found_default |= default.is_some(); if found_default { - Some((Ident::with_empty_ctxt(param.ident.name), Res::Err)) + Some((Ident::with_dummy_span(param.ident.name), Res::Err)) } else { None } @@ -459,7 +459,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> { false } }) - .map(|param| (Ident::with_empty_ctxt(param.ident.name), Res::Err))); + .map(|param| (Ident::with_dummy_span(param.ident.name), Res::Err))); for param in &generics.params { match param.kind { @@ -476,7 +476,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> { } // Allow all following defaults to refer to this type parameter. - default_ban_rib.bindings.remove(&Ident::with_empty_ctxt(param.ident.name)); + default_ban_rib.bindings.remove(&Ident::with_dummy_span(param.ident.name)); } GenericParamKind::Const { ref ty } => { self.ribs[TypeNS].push(const_ty_param_ban_rib); @@ -965,7 +965,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { let mut self_type_rib = Rib::new(NormalRibKind); // Plain insert (no renaming, since types are not currently hygienic) - self_type_rib.bindings.insert(Ident::with_empty_ctxt(kw::SelfUpper), self_res); + self_type_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), self_res); self.ribs[TypeNS].push(self_type_rib); f(self); self.ribs[TypeNS].pop(); @@ -976,7 +976,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { { let self_res = Res::SelfCtor(impl_id); let mut self_type_rib = Rib::new(NormalRibKind); - self_type_rib.bindings.insert(Ident::with_empty_ctxt(kw::SelfUpper), self_res); + self_type_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), self_res); self.ribs[ValueNS].push(self_type_rib); f(self); self.ribs[ValueNS].pop(); @@ -1476,7 +1476,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { self.r.trait_map.insert(id, traits); } - let mut std_path = vec![Segment::from_ident(Ident::with_empty_ctxt(sym::std))]; + let mut std_path = vec![Segment::from_ident(Ident::with_dummy_span(sym::std))]; std_path.extend(path); if self.r.primitive_type_table.primitive_types.contains_key(&path[0].ident.name) { let cl = CrateLint::No; @@ -1507,7 +1507,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { fn self_type_is_available(&mut self, span: Span) -> bool { let binding = self.resolve_ident_in_lexical_scope( - Ident::with_empty_ctxt(kw::SelfUpper), + Ident::with_dummy_span(kw::SelfUpper), TypeNS, None, span, diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 8b2e371f0f61..60a368fbb4bd 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -985,11 +985,11 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> { } else { kw::Crate }; - let segments = iter::once(Ident::with_empty_ctxt(root)) + let segments = iter::once(Ident::with_dummy_span(root)) .chain( crate_root.into_iter() .chain(components.iter().cloned()) - .map(Ident::with_empty_ctxt) + .map(Ident::with_dummy_span) ).map(|i| self.new_ast_path_segment(i)).collect::>(); let path = ast::Path { @@ -1060,11 +1060,11 @@ impl<'a> Resolver<'a> { .collect(); if !attr::contains_name(&krate.attrs, sym::no_core) { - extern_prelude.insert(Ident::with_empty_ctxt(sym::core), Default::default()); + extern_prelude.insert(Ident::with_dummy_span(sym::core), Default::default()); if !attr::contains_name(&krate.attrs, sym::no_std) { - extern_prelude.insert(Ident::with_empty_ctxt(sym::std), Default::default()); + extern_prelude.insert(Ident::with_dummy_span(sym::std), Default::default()); if session.rust_2018() { - extern_prelude.insert(Ident::with_empty_ctxt(sym::meta), Default::default()); + extern_prelude.insert(Ident::with_dummy_span(sym::meta), Default::default()); } } } @@ -2624,7 +2624,7 @@ impl<'a> Resolver<'a> { let path = if path_str.starts_with("::") { ast::Path { span, - segments: iter::once(Ident::with_empty_ctxt(kw::PathRoot)) + segments: iter::once(Ident::with_dummy_span(kw::PathRoot)) .chain({ path_str.split("::").skip(1).map(Ident::from_str) }) @@ -2713,7 +2713,7 @@ fn module_to_string(module: Module<'_>) -> Option { fn collect_mod(names: &mut Vec, module: Module<'_>) { if let ModuleKind::Def(.., name) = module.kind { if let Some(parent) = module.parent { - names.push(Ident::with_empty_ctxt(name)); + names.push(Ident::with_dummy_span(name)); collect_mod(names, parent); } } else { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 92f8fb30db8e..fc1ee649e287 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2943,7 +2943,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index), (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut), }; - (tr, ast::Ident::with_empty_ctxt(name)) + (tr, ast::Ident::with_dummy_span(name)) } fn try_overloaded_place_op(&self, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index d5becd2e1a94..fede9e930101 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -930,7 +930,7 @@ impl Attributes { if attr.check_name(sym::enable) { if let Some(feat) = attr.value_str() { let meta = attr::mk_name_value_item_str( - Ident::with_empty_ctxt(sym::target_feature), feat, DUMMY_SP + Ident::with_dummy_span(sym::target_feature), feat, DUMMY_SP ); if let Ok(feat_cfg) = Cfg::parse(&meta) { cfg &= feat_cfg; diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index 85c661d320a7..bcf03b5237a8 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -327,7 +327,7 @@ impl Attribute { if self.is_sugared_doc { let comment = self.value_str().unwrap(); let meta = mk_name_value_item_str( - Ident::with_empty_ctxt(sym::doc), + Ident::with_dummy_span(sym::doc), Symbol::intern(&strip_doc_comment_decoration(&comment.as_str())), DUMMY_SP, ); @@ -412,7 +412,7 @@ pub fn mk_sugared_doc_attr(text: Symbol, span: Span) -> Attribute { Attribute { id: mk_attr_id(), style, - path: Path::from_ident(Ident::with_empty_ctxt(sym::doc).with_span_pos(span)), + path: Path::from_ident(Ident::with_dummy_span(sym::doc).with_span_pos(span)), tokens: MetaItemKind::NameValue(lit).tokens(span), is_sugared_doc: true, span, diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index 80591ad304df..9618b5acfb0f 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -172,7 +172,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt<'_>, (descriptions.len(), ecx.expr_vec(span, descriptions)) }); - let static_ = ecx.lifetime(span, Ident::with_empty_ctxt(kw::StaticLifetime)); + let static_ = ecx.lifetime(span, Ident::with_dummy_span(kw::StaticLifetime)); let ty_str = ecx.ty_rptr( span, ecx.ty_ident(span, ecx.ident_of("str")), diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index d9fd31db4dd6..fd6b9138fdee 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -872,7 +872,7 @@ impl<'a> ExtCtxt<'a> { pub fn std_path(&self, components: &[Symbol]) -> Vec { let def_site = DUMMY_SP.apply_mark(self.current_expansion.id); iter::once(Ident::new(kw::DollarCrate, def_site)) - .chain(components.iter().map(|&s| Ident::with_empty_ctxt(s))) + .chain(components.iter().map(|&s| Ident::with_dummy_span(s))) .collect() } pub fn name_of(&self, st: &str) -> ast::Name { diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 38f46ee207ca..e2ac4d573a1e 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -340,7 +340,7 @@ impl<'a> ExtCtxt<'a> { self.expr_path(self.path_ident(span, id)) } pub fn expr_self(&self, span: Span) -> P { - self.expr_ident(span, Ident::with_empty_ctxt(kw::SelfLower)) + self.expr_ident(span, Ident::with_dummy_span(kw::SelfLower)) } pub fn expr_binary(&self, sp: Span, op: ast::BinOpKind, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index aa409199afd6..5f4074a217ad 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1249,21 +1249,21 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { let include_info = vec![ ast::NestedMetaItem::MetaItem( attr::mk_name_value_item_str( - Ident::with_empty_ctxt(sym::file), + Ident::with_dummy_span(sym::file), file, DUMMY_SP, ), ), ast::NestedMetaItem::MetaItem( attr::mk_name_value_item_str( - Ident::with_empty_ctxt(sym::contents), + Ident::with_dummy_span(sym::contents), src_interned, DUMMY_SP, ), ), ]; - let include_ident = Ident::with_empty_ctxt(sym::include); + let include_ident = Ident::with_dummy_span(sym::include); let item = attr::mk_list_item(include_ident, include_info); items.push(ast::NestedMetaItem::MetaItem(item)); } @@ -1325,7 +1325,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { } } - let meta = attr::mk_list_item(Ident::with_empty_ctxt(sym::doc), items); + let meta = attr::mk_list_item(Ident::with_dummy_span(sym::doc), items); *at = attr::Attribute { span: at.span, id: at.id, diff --git a/src/libsyntax/parse/parser/module.rs b/src/libsyntax/parse/parser/module.rs index 58a7ffba948b..3f6f87b1c44b 100644 --- a/src/libsyntax/parse/parser/module.rs +++ b/src/libsyntax/parse/parser/module.rs @@ -60,7 +60,7 @@ impl<'a> Parser<'a> { // Record that we fetched the mod from an external file if warn { let attr = attr::mk_attr_outer( - attr::mk_word_item(Ident::with_empty_ctxt(sym::warn_directory_ownership))); + attr::mk_word_item(Ident::with_dummy_span(sym::warn_directory_ownership))); attr::mark_known(&attr); attrs.push(attr); } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 5955b9138429..8a7009828bc4 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -123,13 +123,13 @@ pub fn print_crate<'a>(cm: &'a SourceMap, // of the feature gate, so we fake them up here. // #![feature(prelude_import)] - let pi_nested = attr::mk_nested_word_item(ast::Ident::with_empty_ctxt(sym::prelude_import)); - let list = attr::mk_list_item(ast::Ident::with_empty_ctxt(sym::feature), vec![pi_nested]); + let pi_nested = attr::mk_nested_word_item(ast::Ident::with_dummy_span(sym::prelude_import)); + let list = attr::mk_list_item(ast::Ident::with_dummy_span(sym::feature), vec![pi_nested]); let fake_attr = attr::mk_attr_inner(list); s.print_attribute(&fake_attr); // #![no_std] - let no_std_meta = attr::mk_word_item(ast::Ident::with_empty_ctxt(sym::no_std)); + let no_std_meta = attr::mk_word_item(ast::Ident::with_dummy_span(sym::no_std)); let fake_attr = attr::mk_attr_inner(no_std_meta); s.print_attribute(&fake_attr); } diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs index d80da566185c..5a02ae0afb96 100644 --- a/src/libsyntax_ext/deriving/clone.rs +++ b/src/libsyntax_ext/deriving/clone.rs @@ -129,7 +129,7 @@ fn cs_clone_shallow(name: &str, if is_union { // let _: AssertParamIsCopy; let self_ty = - cx.ty_path(cx.path_ident(trait_span, ast::Ident::with_empty_ctxt(kw::SelfUpper))); + cx.ty_path(cx.path_ident(trait_span, ast::Ident::with_dummy_span(kw::SelfUpper))); assert_ty_bounds(cx, &mut stmts, self_ty, trait_span, "AssertParamIsCopy"); } else { match *substr.fields { diff --git a/src/libsyntax_ext/deriving/debug.rs b/src/libsyntax_ext/deriving/debug.rs index 15e93f2843a1..1d5234a9b7b4 100644 --- a/src/libsyntax_ext/deriving/debug.rs +++ b/src/libsyntax_ext/deriving/debug.rs @@ -82,7 +82,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> let expr = cx.expr_method_call(span, builder_expr.clone(), - Ident::with_empty_ctxt(sym::field), + Ident::with_dummy_span(sym::field), vec![field]); // Use `let _ = expr;` to avoid triggering the @@ -106,7 +106,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> let field = cx.expr_addr_of(field.span, field); let expr = cx.expr_method_call(span, builder_expr.clone(), - Ident::with_empty_ctxt(sym::field), + Ident::with_dummy_span(sym::field), vec![name, field]); stmts.push(stmt_let_undescore(cx, span, expr)); } diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index d080dc37a926..4bf004a71e4d 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -928,7 +928,7 @@ impl<'a> MethodDef<'a> { let args = { let self_args = explicit_self.map(|explicit_self| { - let ident = Ident::with_empty_ctxt(kw::SelfLower).with_span_pos(trait_.span); + let ident = Ident::with_dummy_span(kw::SelfLower).with_span_pos(trait_.span); ast::Arg::from_self(ThinVec::default(), explicit_self, ident) }); let nonself_args = arg_types.into_iter() diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs index 442f27c78218..9834130fa23f 100644 --- a/src/libsyntax_ext/env.rs +++ b/src/libsyntax_ext/env.rs @@ -23,13 +23,13 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>, let sp = sp.apply_mark(cx.current_expansion.id); let e = match env::var(&*var.as_str()) { Err(..) => { - let lt = cx.lifetime(sp, Ident::with_empty_ctxt(kw::StaticLifetime)); + let lt = cx.lifetime(sp, Ident::with_dummy_span(kw::StaticLifetime)); cx.expr_path(cx.path_all(sp, true, cx.std_path(&[sym::option, sym::Option, sym::None]), vec![GenericArg::Type(cx.ty_rptr(sp, cx.ty_ident(sp, - Ident::with_empty_ctxt(sym::str)), + Ident::with_dummy_span(sym::str)), Some(lt), ast::Mutability::Immutable))], vec![])) diff --git a/src/libsyntax_ext/global_allocator.rs b/src/libsyntax_ext/global_allocator.rs index b1f6f55732a9..d2121abe3b46 100644 --- a/src/libsyntax_ext/global_allocator.rs +++ b/src/libsyntax_ext/global_allocator.rs @@ -44,7 +44,7 @@ pub fn expand( let const_ty = ecx.ty(span, TyKind::Tup(Vec::new())); let const_body = ecx.expr_block(ecx.block(span, stmts)); let const_item = - ecx.item_const(span, Ident::with_empty_ctxt(kw::Underscore), const_ty, const_body); + ecx.item_const(span, Ident::with_dummy_span(kw::Underscore), const_ty, const_body); // Return the original item and the new methods. vec![Annotatable::Item(item), Annotatable::Item(const_item)] @@ -120,7 +120,7 @@ impl AllocFnFactory<'_, '_> { ) -> P { match *ty { AllocatorTy::Layout => { - let usize = self.cx.path_ident(self.span, Ident::with_empty_ctxt(sym::usize)); + let usize = self.cx.path_ident(self.span, Ident::with_dummy_span(sym::usize)); let ty_usize = self.cx.ty_path(usize); let size = ident(); let align = ident(); @@ -178,12 +178,12 @@ impl AllocFnFactory<'_, '_> { } fn usize(&self) -> P { - let usize = self.cx.path_ident(self.span, Ident::with_empty_ctxt(sym::usize)); + let usize = self.cx.path_ident(self.span, Ident::with_dummy_span(sym::usize)); self.cx.ty_path(usize) } fn ptr_u8(&self) -> P { - let u8 = self.cx.path_ident(self.span, Ident::with_empty_ctxt(sym::u8)); + let u8 = self.cx.path_ident(self.span, Ident::with_dummy_span(sym::u8)); let ty_u8 = self.cx.ty_path(u8); self.cx.ty_ptr(self.span, ty_u8, Mutability::Mutable) } diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 0f3f5c0cd0ee..3ded808bb358 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -42,7 +42,7 @@ pub mod test_harness; pub fn register_builtin_macros(resolver: &mut dyn syntax::ext::base::Resolver, edition: Edition) { let mut register = |name, kind| resolver.register_builtin_macro( - Ident::with_empty_ctxt(name), SyntaxExtension { + Ident::with_dummy_span(name), SyntaxExtension { is_builtin: true, ..SyntaxExtension::default(kind, edition) }, ); diff --git a/src/libsyntax_ext/plugin_macro_defs.rs b/src/libsyntax_ext/plugin_macro_defs.rs index a725f5e46ad1..15737314b223 100644 --- a/src/libsyntax_ext/plugin_macro_defs.rs +++ b/src/libsyntax_ext/plugin_macro_defs.rs @@ -48,7 +48,7 @@ pub fn inject( [sym::rustc_attrs][..].into(), )); for (name, ext) in named_exts { - resolver.register_builtin_macro(Ident::with_empty_ctxt(name), ext); + resolver.register_builtin_macro(Ident::with_dummy_span(name), ext); extra_items.push(plugin_macro_def(name, span)); } // The `macro_rules` items must be inserted before any other items. diff --git a/src/libsyntax_ext/proc_macro_harness.rs b/src/libsyntax_ext/proc_macro_harness.rs index 70325539f301..62c74b2b9c6b 100644 --- a/src/libsyntax_ext/proc_macro_harness.rs +++ b/src/libsyntax_ext/proc_macro_harness.rs @@ -337,7 +337,7 @@ fn mk_decls( let doc = cx.meta_list(span, sym::doc, vec![hidden]); let doc_hidden = cx.attribute(doc); - let proc_macro = Ident::with_empty_ctxt(sym::proc_macro); + let proc_macro = Ident::with_dummy_span(sym::proc_macro); let krate = cx.item(span, proc_macro, Vec::new(), @@ -349,7 +349,7 @@ fn mk_decls( let custom_derive = Ident::from_str("custom_derive"); let attr = Ident::from_str("attr"); let bang = Ident::from_str("bang"); - let crate_kw = Ident::with_empty_ctxt(kw::Crate); + let crate_kw = Ident::with_dummy_span(kw::Crate); let decls = { let local_path = |sp: Span, name| { diff --git a/src/libsyntax_ext/standard_library_imports.rs b/src/libsyntax_ext/standard_library_imports.rs index 68b13bdd171a..4382fb8af858 100644 --- a/src/libsyntax_ext/standard_library_imports.rs +++ b/src/libsyntax_ext/standard_library_imports.rs @@ -32,7 +32,7 @@ pub fn inject( // HACK(eddyb) gensym the injected crates on the Rust 2018 edition, // so they don't accidentally interfere with the new import paths. let orig_name_sym = Symbol::intern(orig_name_str); - let orig_name_ident = Ident::with_empty_ctxt(orig_name_sym); + let orig_name_ident = Ident::with_dummy_span(orig_name_sym); let (rename, orig_name) = if rust_2018 { (orig_name_ident.gensym(), Some(orig_name_sym)) } else { @@ -40,7 +40,7 @@ pub fn inject( }; krate.module.items.insert(0, P(ast::Item { attrs: vec![attr::mk_attr_outer( - attr::mk_word_item(ast::Ident::with_empty_ctxt(sym::macro_use)) + attr::mk_word_item(ast::Ident::with_dummy_span(sym::macro_use)) )], vis: dummy_spanned(ast::VisibilityKind::Inherited), node: ast::ItemKind::ExternCrate(alt_std_name.or(orig_name)), @@ -66,7 +66,7 @@ pub fn inject( vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Inherited), node: ast::ItemKind::Use(P(ast::UseTree { prefix: ast::Path { - segments: iter::once(ast::Ident::with_empty_ctxt(kw::PathRoot)) + segments: iter::once(ast::Ident::with_dummy_span(kw::PathRoot)) .chain( [name, "prelude", "v1"].iter().cloned() .map(ast::Ident::from_str) diff --git a/src/libsyntax_ext/test_harness.rs b/src/libsyntax_ext/test_harness.rs index 0267637e5406..ab108290a938 100644 --- a/src/libsyntax_ext/test_harness.rs +++ b/src/libsyntax_ext/test_harness.rs @@ -150,7 +150,7 @@ impl MutVisitor for EntryPointCleaner { EntryPointType::MainAttr | EntryPointType::Start => item.map(|ast::Item {id, ident, attrs, node, vis, span, tokens}| { - let allow_ident = Ident::with_empty_ctxt(sym::allow); + let allow_ident = Ident::with_dummy_span(sym::allow); let dc_nested = attr::mk_nested_word_item(Ident::from_str("dead_code")); let allow_dead_code_item = attr::mk_list_item(allow_ident, vec![dc_nested]); let allow_dead_code = attr::mk_attr_outer(allow_dead_code_item); @@ -191,7 +191,7 @@ fn mk_reexport_mod(cx: &mut TestCtxt<'_>, tests: Vec, tested_submods: Vec<(Ident, Ident)>) -> (P, Ident) { - let super_ = Ident::with_empty_ctxt(kw::Super); + let super_ = Ident::with_dummy_span(kw::Super); let items = tests.into_iter().map(|r| { cx.ext_cx.item_use_simple(DUMMY_SP, dummy_spanned(ast::VisibilityKind::Public), @@ -274,7 +274,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P { [sym::main, sym::test, sym::rustc_attrs][..].into(), )); let ecx = &cx.ext_cx; - let test_id = Ident::with_empty_ctxt(sym::test); + let test_id = Ident::with_dummy_span(sym::test); // test::test_main_static(...) let mut test_runner = cx.test_runner.clone().unwrap_or( diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 6f5a458a874e..e2d1635f3121 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -744,25 +744,25 @@ impl Ident { Ident { name, span } } - /// Constructs a new identifier with an empty syntax context. + /// Constructs a new identifier with a dummy span. #[inline] - pub const fn with_empty_ctxt(name: Symbol) -> Ident { + pub const fn with_dummy_span(name: Symbol) -> Ident { Ident::new(name, DUMMY_SP) } #[inline] pub fn invalid() -> Ident { - Ident::with_empty_ctxt(kw::Invalid) + Ident::with_dummy_span(kw::Invalid) } /// Maps an interned string to an identifier with an empty syntax context. pub fn from_interned_str(string: InternedString) -> Ident { - Ident::with_empty_ctxt(string.as_symbol()) + Ident::with_dummy_span(string.as_symbol()) } /// Maps a string to an identifier with an empty span. pub fn from_str(string: &str) -> Ident { - Ident::with_empty_ctxt(Symbol::intern(string)) + Ident::with_dummy_span(Symbol::intern(string)) } /// Maps a string and a span to an identifier. From 73dee258c19a6e9e8249a0d7ff1db54014d0c7a1 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 11 Aug 2019 03:00:05 +0300 Subject: [PATCH 21/35] hygiene: Remove `Option`s from functions returning `ExpnInfo` The expansion info is not optional and should always exist --- src/librustc/lint/internal.rs | 33 +++++--------- src/librustc/lint/mod.rs | 19 +++----- src/librustc/traits/error_reporting.rs | 8 ++-- src/librustc/ty/query/on_disk_cache.rs | 18 +++----- src/librustc_codegen_ssa/back/write.rs | 5 +- src/librustc_lint/unused.rs | 5 +- src/librustc_resolve/macros.rs | 3 +- src/libsyntax/ext/base.rs | 21 +++------ src/libsyntax/ext/expand.rs | 2 +- src/libsyntax/ext/proc_macro_server.rs | 4 +- src/libsyntax/parse/parser.rs | 1 - src/libsyntax/source_map.rs | 13 +++--- src/libsyntax_pos/hygiene.rs | 58 +++++++++--------------- src/libsyntax_pos/lib.rs | 63 +++++++++++--------------- 14 files changed, 98 insertions(+), 155 deletions(-) diff --git a/src/librustc/lint/internal.rs b/src/librustc/lint/internal.rs index d9ad34a5297f..29106fe000bb 100644 --- a/src/librustc/lint/internal.rs +++ b/src/librustc/lint/internal.rs @@ -9,7 +9,6 @@ use errors::Applicability; use rustc_data_structures::fx::FxHashMap; use syntax::ast::{Ident, Item, ItemKind}; use syntax::symbol::{sym, Symbol}; -use syntax_pos::ExpnInfo; declare_tool_lint! { pub rustc::DEFAULT_HASH_TYPES, @@ -228,30 +227,20 @@ impl EarlyLintPass for LintPassImpl { if let ItemKind::Impl(_, _, _, _, Some(lint_pass), _, _) = &item.node { if let Some(last) = lint_pass.path.segments.last() { if last.ident.name == sym::LintPass { - match &lint_pass.path.span.ctxt().outer_expn_info() { - Some(info) if is_lint_pass_expansion(info) => {} - _ => { - cx.struct_span_lint( - LINT_PASS_IMPL_WITHOUT_MACRO, - lint_pass.path.span, - "implementing `LintPass` by hand", - ) - .help("try using `declare_lint_pass!` or `impl_lint_pass!` instead") - .emit(); - } + let expn_info = lint_pass.path.span.ctxt().outer_expn_info(); + let call_site = expn_info.call_site; + if expn_info.kind.descr() != sym::impl_lint_pass && + call_site.ctxt().outer_expn_info().kind.descr() != sym::declare_lint_pass { + cx.struct_span_lint( + LINT_PASS_IMPL_WITHOUT_MACRO, + lint_pass.path.span, + "implementing `LintPass` by hand", + ) + .help("try using `declare_lint_pass!` or `impl_lint_pass!` instead") + .emit(); } } } } } } - -fn is_lint_pass_expansion(expn_info: &ExpnInfo) -> bool { - if expn_info.kind.descr() == sym::impl_lint_pass { - true - } else if let Some(info) = expn_info.call_site.ctxt().outer_expn_info() { - info.kind.descr() == sym::declare_lint_pass - } else { - false - } -} diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 8cb5b1e26d94..3729ee81f5c6 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -885,21 +885,16 @@ pub fn provide(providers: &mut Providers<'_>) { /// This is used to test whether a lint should not even begin to figure out whether it should /// be reported on the current node. pub fn in_external_macro(sess: &Session, span: Span) -> bool { - let info = match span.ctxt().outer_expn_info() { - Some(info) => info, - // no ExpnInfo means this span doesn't come from a macro - None => return false, - }; - - match info.kind { + let expn_info = span.ctxt().outer_expn_info(); + match expn_info.kind { ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) => false, ExpnKind::Desugaring(_) => true, // well, it's "external" ExpnKind::Macro(MacroKind::Bang, _) => { - if info.def_site.is_dummy() { + if expn_info.def_site.is_dummy() { // dummy span for the def_site means it's an external macro return true; } - match sess.source_map().span_to_snippet(info.def_site) { + match sess.source_map().span_to_snippet(expn_info.def_site) { Ok(code) => !code.starts_with("macro_rules"), // no snippet = external macro or compiler-builtin expansion Err(_) => true, @@ -911,10 +906,8 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool { /// Returns whether `span` originates in a derive macro's expansion pub fn in_derive_expansion(span: Span) -> bool { - if let Some(info) = span.ctxt().outer_expn_info() { - if let ExpnKind::Macro(MacroKind::Derive, _) = info.kind { - return true; - } + if let ExpnKind::Macro(MacroKind::Derive, _) = span.ctxt().outer_expn_info().kind { + return true; } false } diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 83bd5c56040e..20568d4709b6 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -36,7 +36,7 @@ use errors::{Applicability, DiagnosticBuilder}; use std::fmt; use syntax::ast; use syntax::symbol::sym; -use syntax_pos::{DUMMY_SP, Span, ExpnInfo, ExpnKind}; +use syntax_pos::{DUMMY_SP, Span, ExpnKind}; impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn report_fulfillment_errors(&self, @@ -61,9 +61,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // We want to ignore desugarings here: spans are equivalent even // if one is the result of a desugaring and the other is not. let mut span = error.obligation.cause.span; - if let Some(ExpnInfo { kind: ExpnKind::Desugaring(_), def_site, .. }) - = span.ctxt().outer_expn_info() { - span = def_site; + let expn_info = span.ctxt().outer_expn_info(); + if let ExpnKind::Desugaring(_) = expn_info.kind { + span = expn_info.call_site; } error_map.entry(span).or_default().push( diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index 1c5baa638c2b..2286271b9eb4 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -820,18 +820,14 @@ where TAG_NO_EXPANSION_INFO.encode(self) } else { let (expn_id, expn_info) = span_data.ctxt.outer_expn_with_info(); - if let Some(expn_info) = expn_info { - if let Some(pos) = self.expn_info_shorthands.get(&expn_id).cloned() { - TAG_EXPANSION_INFO_SHORTHAND.encode(self)?; - pos.encode(self) - } else { - TAG_EXPANSION_INFO_INLINE.encode(self)?; - let pos = AbsoluteBytePos::new(self.position()); - self.expn_info_shorthands.insert(expn_id, pos); - expn_info.encode(self) - } + if let Some(pos) = self.expn_info_shorthands.get(&expn_id).cloned() { + TAG_EXPANSION_INFO_SHORTHAND.encode(self)?; + pos.encode(self) } else { - TAG_NO_EXPANSION_INFO.encode(self) + TAG_EXPANSION_INFO_INLINE.encode(self)?; + let pos = AbsoluteBytePos::new(self.position()); + self.expn_info_shorthands.insert(expn_id, pos); + expn_info.encode(self) } } } diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index c9e4663fdbdd..240264a98220 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -1775,10 +1775,7 @@ impl SharedEmitterMain { } } Ok(SharedEmitterMessage::InlineAsmError(cookie, msg)) => { - match ExpnId::from_u32(cookie).expn_info() { - Some(ei) => sess.span_err(ei.call_site, &msg), - None => sess.err(&msg), - } + sess.span_err(ExpnId::from_u32(cookie).expn_info().call_site, &msg) } Ok(SharedEmitterMessage::AbortIfErrors) => { sess.abort_if_errors(); diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 9cad8f58d41d..1bb05bda69f5 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -517,9 +517,8 @@ impl EarlyLintPass for UnusedParens { // trigger in situations that macro authors shouldn't have to care about, e.g., // when a parenthesized token tree matched in one macro expansion is matched as // an expression in another and used as a fn/method argument (Issue #47775) - if e.span.ctxt().outer_expn_info() - .map_or(false, |info| info.call_site.from_expansion()) { - return; + if e.span.ctxt().outer_expn_info().call_site.from_expansion() { + return; } let msg = format!("{} argument", call_kind); for arg in args_to_check { diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 71e26dac57c2..97b0f825ee94 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -346,8 +346,7 @@ impl<'a> Resolver<'a> { // Possibly apply the macro helper hack if kind == Some(MacroKind::Bang) && path.len() == 1 && - path[0].ident.span.ctxt().outer_expn_info() - .map_or(false, |info| info.local_inner_macros) { + path[0].ident.span.ctxt().outer_expn_info().local_inner_macros { let root = Ident::new(kw::DollarCrate, path[0].ident.span); path.insert(0, Segment::from_ident(root)); } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index fd6b9138fdee..8eacb96e3ff9 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -756,10 +756,7 @@ impl<'a> ExtCtxt<'a> { pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess } pub fn cfg(&self) -> &ast::CrateConfig { &self.parse_sess.config } pub fn call_site(&self) -> Span { - match self.current_expansion.id.expn_info() { - Some(expn_info) => expn_info.call_site, - None => DUMMY_SP, - } + self.current_expansion.id.expn_info().call_site } pub fn backtrace(&self) -> SyntaxContext { SyntaxContext::root().apply_mark(self.current_expansion.id) @@ -772,17 +769,13 @@ impl<'a> ExtCtxt<'a> { let mut ctxt = self.backtrace(); let mut last_macro = None; loop { - if ctxt.outer_expn_info().map_or(None, |info| { - if info.kind.descr() == sym::include { - // Stop going up the backtrace once include! is encountered - return None; - } - ctxt = info.call_site.ctxt(); - last_macro = Some(info.call_site); - Some(()) - }).is_none() { - break + let expn_info = ctxt.outer_expn_info(); + // Stop going up the backtrace once include! is encountered + if expn_info.is_root() || expn_info.kind.descr() == sym::include { + break; } + ctxt = expn_info.call_site.ctxt(); + last_macro = Some(expn_info.call_site); } last_macro } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 5f4074a217ad..6f3e8f14b0b2 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -475,7 +475,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } if self.cx.current_expansion.depth > self.cx.ecfg.recursion_limit { - let info = self.cx.current_expansion.id.expn_info().unwrap(); + let info = self.cx.current_expansion.id.expn_info(); let suggested_limit = self.cx.ecfg.recursion_limit * 2; let mut err = self.cx.struct_span_err(info.call_site, &format!("recursion limit reached while expanding the macro `{}`", diff --git a/src/libsyntax/ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs index fd93910004ef..d370431a5dae 100644 --- a/src/libsyntax/ext/proc_macro_server.rs +++ b/src/libsyntax/ext/proc_macro_server.rs @@ -362,7 +362,7 @@ pub(crate) struct Rustc<'a> { impl<'a> Rustc<'a> { pub fn new(cx: &'a ExtCtxt<'_>) -> Self { // No way to determine def location for a proc macro right now, so use call location. - let location = cx.current_expansion.id.expn_info().unwrap().call_site; + let location = cx.current_expansion.id.expn_info().call_site; let to_span = |transparency| { location.with_ctxt( SyntaxContext::root() @@ -677,7 +677,7 @@ impl server::Span for Rustc<'_> { self.sess.source_map().lookup_char_pos(span.lo()).file } fn parent(&mut self, span: Self::Span) -> Option { - span.ctxt().outer_expn_info().map(|i| i.call_site) + span.parent() } fn source(&mut self, span: Self::Span) -> Self::Span { span.source_callsite() diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 3b0af88f6510..89725d8b3395 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -13,7 +13,6 @@ mod generics; use crate::ast::{self, AttrStyle, Attribute, Arg, BindingMode, StrStyle, SelfKind}; use crate::ast::{FnDecl, Ident, IsAsync, MacDelimiter, Mutability, TyKind}; use crate::ast::{Visibility, VisibilityKind, Unsafety, CrateSugar}; -use crate::ext::hygiene::SyntaxContext; use crate::source_map::{self, respan}; use crate::parse::{SeqSep, literal, token}; use crate::parse::lexer::UnmatchedBrace; diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs index 74cab00d3c1e..da7eb6add41a 100644 --- a/src/libsyntax/source_map.rs +++ b/src/libsyntax/source_map.rs @@ -31,12 +31,13 @@ mod tests; /// otherwise return the call site span up to the `enclosing_sp` by /// following the `expn_info` chain. pub fn original_sp(sp: Span, enclosing_sp: Span) -> Span { - let call_site1 = sp.ctxt().outer_expn_info().map(|ei| ei.call_site); - let call_site2 = enclosing_sp.ctxt().outer_expn_info().map(|ei| ei.call_site); - match (call_site1, call_site2) { - (None, _) => sp, - (Some(call_site1), Some(call_site2)) if call_site1 == call_site2 => sp, - (Some(call_site1), _) => original_sp(call_site1, enclosing_sp), + let expn_info1 = sp.ctxt().outer_expn_info(); + let expn_info2 = enclosing_sp.ctxt().outer_expn_info(); + if expn_info1.is_root() || + !expn_info2.is_root() && expn_info1.call_site == expn_info2.call_site { + sp + } else { + original_sp(expn_info1.call_site, enclosing_sp) } } diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index c832e058cdf2..743bd437ee5b 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -112,8 +112,8 @@ impl ExpnId { } #[inline] - pub fn expn_info(self) -> Option { - HygieneData::with(|data| data.expn_info(self).cloned()) + pub fn expn_info(self) -> ExpnInfo { + HygieneData::with(|data| data.expn_info(self).clone()) } #[inline] @@ -139,12 +139,9 @@ impl ExpnId { #[inline] pub fn looks_like_proc_macro_derive(self) -> bool { HygieneData::with(|data| { - if data.default_transparency(self) == Transparency::Opaque { - if let Some(expn_info) = data.expn_info(self) { - if let ExpnKind::Macro(MacroKind::Derive, _) = expn_info.kind { - return true; - } - } + let expn_info = data.expn_info(self); + if let ExpnKind::Macro(MacroKind::Derive, _) = expn_info.kind { + return expn_info.default_transparency == Transparency::Opaque; } false }) @@ -190,16 +187,9 @@ impl HygieneData { self.expn_data[expn_id.0 as usize].parent } - fn expn_info(&self, expn_id: ExpnId) -> Option<&ExpnInfo> { - if expn_id != ExpnId::root() { - Some(self.expn_data[expn_id.0 as usize].expn_info.as_ref() - .expect("no expansion info for an expansion ID")) - } else { - // FIXME: Some code relies on `expn_info().is_none()` meaning "no expansion". - // Introduce a method for checking for "no expansion" instead and always return - // `ExpnInfo` from this function instead of the `Option`. - None - } + fn expn_info(&self, expn_id: ExpnId) -> &ExpnInfo { + self.expn_data[expn_id.0 as usize].expn_info.as_ref() + .expect("no expansion info for an expansion ID") } fn is_descendant_of(&self, mut expn_id: ExpnId, ancestor: ExpnId) -> bool { @@ -212,12 +202,6 @@ impl HygieneData { true } - fn default_transparency(&self, expn_id: ExpnId) -> Transparency { - self.expn_info(expn_id).map_or( - Transparency::SemiTransparent, |einfo| einfo.default_transparency - ) - } - fn modern(&self, ctxt: SyntaxContext) -> SyntaxContext { self.syntax_context_data[ctxt.0 as usize].opaque } @@ -256,11 +240,7 @@ impl HygieneData { fn walk_chain(&self, mut span: Span, to: SyntaxContext) -> Span { while span.from_expansion() && span.ctxt() != to { - if let Some(info) = self.expn_info(self.outer_expn(span.ctxt())) { - span = info.call_site; - } else { - break; - } + span = self.expn_info(self.outer_expn(span.ctxt())).call_site; } span } @@ -275,7 +255,9 @@ impl HygieneData { fn apply_mark(&mut self, ctxt: SyntaxContext, expn_id: ExpnId) -> SyntaxContext { assert_ne!(expn_id, ExpnId::root()); - self.apply_mark_with_transparency(ctxt, expn_id, self.default_transparency(expn_id)) + self.apply_mark_with_transparency( + ctxt, expn_id, self.expn_info(expn_id).default_transparency + ) } fn apply_mark_with_transparency(&mut self, ctxt: SyntaxContext, expn_id: ExpnId, @@ -285,8 +267,7 @@ impl HygieneData { return self.apply_mark_internal(ctxt, expn_id, transparency); } - let call_site_ctxt = - self.expn_info(expn_id).map_or(SyntaxContext::root(), |info| info.call_site.ctxt()); + let call_site_ctxt = self.expn_info(expn_id).call_site.ctxt(); let mut call_site_ctxt = if transparency == Transparency::SemiTransparent { self.modern(call_site_ctxt) } else { @@ -581,17 +562,17 @@ impl SyntaxContext { /// `ctxt.outer_expn_info()` is equivalent to but faster than /// `ctxt.outer_expn().expn_info()`. #[inline] - pub fn outer_expn_info(self) -> Option { - HygieneData::with(|data| data.expn_info(data.outer_expn(self)).cloned()) + pub fn outer_expn_info(self) -> ExpnInfo { + HygieneData::with(|data| data.expn_info(data.outer_expn(self)).clone()) } /// `ctxt.outer_expn_with_info()` is equivalent to but faster than /// `{ let outer = ctxt.outer_expn(); (outer, outer.expn_info()) }`. #[inline] - pub fn outer_expn_with_info(self) -> (ExpnId, Option) { + pub fn outer_expn_with_info(self) -> (ExpnId, ExpnInfo) { HygieneData::with(|data| { let outer = data.outer_expn(self); - (outer, data.expn_info(outer).cloned()) + (outer, data.expn_info(outer).clone()) }) } @@ -681,6 +662,11 @@ impl ExpnInfo { ..ExpnInfo::default(kind, call_site, edition) } } + + #[inline] + pub fn is_root(&self) -> bool { + if let ExpnKind::Root = self.kind { true } else { false } + } } /// Expansion kind. diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 7c8539198b96..7af426eaa13f 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -355,20 +355,20 @@ impl Span { /// Returns the source span -- this is either the supplied span, or the span for /// the macro callsite that expanded to it. pub fn source_callsite(self) -> Span { - self.ctxt().outer_expn_info().map(|info| info.call_site.source_callsite()).unwrap_or(self) + let expn_info = self.ctxt().outer_expn_info(); + if !expn_info.is_root() { expn_info.call_site.source_callsite() } else { self } } /// The `Span` for the tokens in the previous macro expansion from which `self` was generated, /// if any. pub fn parent(self) -> Option { - self.ctxt().outer_expn_info().map(|i| i.call_site) + let expn_info = self.ctxt().outer_expn_info(); + if !expn_info.is_root() { Some(expn_info.call_site) } else { None } } /// Edition of the crate from which this span came. pub fn edition(self) -> edition::Edition { - self.ctxt().outer_expn_info().map_or_else(|| { - Edition::from_session() - }, |einfo| einfo.edition) + self.ctxt().outer_expn_info().edition } #[inline] @@ -387,49 +387,39 @@ impl Span { /// else returns the `ExpnInfo` for the macro definition /// corresponding to the source callsite. pub fn source_callee(self) -> Option { - fn source_callee(info: ExpnInfo) -> ExpnInfo { - match info.call_site.ctxt().outer_expn_info() { - Some(info) => source_callee(info), - None => info, - } + fn source_callee(expn_info: ExpnInfo) -> ExpnInfo { + let next_expn_info = expn_info.call_site.ctxt().outer_expn_info(); + if !next_expn_info.is_root() { source_callee(next_expn_info) } else { expn_info } } - self.ctxt().outer_expn_info().map(source_callee) + let expn_info = self.ctxt().outer_expn_info(); + if !expn_info.is_root() { Some(source_callee(expn_info)) } else { None } } /// Checks if a span is "internal" to a macro in which `#[unstable]` /// items can be used (that is, a macro marked with /// `#[allow_internal_unstable]`). pub fn allows_unstable(&self, feature: Symbol) -> bool { - match self.ctxt().outer_expn_info() { - Some(info) => info - .allow_internal_unstable - .map_or(false, |features| features.iter().any(|&f| - f == feature || f == sym::allow_internal_unstable_backcompat_hack - )), - None => false, - } + self.ctxt().outer_expn_info().allow_internal_unstable.map_or(false, |features| { + features.iter().any(|&f| { + f == feature || f == sym::allow_internal_unstable_backcompat_hack + }) + }) } /// Checks if this span arises from a compiler desugaring of kind `kind`. pub fn is_desugaring(&self, kind: DesugaringKind) -> bool { - match self.ctxt().outer_expn_info() { - Some(info) => match info.kind { - ExpnKind::Desugaring(k) => k == kind, - _ => false, - }, - None => false, + match self.ctxt().outer_expn_info().kind { + ExpnKind::Desugaring(k) => k == kind, + _ => false, } } /// Returns the compiler desugaring that created this span, or `None` /// if this span is not from a desugaring. pub fn desugaring_kind(&self) -> Option { - match self.ctxt().outer_expn_info() { - Some(info) => match info.kind { - ExpnKind::Desugaring(k) => Some(k), - _ => None - }, - None => None + match self.ctxt().outer_expn_info().kind { + ExpnKind::Desugaring(k) => Some(k), + _ => None } } @@ -437,16 +427,17 @@ impl Span { /// can be used without triggering the `unsafe_code` lint // (that is, a macro marked with `#[allow_internal_unsafe]`). pub fn allows_unsafe(&self) -> bool { - match self.ctxt().outer_expn_info() { - Some(info) => info.allow_internal_unsafe, - None => false, - } + self.ctxt().outer_expn_info().allow_internal_unsafe } pub fn macro_backtrace(mut self) -> Vec { let mut prev_span = DUMMY_SP; let mut result = vec![]; - while let Some(info) = self.ctxt().outer_expn_info() { + loop { + let info = self.ctxt().outer_expn_info(); + if info.is_root() { + break; + } // Don't print recursive invocations. if !info.call_site.source_equal(&prev_span) { let (pre, post) = match info.kind { From 23b82c32298002f80724a244c2483fd1e8ec1d54 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 12 Aug 2019 21:52:37 +0300 Subject: [PATCH 22/35] resolve: Move macro resolution traces from `Module`s to `Resolver` Traces already contain module info without that. It's easy to forget to call `finalize_*` on a module. In particular, macros enum and trait modules weren't finalized. By happy accident macros weren't placed into those modules until now. --- src/librustc_resolve/build_reduced_graph.rs | 4 +- src/librustc_resolve/late.rs | 3 -- src/librustc_resolve/lib.rs | 18 +++++---- src/librustc_resolve/macros.rs | 14 +++---- src/librustc_resolve/resolve_imports.rs | 4 +- ...eature-gate-rustc-diagnostic-macros.stderr | 12 +++--- .../ui/hygiene/no_implicit_prelude.stderr | 16 ++++---- .../local-modularized-tricky-fail-1.stderr | 38 +++++++++---------- .../ui/imports/shadow_builtin_macros.stderr | 28 +++++++------- src/test/ui/issues/issue-49074.stderr | 12 +++--- .../macro-namespace-reserved-2.stderr | 24 ++++++------ .../ui/reserved/reserved-attr-on-macro.stderr | 12 +++--- 12 files changed, 90 insertions(+), 95 deletions(-) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 0a32b0c6e95d..98ee7203057d 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -1267,9 +1267,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { fn visit_attribute(&mut self, attr: &'b ast::Attribute) { if !attr.is_sugared_doc && is_builtin_attr(attr) { - self.parent_scope.module.builtin_attrs.borrow_mut().push(( - attr.path.segments[0].ident, self.parent_scope.clone() - )); + self.r.builtin_attrs.push((attr.path.segments[0].ident, self.parent_scope.clone())); } visit::walk_attribute(self, attr); } diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 8c15bff71018..e0869d848508 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -574,7 +574,6 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { self.ribs[ValueNS].push(Rib::new(ModuleRibKind(module))); self.ribs[TypeNS].push(Rib::new(ModuleRibKind(module))); - self.r.finalize_current_module_macro_resolutions(module); let ret = f(self); self.parent_scope.module = orig_module; @@ -1227,7 +1226,6 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { self.ribs[ValueNS].push(Rib::new(ModuleRibKind(anonymous_module))); self.ribs[TypeNS].push(Rib::new(ModuleRibKind(anonymous_module))); self.parent_scope.module = anonymous_module; - self.r.finalize_current_module_macro_resolutions(anonymous_module); } else { self.ribs[ValueNS].push(Rib::new(NormalRibKind)); } @@ -1984,7 +1982,6 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { impl<'a> Resolver<'a> { pub(crate) fn late_resolve_crate(&mut self, krate: &Crate) { - self.finalize_current_module_macro_resolutions(self.graph_root); let mut late_resolution_visitor = LateResolutionVisitor::new(self); visit::walk_crate(&mut late_resolution_visitor, krate); for (id, span) in late_resolution_visitor.unused_labels.iter() { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 60a368fbb4bd..3d82ef3d5801 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -418,11 +418,6 @@ pub struct ModuleData<'a> { normal_ancestor_id: DefId, resolutions: RefCell>>>, - single_segment_macro_resolutions: RefCell, - Option<&'a NameBinding<'a>>)>>, - multi_segment_macro_resolutions: RefCell, Span, MacroKind, ParentScope<'a>, - Option)>>, - builtin_attrs: RefCell)>>, // Macro invocations that can expand into items in this module. unresolved_invocations: RefCell>, @@ -459,9 +454,6 @@ impl<'a> ModuleData<'a> { kind, normal_ancestor_id, resolutions: Default::default(), - single_segment_macro_resolutions: RefCell::new(Vec::new()), - multi_segment_macro_resolutions: RefCell::new(Vec::new()), - builtin_attrs: RefCell::new(Vec::new()), unresolved_invocations: Default::default(), no_implicit_prelude: false, glob_importers: RefCell::new(Vec::new()), @@ -896,6 +888,12 @@ pub struct Resolver<'a> { local_macro_def_scopes: FxHashMap>, unused_macros: NodeMap, proc_macro_stubs: NodeSet, + /// Traces collected during macro resolution and validated when it's complete. + single_segment_macro_resolutions: Vec<(Ident, MacroKind, ParentScope<'a>, + Option<&'a NameBinding<'a>>)>, + multi_segment_macro_resolutions: Vec<(Vec, Span, MacroKind, ParentScope<'a>, + Option)>, + builtin_attrs: Vec<(Ident, ParentScope<'a>)>, /// Some built-in derives mark items they are applied to so they are treated specially later. /// Derive macros cannot modify the item themselves and have to store the markers in the global /// context, so they attach the markers to derive container IDs using this resolver table. @@ -1151,6 +1149,9 @@ impl<'a> Resolver<'a> { struct_constructors: Default::default(), unused_macros: Default::default(), proc_macro_stubs: Default::default(), + single_segment_macro_resolutions: Default::default(), + multi_segment_macro_resolutions: Default::default(), + builtin_attrs: Default::default(), special_derives: Default::default(), active_features: features.declared_lib_features.iter().map(|(feat, ..)| *feat) @@ -1203,6 +1204,7 @@ impl<'a> Resolver<'a> { /// Entry point to crate resolution. pub fn resolve_crate(&mut self, krate: &Crate) { ImportResolver { r: self }.finalize_imports(); + self.finalize_macro_resolutions(); self.late_resolve_crate(krate); diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 97b0f825ee94..f54f395063c2 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -366,7 +366,7 @@ impl<'a> Resolver<'a> { if trace { let kind = kind.expect("macro kind must be specified if tracing is enabled"); - parent_scope.module.multi_segment_macro_resolutions.borrow_mut() + self.multi_segment_macro_resolutions .push((path, path_span, kind, parent_scope.clone(), res.ok())); } @@ -383,7 +383,7 @@ impl<'a> Resolver<'a> { if trace { let kind = kind.expect("macro kind must be specified if tracing is enabled"); - parent_scope.module.single_segment_macro_resolutions.borrow_mut() + self.single_segment_macro_resolutions .push((path[0].ident, kind, parent_scope.clone(), binding.ok())); } @@ -693,7 +693,7 @@ impl<'a> Resolver<'a> { } } - pub fn finalize_current_module_macro_resolutions(&mut self, module: Module<'a>) { + crate fn finalize_macro_resolutions(&mut self) { let check_consistency = |this: &mut Self, path: &[Segment], span, kind: MacroKind, initial_res: Option, res: Res| { if let Some(initial_res) = initial_res { @@ -729,8 +729,7 @@ impl<'a> Resolver<'a> { } }; - let macro_resolutions = - mem::take(&mut *module.multi_segment_macro_resolutions.borrow_mut()); + let macro_resolutions = mem::take(&mut self.multi_segment_macro_resolutions); for (mut path, path_span, kind, parent_scope, initial_res) in macro_resolutions { // FIXME: Path resolution will ICE if segment IDs present. for seg in &mut path { seg.id = None; } @@ -757,8 +756,7 @@ impl<'a> Resolver<'a> { } } - let macro_resolutions = - mem::take(&mut *module.single_segment_macro_resolutions.borrow_mut()); + let macro_resolutions = mem::take(&mut self.single_segment_macro_resolutions); for (ident, kind, parent_scope, initial_binding) in macro_resolutions { match self.early_resolve_ident_in_lexical_scope(ident, ScopeSet::Macro(kind), &parent_scope, true, true, ident.span) { @@ -783,7 +781,7 @@ impl<'a> Resolver<'a> { } } - let builtin_attrs = mem::take(&mut *module.builtin_attrs.borrow_mut()); + let builtin_attrs = mem::take(&mut self.builtin_attrs); for (ident, parent_scope) in builtin_attrs { let _ = self.early_resolve_ident_in_lexical_scope( ident, ScopeSet::Macro(MacroKind::Attr), &parent_scope, true, true, ident.span diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 00e89f0fdae0..ef8fcc9ba8a5 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -848,7 +848,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { directive.vis.set(orig_vis); let module = match path_res { PathResult::Module(module) => { - // Consistency checks, analogous to `finalize_current_module_macro_resolutions`. + // Consistency checks, analogous to `finalize_macro_resolutions`. if let Some(initial_module) = directive.imported_module.get() { if !ModuleOrUniformRoot::same_def(module, initial_module) && no_ambiguity { span_bug!(directive.span, "inconsistent resolution for an import"); @@ -973,7 +973,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { match binding { Ok(binding) => { - // Consistency checks, analogous to `finalize_current_module_macro_resolutions`. + // Consistency checks, analogous to `finalize_macro_resolutions`. let initial_res = source_bindings[ns].get().map(|initial_binding| { all_ns_err = false; if let Some(target_binding) = target_bindings[ns].get() { diff --git a/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.stderr b/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.stderr index 478bc09f2919..676b8b9f056c 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.stderr +++ b/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.stderr @@ -4,17 +4,17 @@ error: cannot find macro `__build_diagnostic_array!` in this scope LL | __build_diagnostic_array!(DIAGNOSTICS); | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: cannot find macro `__register_diagnostic!` in this scope - --> $DIR/feature-gate-rustc-diagnostic-macros.rs:4:1 - | -LL | __register_diagnostic!(E0001); - | ^^^^^^^^^^^^^^^^^^^^^ - error: cannot find macro `__diagnostic_used!` in this scope --> $DIR/feature-gate-rustc-diagnostic-macros.rs:8:5 | LL | __diagnostic_used!(E0001); | ^^^^^^^^^^^^^^^^^ +error: cannot find macro `__register_diagnostic!` in this scope + --> $DIR/feature-gate-rustc-diagnostic-macros.rs:4:1 + | +LL | __register_diagnostic!(E0001); + | ^^^^^^^^^^^^^^^^^^^^^ + error: aborting due to 3 previous errors diff --git a/src/test/ui/hygiene/no_implicit_prelude.stderr b/src/test/ui/hygiene/no_implicit_prelude.stderr index a89176fe6907..643f803f6204 100644 --- a/src/test/ui/hygiene/no_implicit_prelude.stderr +++ b/src/test/ui/hygiene/no_implicit_prelude.stderr @@ -1,3 +1,11 @@ +error: cannot find macro `panic!` in this scope + --> $DIR/no_implicit_prelude.rs:16:9 + | +LL | assert_eq!(0, 0); + | ^^^^^^^^^^^^^^^^^ + | + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + error[E0433]: failed to resolve: use of undeclared type or module `Vec` --> $DIR/no_implicit_prelude.rs:11:9 | @@ -7,14 +15,6 @@ LL | fn f() { ::bar::m!(); } LL | Vec::new(); | ^^^ use of undeclared type or module `Vec` -error: cannot find macro `panic!` in this scope - --> $DIR/no_implicit_prelude.rs:16:9 - | -LL | assert_eq!(0, 0); - | ^^^^^^^^^^^^^^^^^ - | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - error[E0599]: no method named `clone` found for type `()` in the current scope --> $DIR/no_implicit_prelude.rs:12:12 | diff --git a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr index 5afdd8889ae7..7d013828bd90 100644 --- a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr +++ b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr @@ -21,25 +21,6 @@ LL | use inner1::*; | ^^^^^^^^^ = help: consider adding an explicit import of `exported` to disambiguate -error[E0659]: `include` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) - --> $DIR/local-modularized-tricky-fail-1.rs:46:1 - | -LL | include!(); - | ^^^^^^^ ambiguous name - | - = note: `include` could refer to a macro from prelude -note: `include` could also refer to the macro defined here - --> $DIR/local-modularized-tricky-fail-1.rs:17:5 - | -LL | / macro_rules! include { -LL | | () => () -LL | | } - | |_____^ -... -LL | define_include!(); - | ------------------ in this macro invocation - = help: use `crate::include` to refer to this macro unambiguously - error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/local-modularized-tricky-fail-1.rs:35:5 | @@ -59,6 +40,25 @@ LL | define_panic!(); | ---------------- in this macro invocation = help: use `crate::panic` to refer to this macro unambiguously +error[E0659]: `include` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) + --> $DIR/local-modularized-tricky-fail-1.rs:46:1 + | +LL | include!(); + | ^^^^^^^ ambiguous name + | + = note: `include` could refer to a macro from prelude +note: `include` could also refer to the macro defined here + --> $DIR/local-modularized-tricky-fail-1.rs:17:5 + | +LL | / macro_rules! include { +LL | | () => () +LL | | } + | |_____^ +... +LL | define_include!(); + | ------------------ in this macro invocation + = help: use `crate::include` to refer to this macro unambiguously + error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/imports/shadow_builtin_macros.stderr b/src/test/ui/imports/shadow_builtin_macros.stderr index c84226ef313c..2f2ab20cdf07 100644 --- a/src/test/ui/imports/shadow_builtin_macros.stderr +++ b/src/test/ui/imports/shadow_builtin_macros.stderr @@ -13,20 +13,6 @@ LL | use foo::*; = help: consider adding an explicit import of `panic` to disambiguate = help: or use `self::panic` to refer to this macro unambiguously -error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) - --> $DIR/shadow_builtin_macros.rs:20:14 - | -LL | fn f() { panic!(); } - | ^^^^^ ambiguous name - | - = note: `panic` could refer to a macro from prelude -note: `panic` could also refer to the macro imported here - --> $DIR/shadow_builtin_macros.rs:19:26 - | -LL | ::two_macros::m!(use foo::panic;); - | ^^^^^^^^^^ - = help: use `self::panic` to refer to this macro unambiguously - error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/shadow_builtin_macros.rs:33:5 | @@ -62,6 +48,20 @@ note: `n` could also refer to the macro imported here LL | #[macro_use(n)] | ^ +error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) + --> $DIR/shadow_builtin_macros.rs:20:14 + | +LL | fn f() { panic!(); } + | ^^^^^ ambiguous name + | + = note: `panic` could refer to a macro from prelude +note: `panic` could also refer to the macro imported here + --> $DIR/shadow_builtin_macros.rs:19:26 + | +LL | ::two_macros::m!(use foo::panic;); + | ^^^^^^^^^^ + = help: use `self::panic` to refer to this macro unambiguously + error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/issues/issue-49074.stderr b/src/test/ui/issues/issue-49074.stderr index c557255ab502..e0d3bb3ecc2e 100644 --- a/src/test/ui/issues/issue-49074.stderr +++ b/src/test/ui/issues/issue-49074.stderr @@ -1,9 +1,3 @@ -error: cannot find attribute macro `marco_use` in this scope - --> $DIR/issue-49074.rs:3:3 - | -LL | #[marco_use] // typo - | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_use` - error: cannot find macro `bar!` in this scope --> $DIR/issue-49074.rs:12:4 | @@ -12,5 +6,11 @@ LL | bar!(); | = help: have you added the `#[macro_use]` on the module/import? +error: cannot find attribute macro `marco_use` in this scope + --> $DIR/issue-49074.rs:3:3 + | +LL | #[marco_use] // typo + | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_use` + error: aborting due to 2 previous errors diff --git a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr index b2f124788286..0c863e919670 100644 --- a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr +++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr @@ -88,18 +88,6 @@ error: expected derive macro, found macro `crate::my_macro` LL | #[derive(crate::my_macro)] | ^^^^^^^^^^^^^^^ not a derive macro -error: cannot find attribute macro `my_macro` in this scope - --> $DIR/macro-namespace-reserved-2.rs:38:3 - | -LL | #[my_macro] - | ^^^^^^^^ - -error: cannot find derive macro `my_macro` in this scope - --> $DIR/macro-namespace-reserved-2.rs:48:10 - | -LL | #[derive(my_macro)] - | ^^^^^^^^ - error: cannot find macro `my_macro_attr!` in this scope --> $DIR/macro-namespace-reserved-2.rs:28:5 | @@ -112,5 +100,17 @@ error: cannot find macro `MyTrait!` in this scope LL | MyTrait!(); | ^^^^^^^ +error: cannot find attribute macro `my_macro` in this scope + --> $DIR/macro-namespace-reserved-2.rs:38:3 + | +LL | #[my_macro] + | ^^^^^^^^ + +error: cannot find derive macro `my_macro` in this scope + --> $DIR/macro-namespace-reserved-2.rs:48:10 + | +LL | #[derive(my_macro)] + | ^^^^^^^^ + error: aborting due to 19 previous errors diff --git a/src/test/ui/reserved/reserved-attr-on-macro.stderr b/src/test/ui/reserved/reserved-attr-on-macro.stderr index d4b97d290ea8..856162b318de 100644 --- a/src/test/ui/reserved/reserved-attr-on-macro.stderr +++ b/src/test/ui/reserved/reserved-attr-on-macro.stderr @@ -7,12 +7,6 @@ LL | #[rustc_attribute_should_be_reserved] = note: for more information, see https://github.com/rust-lang/rust/issues/29642 = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable -error: cannot find attribute macro `rustc_attribute_should_be_reserved` in this scope - --> $DIR/reserved-attr-on-macro.rs:1:3 - | -LL | #[rustc_attribute_should_be_reserved] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: cannot determine resolution for the macro `foo` --> $DIR/reserved-attr-on-macro.rs:10:5 | @@ -21,6 +15,12 @@ LL | foo!(); | = note: import resolution is stuck, try simplifying macro imports +error: cannot find attribute macro `rustc_attribute_should_be_reserved` in this scope + --> $DIR/reserved-attr-on-macro.rs:1:3 + | +LL | #[rustc_attribute_should_be_reserved] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0658`. From cfbb60bf6d83fbcfcca1f2919131aa39fb997b53 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 12 Aug 2019 21:55:42 +0300 Subject: [PATCH 23/35] resolve: Do not "normalize away" trait/enum modules prematurely The previous approach was brittle - what would happen if `ParentScope` wasn't created by `invoc_parent_scope`? That's exactly the case for various uses of `ParentScope` in diagnostics and in built-in attribute validation. --- src/librustc_resolve/lib.rs | 8 +++++--- src/librustc_resolve/macros.rs | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 3d82ef3d5801..6bb2cd037708 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1321,13 +1321,15 @@ impl<'a> Resolver<'a> { ScopeSet::AbsolutePath(ns) => (ns, true), ScopeSet::Macro(_) => (MacroNS, false), }; + // Jump out of trait or enum modules, they do not act as scopes. + let module = parent_scope.module.nearest_item_scope(); let mut scope = match ns { _ if is_absolute_path => Scope::CrateRoot, - TypeNS | ValueNS => Scope::Module(parent_scope.module), + TypeNS | ValueNS => Scope::Module(module), MacroNS => Scope::DeriveHelpers, }; let mut ident = ident.modern(); - let mut use_prelude = !parent_scope.module.no_implicit_prelude; + let mut use_prelude = !module.no_implicit_prelude; loop { let visit = match scope { @@ -1360,7 +1362,7 @@ impl<'a> Resolver<'a> { LegacyScope::Invocation(invoc) => Scope::MacroRules( invoc.output_legacy_scope.get().unwrap_or(invoc.parent_legacy_scope) ), - LegacyScope::Empty => Scope::Module(parent_scope.module), + LegacyScope::Empty => Scope::Module(module), } Scope::CrateRoot => match ns { TypeNS => { diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index f54f395063c2..6d882a6e194d 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -258,7 +258,7 @@ impl<'a> Resolver<'a> { fn invoc_parent_scope(&self, invoc_id: ExpnId, derives: Vec) -> ParentScope<'a> { let invoc = self.invocations[&invoc_id]; ParentScope { - module: invoc.module.nearest_item_scope(), + module: invoc.module, expansion: invoc_id.parent(), legacy: invoc.parent_legacy_scope, derives, From 1a1557c28501d256f3a21099d17a73e1d2c36aa0 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 12 Aug 2019 23:19:36 +0300 Subject: [PATCH 24/35] resolve: Add `ParentScope::default`, eliminate `dummy_parent_scope` Remove some unnecessary parameters from functions --- src/librustc_resolve/build_reduced_graph.rs | 17 +++++++--------- src/librustc_resolve/late.rs | 2 +- src/librustc_resolve/lib.rs | 19 ++++++++++++++---- src/librustc_resolve/macros.rs | 20 ++++++------------- .../passes/collect_intra_doc_links.rs | 3 ++- 5 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 98ee7203057d..016ec55947af 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -163,8 +163,8 @@ impl<'a> Resolver<'a> { let def_id = module.def_id().unwrap(); for child in self.cstore.item_children_untracked(def_id, self.session) { let child = child.map_id(|_| panic!("unexpected id")); - BuildReducedGraphVisitor { parent_scope: self.dummy_parent_scope(), r: self } - .build_reduced_graph_for_external_crate_res(module, child); + BuildReducedGraphVisitor { parent_scope: ParentScope::default(module), r: self } + .build_reduced_graph_for_external_crate_res(child); } module.populated.set(true) } @@ -706,7 +706,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion)); for variant in &(*enum_definition).variants { - self.build_reduced_graph_for_variant(variant, module, vis, expansion); + self.build_reduced_graph_for_variant(variant, module, vis); } } @@ -797,8 +797,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { fn build_reduced_graph_for_variant(&mut self, variant: &Variant, parent: Module<'a>, - vis: ty::Visibility, - expn_id: ExpnId) { + vis: ty::Visibility) { + let expn_id = self.parent_scope.expansion; let ident = variant.ident; // Define a name in the type namespace. @@ -861,11 +861,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } /// Builds the reduced graph for a single item in an external crate. - fn build_reduced_graph_for_external_crate_res( - &mut self, - parent: Module<'a>, - child: Export, - ) { + fn build_reduced_graph_for_external_crate_res(&mut self, child: Export) { + let parent = self.parent_scope.module; let Export { ident, res, vis, span } = child; // FIXME: We shouldn't create the gensym here, it should come from metadata, // but metadata cannot encode gensyms currently, so we create it here. diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index e0869d848508..fbd9f1d48e5e 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -501,8 +501,8 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { fn new(resolver: &'b mut Resolver<'a>) -> LateResolutionVisitor<'a, 'b> { // During late resolution we only track the module component of the parent scope, // although it may be useful to track other components as well for diagnostics. - let parent_scope = resolver.dummy_parent_scope(); let graph_root = resolver.graph_root; + let parent_scope = ParentScope::default(graph_root); LateResolutionVisitor { r: resolver, parent_scope, diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 6bb2cd037708..788252c55fc7 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -130,6 +130,17 @@ pub struct ParentScope<'a> { derives: Vec, } +impl<'a> ParentScope<'a> { + pub fn default(module: Module<'a>) -> ParentScope<'a> { + ParentScope { + module, + expansion: ExpnId::root(), + legacy: LegacyScope::Empty, + derives: Vec::new(), + } + } +} + #[derive(Eq)] struct BindingError { name: Name, @@ -799,7 +810,7 @@ pub struct Resolver<'a> { pub definitions: Definitions, - graph_root: Module<'a>, + pub graph_root: Module<'a>, prelude: Option>, pub extern_prelude: FxHashMap>, @@ -995,7 +1006,7 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> { segments, }; - let parent_scope = &self.dummy_parent_scope(); + let parent_scope = &ParentScope::default(self.graph_root); let res = match self.resolve_ast_path(&path, ns, parent_scope) { Ok(res) => res, Err((span, error)) => { @@ -1069,7 +1080,7 @@ impl<'a> Resolver<'a> { let mut invocations = FxHashMap::default(); invocations.insert(ExpnId::root(), - arenas.alloc_invocation_data(InvocationData::root(graph_root))); + arenas.alloc_invocation_data(InvocationData::default(graph_root))); let mut macro_defs = FxHashMap::default(); macro_defs.insert(ExpnId::root(), root_def_id); @@ -2649,7 +2660,7 @@ impl<'a> Resolver<'a> { let def_id = self.definitions.local_def_id(module_id); self.module_map.get(&def_id).copied().unwrap_or(self.graph_root) }); - let parent_scope = &ParentScope { module, ..self.dummy_parent_scope() }; + let parent_scope = &ParentScope::default(module); let res = self.resolve_ast_path(&path, ns, parent_scope).map_err(|_| ())?; Ok((path, res)) } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 6d882a6e194d..754983e3bd42 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -43,9 +43,9 @@ pub struct InvocationData<'a> { } impl<'a> InvocationData<'a> { - pub fn root(graph_root: Module<'a>) -> Self { + pub fn default(module: Module<'a>) -> Self { InvocationData { - module: graph_root, + module, parent_legacy_scope: LegacyScope::Empty, output_legacy_scope: Cell::new(None), } @@ -120,17 +120,13 @@ impl<'a> base::Resolver for Resolver<'a> { } fn get_module_scope(&mut self, id: ast::NodeId) -> ExpnId { - let span = DUMMY_SP.fresh_expansion(ExpnId::root(), ExpnInfo::default( + let expn_id = ExpnId::fresh(ExpnId::root(), Some(ExpnInfo::default( ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, self.session.edition() - )); - let expn_id = span.ctxt().outer_expn(); + ))); let module = self.module_map[&self.definitions.local_def_id(id)]; + let invocation_data = self.arenas.alloc_invocation_data(InvocationData::default(module)); self.definitions.set_invocation_parent(expn_id, module.def_id().unwrap().index); - self.invocations.insert(expn_id, self.arenas.alloc_invocation_data(InvocationData { - module, - parent_legacy_scope: LegacyScope::Empty, - output_legacy_scope: Cell::new(None), - })); + self.invocations.insert(expn_id, invocation_data); expn_id } @@ -251,10 +247,6 @@ impl<'a> base::Resolver for Resolver<'a> { } impl<'a> Resolver<'a> { - pub fn dummy_parent_scope(&self) -> ParentScope<'a> { - self.invoc_parent_scope(ExpnId::root(), Vec::new()) - } - fn invoc_parent_scope(&self, invoc_id: ExpnId, derives: Vec) -> ParentScope<'a> { let invoc = self.invocations[&invoc_id]; ParentScope { diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 5c9fac7eab42..5767b5b3b46a 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -4,6 +4,7 @@ use rustc::hir::def_id::DefId; use rustc::hir; use rustc::lint as lint; use rustc::ty; +use rustc_resolve::ParentScope; use syntax; use syntax::ast::{self, Ident}; use syntax::ext::base::SyntaxExtensionKind; @@ -431,7 +432,7 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option { let path = ast::Path::from_ident(Ident::from_str(path_str)); cx.enter_resolver(|resolver| { if let Ok((Some(ext), res)) = resolver.resolve_macro_path( - &path, None, &resolver.dummy_parent_scope(), false, false + &path, None, &ParentScope::default(resolver.graph_root), false, false ) { if let SyntaxExtensionKind::LegacyBang { .. } = ext.kind { return Some(res.map_id(|_| panic!("unexpected id"))); From 59dd07ae2bbc8d6c46bdb5f3d5b93a6729848311 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 12 Aug 2019 23:39:49 +0300 Subject: [PATCH 25/35] resolve: Eliminate `InvocationData` It was very similar to `ParentScope` and mostly could be replaced by it. --- src/librustc_resolve/build_reduced_graph.rs | 23 +++--- src/librustc_resolve/lib.rs | 29 ++++--- src/librustc_resolve/macros.rs | 92 +++++++-------------- 3 files changed, 53 insertions(+), 91 deletions(-) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 016ec55947af..51a0a7456885 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -3,7 +3,7 @@ //! Here we build the "reduced graph": the graph of the module tree without //! any imports resolved. -use crate::macros::{InvocationData, LegacyBinding, LegacyScope}; +use crate::macros::{LegacyBinding, LegacyScope}; use crate::resolve_imports::ImportDirective; use crate::resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport}; use crate::{Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding}; @@ -1063,20 +1063,17 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { false } - fn visit_invoc(&mut self, id: ast::NodeId) -> &'a InvocationData<'a> { + fn visit_invoc(&mut self, id: ast::NodeId) -> LegacyScope<'a> { let invoc_id = id.placeholder_to_expn_id(); - self.parent_scope.module.unresolved_invocations.borrow_mut().insert(invoc_id); + let parent_scope = self.parent_scope.clone(); + parent_scope.module.unresolved_invocations.borrow_mut().insert(invoc_id); - let invocation_data = self.r.arenas.alloc_invocation_data(InvocationData { - module: self.parent_scope.module, - parent_legacy_scope: self.parent_scope.legacy, - output_legacy_scope: Cell::new(None), - }); - let old_invocation_data = self.r.invocations.insert(invoc_id, invocation_data); - assert!(old_invocation_data.is_none(), "invocation data is reset for an invocation"); + let old_parent_scope = + self.r.invocation_parent_scopes.insert(invoc_id, parent_scope.clone()); + assert!(old_parent_scope.is_none(), "invocation data is reset for an invocation"); - invocation_data + LegacyScope::Invocation(invoc_id) } fn proc_macro_stub(item: &ast::Item) -> Option<(MacroKind, Ident, Span)> { @@ -1177,7 +1174,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { return } ItemKind::Mac(..) => { - self.parent_scope.legacy = LegacyScope::Invocation(self.visit_invoc(item.id)); + self.parent_scope.legacy = self.visit_invoc(item.id); return } ItemKind::Mod(..) => self.contains_macro_use(&item.attrs), @@ -1196,7 +1193,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { fn visit_stmt(&mut self, stmt: &'b ast::Stmt) { if let ast::StmtKind::Mac(..) = stmt.node { - self.parent_scope.legacy = LegacyScope::Invocation(self.visit_invoc(stmt.id)); + self.parent_scope.legacy = self.visit_invoc(stmt.id); } else { visit::walk_stmt(self, stmt); } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 788252c55fc7..85f8d07bf9bd 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -54,7 +54,7 @@ use diagnostics::{Suggestion, ImportSuggestion}; use diagnostics::{find_span_of_binding_until_next_binding, extend_span_to_previous_binding}; use late::{PathSource, Rib, RibKind::*}; use resolve_imports::{ImportDirective, ImportDirectiveSubclass, NameResolution, ImportResolver}; -use macros::{InvocationData, LegacyBinding, LegacyScope}; +use macros::{LegacyBinding, LegacyScope}; type Res = def::Res; @@ -911,9 +911,12 @@ pub struct Resolver<'a> { /// FIXME: Find a way for `PartialEq` and `Eq` to emulate `#[structural_match]` /// by marking the produced impls rather than the original items. special_derives: FxHashMap, - - /// Maps the `ExpnId` of an expansion to its containing module or block. - invocations: FxHashMap>, + /// Parent scopes in which the macros were invoked. + /// FIXME: `derives` are missing in these parent scopes and need to be taken from elsewhere. + invocation_parent_scopes: FxHashMap>, + /// Legacy scopes *produced* by expanding the macro invocations, + /// include all the `macro_rules` items and other invocations generated by them. + output_legacy_scopes: FxHashMap>, /// Avoid duplicated errors for "name already defined". name_already_seen: FxHashMap, @@ -936,7 +939,6 @@ pub struct ResolverArenas<'a> { name_bindings: arena::TypedArena>, import_directives: arena::TypedArena>, name_resolutions: arena::TypedArena>>, - invocation_data: arena::TypedArena>, legacy_bindings: arena::TypedArena>, } @@ -961,10 +963,6 @@ impl<'a> ResolverArenas<'a> { fn alloc_name_resolution(&'a self) -> &'a RefCell> { self.name_resolutions.alloc(Default::default()) } - fn alloc_invocation_data(&'a self, expansion_data: InvocationData<'a>) - -> &'a InvocationData<'a> { - self.invocation_data.alloc(expansion_data) - } fn alloc_legacy_binding(&'a self, binding: LegacyBinding<'a>) -> &'a LegacyBinding<'a> { self.legacy_bindings.alloc(binding) } @@ -1078,9 +1076,8 @@ impl<'a> Resolver<'a> { } } - let mut invocations = FxHashMap::default(); - invocations.insert(ExpnId::root(), - arenas.alloc_invocation_data(InvocationData::default(graph_root))); + let mut invocation_parent_scopes = FxHashMap::default(); + invocation_parent_scopes.insert(ExpnId::root(), ParentScope::default(graph_root)); let mut macro_defs = FxHashMap::default(); macro_defs.insert(ExpnId::root(), root_def_id); @@ -1152,7 +1149,8 @@ impl<'a> Resolver<'a> { dummy_ext_bang: Lrc::new(SyntaxExtension::dummy_bang(session.edition())), dummy_ext_derive: Lrc::new(SyntaxExtension::dummy_derive(session.edition())), non_macro_attrs: [non_macro_attr(false), non_macro_attr(true)], - invocations, + invocation_parent_scopes, + output_legacy_scopes: Default::default(), macro_defs, local_macro_def_scopes: FxHashMap::default(), name_already_seen: FxHashMap::default(), @@ -1370,8 +1368,9 @@ impl<'a> Resolver<'a> { LegacyScope::Binding(binding) => Scope::MacroRules( binding.parent_legacy_scope ), - LegacyScope::Invocation(invoc) => Scope::MacroRules( - invoc.output_legacy_scope.get().unwrap_or(invoc.parent_legacy_scope) + LegacyScope::Invocation(invoc_id) => Scope::MacroRules( + self.output_legacy_scopes.get(&invoc_id).cloned() + .unwrap_or(self.invocation_parent_scopes[&invoc_id].legacy) ), LegacyScope::Empty => Scope::Module(module), } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 754983e3bd42..e64ca61b7efd 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -1,6 +1,6 @@ use crate::{AmbiguityError, AmbiguityKind, AmbiguityErrorMisc, Determinacy}; use crate::{CrateLint, Resolver, ResolutionError, Scope, ScopeSet, ParentScope, Weak}; -use crate::{Module, ModuleKind, NameBinding, PathResult, Segment, ToNameBinding}; +use crate::{ModuleKind, NameBinding, PathResult, Segment, ToNameBinding}; use crate::{ModuleOrUniformRoot, KNOWN_TOOLS}; use crate::Namespace::*; use crate::build_reduced_graph::BuildReducedGraphVisitor; @@ -22,36 +22,11 @@ use syntax::feature_gate::GateIssue; use syntax::symbol::{Symbol, kw, sym}; use syntax_pos::{Span, DUMMY_SP}; -use std::cell::Cell; use std::{mem, ptr}; use rustc_data_structures::sync::Lrc; type Res = def::Res; -// FIXME: Merge this with `ParentScope`. -#[derive(Clone, Debug)] -pub struct InvocationData<'a> { - /// The module in which the macro was invoked. - crate module: Module<'a>, - /// The legacy scope in which the macro was invoked. - /// The invocation path is resolved in this scope. - crate parent_legacy_scope: LegacyScope<'a>, - /// The legacy scope *produced* by expanding this macro invocation, - /// includes all the macro_rules items, other invocations, etc generated by it. - /// `None` if the macro is not expanded yet. - crate output_legacy_scope: Cell>>, -} - -impl<'a> InvocationData<'a> { - pub fn default(module: Module<'a>) -> Self { - InvocationData { - module, - parent_legacy_scope: LegacyScope::Empty, - output_legacy_scope: Cell::new(None), - } - } -} - /// Binding produced by a `macro_rules` item. /// Not modularized, can shadow previous legacy bindings, etc. #[derive(Debug)] @@ -75,7 +50,7 @@ pub enum LegacyScope<'a> { Binding(&'a LegacyBinding<'a>), /// The scope introduced by a macro invocation that can potentially /// create a `macro_rules!` macro definition. - Invocation(&'a InvocationData<'a>), + Invocation(ExpnId), } // Macro namespace is separated into two sub-namespaces, one for bang macros and @@ -124,9 +99,8 @@ impl<'a> base::Resolver for Resolver<'a> { ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, self.session.edition() ))); let module = self.module_map[&self.definitions.local_def_id(id)]; - let invocation_data = self.arenas.alloc_invocation_data(InvocationData::default(module)); + self.invocation_parent_scopes.insert(expn_id, ParentScope::default(module)); self.definitions.set_invocation_parent(expn_id, module.def_id().unwrap().index); - self.invocations.insert(expn_id, invocation_data); expn_id } @@ -140,29 +114,29 @@ impl<'a> base::Resolver for Resolver<'a> { }); } - fn visit_ast_fragment_with_placeholders(&mut self, expn_id: ExpnId, fragment: &AstFragment, - derives: &[ExpnId]) { - fragment.visit_with(&mut DefCollector::new(&mut self.definitions, expn_id)); - - let invocation = self.invocations[&expn_id]; - invocation.module.unresolved_invocations.borrow_mut().remove(&expn_id); - invocation.module.unresolved_invocations.borrow_mut().extend(derives); - let parent_def = self.definitions.invocation_parent(expn_id); + fn visit_ast_fragment_with_placeholders( + &mut self, expansion: ExpnId, fragment: &AstFragment, derives: &[ExpnId] + ) { + // Fill in some data for derives if the fragment is from a derive container. + let parent_scope = self.invocation_parent_scopes[&expansion].clone(); + let parent_def = self.definitions.invocation_parent(expansion); + self.invocation_parent_scopes.extend( + derives.iter().map(|&derive| (derive, parent_scope.clone())) + ); for &derive_invoc_id in derives { self.definitions.set_invocation_parent(derive_invoc_id, parent_def); } - self.invocations.extend(derives.iter().map(|&derive| (derive, invocation))); - let mut visitor = BuildReducedGraphVisitor { - r: self, - parent_scope: ParentScope { - module: invocation.module, - expansion: expn_id, - legacy: invocation.parent_legacy_scope, - derives: Vec::new(), - }, - }; + parent_scope.module.unresolved_invocations.borrow_mut().remove(&expansion); + parent_scope.module.unresolved_invocations.borrow_mut().extend(derives); + + // Integrate the new AST fragment into all the definition and module structures. + // We are inside the `expansion` new, but other parent scope components are still the same. + fragment.visit_with(&mut DefCollector::new(&mut self.definitions, expansion)); + let parent_scope = ParentScope { expansion, ..parent_scope }; + let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope }; fragment.visit_with(&mut visitor); - invocation.output_legacy_scope.set(Some(visitor.parent_scope.legacy)); + let output_legacy_scope = visitor.parent_scope.legacy; + self.output_legacy_scopes.insert(expansion, output_legacy_scope); } fn register_builtin_macro(&mut self, ident: ast::Ident, ext: SyntaxExtension) { @@ -178,7 +152,8 @@ impl<'a> base::Resolver for Resolver<'a> { fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: ExpnId, force: bool) -> Result>, Indeterminate> { - let (path, kind, derives_in_scope, after_derive) = match invoc.kind { + let parent_scope = &self.invocation_parent_scopes[&invoc_id].clone(); + let (path, kind, derives, after_derive) = match invoc.kind { InvocationKind::Attr { ref attr, ref derives, after_derive, .. } => (&attr.path, MacroKind::Attr, derives.clone(), after_derive), InvocationKind::Bang { ref mac, .. } => @@ -192,7 +167,6 @@ impl<'a> base::Resolver for Resolver<'a> { // will automatically knows about itself. let mut result = Ok(None); if derives.len() > 1 { - let parent_scope = &self.invoc_parent_scope(invoc_id, Vec::new()); for path in derives { match self.resolve_macro_path(path, Some(MacroKind::Derive), parent_scope, true, force) { @@ -209,7 +183,8 @@ impl<'a> base::Resolver for Resolver<'a> { } }; - let parent_scope = &self.invoc_parent_scope(invoc_id, derives_in_scope); + // Derives are not included when `invocations` are collected, so we have to add them here. + let parent_scope = &ParentScope { derives, ..parent_scope.clone() }; let (ext, res) = self.smart_resolve_macro_path(path, kind, parent_scope, force)?; let span = invoc.span(); @@ -247,16 +222,6 @@ impl<'a> base::Resolver for Resolver<'a> { } impl<'a> Resolver<'a> { - fn invoc_parent_scope(&self, invoc_id: ExpnId, derives: Vec) -> ParentScope<'a> { - let invoc = self.invocations[&invoc_id]; - ParentScope { - module: invoc.module, - expansion: invoc_id.parent(), - legacy: invoc.parent_legacy_scope, - derives, - } - } - /// Resolve macro path with error reporting and recovery. fn smart_resolve_macro_path( &mut self, @@ -466,8 +431,9 @@ impl<'a> Resolver<'a> { Scope::MacroRules(legacy_scope) => match legacy_scope { LegacyScope::Binding(legacy_binding) if ident == legacy_binding.ident => Ok((legacy_binding.binding, Flags::MACRO_RULES)), - LegacyScope::Invocation(invoc) if invoc.output_legacy_scope.get().is_none() => - Err(Determinacy::Undetermined), + LegacyScope::Invocation(invoc_id) + if !this.output_legacy_scopes.contains_key(&invoc_id) => + Err(Determinacy::Undetermined), _ => Err(Determinacy::Determined), } Scope::CrateRoot => { From ea68bc85e01c17bdef5a593188d7a185c6014302 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 13 Aug 2019 01:39:10 +0300 Subject: [PATCH 26/35] resolve: Make `ParentScope` `Copy` By allocating its derive paths on the resolver arena. --- src/librustc_resolve/build_reduced_graph.rs | 17 ++++++------- src/librustc_resolve/diagnostics.rs | 4 +-- src/librustc_resolve/lib.rs | 14 +++++++---- src/librustc_resolve/macros.rs | 28 ++++++++++----------- src/librustc_resolve/resolve_imports.rs | 2 +- 5 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 51a0a7456885..bfb7844b543c 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -300,10 +300,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { root_id: NodeId, vis: ty::Visibility, ) { - let parent_scope = &self.parent_scope; - let current_module = parent_scope.module; + let current_module = self.parent_scope.module; let directive = self.r.arenas.alloc_import_directive(ImportDirective { - parent_scope: parent_scope.clone(), + parent_scope: self.parent_scope, module_path, imported_module: Cell::new(None), subclass, @@ -601,7 +600,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { let directive = self.r.arenas.alloc_import_directive(ImportDirective { root_id: item.id, id: item.id, - parent_scope: self.parent_scope.clone(), + parent_scope: self.parent_scope, imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))), subclass: ImportDirectiveSubclass::ExternCrate { source: orig_name, @@ -994,7 +993,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { |this: &Self, span| this.r.arenas.alloc_import_directive(ImportDirective { root_id: item.id, id: item.id, - parent_scope: this.parent_scope.clone(), + parent_scope: this.parent_scope, imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))), subclass: ImportDirectiveSubclass::MacroUse, use_span_with_attributes: item.span_with_attributes(), @@ -1066,11 +1065,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { fn visit_invoc(&mut self, id: ast::NodeId) -> LegacyScope<'a> { let invoc_id = id.placeholder_to_expn_id(); - let parent_scope = self.parent_scope.clone(); - parent_scope.module.unresolved_invocations.borrow_mut().insert(invoc_id); + self.parent_scope.module.unresolved_invocations.borrow_mut().insert(invoc_id); - let old_parent_scope = - self.r.invocation_parent_scopes.insert(invoc_id, parent_scope.clone()); + let old_parent_scope = self.r.invocation_parent_scopes.insert(invoc_id, self.parent_scope); assert!(old_parent_scope.is_none(), "invocation data is reset for an invocation"); LegacyScope::Invocation(invoc_id) @@ -1261,7 +1258,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { fn visit_attribute(&mut self, attr: &'b ast::Attribute) { if !attr.is_sugared_doc && is_builtin_attr(attr) { - self.r.builtin_attrs.push((attr.path.segments[0].ident, self.parent_scope.clone())); + self.r.builtin_attrs.push((attr.path.segments[0].ident, self.parent_scope)); } visit::walk_attribute(self, attr); } diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index f824dfe8e781..8ec5d64ef3d0 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -376,9 +376,9 @@ impl<'a> Resolver<'a> { Scope::DeriveHelpers => { let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper); if filter_fn(res) { - for derive in &parent_scope.derives { + for derive in parent_scope.derives { let parent_scope = - &ParentScope { derives: Vec::new(), ..*parent_scope }; + &ParentScope { derives: &[], ..*parent_scope }; if let Ok((Some(ext), _)) = this.resolve_macro_path( derive, Some(MacroKind::Derive), parent_scope, false, false ) { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 85f8d07bf9bd..b0944b480a2d 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -122,12 +122,12 @@ enum ScopeSet { /// Serves as a starting point for the scope visitor. /// This struct is currently used only for early resolution (imports and macros), /// but not for late resolution yet. -#[derive(Clone, Debug)] +#[derive(Clone, Copy, Debug)] pub struct ParentScope<'a> { module: Module<'a>, expansion: ExpnId, legacy: LegacyScope<'a>, - derives: Vec, + derives: &'a [ast::Path], } impl<'a> ParentScope<'a> { @@ -136,7 +136,7 @@ impl<'a> ParentScope<'a> { module, expansion: ExpnId::root(), legacy: LegacyScope::Empty, - derives: Vec::new(), + derives: &[], } } } @@ -940,6 +940,7 @@ pub struct ResolverArenas<'a> { import_directives: arena::TypedArena>, name_resolutions: arena::TypedArena>>, legacy_bindings: arena::TypedArena>, + ast_paths: arena::TypedArena, } impl<'a> ResolverArenas<'a> { @@ -966,6 +967,9 @@ impl<'a> ResolverArenas<'a> { fn alloc_legacy_binding(&'a self, binding: LegacyBinding<'a>) -> &'a LegacyBinding<'a> { self.legacy_bindings.alloc(binding) } + fn alloc_ast_paths(&'a self, paths: &[ast::Path]) -> &'a [ast::Path] { + self.ast_paths.alloc_from_iter(paths.iter().cloned()) + } } impl<'a, 'b> ty::DefIdTree for &'a Resolver<'b> { @@ -1515,7 +1519,7 @@ impl<'a> Resolver<'a> { self.hygienic_lexical_parent(module, &mut ident.span) }; module = unwrap_or!(opt_module, break); - let adjusted_parent_scope = &ParentScope { module, ..parent_scope.clone() }; + let adjusted_parent_scope = &ParentScope { module, ..*parent_scope }; let result = self.resolve_ident_in_module_unadjusted( ModuleOrUniformRoot::Module(module), ident, @@ -1651,7 +1655,7 @@ impl<'a> Resolver<'a> { ModuleOrUniformRoot::Module(m) => { if let Some(def) = ident.span.modernize_and_adjust(m.expansion) { tmp_parent_scope = - ParentScope { module: self.macro_def_scope(def), ..parent_scope.clone() }; + ParentScope { module: self.macro_def_scope(def), ..*parent_scope }; adjusted_parent_scope = &tmp_parent_scope; } } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index e64ca61b7efd..dd8e34070311 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -118,11 +118,9 @@ impl<'a> base::Resolver for Resolver<'a> { &mut self, expansion: ExpnId, fragment: &AstFragment, derives: &[ExpnId] ) { // Fill in some data for derives if the fragment is from a derive container. - let parent_scope = self.invocation_parent_scopes[&expansion].clone(); + let parent_scope = self.invocation_parent_scopes[&expansion]; let parent_def = self.definitions.invocation_parent(expansion); - self.invocation_parent_scopes.extend( - derives.iter().map(|&derive| (derive, parent_scope.clone())) - ); + self.invocation_parent_scopes.extend(derives.iter().map(|&derive| (derive, parent_scope))); for &derive_invoc_id in derives { self.definitions.set_invocation_parent(derive_invoc_id, parent_def); } @@ -152,14 +150,14 @@ impl<'a> base::Resolver for Resolver<'a> { fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: ExpnId, force: bool) -> Result>, Indeterminate> { - let parent_scope = &self.invocation_parent_scopes[&invoc_id].clone(); + let parent_scope = self.invocation_parent_scopes[&invoc_id]; let (path, kind, derives, after_derive) = match invoc.kind { InvocationKind::Attr { ref attr, ref derives, after_derive, .. } => - (&attr.path, MacroKind::Attr, derives.clone(), after_derive), + (&attr.path, MacroKind::Attr, self.arenas.alloc_ast_paths(derives), after_derive), InvocationKind::Bang { ref mac, .. } => - (&mac.path, MacroKind::Bang, Vec::new(), false), + (&mac.path, MacroKind::Bang, &[][..], false), InvocationKind::Derive { ref path, .. } => - (path, MacroKind::Derive, Vec::new(), false), + (path, MacroKind::Derive, &[][..], false), InvocationKind::DeriveContainer { ref derives, .. } => { // Block expansion of derives in the container until we know whether one of them // is a built-in `Copy`. Skip the resolution if there's only one derive - either @@ -169,7 +167,7 @@ impl<'a> base::Resolver for Resolver<'a> { if derives.len() > 1 { for path in derives { match self.resolve_macro_path(path, Some(MacroKind::Derive), - parent_scope, true, force) { + &parent_scope, true, force) { Ok((Some(ref ext), _)) if ext.is_derive_copy => { self.add_derives(invoc.expansion_data.id, SpecialDerives::COPY); return Ok(None); @@ -184,7 +182,7 @@ impl<'a> base::Resolver for Resolver<'a> { }; // Derives are not included when `invocations` are collected, so we have to add them here. - let parent_scope = &ParentScope { derives, ..parent_scope.clone() }; + let parent_scope = &ParentScope { derives, ..parent_scope }; let (ext, res) = self.smart_resolve_macro_path(path, kind, parent_scope, force)?; let span = invoc.span(); @@ -324,7 +322,7 @@ impl<'a> Resolver<'a> { if trace { let kind = kind.expect("macro kind must be specified if tracing is enabled"); self.multi_segment_macro_resolutions - .push((path, path_span, kind, parent_scope.clone(), res.ok())); + .push((path, path_span, kind, *parent_scope, res.ok())); } self.prohibit_imported_non_macro_attrs(None, res.ok(), path_span); @@ -341,7 +339,7 @@ impl<'a> Resolver<'a> { if trace { let kind = kind.expect("macro kind must be specified if tracing is enabled"); self.single_segment_macro_resolutions - .push((path[0].ident, kind, parent_scope.clone(), binding.ok())); + .push((path[0].ident, kind, *parent_scope, binding.ok())); } let res = binding.map(|binding| binding.res()); @@ -410,8 +408,8 @@ impl<'a> Resolver<'a> { let result = match scope { Scope::DeriveHelpers => { let mut result = Err(Determinacy::Determined); - for derive in &parent_scope.derives { - let parent_scope = &ParentScope { derives: Vec::new(), ..*parent_scope }; + for derive in parent_scope.derives { + let parent_scope = &ParentScope { derives: &[], ..*parent_scope }; match this.resolve_macro_path(derive, Some(MacroKind::Derive), parent_scope, true, force) { Ok((Some(ext), _)) => if ext.helper_attrs.contains(&ident.name) { @@ -457,7 +455,7 @@ impl<'a> Resolver<'a> { } } Scope::Module(module) => { - let adjusted_parent_scope = &ParentScope { module, ..parent_scope.clone() }; + let adjusted_parent_scope = &ParentScope { module, ..*parent_scope }; let binding = this.resolve_ident_in_module_unadjusted_ext( ModuleOrUniformRoot::Module(module), ident, diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index ef8fcc9ba8a5..0e3bdc1274a6 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -394,7 +394,7 @@ impl<'a> Resolver<'a> { match ident.span.glob_adjust(module.expansion, glob_import.span) { Some(Some(def)) => { tmp_parent_scope = - ParentScope { module: self.macro_def_scope(def), ..parent_scope.clone() }; + ParentScope { module: self.macro_def_scope(def), ..*parent_scope }; adjusted_parent_scope = &tmp_parent_scope; } Some(None) => {} From 310ee4d98c9a421487914d12474f121a75197bf2 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 13 Aug 2019 02:13:36 +0300 Subject: [PATCH 27/35] resolve: Privatize `BuildReducedGraphVisitor` --- src/librustc_resolve/build_reduced_graph.rs | 27 ++++++++++++++------- src/librustc_resolve/diagnostics.rs | 2 +- src/librustc_resolve/lib.rs | 5 ++-- src/librustc_resolve/macros.rs | 7 ++---- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index bfb7844b543c..d8799f8332f4 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -30,6 +30,7 @@ use syntax::attr; use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId}; use syntax::ast::{MetaItemKind, StmtKind, TraitItem, TraitItemKind, Variant}; use syntax::ext::base::{MacroKind, SyntaxExtension}; +use syntax::ext::expand::AstFragment; use syntax::ext::hygiene::ExpnId; use syntax::feature_gate::is_builtin_attr; use syntax::parse::token::{self, Token}; @@ -67,7 +68,7 @@ impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, ExpnId) { } } -pub(crate) struct IsMacroExport; +struct IsMacroExport; impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, ExpnId, IsMacroExport) { fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> { @@ -84,7 +85,7 @@ impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, ExpnId, IsMacroExport impl<'a> Resolver<'a> { /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined; /// otherwise, reports an error. - pub fn define(&mut self, parent: Module<'a>, ident: Ident, ns: Namespace, def: T) + crate fn define(&mut self, parent: Module<'a>, ident: Ident, ns: Namespace, def: T) where T: ToNameBinding<'a>, { let binding = def.to_name_binding(self.arenas); @@ -93,7 +94,7 @@ impl<'a> Resolver<'a> { } } - pub fn get_module(&mut self, def_id: DefId) -> Module<'a> { + crate fn get_module(&mut self, def_id: DefId) -> Module<'a> { if def_id.krate == LOCAL_CRATE { return self.module_map[&def_id] } @@ -119,7 +120,7 @@ impl<'a> Resolver<'a> { module } - pub fn macro_def_scope(&mut self, expn_id: ExpnId) -> Module<'a> { + crate fn macro_def_scope(&mut self, expn_id: ExpnId) -> Module<'a> { let def_id = match self.macro_defs.get(&expn_id) { Some(def_id) => *def_id, None => return self.graph_root, @@ -141,7 +142,7 @@ impl<'a> Resolver<'a> { } } - crate fn get_macro_by_def_id(&mut self, def_id: DefId) -> Option> { + fn get_macro_by_def_id(&mut self, def_id: DefId) -> Option> { if let Some(ext) = self.macro_map.get(&def_id) { return Some(ext.clone()); } @@ -158,7 +159,7 @@ impl<'a> Resolver<'a> { /// Ensures that the reduced graph rooted at the given external module /// is built, building it if it is not. - pub fn populate_module_if_necessary(&mut self, module: Module<'a>) { + crate fn populate_module_if_necessary(&mut self, module: Module<'a>) { if module.populated.get() { return } let def_id = module.def_id().unwrap(); for child in self.cstore.item_children_untracked(def_id, self.session) { @@ -168,11 +169,19 @@ impl<'a> Resolver<'a> { } module.populated.set(true) } + + crate fn build_reduced_graph( + &mut self, fragment: &AstFragment, parent_scope: ParentScope<'a> + ) -> LegacyScope<'a> { + let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope }; + fragment.visit_with(&mut visitor); + visitor.parent_scope.legacy + } } -pub struct BuildReducedGraphVisitor<'a, 'b> { - pub r: &'b mut Resolver<'a>, - pub parent_scope: ParentScope<'a>, +struct BuildReducedGraphVisitor<'a, 'b> { + r: &'b mut Resolver<'a>, + parent_scope: ParentScope<'a>, } impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 8ec5d64ef3d0..861b0fd44ac4 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -455,7 +455,7 @@ impl<'a> Resolver<'a> { let mut tmp_suggestions = Vec::new(); add_module_candidates(prelude, &mut tmp_suggestions, filter_fn); suggestions.extend(tmp_suggestions.into_iter().filter(|s| { - use_prelude || this.is_builtin_macro(s.res.opt_def_id()) + use_prelude || this.is_builtin_macro(s.res) })); } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index b0944b480a2d..0cf9aa72d783 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1196,9 +1196,8 @@ impl<'a> Resolver<'a> { f(self, MacroNS); } - fn is_builtin_macro(&mut self, def_id: Option) -> bool { - def_id.and_then(|def_id| self.get_macro_by_def_id(def_id)) - .map_or(false, |ext| ext.is_builtin) + fn is_builtin_macro(&mut self, res: Res) -> bool { + self.get_macro(res).map_or(false, |ext| ext.is_builtin) } fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId { diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index dd8e34070311..0a63dd2558d3 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -3,7 +3,6 @@ use crate::{CrateLint, Resolver, ResolutionError, Scope, ScopeSet, ParentScope, use crate::{ModuleKind, NameBinding, PathResult, Segment, ToNameBinding}; use crate::{ModuleOrUniformRoot, KNOWN_TOOLS}; use crate::Namespace::*; -use crate::build_reduced_graph::BuildReducedGraphVisitor; use crate::resolve_imports::ImportResolver; use rustc::hir::def::{self, DefKind, NonMacroAttrKind}; use rustc::hir::map::DefCollector; @@ -131,9 +130,7 @@ impl<'a> base::Resolver for Resolver<'a> { // We are inside the `expansion` new, but other parent scope components are still the same. fragment.visit_with(&mut DefCollector::new(&mut self.definitions, expansion)); let parent_scope = ParentScope { expansion, ..parent_scope }; - let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope }; - fragment.visit_with(&mut visitor); - let output_legacy_scope = visitor.parent_scope.legacy; + let output_legacy_scope = self.build_reduced_graph(fragment, parent_scope); self.output_legacy_scopes.insert(expansion, output_legacy_scope); } @@ -530,7 +527,7 @@ impl<'a> Resolver<'a> { false, path_span, ) { - if use_prelude || this.is_builtin_macro(binding.res().opt_def_id()) { + if use_prelude || this.is_builtin_macro(binding.res()) { result = Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE)); } } From aca1353240e03eaba4b3540e1c7b3dea99d5c8ac Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 13 Aug 2019 02:46:42 +0300 Subject: [PATCH 28/35] resolve: Add some comments to the main modules --- src/librustc_resolve/build_reduced_graph.rs | 8 +++++--- src/librustc_resolve/late.rs | 7 +++++++ src/librustc_resolve/lib.rs | 9 +++++++++ src/librustc_resolve/macros.rs | 3 +++ src/librustc_resolve/resolve_imports.rs | 2 ++ 5 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index d8799f8332f4..c42a933a954a 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -1,7 +1,9 @@ -//! Reduced graph building. +//! After we obtain a fresh AST fragment from a macro, code in this module helps to integrate +//! that fragment into the module structures that are already partially built. //! -//! Here we build the "reduced graph": the graph of the module tree without -//! any imports resolved. +//! Items from the fragment are placed into modules, +//! unexpanded macros in the fragment are visited and registered. +//! Imports are also considered items and placed into modules here, but not resolved yet. use crate::macros::{LegacyBinding, LegacyScope}; use crate::resolve_imports::ImportDirective; diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index fbd9f1d48e5e..d97ee61d839a 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -1,3 +1,10 @@ +//! "Late resolution" is the pass that resolves most of names in a crate beside imports and macros. +//! It runs when the crate is fully expanded and its module structure is fully built. +//! So it just walks through the crate and resolves all the expressions, types, etc. +//! +//! If you wonder why there's no `early.rs`, that's because it's split into three files - +//! `build_reduced_graph.rs`, `macros.rs` and `resolve_imports.rs`. + use GenericParameters::*; use RibKind::*; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 0cf9aa72d783..2b55f9dc79d0 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1,3 +1,12 @@ +//! This crate is responsible for the part of name resolution that doesn't require type checker. +//! +//! Module structure of the crate is built here. +//! Paths in macros, imports, expressions, types, patterns are resolved here. +//! Label names are resolved here as well. +//! +//! Type-relative name resolution (methods, fields, associated items) happens in `librustc_typeck`. +//! Lifetime names are resolved in `librustc/middle/resolve_lifetime.rs`. + #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(crate_visibility_modifier)] diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 0a63dd2558d3..2f9bee749081 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -1,3 +1,6 @@ +//! A bunch of methods and structures more or less related to resolving macros and +//! interface provided by `Resolver` to macro expander. + use crate::{AmbiguityError, AmbiguityKind, AmbiguityErrorMisc, Determinacy}; use crate::{CrateLint, Resolver, ResolutionError, Scope, ScopeSet, ParentScope, Weak}; use crate::{ModuleKind, NameBinding, PathResult, Segment, ToNameBinding}; diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 0e3bdc1274a6..693893e9ef13 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -1,3 +1,5 @@ +//! A bunch of methods and structures more or less related to resolving imports. + use ImportDirectiveSubclass::*; use crate::{AmbiguityError, AmbiguityKind, AmbiguityErrorMisc}; From 1a447738b8a7ac8f0a47a134f9fa1a60a4621620 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 13 Aug 2019 03:34:46 +0300 Subject: [PATCH 29/35] hygiene: Merge `ExpnInfo` and `InternalExpnData` --- src/librustc/hir/lowering.rs | 2 +- src/librustc/ich/impls_syntax.rs | 3 +- src/librustc/ty/query/on_disk_cache.rs | 4 +- src/librustc_resolve/macros.rs | 11 +-- src/libsyntax/ext/base.rs | 5 +- src/libsyntax/ext/expand.rs | 15 ++-- src/libsyntax_ext/deriving/clone.rs | 2 +- src/libsyntax_ext/deriving/cmp/eq.rs | 2 +- src/libsyntax_ext/deriving/cmp/partial_eq.rs | 2 +- src/libsyntax_ext/deriving/generic/mod.rs | 2 +- src/libsyntax_ext/plugin_macro_defs.rs | 4 +- src/libsyntax_ext/proc_macro_harness.rs | 3 +- src/libsyntax_ext/standard_library_imports.rs | 4 +- src/libsyntax_ext/test_harness.rs | 5 +- src/libsyntax_pos/hygiene.rs | 70 +++++++++---------- 15 files changed, 67 insertions(+), 67 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index f942a0fb8579..0b7dacf8383e 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -704,7 +704,7 @@ impl<'a> LoweringContext<'a> { span: Span, allow_internal_unstable: Option>, ) -> Span { - span.fresh_expansion(ExpnId::root(), ExpnInfo { + span.fresh_expansion(ExpnInfo { def_site: span, allow_internal_unstable, ..ExpnInfo::default(ExpnKind::Desugaring(reason), span, self.sess.edition()) diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 5cc8324b3160..22e2cff35952 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -398,8 +398,9 @@ impl_stable_hash_for!(enum ::syntax_pos::hygiene::Transparency { }); impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnInfo { - call_site, kind, + parent -> _, + call_site, def_site, default_transparency, allow_internal_unstable, diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index 2286271b9eb4..351b9988bb25 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -588,13 +588,13 @@ impl<'a, 'tcx> SpecializedDecoder for CacheDecoder<'a, 'tcx> { let expn_info_tag = u8::decode(self)?; - // FIXME(mw): This method does not restore `InternalExpnData::parent` or + // FIXME(mw): This method does not restore `ExpnInfo::parent` or // `SyntaxContextData::prev_ctxt` or `SyntaxContextData::opaque`. These things // don't seem to be used after HIR lowering, so everything should be fine // as long as incremental compilation does not kick in before that. let location = || Span::with_root_ctxt(lo, hi); let recover_from_expn_info = |this: &Self, expn_info, pos| { - let span = location().fresh_expansion(ExpnId::root(), expn_info); + let span = location().fresh_expansion(expn_info); this.synthetic_expansion_infos.borrow_mut().insert(pos, span.ctxt()); span }; diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 2f9bee749081..58e785ab8c25 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -97,7 +97,7 @@ impl<'a> base::Resolver for Resolver<'a> { } fn get_module_scope(&mut self, id: ast::NodeId) -> ExpnId { - let expn_id = ExpnId::fresh(ExpnId::root(), Some(ExpnInfo::default( + let expn_id = ExpnId::fresh(Some(ExpnInfo::default( ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, self.session.edition() ))); let module = self.module_map[&self.definitions.local_def_id(id)]; @@ -120,7 +120,8 @@ impl<'a> base::Resolver for Resolver<'a> { &mut self, expansion: ExpnId, fragment: &AstFragment, derives: &[ExpnId] ) { // Fill in some data for derives if the fragment is from a derive container. - let parent_scope = self.invocation_parent_scopes[&expansion]; + // We are inside the `expansion` now, but other parent scope components are still the same. + let parent_scope = ParentScope { expansion, ..self.invocation_parent_scopes[&expansion] }; let parent_def = self.definitions.invocation_parent(expansion); self.invocation_parent_scopes.extend(derives.iter().map(|&derive| (derive, parent_scope))); for &derive_invoc_id in derives { @@ -130,9 +131,7 @@ impl<'a> base::Resolver for Resolver<'a> { parent_scope.module.unresolved_invocations.borrow_mut().extend(derives); // Integrate the new AST fragment into all the definition and module structures. - // We are inside the `expansion` new, but other parent scope components are still the same. fragment.visit_with(&mut DefCollector::new(&mut self.definitions, expansion)); - let parent_scope = ParentScope { expansion, ..parent_scope }; let output_legacy_scope = self.build_reduced_graph(fragment, parent_scope); self.output_legacy_scopes.insert(expansion, output_legacy_scope); } @@ -186,7 +185,9 @@ impl<'a> base::Resolver for Resolver<'a> { let (ext, res) = self.smart_resolve_macro_path(path, kind, parent_scope, force)?; let span = invoc.span(); - invoc.expansion_data.id.set_expn_info(ext.expn_info(span, fast_print_path(path))); + invoc.expansion_data.id.set_expn_info( + ext.expn_info(parent_scope.expansion, span, fast_print_path(path)) + ); if let Res::Def(_, def_id) = res { if after_derive { diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 8eacb96e3ff9..734b566b3ad1 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -640,10 +640,11 @@ impl SyntaxExtension { SyntaxExtension::default(SyntaxExtensionKind::NonMacroAttr { mark_used }, edition) } - pub fn expn_info(&self, call_site: Span, descr: Symbol) -> ExpnInfo { + pub fn expn_info(&self, parent: ExpnId, call_site: Span, descr: Symbol) -> ExpnInfo { ExpnInfo { - call_site, kind: ExpnKind::Macro(self.macro_kind(), descr), + parent, + call_site, def_site: self.span, default_transparency: self.default_transparency, allow_internal_unstable: self.allow_internal_unstable.clone(), diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 6f3e8f14b0b2..4233d5c0a222 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -353,7 +353,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { derives.reserve(traits.len()); invocations.reserve(traits.len()); for path in traits { - let expn_id = ExpnId::fresh(self.cx.current_expansion.id, None); + let expn_id = ExpnId::fresh(None); derives.push(expn_id); invocations.push(Invocation { kind: InvocationKind::Derive { path, item: item.clone() }, @@ -800,13 +800,16 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { // with exception of the derive container case which is not resolved and can get // its expansion info immediately. let expn_info = match &kind { - InvocationKind::DeriveContainer { item, .. } => Some(ExpnInfo::default( - ExpnKind::Macro(MacroKind::Attr, sym::derive), - item.span(), self.cx.parse_sess.edition, - )), + InvocationKind::DeriveContainer { item, .. } => Some(ExpnInfo { + parent: self.cx.current_expansion.id, + ..ExpnInfo::default( + ExpnKind::Macro(MacroKind::Attr, sym::derive), + item.span(), self.cx.parse_sess.edition, + ) + }), _ => None, }; - let expn_id = ExpnId::fresh(self.cx.current_expansion.id, expn_info); + let expn_id = ExpnId::fresh(expn_info); self.invocations.push(Invocation { kind, fragment_kind, diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs index 5a02ae0afb96..73df625d5ee6 100644 --- a/src/libsyntax_ext/deriving/clone.rs +++ b/src/libsyntax_ext/deriving/clone.rs @@ -35,7 +35,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>, match annitem.node { ItemKind::Struct(_, Generics { ref params, .. }) | ItemKind::Enum(_, Generics { ref params, .. }) => { - let container_id = cx.current_expansion.id.parent(); + let container_id = cx.current_expansion.id.expn_info().parent; if cx.resolver.has_derives(container_id, SpecialDerives::COPY) && !params.iter().any(|param| match param.kind { ast::GenericParamKind::Type { .. } => true, diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs index 5d7c4a84389c..1ef34a680041 100644 --- a/src/libsyntax_ext/deriving/cmp/eq.rs +++ b/src/libsyntax_ext/deriving/cmp/eq.rs @@ -13,7 +13,7 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt<'_>, mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable)) { - cx.resolver.add_derives(cx.current_expansion.id.parent(), SpecialDerives::EQ); + cx.resolver.add_derives(cx.current_expansion.id.expn_info().parent, SpecialDerives::EQ); let inline = cx.meta_word(span, sym::inline); let hidden = cx.meta_list_item_word(span, sym::hidden); diff --git a/src/libsyntax_ext/deriving/cmp/partial_eq.rs b/src/libsyntax_ext/deriving/cmp/partial_eq.rs index 7d7c4ae22a8a..76befc98591e 100644 --- a/src/libsyntax_ext/deriving/cmp/partial_eq.rs +++ b/src/libsyntax_ext/deriving/cmp/partial_eq.rs @@ -13,7 +13,7 @@ pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt<'_>, mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable)) { - cx.resolver.add_derives(cx.current_expansion.id.parent(), SpecialDerives::PARTIAL_EQ); + cx.resolver.add_derives(cx.current_expansion.id.expn_info().parent, SpecialDerives::PARTIAL_EQ); // structures are equal if all fields are equal, and non equal, if // any fields are not equal or if the enum variants are different diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 4bf004a71e4d..6b739e27eee8 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -425,7 +425,7 @@ impl<'a> TraitDef<'a> { return; } }; - let container_id = cx.current_expansion.id.parent(); + let container_id = cx.current_expansion.id.expn_info().parent; let is_always_copy = cx.resolver.has_derives(container_id, SpecialDerives::COPY) && has_no_type_params; diff --git a/src/libsyntax_ext/plugin_macro_defs.rs b/src/libsyntax_ext/plugin_macro_defs.rs index 15737314b223..b34a250881a3 100644 --- a/src/libsyntax_ext/plugin_macro_defs.rs +++ b/src/libsyntax_ext/plugin_macro_defs.rs @@ -11,7 +11,7 @@ use syntax::source_map::respan; use syntax::symbol::sym; use syntax::tokenstream::*; use syntax_pos::{Span, DUMMY_SP}; -use syntax_pos::hygiene::{ExpnId, ExpnInfo, ExpnKind, MacroKind}; +use syntax_pos::hygiene::{ExpnInfo, ExpnKind, MacroKind}; use std::mem; @@ -43,7 +43,7 @@ pub fn inject( ) { if !named_exts.is_empty() { let mut extra_items = Vec::new(); - let span = DUMMY_SP.fresh_expansion(ExpnId::root(), ExpnInfo::allow_unstable( + let span = DUMMY_SP.fresh_expansion(ExpnInfo::allow_unstable( ExpnKind::Macro(MacroKind::Attr, sym::plugin), DUMMY_SP, edition, [sym::rustc_attrs][..].into(), )); diff --git a/src/libsyntax_ext/proc_macro_harness.rs b/src/libsyntax_ext/proc_macro_harness.rs index 62c74b2b9c6b..9d8a8c17ba2d 100644 --- a/src/libsyntax_ext/proc_macro_harness.rs +++ b/src/libsyntax_ext/proc_macro_harness.rs @@ -6,7 +6,6 @@ use syntax::attr; use syntax::source_map::{ExpnInfo, ExpnKind, respan}; use syntax::ext::base::{ExtCtxt, MacroKind}; use syntax::ext::expand::{AstFragment, ExpansionConfig}; -use syntax::ext::hygiene::ExpnId; use syntax::ext::proc_macro::is_proc_macro_attr; use syntax::parse::ParseSess; use syntax::ptr::P; @@ -328,7 +327,7 @@ fn mk_decls( custom_attrs: &[ProcMacroDef], custom_macros: &[ProcMacroDef], ) -> P { - let span = DUMMY_SP.fresh_expansion(ExpnId::root(), ExpnInfo::allow_unstable( + let span = DUMMY_SP.fresh_expansion(ExpnInfo::allow_unstable( ExpnKind::Macro(MacroKind::Attr, sym::proc_macro), DUMMY_SP, cx.parse_sess.edition, [sym::rustc_attrs, sym::proc_macro_internals][..].into(), )); diff --git a/src/libsyntax_ext/standard_library_imports.rs b/src/libsyntax_ext/standard_library_imports.rs index 4382fb8af858..c00412486522 100644 --- a/src/libsyntax_ext/standard_library_imports.rs +++ b/src/libsyntax_ext/standard_library_imports.rs @@ -1,6 +1,6 @@ use syntax::{ast, attr}; use syntax::edition::Edition; -use syntax::ext::hygiene::{ExpnId, MacroKind}; +use syntax::ext::hygiene::MacroKind; use syntax::ptr::P; use syntax::source_map::{ExpnInfo, ExpnKind, dummy_spanned, respan}; use syntax::symbol::{Ident, Symbol, kw, sym}; @@ -55,7 +55,7 @@ pub fn inject( // the prelude. let name = names[0]; - let span = DUMMY_SP.fresh_expansion(ExpnId::root(), ExpnInfo::allow_unstable( + let span = DUMMY_SP.fresh_expansion(ExpnInfo::allow_unstable( ExpnKind::Macro(MacroKind::Attr, sym::std_inject), DUMMY_SP, edition, [sym::prelude_import][..].into(), )); diff --git a/src/libsyntax_ext/test_harness.rs b/src/libsyntax_ext/test_harness.rs index ab108290a938..3fb1c1bd0224 100644 --- a/src/libsyntax_ext/test_harness.rs +++ b/src/libsyntax_ext/test_harness.rs @@ -5,9 +5,8 @@ use smallvec::{smallvec, SmallVec}; use syntax::ast::{self, Ident}; use syntax::attr; use syntax::entry::{self, EntryPointType}; -use syntax::ext::base::{ExtCtxt, Resolver}; +use syntax::ext::base::{ExtCtxt, MacroKind, Resolver}; use syntax::ext::expand::{AstFragment, ExpansionConfig}; -use syntax::ext::hygiene::{ExpnId, MacroKind}; use syntax::feature_gate::Features; use syntax::mut_visit::{*, ExpectOne}; use syntax::parse::ParseSess; @@ -269,7 +268,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P { // #![main] // test::test_main_static(&[..tests]); // } - let sp = DUMMY_SP.fresh_expansion(ExpnId::root(), ExpnInfo::allow_unstable( + let sp = DUMMY_SP.fresh_expansion(ExpnInfo::allow_unstable( ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, cx.ext_cx.parse_sess.edition, [sym::main, sym::test, sym::rustc_attrs][..].into(), )); diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index 743bd437ee5b..1dba466625ae 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -56,16 +56,6 @@ struct SyntaxContextData { #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] pub struct ExpnId(u32); -// FIXME: Find a way to merge this with `ExpnInfo`. -#[derive(Debug)] -struct InternalExpnData { - parent: ExpnId, - /// Each expansion should have an associated expansion info, but sometimes there's a delay - /// between creation of an expansion ID and obtaining its info (e.g. macros are collected - /// first and then resolved later), so we use an `Option` here. - expn_info: Option, -} - /// A property of a macro expansion that determines how identifiers /// produced by that expansion are resolved. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Hash, Debug, RustcEncodable, RustcDecodable)] @@ -86,8 +76,8 @@ pub enum Transparency { } impl ExpnId { - pub fn fresh(parent: ExpnId, expn_info: Option) -> Self { - HygieneData::with(|data| data.fresh_expn(parent, expn_info)) + pub fn fresh(expn_info: Option) -> Self { + HygieneData::with(|data| data.fresh_expn(expn_info)) } /// The ID of the theoretical expansion that generates freshly parsed, unexpanded AST. @@ -106,11 +96,6 @@ impl ExpnId { ExpnId(raw) } - #[inline] - pub fn parent(self) -> ExpnId { - HygieneData::with(|data| data.parent_expn(self)) - } - #[inline] pub fn expn_info(self) -> ExpnInfo { HygieneData::with(|data| data.expn_info(self).clone()) @@ -119,7 +104,7 @@ impl ExpnId { #[inline] pub fn set_expn_info(self, info: ExpnInfo) { HygieneData::with(|data| { - let old_info = &mut data.expn_data[self.0 as usize].expn_info; + let old_info = &mut data.expn_data[self.0 as usize]; assert!(old_info.is_none(), "expansion info is reset for an expansion ID"); *old_info = Some(info); }) @@ -150,7 +135,10 @@ impl ExpnId { #[derive(Debug)] crate struct HygieneData { - expn_data: Vec, + /// Each expansion should have an associated expansion info, but sometimes there's a delay + /// between creation of an expansion ID and obtaining its info (e.g. macros are collected + /// first and then resolved later), so we use an `Option` here. + expn_data: Vec>, syntax_context_data: Vec, syntax_context_map: FxHashMap<(SyntaxContext, ExpnId, Transparency), SyntaxContext>, } @@ -158,10 +146,7 @@ crate struct HygieneData { impl HygieneData { crate fn new(edition: Edition) -> Self { HygieneData { - expn_data: vec![InternalExpnData { - parent: ExpnId::root(), - expn_info: Some(ExpnInfo::default(ExpnKind::Root, DUMMY_SP, edition)), - }], + expn_data: vec![Some(ExpnInfo::default(ExpnKind::Root, DUMMY_SP, edition))], syntax_context_data: vec![SyntaxContextData { outer_expn: ExpnId::root(), outer_transparency: Transparency::Opaque, @@ -178,17 +163,13 @@ impl HygieneData { GLOBALS.with(|globals| f(&mut *globals.hygiene_data.borrow_mut())) } - fn fresh_expn(&mut self, parent: ExpnId, expn_info: Option) -> ExpnId { - self.expn_data.push(InternalExpnData { parent, expn_info }); + fn fresh_expn(&mut self, expn_info: Option) -> ExpnId { + self.expn_data.push(expn_info); ExpnId(self.expn_data.len() as u32 - 1) } - fn parent_expn(&self, expn_id: ExpnId) -> ExpnId { - self.expn_data[expn_id.0 as usize].parent - } - fn expn_info(&self, expn_id: ExpnId) -> &ExpnInfo { - self.expn_data[expn_id.0 as usize].expn_info.as_ref() + self.expn_data[expn_id.0 as usize].as_ref() .expect("no expansion info for an expansion ID") } @@ -197,7 +178,7 @@ impl HygieneData { if expn_id == ExpnId::root() { return false; } - expn_id = self.parent_expn(expn_id); + expn_id = self.expn_info(expn_id).parent; } true } @@ -593,9 +574,9 @@ impl Span { /// other compiler-generated code to set per-span properties like allowed unstable features. /// The returned span belongs to the created expansion and has the new properties, /// but its location is inherited from the current span. - pub fn fresh_expansion(self, parent: ExpnId, expn_info: ExpnInfo) -> Span { + pub fn fresh_expansion(self, expn_info: ExpnInfo) -> Span { HygieneData::with(|data| { - let expn_id = data.fresh_expn(parent, Some(expn_info)); + let expn_id = data.fresh_expn(Some(expn_info)); self.with_ctxt(data.apply_mark(SyntaxContext::root(), expn_id)) }) } @@ -606,6 +587,10 @@ impl Span { #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] pub struct ExpnInfo { // --- The part unique to each expansion. + /// The kind of this expansion - macro or compiler desugaring. + pub kind: ExpnKind, + /// The expansion that produced this expansion. + pub parent: ExpnId, /// The location of the actual macro invocation or syntax sugar , e.g. /// `let x = foo!();` or `if let Some(y) = x {}` /// @@ -616,8 +601,6 @@ pub struct ExpnInfo { /// call_site span would have its own ExpnInfo, with the call_site /// pointing to the `foo!` invocation. pub call_site: Span, - /// The kind of this expansion - macro or compiler desugaring. - pub kind: ExpnKind, // --- The part specific to the macro/desugaring definition. // --- FIXME: Share it between expansions with the same definition. @@ -644,8 +627,9 @@ impl ExpnInfo { /// Constructs an expansion info with default properties. pub fn default(kind: ExpnKind, call_site: Span, edition: Edition) -> ExpnInfo { ExpnInfo { - call_site, kind, + parent: ExpnId::root(), + call_site, def_site: DUMMY_SP, default_transparency: Transparency::SemiTransparent, allow_internal_unstable: None, @@ -753,6 +737,18 @@ impl DesugaringKind { } } +impl Encodable for ExpnId { + fn encode(&self, _: &mut E) -> Result<(), E::Error> { + Ok(()) // FIXME(jseyfried) intercrate hygiene + } +} + +impl Decodable for ExpnId { + fn decode(_: &mut D) -> Result { + Ok(ExpnId::root()) // FIXME(jseyfried) intercrate hygiene + } +} + impl Encodable for SyntaxContext { fn encode(&self, _: &mut E) -> Result<(), E::Error> { Ok(()) // FIXME(jseyfried) intercrate hygiene @@ -760,7 +756,7 @@ impl Encodable for SyntaxContext { } impl Decodable for SyntaxContext { - fn decode(_: &mut D) -> Result { + fn decode(_: &mut D) -> Result { Ok(SyntaxContext::root()) // FIXME(jseyfried) intercrate hygiene } } From 74190a5e1c7439b001296fbc41da67682fd1d9bf Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 13 Aug 2019 22:48:27 +0300 Subject: [PATCH 30/35] syntax_pos: Remove the duplicate global edition It was introduced to avoid going through `hygiene_data`, but now it's read only once, when `ParseSess` is created, so going through a lock is ok. --- src/libsyntax/parse/lexer/tests.rs | 32 ++++-------------------------- src/libsyntax/parse/mod.rs | 3 ++- src/libsyntax_pos/edition.rs | 5 ----- src/libsyntax_pos/lib.rs | 2 -- 4 files changed, 6 insertions(+), 36 deletions(-) diff --git a/src/libsyntax/parse/lexer/tests.rs b/src/libsyntax/parse/lexer/tests.rs index 1e4d9048b41b..94570140996f 100644 --- a/src/libsyntax/parse/lexer/tests.rs +++ b/src/libsyntax/parse/lexer/tests.rs @@ -1,41 +1,17 @@ use super::*; -use crate::ast::CrateConfig; use crate::symbol::Symbol; use crate::source_map::{SourceMap, FilePathMapping}; -use crate::feature_gate::UnstableFeatures; use crate::parse::token; -use crate::diagnostics::plugin::ErrorMap; use crate::with_default_globals; use std::io; use std::path::PathBuf; -use syntax_pos::{BytePos, Span, edition::Edition}; -use rustc_data_structures::fx::{FxHashSet, FxHashMap}; -use rustc_data_structures::sync::{Lock, Once}; +use errors::{Handler, emitter::EmitterWriter}; +use syntax_pos::{BytePos, Span}; fn mk_sess(sm: Lrc) -> ParseSess { - let emitter = errors::emitter::EmitterWriter::new(Box::new(io::sink()), - Some(sm.clone()), - false, - false, - false); - ParseSess { - span_diagnostic: errors::Handler::with_emitter(true, None, Box::new(emitter)), - unstable_features: UnstableFeatures::from_environment(), - config: CrateConfig::default(), - included_mod_stack: Lock::new(Vec::new()), - source_map: sm, - missing_fragment_specifiers: Lock::new(FxHashSet::default()), - raw_identifier_spans: Lock::new(Vec::new()), - registered_diagnostics: Lock::new(ErrorMap::new()), - buffered_lints: Lock::new(vec![]), - edition: Edition::from_session(), - ambiguous_block_expr_parse: Lock::new(FxHashMap::default()), - param_attr_spans: Lock::new(Vec::new()), - let_chains_spans: Lock::new(Vec::new()), - async_closure_spans: Lock::new(Vec::new()), - injected_crate_name: Once::new(), - } + let emitter = EmitterWriter::new(Box::new(io::sink()), Some(sm.clone()), false, false, false); + ParseSess::with_span_handler(Handler::with_emitter(true, None, Box::new(emitter)), sm) } // open a string reader for the given string diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 80aa7a35266e..a1bcc455eb4c 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -16,6 +16,7 @@ use errors::{Applicability, FatalError, Level, Handler, ColorConfig, Diagnostic, use rustc_data_structures::sync::{Lrc, Lock, Once}; use syntax_pos::{Span, SourceFile, FileName, MultiSpan}; use syntax_pos::edition::Edition; +use syntax_pos::hygiene::ExpnId; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; use std::borrow::Cow; @@ -86,7 +87,7 @@ impl ParseSess { included_mod_stack: Lock::new(vec![]), source_map, buffered_lints: Lock::new(vec![]), - edition: Edition::from_session(), + edition: ExpnId::root().expn_info().edition, ambiguous_block_expr_parse: Lock::new(FxHashMap::default()), param_attr_spans: Lock::new(Vec::new()), let_chains_spans: Lock::new(Vec::new()), diff --git a/src/libsyntax_pos/edition.rs b/src/libsyntax_pos/edition.rs index 20216568426f..00cd00f28378 100644 --- a/src/libsyntax_pos/edition.rs +++ b/src/libsyntax_pos/edition.rs @@ -1,7 +1,6 @@ use crate::symbol::{Symbol, sym}; use std::fmt; use std::str::FromStr; -use crate::GLOBALS; /// The edition of the compiler (RFC 2052) #[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Debug, RustcEncodable, RustcDecodable, Eq)] @@ -39,10 +38,6 @@ impl fmt::Display for Edition { } impl Edition { - pub fn from_session() -> Edition { - GLOBALS.with(|globals| globals.edition) - } - pub fn lint_name(&self) -> &'static str { match *self { Edition::Edition2015 => "rust_2015_compatibility", diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 7af426eaa13f..ae538677a3aa 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -49,7 +49,6 @@ pub struct Globals { symbol_interner: Lock, span_interner: Lock, hygiene_data: Lock, - edition: Edition, } impl Globals { @@ -58,7 +57,6 @@ impl Globals { symbol_interner: Lock::new(symbol::Interner::fresh()), span_interner: Lock::new(span_encoding::SpanInterner::default()), hygiene_data: Lock::new(hygiene::HygieneData::new(edition)), - edition, } } } From 650f19aeae94eff687382859603929cd2dd463bc Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 13 Aug 2019 23:39:48 +0300 Subject: [PATCH 31/35] hygiene: Merge a tiny bit of the "share expansion definition data" PR --- src/librustc/hir/lowering.rs | 1 - src/libsyntax_pos/hygiene.rs | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 0b7dacf8383e..8c1ce5983b8c 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -705,7 +705,6 @@ impl<'a> LoweringContext<'a> { allow_internal_unstable: Option>, ) -> Span { span.fresh_expansion(ExpnInfo { - def_site: span, allow_internal_unstable, ..ExpnInfo::default(ExpnKind::Desugaring(reason), span, self.sess.edition()) }) diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index 1dba466625ae..4d9496f94fbd 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -603,7 +603,9 @@ pub struct ExpnInfo { pub call_site: Span, // --- The part specific to the macro/desugaring definition. - // --- FIXME: Share it between expansions with the same definition. + // --- It may be reasonable to share this part between expansions with the same definition, + // --- but such sharing is known to bring some minor inconveniences without also bringing + // --- noticeable perf improvements (PR #62898). /// The span of the macro definition (possibly dummy). /// This span serves only informational purpose and is not used for resolution. pub def_site: Span, From 136db2235a754f91f8a0a6bf6d985d77fe97f8db Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 13 Aug 2019 23:56:42 +0300 Subject: [PATCH 32/35] hygiene: `ExpnInfo` -> `ExpnData` For naming consistency with everything else in this area --- src/librustc/hir/lowering.rs | 6 +- src/librustc/ich/hcx.rs | 2 +- src/librustc/ich/impls_syntax.rs | 2 +- src/librustc/lint/internal.rs | 8 +- src/librustc/lint/mod.rs | 10 +-- src/librustc/traits/error_reporting.rs | 6 +- src/librustc/ty/query/on_disk_cache.rs | 68 +++++++------- src/librustc_codegen_ssa/back/write.rs | 2 +- src/librustc_lint/unused.rs | 2 +- src/librustc_resolve/macros.rs | 10 +-- src/libsyntax/ext/base.rs | 18 ++-- src/libsyntax/ext/expand.rs | 20 ++--- src/libsyntax/ext/proc_macro_server.rs | 2 +- src/libsyntax/parse/mod.rs | 2 +- src/libsyntax/source_map.rs | 14 +-- src/libsyntax_ext/deriving/clone.rs | 2 +- src/libsyntax_ext/deriving/cmp/eq.rs | 2 +- src/libsyntax_ext/deriving/cmp/partial_eq.rs | 2 +- src/libsyntax_ext/deriving/generic/mod.rs | 2 +- src/libsyntax_ext/plugin_macro_defs.rs | 4 +- src/libsyntax_ext/proc_macro_harness.rs | 4 +- src/libsyntax_ext/standard_library_imports.rs | 4 +- src/libsyntax_ext/test_harness.rs | 4 +- src/libsyntax_pos/hygiene.rs | 90 +++++++++---------- src/libsyntax_pos/lib.rs | 50 +++++------ 25 files changed, 168 insertions(+), 168 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 8c1ce5983b8c..0f6e834ca26d 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -67,7 +67,7 @@ use syntax::errors; use syntax::ext::base::SpecialDerives; use syntax::ext::hygiene::ExpnId; use syntax::print::pprust; -use syntax::source_map::{respan, ExpnInfo, ExpnKind, DesugaringKind, Spanned}; +use syntax::source_map::{respan, ExpnData, ExpnKind, DesugaringKind, Spanned}; use syntax::symbol::{kw, sym, Symbol}; use syntax::tokenstream::{TokenStream, TokenTree}; use syntax::parse::token::{self, Token}; @@ -704,9 +704,9 @@ impl<'a> LoweringContext<'a> { span: Span, allow_internal_unstable: Option>, ) -> Span { - span.fresh_expansion(ExpnInfo { + span.fresh_expansion(ExpnData { allow_internal_unstable, - ..ExpnInfo::default(ExpnKind::Desugaring(reason), span, self.sess.edition()) + ..ExpnData::default(ExpnKind::Desugaring(reason), span, self.sess.edition()) }) } diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 39f6b0d43444..e77faea1e4c5 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -370,7 +370,7 @@ impl<'a> HashStable> for Span { } let mut hasher = StableHasher::new(); - expn_id.expn_info().hash_stable(hcx, &mut hasher); + expn_id.expn_data().hash_stable(hcx, &mut hasher); let sub_hash: Fingerprint = hasher.finish(); let sub_hash = sub_hash.to_smaller_hash(); cache.borrow_mut().insert(expn_id, sub_hash); diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 22e2cff35952..7003f71c8baa 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -397,7 +397,7 @@ impl_stable_hash_for!(enum ::syntax_pos::hygiene::Transparency { Opaque, }); -impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnInfo { +impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnData { kind, parent -> _, call_site, diff --git a/src/librustc/lint/internal.rs b/src/librustc/lint/internal.rs index 29106fe000bb..be73b305e2c5 100644 --- a/src/librustc/lint/internal.rs +++ b/src/librustc/lint/internal.rs @@ -227,10 +227,10 @@ impl EarlyLintPass for LintPassImpl { if let ItemKind::Impl(_, _, _, _, Some(lint_pass), _, _) = &item.node { if let Some(last) = lint_pass.path.segments.last() { if last.ident.name == sym::LintPass { - let expn_info = lint_pass.path.span.ctxt().outer_expn_info(); - let call_site = expn_info.call_site; - if expn_info.kind.descr() != sym::impl_lint_pass && - call_site.ctxt().outer_expn_info().kind.descr() != sym::declare_lint_pass { + let expn_data = lint_pass.path.span.ctxt().outer_expn_data(); + let call_site = expn_data.call_site; + if expn_data.kind.descr() != sym::impl_lint_pass && + call_site.ctxt().outer_expn_data().kind.descr() != sym::declare_lint_pass { cx.struct_span_lint( LINT_PASS_IMPL_WITHOUT_MACRO, lint_pass.path.span, diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 3729ee81f5c6..2b58627cdea5 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -885,16 +885,16 @@ pub fn provide(providers: &mut Providers<'_>) { /// This is used to test whether a lint should not even begin to figure out whether it should /// be reported on the current node. pub fn in_external_macro(sess: &Session, span: Span) -> bool { - let expn_info = span.ctxt().outer_expn_info(); - match expn_info.kind { + let expn_data = span.ctxt().outer_expn_data(); + match expn_data.kind { ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) => false, ExpnKind::Desugaring(_) => true, // well, it's "external" ExpnKind::Macro(MacroKind::Bang, _) => { - if expn_info.def_site.is_dummy() { + if expn_data.def_site.is_dummy() { // dummy span for the def_site means it's an external macro return true; } - match sess.source_map().span_to_snippet(expn_info.def_site) { + match sess.source_map().span_to_snippet(expn_data.def_site) { Ok(code) => !code.starts_with("macro_rules"), // no snippet = external macro or compiler-builtin expansion Err(_) => true, @@ -906,7 +906,7 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool { /// Returns whether `span` originates in a derive macro's expansion pub fn in_derive_expansion(span: Span) -> bool { - if let ExpnKind::Macro(MacroKind::Derive, _) = span.ctxt().outer_expn_info().kind { + if let ExpnKind::Macro(MacroKind::Derive, _) = span.ctxt().outer_expn_data().kind { return true; } false diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 20568d4709b6..ba92e851141a 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -61,9 +61,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // We want to ignore desugarings here: spans are equivalent even // if one is the result of a desugaring and the other is not. let mut span = error.obligation.cause.span; - let expn_info = span.ctxt().outer_expn_info(); - if let ExpnKind::Desugaring(_) = expn_info.kind { - span = expn_info.call_site; + let expn_data = span.ctxt().outer_expn_data(); + if let ExpnKind::Desugaring(_) = expn_data.kind { + span = expn_data.call_site; } error_map.entry(span).or_default().push( diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index 351b9988bb25..8bf01970eb59 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -23,16 +23,16 @@ use std::mem; use syntax::ast::NodeId; use syntax::source_map::{SourceMap, StableSourceFileId}; use syntax_pos::{BytePos, Span, DUMMY_SP, SourceFile}; -use syntax_pos::hygiene::{ExpnId, SyntaxContext, ExpnInfo}; +use syntax_pos::hygiene::{ExpnId, SyntaxContext, ExpnData}; const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE; const TAG_CLEAR_CROSS_CRATE_CLEAR: u8 = 0; const TAG_CLEAR_CROSS_CRATE_SET: u8 = 1; -const TAG_NO_EXPANSION_INFO: u8 = 0; -const TAG_EXPANSION_INFO_SHORTHAND: u8 = 1; -const TAG_EXPANSION_INFO_INLINE: u8 = 2; +const TAG_NO_EXPN_DATA: u8 = 0; +const TAG_EXPN_DATA_SHORTHAND: u8 = 1; +const TAG_EXPN_DATA_INLINE: u8 = 2; const TAG_VALID_SPAN: u8 = 0; const TAG_INVALID_SPAN: u8 = 1; @@ -58,7 +58,7 @@ pub struct OnDiskCache<'sess> { // These two fields caches that are populated lazily during decoding. file_index_to_file: Lock>>, - synthetic_expansion_infos: Lock>, + synthetic_syntax_contexts: Lock>, // A map from dep-node to the position of the cached query result in // `serialized_data`. @@ -135,7 +135,7 @@ impl<'sess> OnDiskCache<'sess> { current_diagnostics: Default::default(), query_result_index: footer.query_result_index.into_iter().collect(), prev_diagnostics_index: footer.diagnostics_index.into_iter().collect(), - synthetic_expansion_infos: Default::default(), + synthetic_syntax_contexts: Default::default(), alloc_decoding_state: AllocDecodingState::new(footer.interpret_alloc_index), } } @@ -151,7 +151,7 @@ impl<'sess> OnDiskCache<'sess> { current_diagnostics: Default::default(), query_result_index: Default::default(), prev_diagnostics_index: Default::default(), - synthetic_expansion_infos: Default::default(), + synthetic_syntax_contexts: Default::default(), alloc_decoding_state: AllocDecodingState::new(Vec::new()), } } @@ -185,7 +185,7 @@ impl<'sess> OnDiskCache<'sess> { encoder, type_shorthands: Default::default(), predicate_shorthands: Default::default(), - expn_info_shorthands: Default::default(), + expn_data_shorthands: Default::default(), interpret_allocs: Default::default(), interpret_allocs_inverse: Vec::new(), source_map: CachingSourceMapView::new(tcx.sess.source_map()), @@ -383,7 +383,7 @@ impl<'sess> OnDiskCache<'sess> { cnum_map: self.cnum_map.get(), file_index_to_file: &self.file_index_to_file, file_index_to_stable_id: &self.file_index_to_stable_id, - synthetic_expansion_infos: &self.synthetic_expansion_infos, + synthetic_syntax_contexts: &self.synthetic_syntax_contexts, alloc_decoding_session: self.alloc_decoding_state.new_decoding_session(), }; @@ -440,7 +440,7 @@ struct CacheDecoder<'a, 'tcx> { opaque: opaque::Decoder<'a>, source_map: &'a SourceMap, cnum_map: &'a IndexVec>, - synthetic_expansion_infos: &'a Lock>, + synthetic_syntax_contexts: &'a Lock>, file_index_to_file: &'a Lock>>, file_index_to_stable_id: &'a FxHashMap, alloc_decoding_session: AllocDecodingSession<'a>, @@ -586,37 +586,37 @@ impl<'a, 'tcx> SpecializedDecoder for CacheDecoder<'a, 'tcx> { let lo = file_lo.lines[line_lo - 1] + col_lo; let hi = lo + len; - let expn_info_tag = u8::decode(self)?; + let expn_data_tag = u8::decode(self)?; - // FIXME(mw): This method does not restore `ExpnInfo::parent` or + // FIXME(mw): This method does not restore `ExpnData::parent` or // `SyntaxContextData::prev_ctxt` or `SyntaxContextData::opaque`. These things // don't seem to be used after HIR lowering, so everything should be fine // as long as incremental compilation does not kick in before that. let location = || Span::with_root_ctxt(lo, hi); - let recover_from_expn_info = |this: &Self, expn_info, pos| { - let span = location().fresh_expansion(expn_info); - this.synthetic_expansion_infos.borrow_mut().insert(pos, span.ctxt()); + let recover_from_expn_data = |this: &Self, expn_data, pos| { + let span = location().fresh_expansion(expn_data); + this.synthetic_syntax_contexts.borrow_mut().insert(pos, span.ctxt()); span }; - Ok(match expn_info_tag { - TAG_NO_EXPANSION_INFO => { + Ok(match expn_data_tag { + TAG_NO_EXPN_DATA => { location() } - TAG_EXPANSION_INFO_INLINE => { - let expn_info = Decodable::decode(self)?; - recover_from_expn_info( - self, expn_info, AbsoluteBytePos::new(self.opaque.position()) + TAG_EXPN_DATA_INLINE => { + let expn_data = Decodable::decode(self)?; + recover_from_expn_data( + self, expn_data, AbsoluteBytePos::new(self.opaque.position()) ) } - TAG_EXPANSION_INFO_SHORTHAND => { + TAG_EXPN_DATA_SHORTHAND => { let pos = AbsoluteBytePos::decode(self)?; - let cached_ctxt = self.synthetic_expansion_infos.borrow().get(&pos).cloned(); + let cached_ctxt = self.synthetic_syntax_contexts.borrow().get(&pos).cloned(); if let Some(ctxt) = cached_ctxt { Span::new(lo, hi, ctxt) } else { - let expn_info = - self.with_position(pos.to_usize(), |this| ExpnInfo::decode(this))?; - recover_from_expn_info(self, expn_info, pos) + let expn_data = + self.with_position(pos.to_usize(), |this| ExpnData::decode(this))?; + recover_from_expn_data(self, expn_data, pos) } } _ => { @@ -725,7 +725,7 @@ struct CacheEncoder<'a, 'tcx, E: ty_codec::TyEncoder> { encoder: &'a mut E, type_shorthands: FxHashMap, usize>, predicate_shorthands: FxHashMap, usize>, - expn_info_shorthands: FxHashMap, + expn_data_shorthands: FxHashMap, interpret_allocs: FxHashMap, interpret_allocs_inverse: Vec, source_map: CachingSourceMapView<'tcx>, @@ -817,17 +817,17 @@ where len.encode(self)?; if span_data.ctxt == SyntaxContext::root() { - TAG_NO_EXPANSION_INFO.encode(self) + TAG_NO_EXPN_DATA.encode(self) } else { - let (expn_id, expn_info) = span_data.ctxt.outer_expn_with_info(); - if let Some(pos) = self.expn_info_shorthands.get(&expn_id).cloned() { - TAG_EXPANSION_INFO_SHORTHAND.encode(self)?; + let (expn_id, expn_data) = span_data.ctxt.outer_expn_with_data(); + if let Some(pos) = self.expn_data_shorthands.get(&expn_id).cloned() { + TAG_EXPN_DATA_SHORTHAND.encode(self)?; pos.encode(self) } else { - TAG_EXPANSION_INFO_INLINE.encode(self)?; + TAG_EXPN_DATA_INLINE.encode(self)?; let pos = AbsoluteBytePos::new(self.position()); - self.expn_info_shorthands.insert(expn_id, pos); - expn_info.encode(self) + self.expn_data_shorthands.insert(expn_id, pos); + expn_data.encode(self) } } } diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 240264a98220..eec098426239 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -1775,7 +1775,7 @@ impl SharedEmitterMain { } } Ok(SharedEmitterMessage::InlineAsmError(cookie, msg)) => { - sess.span_err(ExpnId::from_u32(cookie).expn_info().call_site, &msg) + sess.span_err(ExpnId::from_u32(cookie).expn_data().call_site, &msg) } Ok(SharedEmitterMessage::AbortIfErrors) => { sess.abort_if_errors(); diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 1bb05bda69f5..90e467713968 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -517,7 +517,7 @@ impl EarlyLintPass for UnusedParens { // trigger in situations that macro authors shouldn't have to care about, e.g., // when a parenthesized token tree matched in one macro expansion is matched as // an expression in another and used as a fn/method argument (Issue #47775) - if e.span.ctxt().outer_expn_info().call_site.from_expansion() { + if e.span.ctxt().outer_expn_data().call_site.from_expansion() { return; } let msg = format!("{} argument", call_kind); diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 58e785ab8c25..2ca8771cda6a 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -17,7 +17,7 @@ use syntax::edition::Edition; use syntax::ext::base::{self, Indeterminate, SpecialDerives}; use syntax::ext::base::{MacroKind, SyntaxExtension}; use syntax::ext::expand::{AstFragment, Invocation, InvocationKind}; -use syntax::ext::hygiene::{self, ExpnId, ExpnInfo, ExpnKind}; +use syntax::ext::hygiene::{self, ExpnId, ExpnData, ExpnKind}; use syntax::ext::tt::macro_rules; use syntax::feature_gate::{emit_feature_err, is_builtin_attr_name}; use syntax::feature_gate::GateIssue; @@ -97,7 +97,7 @@ impl<'a> base::Resolver for Resolver<'a> { } fn get_module_scope(&mut self, id: ast::NodeId) -> ExpnId { - let expn_id = ExpnId::fresh(Some(ExpnInfo::default( + let expn_id = ExpnId::fresh(Some(ExpnData::default( ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, self.session.edition() ))); let module = self.module_map[&self.definitions.local_def_id(id)]; @@ -185,8 +185,8 @@ impl<'a> base::Resolver for Resolver<'a> { let (ext, res) = self.smart_resolve_macro_path(path, kind, parent_scope, force)?; let span = invoc.span(); - invoc.expansion_data.id.set_expn_info( - ext.expn_info(parent_scope.expansion, span, fast_print_path(path)) + invoc.expansion_data.id.set_expn_data( + ext.expn_data(parent_scope.expansion, span, fast_print_path(path)) ); if let Res::Def(_, def_id) = res { @@ -302,7 +302,7 @@ impl<'a> Resolver<'a> { // Possibly apply the macro helper hack if kind == Some(MacroKind::Bang) && path.len() == 1 && - path[0].ident.span.ctxt().outer_expn_info().local_inner_macros { + path[0].ident.span.ctxt().outer_expn_data().local_inner_macros { let root = Ident::new(kw::DollarCrate, path[0].ident.span); path.insert(0, Segment::from_ident(root)); } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 734b566b3ad1..fb1bf4d7160e 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -15,7 +15,7 @@ use crate::tokenstream::{self, TokenStream, TokenTree}; use errors::{DiagnosticBuilder, DiagnosticId}; use smallvec::{smallvec, SmallVec}; use syntax_pos::{FileName, Span, MultiSpan, DUMMY_SP}; -use syntax_pos::hygiene::{ExpnInfo, ExpnKind}; +use syntax_pos::hygiene::{ExpnData, ExpnKind}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{self, Lrc}; @@ -640,8 +640,8 @@ impl SyntaxExtension { SyntaxExtension::default(SyntaxExtensionKind::NonMacroAttr { mark_used }, edition) } - pub fn expn_info(&self, parent: ExpnId, call_site: Span, descr: Symbol) -> ExpnInfo { - ExpnInfo { + pub fn expn_data(&self, parent: ExpnId, call_site: Span, descr: Symbol) -> ExpnData { + ExpnData { kind: ExpnKind::Macro(self.macro_kind(), descr), parent, call_site, @@ -708,7 +708,7 @@ pub struct ExpansionData { /// One of these is made during expansion and incrementally updated as we go; /// when a macro expansion occurs, the resulting nodes have the `backtrace() -/// -> expn_info` of their expansion context stored into their span. +/// -> expn_data` of their expansion context stored into their span. pub struct ExtCtxt<'a> { pub parse_sess: &'a parse::ParseSess, pub ecfg: expand::ExpansionConfig<'a>, @@ -757,7 +757,7 @@ impl<'a> ExtCtxt<'a> { pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess } pub fn cfg(&self) -> &ast::CrateConfig { &self.parse_sess.config } pub fn call_site(&self) -> Span { - self.current_expansion.id.expn_info().call_site + self.current_expansion.id.expn_data().call_site } pub fn backtrace(&self) -> SyntaxContext { SyntaxContext::root().apply_mark(self.current_expansion.id) @@ -770,13 +770,13 @@ impl<'a> ExtCtxt<'a> { let mut ctxt = self.backtrace(); let mut last_macro = None; loop { - let expn_info = ctxt.outer_expn_info(); + let expn_data = ctxt.outer_expn_data(); // Stop going up the backtrace once include! is encountered - if expn_info.is_root() || expn_info.kind.descr() == sym::include { + if expn_data.is_root() || expn_data.kind.descr() == sym::include { break; } - ctxt = expn_info.call_site.ctxt(); - last_macro = Some(expn_info.call_site); + ctxt = expn_data.call_site.ctxt(); + last_macro = Some(expn_data.call_site); } last_macro } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 4233d5c0a222..e7deadbc9a04 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -5,7 +5,7 @@ use crate::source_map::respan; use crate::config::StripUnconfigured; use crate::ext::base::*; use crate::ext::proc_macro::collect_derives; -use crate::ext::hygiene::{ExpnId, SyntaxContext, ExpnInfo, ExpnKind}; +use crate::ext::hygiene::{ExpnId, SyntaxContext, ExpnData, ExpnKind}; use crate::ext::tt::macro_rules::annotate_err_with_kind; use crate::ext::placeholders::{placeholder, PlaceholderExpander}; use crate::feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err}; @@ -475,11 +475,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } if self.cx.current_expansion.depth > self.cx.ecfg.recursion_limit { - let info = self.cx.current_expansion.id.expn_info(); + let expn_data = self.cx.current_expansion.id.expn_data(); let suggested_limit = self.cx.ecfg.recursion_limit * 2; - let mut err = self.cx.struct_span_err(info.call_site, + let mut err = self.cx.struct_span_err(expn_data.call_site, &format!("recursion limit reached while expanding the macro `{}`", - info.kind.descr())); + expn_data.kind.descr())); err.help(&format!( "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate", suggested_limit)); @@ -796,20 +796,20 @@ struct InvocationCollector<'a, 'b> { impl<'a, 'b> InvocationCollector<'a, 'b> { fn collect(&mut self, fragment_kind: AstFragmentKind, kind: InvocationKind) -> AstFragment { - // Expansion info for all the collected invocations is set upon their resolution, + // Expansion data for all the collected invocations is set upon their resolution, // with exception of the derive container case which is not resolved and can get - // its expansion info immediately. - let expn_info = match &kind { - InvocationKind::DeriveContainer { item, .. } => Some(ExpnInfo { + // its expansion data immediately. + let expn_data = match &kind { + InvocationKind::DeriveContainer { item, .. } => Some(ExpnData { parent: self.cx.current_expansion.id, - ..ExpnInfo::default( + ..ExpnData::default( ExpnKind::Macro(MacroKind::Attr, sym::derive), item.span(), self.cx.parse_sess.edition, ) }), _ => None, }; - let expn_id = ExpnId::fresh(expn_info); + let expn_id = ExpnId::fresh(expn_data); self.invocations.push(Invocation { kind, fragment_kind, diff --git a/src/libsyntax/ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs index d370431a5dae..1619fa699419 100644 --- a/src/libsyntax/ext/proc_macro_server.rs +++ b/src/libsyntax/ext/proc_macro_server.rs @@ -362,7 +362,7 @@ pub(crate) struct Rustc<'a> { impl<'a> Rustc<'a> { pub fn new(cx: &'a ExtCtxt<'_>) -> Self { // No way to determine def location for a proc macro right now, so use call location. - let location = cx.current_expansion.id.expn_info().call_site; + let location = cx.current_expansion.id.expn_data().call_site; let to_span = |transparency| { location.with_ctxt( SyntaxContext::root() diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index a1bcc455eb4c..26f78b9c5c78 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -87,7 +87,7 @@ impl ParseSess { included_mod_stack: Lock::new(vec![]), source_map, buffered_lints: Lock::new(vec![]), - edition: ExpnId::root().expn_info().edition, + edition: ExpnId::root().expn_data().edition, ambiguous_block_expr_parse: Lock::new(FxHashMap::default()), param_attr_spans: Lock::new(Vec::new()), let_chains_spans: Lock::new(Vec::new()), diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs index da7eb6add41a..940687cb5d4e 100644 --- a/src/libsyntax/source_map.rs +++ b/src/libsyntax/source_map.rs @@ -8,7 +8,7 @@ //! information, source code snippets, etc. pub use syntax_pos::*; -pub use syntax_pos::hygiene::{ExpnKind, ExpnInfo}; +pub use syntax_pos::hygiene::{ExpnKind, ExpnData}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::StableHasher; @@ -29,15 +29,15 @@ mod tests; /// Returns the span itself if it doesn't come from a macro expansion, /// otherwise return the call site span up to the `enclosing_sp` by -/// following the `expn_info` chain. +/// following the `expn_data` chain. pub fn original_sp(sp: Span, enclosing_sp: Span) -> Span { - let expn_info1 = sp.ctxt().outer_expn_info(); - let expn_info2 = enclosing_sp.ctxt().outer_expn_info(); - if expn_info1.is_root() || - !expn_info2.is_root() && expn_info1.call_site == expn_info2.call_site { + let expn_data1 = sp.ctxt().outer_expn_data(); + let expn_data2 = enclosing_sp.ctxt().outer_expn_data(); + if expn_data1.is_root() || + !expn_data2.is_root() && expn_data1.call_site == expn_data2.call_site { sp } else { - original_sp(expn_info1.call_site, enclosing_sp) + original_sp(expn_data1.call_site, enclosing_sp) } } diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs index 73df625d5ee6..d030ea4a56eb 100644 --- a/src/libsyntax_ext/deriving/clone.rs +++ b/src/libsyntax_ext/deriving/clone.rs @@ -35,7 +35,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>, match annitem.node { ItemKind::Struct(_, Generics { ref params, .. }) | ItemKind::Enum(_, Generics { ref params, .. }) => { - let container_id = cx.current_expansion.id.expn_info().parent; + let container_id = cx.current_expansion.id.expn_data().parent; if cx.resolver.has_derives(container_id, SpecialDerives::COPY) && !params.iter().any(|param| match param.kind { ast::GenericParamKind::Type { .. } => true, diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs index 1ef34a680041..54027c600b4c 100644 --- a/src/libsyntax_ext/deriving/cmp/eq.rs +++ b/src/libsyntax_ext/deriving/cmp/eq.rs @@ -13,7 +13,7 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt<'_>, mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable)) { - cx.resolver.add_derives(cx.current_expansion.id.expn_info().parent, SpecialDerives::EQ); + cx.resolver.add_derives(cx.current_expansion.id.expn_data().parent, SpecialDerives::EQ); let inline = cx.meta_word(span, sym::inline); let hidden = cx.meta_list_item_word(span, sym::hidden); diff --git a/src/libsyntax_ext/deriving/cmp/partial_eq.rs b/src/libsyntax_ext/deriving/cmp/partial_eq.rs index 76befc98591e..91e1e80e4fbf 100644 --- a/src/libsyntax_ext/deriving/cmp/partial_eq.rs +++ b/src/libsyntax_ext/deriving/cmp/partial_eq.rs @@ -13,7 +13,7 @@ pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt<'_>, mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable)) { - cx.resolver.add_derives(cx.current_expansion.id.expn_info().parent, SpecialDerives::PARTIAL_EQ); + cx.resolver.add_derives(cx.current_expansion.id.expn_data().parent, SpecialDerives::PARTIAL_EQ); // structures are equal if all fields are equal, and non equal, if // any fields are not equal or if the enum variants are different diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 6b739e27eee8..55fb7677038b 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -425,7 +425,7 @@ impl<'a> TraitDef<'a> { return; } }; - let container_id = cx.current_expansion.id.expn_info().parent; + let container_id = cx.current_expansion.id.expn_data().parent; let is_always_copy = cx.resolver.has_derives(container_id, SpecialDerives::COPY) && has_no_type_params; diff --git a/src/libsyntax_ext/plugin_macro_defs.rs b/src/libsyntax_ext/plugin_macro_defs.rs index b34a250881a3..dbfd8fe98f38 100644 --- a/src/libsyntax_ext/plugin_macro_defs.rs +++ b/src/libsyntax_ext/plugin_macro_defs.rs @@ -11,7 +11,7 @@ use syntax::source_map::respan; use syntax::symbol::sym; use syntax::tokenstream::*; use syntax_pos::{Span, DUMMY_SP}; -use syntax_pos::hygiene::{ExpnInfo, ExpnKind, MacroKind}; +use syntax_pos::hygiene::{ExpnData, ExpnKind, MacroKind}; use std::mem; @@ -43,7 +43,7 @@ pub fn inject( ) { if !named_exts.is_empty() { let mut extra_items = Vec::new(); - let span = DUMMY_SP.fresh_expansion(ExpnInfo::allow_unstable( + let span = DUMMY_SP.fresh_expansion(ExpnData::allow_unstable( ExpnKind::Macro(MacroKind::Attr, sym::plugin), DUMMY_SP, edition, [sym::rustc_attrs][..].into(), )); diff --git a/src/libsyntax_ext/proc_macro_harness.rs b/src/libsyntax_ext/proc_macro_harness.rs index 9d8a8c17ba2d..e772eaf83496 100644 --- a/src/libsyntax_ext/proc_macro_harness.rs +++ b/src/libsyntax_ext/proc_macro_harness.rs @@ -3,7 +3,7 @@ use std::mem; use smallvec::smallvec; use syntax::ast::{self, Ident}; use syntax::attr; -use syntax::source_map::{ExpnInfo, ExpnKind, respan}; +use syntax::source_map::{ExpnData, ExpnKind, respan}; use syntax::ext::base::{ExtCtxt, MacroKind}; use syntax::ext::expand::{AstFragment, ExpansionConfig}; use syntax::ext::proc_macro::is_proc_macro_attr; @@ -327,7 +327,7 @@ fn mk_decls( custom_attrs: &[ProcMacroDef], custom_macros: &[ProcMacroDef], ) -> P { - let span = DUMMY_SP.fresh_expansion(ExpnInfo::allow_unstable( + let span = DUMMY_SP.fresh_expansion(ExpnData::allow_unstable( ExpnKind::Macro(MacroKind::Attr, sym::proc_macro), DUMMY_SP, cx.parse_sess.edition, [sym::rustc_attrs, sym::proc_macro_internals][..].into(), )); diff --git a/src/libsyntax_ext/standard_library_imports.rs b/src/libsyntax_ext/standard_library_imports.rs index c00412486522..8ca376341fcd 100644 --- a/src/libsyntax_ext/standard_library_imports.rs +++ b/src/libsyntax_ext/standard_library_imports.rs @@ -2,7 +2,7 @@ use syntax::{ast, attr}; use syntax::edition::Edition; use syntax::ext::hygiene::MacroKind; use syntax::ptr::P; -use syntax::source_map::{ExpnInfo, ExpnKind, dummy_spanned, respan}; +use syntax::source_map::{ExpnData, ExpnKind, dummy_spanned, respan}; use syntax::symbol::{Ident, Symbol, kw, sym}; use syntax_pos::DUMMY_SP; @@ -55,7 +55,7 @@ pub fn inject( // the prelude. let name = names[0]; - let span = DUMMY_SP.fresh_expansion(ExpnInfo::allow_unstable( + let span = DUMMY_SP.fresh_expansion(ExpnData::allow_unstable( ExpnKind::Macro(MacroKind::Attr, sym::std_inject), DUMMY_SP, edition, [sym::prelude_import][..].into(), )); diff --git a/src/libsyntax_ext/test_harness.rs b/src/libsyntax_ext/test_harness.rs index 3fb1c1bd0224..4a6ea0ebf85e 100644 --- a/src/libsyntax_ext/test_harness.rs +++ b/src/libsyntax_ext/test_harness.rs @@ -11,7 +11,7 @@ use syntax::feature_gate::Features; use syntax::mut_visit::{*, ExpectOne}; use syntax::parse::ParseSess; use syntax::ptr::P; -use syntax::source_map::{ExpnInfo, ExpnKind, dummy_spanned}; +use syntax::source_map::{ExpnData, ExpnKind, dummy_spanned}; use syntax::symbol::{kw, sym, Symbol}; use syntax_pos::{Span, DUMMY_SP}; @@ -268,7 +268,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P { // #![main] // test::test_main_static(&[..tests]); // } - let sp = DUMMY_SP.fresh_expansion(ExpnInfo::allow_unstable( + let sp = DUMMY_SP.fresh_expansion(ExpnData::allow_unstable( ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, cx.ext_cx.parse_sess.edition, [sym::main, sym::test, sym::rustc_attrs][..].into(), )); diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index 4d9496f94fbd..87d930f897af 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -13,8 +13,8 @@ // // This explains why `HygieneData`, `SyntaxContext` and `ExpnId` have interfaces // with a certain amount of redundancy in them. For example, -// `SyntaxContext::outer_expn_info` combines `SyntaxContext::outer` and -// `ExpnId::expn_info` so that two `HygieneData` accesses can be performed within +// `SyntaxContext::outer_expn_data` combines `SyntaxContext::outer` and +// `ExpnId::expn_data` so that two `HygieneData` accesses can be performed within // a single `HygieneData::with` call. // // It also explains why many functions appear in `HygieneData` and again in @@ -76,8 +76,8 @@ pub enum Transparency { } impl ExpnId { - pub fn fresh(expn_info: Option) -> Self { - HygieneData::with(|data| data.fresh_expn(expn_info)) + pub fn fresh(expn_data: Option) -> Self { + HygieneData::with(|data| data.fresh_expn(expn_data)) } /// The ID of the theoretical expansion that generates freshly parsed, unexpanded AST. @@ -97,16 +97,16 @@ impl ExpnId { } #[inline] - pub fn expn_info(self) -> ExpnInfo { - HygieneData::with(|data| data.expn_info(self).clone()) + pub fn expn_data(self) -> ExpnData { + HygieneData::with(|data| data.expn_data(self).clone()) } #[inline] - pub fn set_expn_info(self, info: ExpnInfo) { + pub fn set_expn_data(self, expn_data: ExpnData) { HygieneData::with(|data| { - let old_info = &mut data.expn_data[self.0 as usize]; - assert!(old_info.is_none(), "expansion info is reset for an expansion ID"); - *old_info = Some(info); + let old_expn_data = &mut data.expn_data[self.0 as usize]; + assert!(old_expn_data.is_none(), "expansion data is reset for an expansion ID"); + *old_expn_data = Some(expn_data); }) } @@ -124,9 +124,9 @@ impl ExpnId { #[inline] pub fn looks_like_proc_macro_derive(self) -> bool { HygieneData::with(|data| { - let expn_info = data.expn_info(self); - if let ExpnKind::Macro(MacroKind::Derive, _) = expn_info.kind { - return expn_info.default_transparency == Transparency::Opaque; + let expn_data = data.expn_data(self); + if let ExpnKind::Macro(MacroKind::Derive, _) = expn_data.kind { + return expn_data.default_transparency == Transparency::Opaque; } false }) @@ -135,10 +135,10 @@ impl ExpnId { #[derive(Debug)] crate struct HygieneData { - /// Each expansion should have an associated expansion info, but sometimes there's a delay - /// between creation of an expansion ID and obtaining its info (e.g. macros are collected + /// Each expansion should have an associated expansion data, but sometimes there's a delay + /// between creation of an expansion ID and obtaining its data (e.g. macros are collected /// first and then resolved later), so we use an `Option` here. - expn_data: Vec>, + expn_data: Vec>, syntax_context_data: Vec, syntax_context_map: FxHashMap<(SyntaxContext, ExpnId, Transparency), SyntaxContext>, } @@ -146,7 +146,7 @@ crate struct HygieneData { impl HygieneData { crate fn new(edition: Edition) -> Self { HygieneData { - expn_data: vec![Some(ExpnInfo::default(ExpnKind::Root, DUMMY_SP, edition))], + expn_data: vec![Some(ExpnData::default(ExpnKind::Root, DUMMY_SP, edition))], syntax_context_data: vec![SyntaxContextData { outer_expn: ExpnId::root(), outer_transparency: Transparency::Opaque, @@ -163,14 +163,14 @@ impl HygieneData { GLOBALS.with(|globals| f(&mut *globals.hygiene_data.borrow_mut())) } - fn fresh_expn(&mut self, expn_info: Option) -> ExpnId { - self.expn_data.push(expn_info); + fn fresh_expn(&mut self, expn_data: Option) -> ExpnId { + self.expn_data.push(expn_data); ExpnId(self.expn_data.len() as u32 - 1) } - fn expn_info(&self, expn_id: ExpnId) -> &ExpnInfo { + fn expn_data(&self, expn_id: ExpnId) -> &ExpnData { self.expn_data[expn_id.0 as usize].as_ref() - .expect("no expansion info for an expansion ID") + .expect("no expansion data for an expansion ID") } fn is_descendant_of(&self, mut expn_id: ExpnId, ancestor: ExpnId) -> bool { @@ -178,7 +178,7 @@ impl HygieneData { if expn_id == ExpnId::root() { return false; } - expn_id = self.expn_info(expn_id).parent; + expn_id = self.expn_data(expn_id).parent; } true } @@ -221,7 +221,7 @@ impl HygieneData { fn walk_chain(&self, mut span: Span, to: SyntaxContext) -> Span { while span.from_expansion() && span.ctxt() != to { - span = self.expn_info(self.outer_expn(span.ctxt())).call_site; + span = self.expn_data(self.outer_expn(span.ctxt())).call_site; } span } @@ -237,7 +237,7 @@ impl HygieneData { fn apply_mark(&mut self, ctxt: SyntaxContext, expn_id: ExpnId) -> SyntaxContext { assert_ne!(expn_id, ExpnId::root()); self.apply_mark_with_transparency( - ctxt, expn_id, self.expn_info(expn_id).default_transparency + ctxt, expn_id, self.expn_data(expn_id).default_transparency ) } @@ -248,7 +248,7 @@ impl HygieneData { return self.apply_mark_internal(ctxt, expn_id, transparency); } - let call_site_ctxt = self.expn_info(expn_id).call_site.ctxt(); + let call_site_ctxt = self.expn_data(expn_id).call_site.ctxt(); let mut call_site_ctxt = if transparency == Transparency::SemiTransparent { self.modern(call_site_ctxt) } else { @@ -540,20 +540,20 @@ impl SyntaxContext { HygieneData::with(|data| data.outer_expn(self)) } - /// `ctxt.outer_expn_info()` is equivalent to but faster than - /// `ctxt.outer_expn().expn_info()`. + /// `ctxt.outer_expn_data()` is equivalent to but faster than + /// `ctxt.outer_expn().expn_data()`. #[inline] - pub fn outer_expn_info(self) -> ExpnInfo { - HygieneData::with(|data| data.expn_info(data.outer_expn(self)).clone()) + pub fn outer_expn_data(self) -> ExpnData { + HygieneData::with(|data| data.expn_data(data.outer_expn(self)).clone()) } - /// `ctxt.outer_expn_with_info()` is equivalent to but faster than - /// `{ let outer = ctxt.outer_expn(); (outer, outer.expn_info()) }`. + /// `ctxt.outer_expn_with_data()` is equivalent to but faster than + /// `{ let outer = ctxt.outer_expn(); (outer, outer.expn_data()) }`. #[inline] - pub fn outer_expn_with_info(self) -> (ExpnId, ExpnInfo) { + pub fn outer_expn_with_data(self) -> (ExpnId, ExpnData) { HygieneData::with(|data| { let outer = data.outer_expn(self); - (outer, data.expn_info(outer).clone()) + (outer, data.expn_data(outer).clone()) }) } @@ -574,9 +574,9 @@ impl Span { /// other compiler-generated code to set per-span properties like allowed unstable features. /// The returned span belongs to the created expansion and has the new properties, /// but its location is inherited from the current span. - pub fn fresh_expansion(self, expn_info: ExpnInfo) -> Span { + pub fn fresh_expansion(self, expn_data: ExpnData) -> Span { HygieneData::with(|data| { - let expn_id = data.fresh_expn(Some(expn_info)); + let expn_id = data.fresh_expn(Some(expn_data)); self.with_ctxt(data.apply_mark(SyntaxContext::root(), expn_id)) }) } @@ -585,7 +585,7 @@ impl Span { /// A subset of properties from both macro definition and macro call available through global data. /// Avoid using this if you have access to the original definition or call structures. #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] -pub struct ExpnInfo { +pub struct ExpnData { // --- The part unique to each expansion. /// The kind of this expansion - macro or compiler desugaring. pub kind: ExpnKind, @@ -598,7 +598,7 @@ pub struct ExpnInfo { /// `foo!()` invoked `bar!()` internally, and there was an /// expression inside `bar!`; the call_site of the expression in /// the expansion would point to the `bar!` invocation; that - /// call_site span would have its own ExpnInfo, with the call_site + /// call_site span would have its own ExpnData, with the call_site /// pointing to the `foo!` invocation. pub call_site: Span, @@ -609,7 +609,7 @@ pub struct ExpnInfo { /// The span of the macro definition (possibly dummy). /// This span serves only informational purpose and is not used for resolution. pub def_site: Span, - /// Transparency used by `apply_mark` for the expansion with this expansion info by default. + /// Transparency used by `apply_mark` for the expansion with this expansion data by default. pub default_transparency: Transparency, /// List of #[unstable]/feature-gated features that the macro is allowed to use /// internally without forcing the whole crate to opt-in @@ -625,10 +625,10 @@ pub struct ExpnInfo { pub edition: Edition, } -impl ExpnInfo { - /// Constructs an expansion info with default properties. - pub fn default(kind: ExpnKind, call_site: Span, edition: Edition) -> ExpnInfo { - ExpnInfo { +impl ExpnData { + /// Constructs expansion data with default properties. + pub fn default(kind: ExpnKind, call_site: Span, edition: Edition) -> ExpnData { + ExpnData { kind, parent: ExpnId::root(), call_site, @@ -642,10 +642,10 @@ impl ExpnInfo { } pub fn allow_unstable(kind: ExpnKind, call_site: Span, edition: Edition, - allow_internal_unstable: Lrc<[Symbol]>) -> ExpnInfo { - ExpnInfo { + allow_internal_unstable: Lrc<[Symbol]>) -> ExpnData { + ExpnData { allow_internal_unstable: Some(allow_internal_unstable), - ..ExpnInfo::default(kind, call_site, edition) + ..ExpnData::default(kind, call_site, edition) } } diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index ae538677a3aa..aa36fe27d8ec 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -21,7 +21,7 @@ use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; pub mod edition; use edition::Edition; pub mod hygiene; -pub use hygiene::{ExpnId, SyntaxContext, ExpnInfo, ExpnKind, MacroKind, DesugaringKind}; +pub use hygiene::{ExpnId, SyntaxContext, ExpnData, ExpnKind, MacroKind, DesugaringKind}; mod span_encoding; pub use span_encoding::{Span, DUMMY_SP}; @@ -353,20 +353,20 @@ impl Span { /// Returns the source span -- this is either the supplied span, or the span for /// the macro callsite that expanded to it. pub fn source_callsite(self) -> Span { - let expn_info = self.ctxt().outer_expn_info(); - if !expn_info.is_root() { expn_info.call_site.source_callsite() } else { self } + let expn_data = self.ctxt().outer_expn_data(); + if !expn_data.is_root() { expn_data.call_site.source_callsite() } else { self } } /// The `Span` for the tokens in the previous macro expansion from which `self` was generated, /// if any. pub fn parent(self) -> Option { - let expn_info = self.ctxt().outer_expn_info(); - if !expn_info.is_root() { Some(expn_info.call_site) } else { None } + let expn_data = self.ctxt().outer_expn_data(); + if !expn_data.is_root() { Some(expn_data.call_site) } else { None } } /// Edition of the crate from which this span came. pub fn edition(self) -> edition::Edition { - self.ctxt().outer_expn_info().edition + self.ctxt().outer_expn_data().edition } #[inline] @@ -382,22 +382,22 @@ impl Span { /// Returns the source callee. /// /// Returns `None` if the supplied span has no expansion trace, - /// else returns the `ExpnInfo` for the macro definition + /// else returns the `ExpnData` for the macro definition /// corresponding to the source callsite. - pub fn source_callee(self) -> Option { - fn source_callee(expn_info: ExpnInfo) -> ExpnInfo { - let next_expn_info = expn_info.call_site.ctxt().outer_expn_info(); - if !next_expn_info.is_root() { source_callee(next_expn_info) } else { expn_info } + pub fn source_callee(self) -> Option { + fn source_callee(expn_data: ExpnData) -> ExpnData { + let next_expn_data = expn_data.call_site.ctxt().outer_expn_data(); + if !next_expn_data.is_root() { source_callee(next_expn_data) } else { expn_data } } - let expn_info = self.ctxt().outer_expn_info(); - if !expn_info.is_root() { Some(source_callee(expn_info)) } else { None } + let expn_data = self.ctxt().outer_expn_data(); + if !expn_data.is_root() { Some(source_callee(expn_data)) } else { None } } /// Checks if a span is "internal" to a macro in which `#[unstable]` /// items can be used (that is, a macro marked with /// `#[allow_internal_unstable]`). pub fn allows_unstable(&self, feature: Symbol) -> bool { - self.ctxt().outer_expn_info().allow_internal_unstable.map_or(false, |features| { + self.ctxt().outer_expn_data().allow_internal_unstable.map_or(false, |features| { features.iter().any(|&f| { f == feature || f == sym::allow_internal_unstable_backcompat_hack }) @@ -406,7 +406,7 @@ impl Span { /// Checks if this span arises from a compiler desugaring of kind `kind`. pub fn is_desugaring(&self, kind: DesugaringKind) -> bool { - match self.ctxt().outer_expn_info().kind { + match self.ctxt().outer_expn_data().kind { ExpnKind::Desugaring(k) => k == kind, _ => false, } @@ -415,7 +415,7 @@ impl Span { /// Returns the compiler desugaring that created this span, or `None` /// if this span is not from a desugaring. pub fn desugaring_kind(&self) -> Option { - match self.ctxt().outer_expn_info().kind { + match self.ctxt().outer_expn_data().kind { ExpnKind::Desugaring(k) => Some(k), _ => None } @@ -425,20 +425,20 @@ impl Span { /// can be used without triggering the `unsafe_code` lint // (that is, a macro marked with `#[allow_internal_unsafe]`). pub fn allows_unsafe(&self) -> bool { - self.ctxt().outer_expn_info().allow_internal_unsafe + self.ctxt().outer_expn_data().allow_internal_unsafe } pub fn macro_backtrace(mut self) -> Vec { let mut prev_span = DUMMY_SP; let mut result = vec![]; loop { - let info = self.ctxt().outer_expn_info(); - if info.is_root() { + let expn_data = self.ctxt().outer_expn_data(); + if expn_data.is_root() { break; } // Don't print recursive invocations. - if !info.call_site.source_equal(&prev_span) { - let (pre, post) = match info.kind { + if !expn_data.call_site.source_equal(&prev_span) { + let (pre, post) = match expn_data.kind { ExpnKind::Root => break, ExpnKind::Desugaring(..) => ("desugaring of ", ""), ExpnKind::Macro(macro_kind, _) => match macro_kind { @@ -448,14 +448,14 @@ impl Span { } }; result.push(MacroBacktrace { - call_site: info.call_site, - macro_decl_name: format!("{}{}{}", pre, info.kind.descr(), post), - def_site_span: info.def_site, + call_site: expn_data.call_site, + macro_decl_name: format!("{}{}{}", pre, expn_data.kind.descr(), post), + def_site_span: expn_data.def_site, }); } prev_span = self; - self = info.call_site; + self = expn_data.call_site; } result } From c76277340e3e5e8d6aca9c926c45cac3484eb5f8 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 15 Aug 2019 20:47:15 +0300 Subject: [PATCH 33/35] resolve: `ParentScope::default` -> `ParentScope::module` --- src/librustc_resolve/build_reduced_graph.rs | 2 +- src/librustc_resolve/late.rs | 2 +- src/librustc_resolve/lib.rs | 10 ++++++---- src/librustc_resolve/macros.rs | 2 +- src/librustdoc/passes/collect_intra_doc_links.rs | 2 +- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index c42a933a954a..539e4a301e01 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -166,7 +166,7 @@ impl<'a> Resolver<'a> { let def_id = module.def_id().unwrap(); for child in self.cstore.item_children_untracked(def_id, self.session) { let child = child.map_id(|_| panic!("unexpected id")); - BuildReducedGraphVisitor { parent_scope: ParentScope::default(module), r: self } + BuildReducedGraphVisitor { parent_scope: ParentScope::module(module), r: self } .build_reduced_graph_for_external_crate_res(child); } module.populated.set(true) diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index d97ee61d839a..ffdfd85002bc 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -509,7 +509,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { // During late resolution we only track the module component of the parent scope, // although it may be useful to track other components as well for diagnostics. let graph_root = resolver.graph_root; - let parent_scope = ParentScope::default(graph_root); + let parent_scope = ParentScope::module(graph_root); LateResolutionVisitor { r: resolver, parent_scope, diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 2b55f9dc79d0..9b5eb51eb582 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -140,7 +140,9 @@ pub struct ParentScope<'a> { } impl<'a> ParentScope<'a> { - pub fn default(module: Module<'a>) -> ParentScope<'a> { + /// Creates a parent scope with the passed argument used as the module scope component, + /// and other scope components set to default empty values. + pub fn module(module: Module<'a>) -> ParentScope<'a> { ParentScope { module, expansion: ExpnId::root(), @@ -1017,7 +1019,7 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> { segments, }; - let parent_scope = &ParentScope::default(self.graph_root); + let parent_scope = &ParentScope::module(self.graph_root); let res = match self.resolve_ast_path(&path, ns, parent_scope) { Ok(res) => res, Err((span, error)) => { @@ -1090,7 +1092,7 @@ impl<'a> Resolver<'a> { } let mut invocation_parent_scopes = FxHashMap::default(); - invocation_parent_scopes.insert(ExpnId::root(), ParentScope::default(graph_root)); + invocation_parent_scopes.insert(ExpnId::root(), ParentScope::module(graph_root)); let mut macro_defs = FxHashMap::default(); macro_defs.insert(ExpnId::root(), root_def_id); @@ -2671,7 +2673,7 @@ impl<'a> Resolver<'a> { let def_id = self.definitions.local_def_id(module_id); self.module_map.get(&def_id).copied().unwrap_or(self.graph_root) }); - let parent_scope = &ParentScope::default(module); + let parent_scope = &ParentScope::module(module); let res = self.resolve_ast_path(&path, ns, parent_scope).map_err(|_| ())?; Ok((path, res)) } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 2ca8771cda6a..079145e816cd 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -101,7 +101,7 @@ impl<'a> base::Resolver for Resolver<'a> { ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, self.session.edition() ))); let module = self.module_map[&self.definitions.local_def_id(id)]; - self.invocation_parent_scopes.insert(expn_id, ParentScope::default(module)); + self.invocation_parent_scopes.insert(expn_id, ParentScope::module(module)); self.definitions.set_invocation_parent(expn_id, module.def_id().unwrap().index); expn_id } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 5767b5b3b46a..c73c46472d80 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -432,7 +432,7 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option { let path = ast::Path::from_ident(Ident::from_str(path_str)); cx.enter_resolver(|resolver| { if let Ok((Some(ext), res)) = resolver.resolve_macro_path( - &path, None, &ParentScope::default(resolver.graph_root), false, false + &path, None, &ParentScope::module(resolver.graph_root), false, false ) { if let SyntaxExtensionKind::LegacyBang { .. } = ext.kind { return Some(res.map_id(|_| panic!("unexpected id"))); From fbf1efb949b9d76b4964b7b6a7a606de116ecb46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 15 Aug 2019 11:46:52 -0700 Subject: [PATCH 34/35] Do not suggest `try_into` for base types inside of macro expansions --- src/librustc_typeck/check/demand.rs | 4 ++++ .../ui/suggestions/dont-suggest-try_into-in-macros.rs | 3 +++ .../dont-suggest-try_into-in-macros.stderr | 11 +++++++++++ 3 files changed, 18 insertions(+) create mode 100644 src/test/ui/suggestions/dont-suggest-try_into-in-macros.rs create mode 100644 src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index ed25601208ad..f3b56b31b775 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -554,6 +554,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // FIXME(estebank): modify once we decide to suggest `as` casts return false; } + if !self.tcx.sess.source_map().span_to_filename(expr.span).is_real() { + // Ignore if span is from within a macro. + return false; + } // If casting this expression to a given numeric type would be appropriate in case of a type // mismatch. diff --git a/src/test/ui/suggestions/dont-suggest-try_into-in-macros.rs b/src/test/ui/suggestions/dont-suggest-try_into-in-macros.rs new file mode 100644 index 000000000000..d625199c937c --- /dev/null +++ b/src/test/ui/suggestions/dont-suggest-try_into-in-macros.rs @@ -0,0 +1,3 @@ +fn main() { + assert_eq!(10u64, 10usize); //~ ERROR mismatched types +} diff --git a/src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr b/src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr new file mode 100644 index 000000000000..f04306997a9e --- /dev/null +++ b/src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> $DIR/dont-suggest-try_into-in-macros.rs:2:5 + | +LL | assert_eq!(10u64, 10usize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected u64, found usize + | + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From e046a7af49d37b0179078c83387925f8abc2555f Mon Sep 17 00:00:00 2001 From: Jens Hausdorf Date: Thu, 15 Aug 2019 22:16:59 +0200 Subject: [PATCH 35/35] Fix typo in DoubleEndedIterator::nth_back doc --- src/libcore/iter/traits/double_ended.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/iter/traits/double_ended.rs b/src/libcore/iter/traits/double_ended.rs index 8e5bc9b664cf..006b243ca42a 100644 --- a/src/libcore/iter/traits/double_ended.rs +++ b/src/libcore/iter/traits/double_ended.rs @@ -69,7 +69,7 @@ pub trait DoubleEndedIterator: Iterator { /// Returns the `n`th element from the end of the iterator. /// /// This is essentially the reversed version of [`nth`]. Although like most indexing - /// operations, the count starts from zero, so `nth_back(0)` returns the first value fro + /// operations, the count starts from zero, so `nth_back(0)` returns the first value from /// the end, `nth_back(1)` the second, and so on. /// /// Note that all elements between the end and the returned element will be