| //@ run-pass |
| //! Test that users are able to retrieve all associated items from a definition. |
| //! definition. |
| |
| //@ ignore-stage1 |
| //@ ignore-cross-compile |
| //@ ignore-remote |
| //@ edition: 2021 |
| |
| #![feature(rustc_private)] |
| #![feature(assert_matches)] |
| |
| extern crate rustc_middle; |
| |
| extern crate rustc_driver; |
| extern crate rustc_interface; |
| extern crate rustc_public; |
| |
| use std::collections::HashSet; |
| use std::io::Write; |
| use std::ops::ControlFlow; |
| |
| use rustc_public::ty::*; |
| use rustc_public::{CrateDef, *}; |
| |
| const CRATE_NAME: &str = "crate_assoc_items"; |
| |
| /// This function uses the Stable MIR APIs to get information about the test crate. |
| fn test_assoc_items() -> ControlFlow<()> { |
| let local_crate = rustc_public::local_crate(); |
| check_items( |
| &local_crate.fn_defs(), |
| &[ |
| "AStruct::new", |
| "<AStruct as ATrait>::assoc_fn_no_self", |
| "<AStruct as ATrait>::assoc_fn_has_self", |
| "ATrait::rpitit", |
| "ATrait::assoc_fn_has_self", |
| "ATrait::assoc_fn_no_self", |
| "<AStruct as ATrait>::rpitit", |
| ], |
| ); |
| |
| let local_impls = local_crate.trait_impls(); |
| let local_traits = local_crate.trait_decls(); |
| |
| let trait_assoc_item_defs: Vec<AssocDef> = |
| local_traits[0].associated_items().iter().map(|assoc_item| assoc_item.def_id).collect(); |
| check_items( |
| &trait_assoc_item_defs, |
| &[ |
| "ATrait::rpitit::{anon_assoc#0}", |
| "ATrait::rpitit", |
| "ATrait::Assoc", |
| "ATrait::assoc_fn_no_self", |
| "ATrait::assoc_fn_has_self", |
| ], |
| ); |
| |
| let impl_assoc_item_defs: Vec<AssocDef> = |
| local_impls[0].associated_items().iter().map(|assoc_item| assoc_item.def_id).collect(); |
| check_items( |
| &impl_assoc_item_defs, |
| &[ |
| "<AStruct as ATrait>::rpitit::{anon_assoc#0}", |
| "<AStruct as ATrait>::rpitit", |
| "<AStruct as ATrait>::Assoc", |
| "<AStruct as ATrait>::assoc_fn_no_self", |
| "<AStruct as ATrait>::assoc_fn_has_self", |
| ], |
| ); |
| |
| ControlFlow::Continue(()) |
| } |
| |
| /// Check if the list of definitions matches the expected list. |
| /// Note that order doesn't matter. |
| fn check_items<T: CrateDef>(items: &[T], expected: &[&str]) { |
| let expected: HashSet<_> = expected.iter().map(|s| s.to_string()).collect(); |
| let item_names: HashSet<_> = items.iter().map(|item| item.name()).collect(); |
| assert_eq!(item_names, expected); |
| } |
| |
| fn main() { |
| let path = "assoc_items.rs"; |
| generate_input(&path).unwrap(); |
| let args = &[ |
| "rustc".to_string(), |
| "--crate-type=lib".to_string(), |
| "--crate-name".to_string(), |
| CRATE_NAME.to_string(), |
| path.to_string(), |
| ]; |
| run!(args, test_assoc_items).unwrap(); |
| } |
| |
| fn generate_input(path: &str) -> std::io::Result<()> { |
| let mut file = std::fs::File::create(path)?; |
| write!( |
| file, |
| r#" |
| #![allow(dead_code, unused_variables)] |
| struct AStruct; |
| |
| impl AStruct {{ |
| const ASSOC_CONST: &str = "Nina"; |
| |
| fn new() -> Self {{ |
| AStruct{{}} |
| }} |
| }} |
| |
| trait ATrait {{ |
| type Assoc; |
| |
| fn assoc_fn_no_self() {{ |
| }} |
| |
| fn assoc_fn_has_self(&self) {{ |
| }} |
| |
| fn rpitit(&self) -> impl std::fmt::Debug {{ |
| "ciallo" |
| }} |
| }} |
| |
| impl ATrait for AStruct {{ |
| type Assoc = u32; |
| |
| fn assoc_fn_no_self() {{ |
| }} |
| |
| fn assoc_fn_has_self(&self) {{ |
| }} |
| |
| fn rpitit(&self) -> impl std::fmt::Debug {{ |
| "ciallo~" |
| }} |
| }} |
| "# |
| )?; |
| Ok(()) |
| } |