diff options
248 files changed, 2242 insertions, 869 deletions
diff --git a/Cargo.lock b/Cargo.lock index 5917757ff3e..6b3a714920b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -882,9 +882,9 @@ dependencies = [ [[package]] name = "curl-sys" -version = "0.4.45+curl-7.78.0" +version = "0.4.48+curl-7.79.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de9e5a72b1c744eb5dd20b2be4d7eb84625070bb5c4ab9b347b70464ab1e62eb" +checksum = "a6a77a741f832116da66aeb126b4f19190ecf46144a74a9bde43c2086f38da0e" dependencies = [ "cc", "libc", diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml index 37f90bf3c10..277cf0f51d3 100644 --- a/compiler/rustc/Cargo.toml +++ b/compiler/rustc/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc-main" version = "0.0.0" -edition = '2018' +edition = "2021" [dependencies] rustc_driver = { path = "../rustc_driver" } diff --git a/compiler/rustc_apfloat/Cargo.toml b/compiler/rustc_apfloat/Cargo.toml index 9f266b1fb97..bb01d4f51b8 100644 --- a/compiler/rustc_apfloat/Cargo.toml +++ b/compiler/rustc_apfloat/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_apfloat" version = "0.0.0" -edition = "2018" +edition = "2021" [dependencies] bitflags = "1.2.1" diff --git a/compiler/rustc_arena/Cargo.toml b/compiler/rustc_arena/Cargo.toml index eba8a2a082f..33ccd044503 100644 --- a/compiler/rustc_arena/Cargo.toml +++ b/compiler/rustc_arena/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_arena" version = "0.0.0" -edition = "2018" +edition = "2021" [dependencies] rustc_data_structures = { path = "../rustc_data_structures" } diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml index 67cf5d92b00..58b967a3704 100644 --- a/compiler/rustc_ast/Cargo.toml +++ b/compiler/rustc_ast/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_ast" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index 4e848a6a2b8..f4859ee4ae9 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_ast_lowering" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index ac7145bed78..a6ea4aa8923 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -55,7 +55,6 @@ impl<'hir> LoweringContext<'_, 'hir> { 0, ParenthesizedGenericArgs::Err, ImplTraitContext::disallowed(), - None, )); let args = self.lower_exprs(args); hir::ExprKind::MethodCall( @@ -328,7 +327,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let mut generic_args = vec![]; for (idx, arg) in args.into_iter().enumerate() { if legacy_args_idx.contains(&idx) { - let parent_def_id = self.current_hir_id_owner.0; + let parent_def_id = self.current_hir_id_owner; let node_id = self.resolver.next_node_id(); // Add a definition for the in-band const def. diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 980036c662a..9f879494d73 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -40,12 +40,9 @@ impl ItemLowerer<'_, '_, '_> { impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> { fn visit_item(&mut self, item: &'a Item) { - self.lctx.allocate_hir_id_counter(item.id); let hir_id = self.lctx.with_hir_id_owner(item.id, |lctx| { - lctx.without_in_scope_lifetime_defs(|lctx| { - let hir_item = lctx.lower_item(item); - lctx.insert_item(hir_item) - }) + let node = lctx.without_in_scope_lifetime_defs(|lctx| lctx.lower_item(item)); + hir::OwnerNode::Item(node) }); self.lctx.with_parent_item_lifetime_defs(hir_id, |this| { @@ -72,26 +69,17 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> { } fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) { - self.lctx.allocate_hir_id_counter(item.id); self.lctx.with_hir_id_owner(item.id, |lctx| match ctxt { - AssocCtxt::Trait => { - let hir_item = lctx.lower_trait_item(item); - lctx.insert_trait_item(hir_item); - } - AssocCtxt::Impl => { - let hir_item = lctx.lower_impl_item(item); - lctx.insert_impl_item(hir_item); - } + AssocCtxt::Trait => hir::OwnerNode::TraitItem(lctx.lower_trait_item(item)), + AssocCtxt::Impl => hir::OwnerNode::ImplItem(lctx.lower_impl_item(item)), }); visit::walk_assoc_item(self, item, ctxt); } fn visit_foreign_item(&mut self, item: &'a ForeignItem) { - self.lctx.allocate_hir_id_counter(item.id); self.lctx.with_hir_id_owner(item.id, |lctx| { - let hir_item = lctx.lower_foreign_item(item); - lctx.insert_foreign_item(hir_item); + hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item)) }); visit::walk_foreign_item(self, item); @@ -106,12 +94,12 @@ impl<'hir> LoweringContext<'_, 'hir> { // only used when lowering a child item of a trait or impl. fn with_parent_item_lifetime_defs<T>( &mut self, - parent_hir_id: hir::ItemId, + parent_hir_id: LocalDefId, f: impl FnOnce(&mut Self) -> T, ) -> T { let old_len = self.in_scope_lifetimes.len(); - let parent_generics = match self.owners[parent_hir_id.def_id].unwrap().expect_item().kind { + let parent_generics = match self.owners[parent_hir_id].unwrap().expect_item().kind { hir::ItemKind::Impl(hir::Impl { ref generics, .. }) | hir::ItemKind::Trait(_, _, ref generics, ..) => generics.params, _ => &[], @@ -186,19 +174,20 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - pub fn lower_item(&mut self, i: &Item) -> hir::Item<'hir> { + fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> { let mut ident = i.ident; - let mut vis = self.lower_visibility(&i.vis, None); + let mut vis = self.lower_visibility(&i.vis); let hir_id = self.lower_node_id(i.id); let attrs = self.lower_attrs(hir_id, &i.attrs); let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, &mut vis, &i.kind); - hir::Item { + let item = hir::Item { def_id: hir_id.expect_owner(), ident: self.lower_ident(ident), kind, vis, span: self.lower_span(i.span), - } + }; + self.arena.alloc(item) } fn lower_item_kind( @@ -480,10 +469,17 @@ impl<'hir> LoweringContext<'_, 'hir> { // Essentially a single `use` which imports two names is desugared into // two imports. for new_node_id in [id1, id2] { - // Associate an HirId to both ids even if there is no resolution. - let new_id = self.allocate_hir_id_counter(new_node_id); - - let res = if let Some(res) = resolutions.next() { res } else { continue }; + let new_id = self.resolver.local_def_id(new_node_id); + let res = if let Some(res) = resolutions.next() { + res + } else { + // Associate an HirId to both ids even if there is no resolution. + let _old = self + .node_id_to_hir_id + .insert(new_node_id, hir::HirId::make_owner(new_id)); + debug_assert!(_old.is_none()); + continue; + }; let ident = *ident; let mut path = path.clone(); for seg in &mut path.segments { @@ -493,24 +489,25 @@ impl<'hir> LoweringContext<'_, 'hir> { self.with_hir_id_owner(new_node_id, |this| { let res = this.lower_res(res); - let path = this.lower_path_extra(res, &path, ParamMode::Explicit, None); + let path = this.lower_path_extra(res, &path, ParamMode::Explicit); let kind = hir::ItemKind::Use(path, hir::UseKind::Single); let vis = this.rebuild_vis(&vis); if let Some(attrs) = attrs { this.attrs.insert(hir::HirId::make_owner(new_id), attrs); } - this.insert_item(hir::Item { + let item = hir::Item { def_id: new_id, ident: this.lower_ident(ident), kind, vis, span: this.lower_span(span), - }); + }; + hir::OwnerNode::Item(this.arena.alloc(item)) }); } - let path = self.lower_path_extra(ret_res, &path, ParamMode::Explicit, None); + let path = self.lower_path_extra(ret_res, &path, ParamMode::Explicit); hir::ItemKind::Use(path, hir::UseKind::Single) } UseTreeKind::Glob => { @@ -550,7 +547,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // Add all the nested `PathListItem`s to the HIR. for &(ref use_tree, id) in trees { - let new_hir_id = self.allocate_hir_id_counter(id); + let new_hir_id = self.resolver.local_def_id(id); let mut prefix = prefix.clone(); @@ -574,13 +571,14 @@ impl<'hir> LoweringContext<'_, 'hir> { this.attrs.insert(hir::HirId::make_owner(new_hir_id), attrs); } - this.insert_item(hir::Item { + let item = hir::Item { def_id: new_hir_id, ident: this.lower_ident(ident), kind, vis, span: this.lower_span(use_tree.span), - }); + }; + hir::OwnerNode::Item(this.arena.alloc(item)) }); } @@ -610,7 +608,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let res = self.expect_full_res_from_use(id).next().unwrap_or(Res::Err); let res = self.lower_res(res); - let path = self.lower_path_extra(res, &prefix, ParamMode::Explicit, None); + let path = self.lower_path_extra(res, &prefix, ParamMode::Explicit); hir::ItemKind::Use(path, hir::UseKind::ListStem) } } @@ -647,11 +645,11 @@ impl<'hir> LoweringContext<'_, 'hir> { respan(self.lower_span(vis.span), vis_kind) } - fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem<'hir> { + fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> { let hir_id = self.lower_node_id(i.id); let def_id = hir_id.expect_owner(); self.lower_attrs(hir_id, &i.attrs); - hir::ForeignItem { + let item = hir::ForeignItem { def_id, ident: self.lower_ident(i.ident), kind: match i.kind { @@ -679,17 +677,17 @@ impl<'hir> LoweringContext<'_, 'hir> { ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type, ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"), }, - vis: self.lower_visibility(&i.vis, None), + vis: self.lower_visibility(&i.vis), span: self.lower_span(i.span), - } + }; + self.arena.alloc(item) } - fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef<'hir> { + fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef { hir::ForeignItemRef { - id: hir::ForeignItemId { def_id: self.allocate_hir_id_counter(i.id) }, + id: hir::ForeignItemId { def_id: self.resolver.local_def_id(i.id) }, ident: self.lower_ident(i.ident), span: self.lower_span(i.span), - vis: self.lower_visibility(&i.vis, Some(i.id)), } } @@ -757,12 +755,12 @@ impl<'hir> LoweringContext<'_, 'hir> { // FIXME(jseyfried): positional field hygiene. None => Ident::new(sym::integer(index), self.lower_span(f.span)), }, - vis: self.lower_visibility(&f.vis, None), + vis: self.lower_visibility(&f.vis), ty, } } - fn lower_trait_item(&mut self, i: &AssocItem) -> hir::TraitItem<'hir> { + fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> { let hir_id = self.lower_node_id(i.id); let trait_item_def_id = hir_id.expect_owner(); @@ -805,13 +803,14 @@ impl<'hir> LoweringContext<'_, 'hir> { }; self.lower_attrs(hir_id, &i.attrs); - hir::TraitItem { + let item = hir::TraitItem { def_id: trait_item_def_id, ident: self.lower_ident(i.ident), generics, kind, span: self.lower_span(i.span), - } + }; + self.arena.alloc(item) } fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef { @@ -841,7 +840,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.expr(span, hir::ExprKind::Err, AttrVec::new()) } - fn lower_impl_item(&mut self, i: &AssocItem) -> hir::ImplItem<'hir> { + fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> { let impl_item_def_id = self.resolver.local_def_id(i.id); let (generics, kind) = match &i.kind { @@ -895,26 +894,26 @@ impl<'hir> LoweringContext<'_, 'hir> { let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value); let hir_id = self.lower_node_id(i.id); self.lower_attrs(hir_id, &i.attrs); - hir::ImplItem { + let item = hir::ImplItem { def_id: hir_id.expect_owner(), ident: self.lower_ident(i.ident), generics, - vis: self.lower_visibility(&i.vis, None), + vis: self.lower_visibility(&i.vis), defaultness, kind, span: self.lower_span(i.span), - } + }; + self.arena.alloc(item) } - fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef<'hir> { + fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef { // Since `default impl` is not yet implemented, this is always true in impls. let has_value = true; let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value); hir::ImplItemRef { - id: hir::ImplItemId { def_id: self.allocate_hir_id_counter(i.id) }, + id: hir::ImplItemId { def_id: self.resolver.local_def_id(i.id) }, ident: self.lower_ident(i.ident), span: self.lower_span(i.span), - vis: self.lower_visibility(&i.vis, Some(i.id)), defaultness, kind: match &i.kind { AssocItemKind::Const(..) => hir::AssocItemKind::Const, @@ -932,25 +931,15 @@ impl<'hir> LoweringContext<'_, 'hir> { /// lowered. This can happen during `lower_impl_item_ref()` where we need to /// lower a `Visibility` value although we haven't lowered the owning /// `ImplItem` in question yet. - fn lower_visibility( - &mut self, - v: &Visibility, - explicit_owner: Option<NodeId>, - ) -> hir::Visibility<'hir> { + fn lower_visibility(&mut self, v: &Visibility) -> hir::Visibility<'hir> { let node = match v.kind { VisibilityKind::Public => hir::VisibilityKind::Public, VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar), VisibilityKind::Restricted { ref path, id } => { debug!("lower_visibility: restricted path id = {:?}", id); - let lowered_id = if let Some(owner) = explicit_owner { - self.lower_node_id_with_owner(id, owner) - } else { - self.lower_node_id(id) - }; - let res = self.expect_full_res(id); - let res = self.lower_res(res); + let lowered_id = self.lower_node_id(id); hir::VisibilityKind::Restricted { - path: self.lower_path_extra(res, path, ParamMode::Explicit, explicit_owner), + path: self.lower_path(id, path, ParamMode::Explicit), hir_id: lowered_id, } } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 66bcd698e6a..3c75089a760 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -80,8 +80,6 @@ mod item; mod pat; mod path; -const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF; - rustc_hir::arena_types!(rustc_arena::declare_arena, 'tcx); struct LoweringContext<'a, 'hir: 'a> { @@ -150,8 +148,8 @@ struct LoweringContext<'a, 'hir: 'a> { /// vector. in_scope_lifetimes: Vec<ParamName>, - current_hir_id_owner: (LocalDefId, u32), - item_local_id_counters: NodeMap<u32>, + current_hir_id_owner: LocalDefId, + item_local_id_counter: hir::ItemLocalId, node_id_to_hir_id: IndexVec<NodeId, Option<hir::HirId>>, allow_try_trait: Option<Lrc<[Symbol]>>, @@ -330,8 +328,8 @@ pub fn lower_crate<'a, 'hir>( is_in_trait_impl: false, is_in_dyn_type: false, anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough, - current_hir_id_owner: (CRATE_DEF_ID, 0), - item_local_id_counters: Default::default(), + current_hir_id_owner: CRATE_DEF_ID, + item_local_id_counter: hir::ItemLocalId::new(0), node_id_to_hir_id: IndexVec::new(), generator_kind: None, task_context: None, @@ -412,15 +410,15 @@ enum AnonymousLifetimeMode { impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_crate(mut self, c: &Crate) -> &'hir hir::Crate<'hir> { - self.lower_node_id(CRATE_NODE_ID); - debug_assert!(self.node_id_to_hir_id[CRATE_NODE_ID] == Some(hir::CRATE_HIR_ID)); + debug_assert_eq!(self.resolver.local_def_id(CRATE_NODE_ID), CRATE_DEF_ID); visit::walk_crate(&mut item::ItemLowerer { lctx: &mut self }, c); - let module = self.arena.alloc(self.lower_mod(&c.items, c.span)); - self.lower_attrs(hir::CRATE_HIR_ID, &c.attrs); - self.owners.ensure_contains_elem(CRATE_DEF_ID, || None); - self.owners[CRATE_DEF_ID] = Some(hir::OwnerNode::Crate(module)); + self.with_hir_id_owner(CRATE_NODE_ID, |lctx| { + let module = lctx.lower_mod(&c.items, c.span); + lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs); + hir::OwnerNode::Crate(lctx.arena.alloc(module)) + }); let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default(); for (k, v) in self.resolver.take_trait_map().into_iter() { @@ -456,47 +454,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.arena.alloc(krate) } - fn insert_item(&mut self, item: hir::Item<'hir>) -> hir::ItemId { - let id = item.item_id(); - let item = self.arena.alloc(item); - self.owners.ensure_contains_elem(id.def_id, || None); - self.owners[id.def_id] = Some(hir::OwnerNode::Item(item)); - id - } - - fn insert_foreign_item(&mut self, item: hir::ForeignItem<'hir>) -> hir::ForeignItemId { - let id = item.foreign_item_id(); - let item = self.arena.alloc(item); - self.owners.ensure_contains_elem(id.def_id, || None); - self.owners[id.def_id] = Some(hir::OwnerNode::ForeignItem(item)); - id - } - - fn insert_impl_item(&mut self, item: hir::ImplItem<'hir>) -> hir::ImplItemId { - let id = item.impl_item_id(); - let item = self.arena.alloc(item); - self.owners.ensure_contains_elem(id.def_id, || None); - self.owners[id.def_id] = Some(hir::OwnerNode::ImplItem(item)); - id - } - - fn insert_trait_item(&mut self, item: hir::TraitItem<'hir>) -> hir::TraitItemId { - let id = item.trait_item_id(); - let item = self.arena.alloc(item); - self.owners.ensure_contains_elem(id.def_id, || None); - self.owners[id.def_id] = Some(hir::OwnerNode::TraitItem(item)); - id - } - - fn allocate_hir_id_counter(&mut self, owner: NodeId) -> LocalDefId { - // Set up the counter if needed. - self.item_local_id_counters.entry(owner).or_insert(0); - // Always allocate the first `HirId` for the owner itself. - let lowered = self.lower_node_id_with_owner(owner, owner); - debug_assert_eq!(lowered.local_id.as_u32(), 0); - lowered.owner - } - fn create_stable_hashing_context(&self) -> LoweringHasher<'_> { LoweringHasher { source_map: CachingSourceMapView::new(self.sess.source_map()), @@ -504,47 +461,30 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn lower_node_id_generic( + fn with_hir_id_owner( &mut self, - ast_node_id: NodeId, - alloc_hir_id: impl FnOnce(&mut Self) -> hir::HirId, - ) -> hir::HirId { - assert_ne!(ast_node_id, DUMMY_NODE_ID); - - let min_size = ast_node_id.as_usize() + 1; + owner: NodeId, + f: impl FnOnce(&mut Self) -> hir::OwnerNode<'hir>, + ) -> LocalDefId { + let def_id = self.resolver.local_def_id(owner); - if min_size > self.node_id_to_hir_id.len() { - self.node_id_to_hir_id.resize(min_size, None); - } + // Always allocate the first `HirId` for the owner itself. + let _old = self.node_id_to_hir_id.insert(owner, hir::HirId::make_owner(def_id)); + debug_assert_eq!(_old, None); - if let Some(existing_hir_id) = self.node_id_to_hir_id[ast_node_id] { - existing_hir_id - } else { - // Generate a new `HirId`. - let hir_id = alloc_hir_id(self); - self.node_id_to_hir_id[ast_node_id] = Some(hir_id); + let current_owner = std::mem::replace(&mut self.current_hir_id_owner, def_id); + let current_local_counter = + std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1)); - hir_id - } - } + let item = f(self); - fn with_hir_id_owner<T>(&mut self, owner: NodeId, f: impl FnOnce(&mut Self) -> T) -> T { - let counter = self - .item_local_id_counters - .insert(owner, HIR_ID_COUNTER_LOCKED) - .unwrap_or_else(|| panic!("no `item_local_id_counters` entry for {:?}", owner)); - let def_id = self.resolver.local_def_id(owner); - let old_owner = std::mem::replace(&mut self.current_hir_id_owner, (def_id, counter)); - let ret = f(self); - let (new_def_id, new_counter) = - std::mem::replace(&mut self.current_hir_id_owner, old_owner); + self.current_hir_id_owner = current_owner; + self.item_local_id_counter = current_local_counter; - debug_assert!(def_id == new_def_id); - debug_assert!(new_counter >= counter); + let _old = self.owners.insert(def_id, item); + debug_assert!(_old.is_none()); - let prev = self.item_local_id_counters.insert(owner, new_counter).unwrap(); - debug_assert!(prev == HIR_ID_COUNTER_LOCKED); - ret + def_id } /// This method allocates a new `HirId` for the given `NodeId` and stores it in @@ -554,34 +494,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// `HirIdValidator` later on, which makes sure that all `NodeId`s got mapped /// properly. Calling the method twice with the same `NodeId` is fine though. fn lower_node_id(&mut self, ast_node_id: NodeId) -> hir::HirId { - self.lower_node_id_generic(ast_node_id, |this| { - let &mut (owner, ref mut local_id_counter) = &mut this.current_hir_id_owner; - let local_id = *local_id_counter; - *local_id_counter += 1; - hir::HirId { owner, local_id: hir::ItemLocalId::from_u32(local_id) } - }) - } - - fn lower_node_id_with_owner(&mut self, ast_node_id: NodeId, owner: NodeId) -> hir::HirId { - self.lower_node_id_generic(ast_node_id, |this| { - let local_id_counter = this - .item_local_id_counters - .get_mut(&owner) - .expect("called `lower_node_id_with_owner` before `allocate_hir_id_counter`"); - let local_id = *local_id_counter; - - // We want to be sure not to modify the counter in the map while it - // is also on the stack. Otherwise we'll get lost updates when writing - // back from the stack to the map. - debug_assert!(local_id != HIR_ID_COUNTER_LOCKED); - - *local_id_counter += 1; - let owner = this.resolver.opt_local_def_id(owner).expect( - "you forgot to call `create_def` or are lowering node-IDs \ - that do not belong to the current owner", - ); + assert_ne!(ast_node_id, DUMMY_NODE_ID); - hir::HirId { owner, local_id: hir::ItemLocalId::from_u32(local_id) } + *self.node_id_to_hir_id.get_or_insert_with(ast_node_id, || { + // Generate a new `HirId`. + let owner = self.current_hir_id_owner; + let local_id = self.item_local_id_counter; + self.item_local_id_counter.increment_by(1); + hir::HirId { owner, local_id } }) } @@ -592,7 +512,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_res(&mut self, res: Res<NodeId>) -> Res { res.map_id(|id| { - self.lower_node_id_generic(id, |_| { + self.node_id_to_hir_id.get(id).copied().flatten().unwrap_or_else(|| { panic!("expected `NodeId` to be lowered already for res {:#?}", res); }) }) @@ -655,7 +575,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// Mark a span as relative to the current owning item. fn lower_span(&self, span: Span) -> Span { if self.sess.opts.debugging_opts.incremental_relative_spans { - span.with_parent(Some(self.current_hir_id_owner.0)) + span.with_parent(Some(self.current_hir_id_owner)) } else { // Do not make spans relative when not using incremental compilation. span @@ -828,7 +748,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // wouldn't have been added yet. let generics = this.lower_generics_mut( generics, - ImplTraitContext::Universal(&mut params, this.current_hir_id_owner.0), + ImplTraitContext::Universal(&mut params, this.current_hir_id_owner), ); let res = f(this, &mut params); (params, (generics, res)) @@ -1034,7 +954,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } AssocTyConstraintKind::Bound { ref bounds } => { let mut capturable_lifetimes; - let mut parent_def_id = self.current_hir_id_owner.0; + let mut parent_def_id = self.current_hir_id_owner; // Piggy-back on the `impl Trait` context to figure out the correct behavior. let (desugar_to_impl_trait, itctx) = match itctx { // We are in the return position: @@ -1162,7 +1082,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Construct an AnonConst where the expr is the "ty"'s path. - let parent_def_id = self.current_hir_id_owner.0; + let parent_def_id = self.current_hir_id_owner; let node_id = self.resolver.next_node_id(); // Add a definition for the in-band const def. @@ -1428,12 +1348,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // frequently opened issues show. let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None); - let opaque_ty_def_id = self.allocate_hir_id_counter(opaque_ty_node_id); + let opaque_ty_def_id = self.resolver.local_def_id(opaque_ty_node_id); - let collected_lifetimes = self.with_hir_id_owner(opaque_ty_node_id, move |lctx| { + let mut collected_lifetimes = Vec::new(); + self.with_hir_id_owner(opaque_ty_node_id, |lctx| { let hir_bounds = lower_bounds(lctx); - let collected_lifetimes = lifetimes_from_impl_trait_bounds( + collected_lifetimes = lifetimes_from_impl_trait_bounds( opaque_ty_node_id, &hir_bounds, capturable_lifetimes, @@ -1486,9 +1407,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; trace!("lower_opaque_impl_trait: {:#?}", opaque_ty_def_id); - lctx.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span); - - collected_lifetimes + lctx.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span) }); let lifetimes = @@ -1510,7 +1429,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { opaque_ty_item: hir::OpaqueTy<'hir>, span: Span, opaque_ty_span: Span, - ) { + ) -> hir::OwnerNode<'hir> { let opaque_ty_item_kind = hir::ItemKind::OpaqueTy(opaque_ty_item); // Generate an `type Foo = impl Trait;` declaration. trace!("registering opaque type with id {:#?}", opaque_ty_id); @@ -1521,11 +1440,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { vis: respan(self.lower_span(span.shrink_to_lo()), hir::VisibilityKind::Inherited), span: self.lower_span(opaque_ty_span), }; - - // Insert the item into the global item list. This usually happens - // automatically for all AST items. But this opaque type item - // does not actually exist in the AST. - self.insert_item(opaque_ty_item); + hir::OwnerNode::Item(self.arena.alloc(opaque_ty_item)) } fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] { @@ -1594,7 +1509,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { if let Some((_, ibty)) = &mut in_band_ty_params { this.lower_ty_direct( ¶m.ty, - ImplTraitContext::Universal(ibty, this.current_hir_id_owner.0), + ImplTraitContext::Universal(ibty, this.current_hir_id_owner), ) } else { this.lower_ty_direct(¶m.ty, ImplTraitContext::disallowed()) @@ -1685,7 +1600,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None); - let opaque_ty_def_id = self.allocate_hir_id_counter(opaque_ty_node_id); + let opaque_ty_def_id = self.resolver.local_def_id(opaque_ty_node_id); // When we create the opaque type for this async fn, it is going to have // to capture all the lifetimes involved in the signature (including in the @@ -1735,7 +1650,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // grow. let input_lifetimes_count = self.in_scope_lifetimes.len() + self.lifetimes_to_define.len(); - let lifetime_params = self.with_hir_id_owner(opaque_ty_node_id, |this| { + let mut lifetime_params = Vec::new(); + self.with_hir_id_owner(opaque_ty_node_id, |this| { // We have to be careful to get elision right here. The // idea is that we create a lifetime parameter for each // lifetime in the return type. So, given a return type @@ -1757,7 +1673,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // // Note: this must be done after lowering the output type, // as the output type may introduce new in-band lifetimes. - let lifetime_params: Vec<(Span, ParamName)> = this + lifetime_params = this .in_scope_lifetimes .iter() .cloned() @@ -1786,9 +1702,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; trace!("exist ty from async fn def id: {:#?}", opaque_ty_def_id); - this.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span); - - lifetime_params + this.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span) }); // As documented above on the variable diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 90a22b5c209..929f427484d 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -99,7 +99,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { num_lifetimes, parenthesized_generic_args, itctx.reborrow(), - None, ) }, )), @@ -147,7 +146,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { 0, ParenthesizedGenericArgs::Err, itctx.reborrow(), - None, )); let qpath = hir::QPath::TypeRelative(ty, hir_segment); @@ -178,7 +176,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { res: Res, p: &Path, param_mode: ParamMode, - explicit_owner: Option<NodeId>, ) -> &'hir hir::Path<'hir> { self.arena.alloc(hir::Path { res, @@ -190,7 +187,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { 0, ParenthesizedGenericArgs::Err, ImplTraitContext::disallowed(), - explicit_owner, ) })), span: self.lower_span(p.span), @@ -205,7 +201,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) -> &'hir hir::Path<'hir> { let res = self.expect_full_res(id); let res = self.lower_res(res); - self.lower_path_extra(res, p, param_mode, None) + self.lower_path_extra(res, p, param_mode) } crate fn lower_path_segment( @@ -216,7 +212,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { expected_lifetimes: usize, parenthesized_generic_args: ParenthesizedGenericArgs, itctx: ImplTraitContext<'_, 'hir>, - explicit_owner: Option<NodeId>, ) -> hir::PathSegment<'hir> { debug!( "path_span: {:?}, lower_path_segment(segment: {:?}, expected_lifetimes: {:?})", @@ -354,11 +349,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } let res = self.expect_full_res(segment.id); - let id = if let Some(owner) = explicit_owner { - self.lower_node_id_with_owner(segment.id, owner) - } else { - self.lower_node_id(segment.id) - }; + let id = self.lower_node_id(segment.id); debug!( "lower_path_segment: ident={:?} original-id={:?} new-id={:?}", segment.ident, segment.id, id, diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml index 4a6eb80fb30..9312a68bc60 100644 --- a/compiler/rustc_ast_passes/Cargo.toml +++ b/compiler/rustc_ast_passes/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_ast_passes" version = "0.0.0" -edition = "2018" +edition = "2021" [dependencies] itertools = "0.9" diff --git a/compiler/rustc_ast_pretty/Cargo.toml b/compiler/rustc_ast_pretty/Cargo.toml index fa88740103b..29f2be4cf46 100644 --- a/compiler/rustc_ast_pretty/Cargo.toml +++ b/compiler/rustc_ast_pretty/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_ast_pretty" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_attr/Cargo.toml b/compiler/rustc_attr/Cargo.toml index 0566379e1f5..ba310a6860e 100644 --- a/compiler/rustc_attr/Cargo.toml +++ b/compiler/rustc_attr/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_attr" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_borrowck/Cargo.toml b/compiler/rustc_borrowck/Cargo.toml index c683c388ba9..75e9c69af4e 100644 --- a/compiler/rustc_borrowck/Cargo.toml +++ b/compiler/rustc_borrowck/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_borrowck" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index 2370ac201b0..fd34f947f72 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_builtin_macros" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index c7626dec4d7..9b9adc2d7f3 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -845,8 +845,7 @@ impl<'a, 'b> Context<'a, 'b> { self.ecx.expr_match(self.macsp, head, vec![arm]) }; - let ident = Ident::from_str_and_span("args", self.macsp); - let args_slice = self.ecx.expr_ident(self.macsp, ident); + let args_slice = self.ecx.expr_addr_of(self.macsp, args_match); // Now create the fmt::Arguments struct with all our locals we created. let (fn_name, fn_args) = if self.all_pieces_simple { @@ -856,25 +855,22 @@ impl<'a, 'b> Context<'a, 'b> { // nonstandard placeholders, if there are any. let fmt = self.ecx.expr_vec_slice(self.macsp, self.pieces); - ("new_v1_formatted", vec![pieces, args_slice, fmt]) + let path = self.ecx.std_path(&[sym::fmt, sym::UnsafeArg, sym::new]); + let unsafe_arg = self.ecx.expr_call_global(self.macsp, path, Vec::new()); + let unsafe_expr = self.ecx.expr_block(P(ast::Block { + stmts: vec![self.ecx.stmt_expr(unsafe_arg)], + id: ast::DUMMY_NODE_ID, + rules: BlockCheckMode::Unsafe(UnsafeSource::CompilerGenerated), + span: self.macsp, + tokens: None, + could_be_bare_literal: false, + })); + + ("new_v1_formatted", vec![pieces, args_slice, fmt, unsafe_expr]) }; let path = self.ecx.std_path(&[sym::fmt, sym::Arguments, Symbol::intern(fn_name)]); - let arguments = self.ecx.expr_call_global(self.macsp, path, fn_args); - let body = self.ecx.expr_block(P(ast::Block { - stmts: vec![self.ecx.stmt_expr(arguments)], - id: ast::DUMMY_NODE_ID, - rules: BlockCheckMode::Unsafe(UnsafeSource::CompilerGenerated), - span: self.macsp, - tokens: None, - could_be_bare_literal: false, - })); - - let ident = Ident::from_str_and_span("args", self.macsp); - let binding_mode = ast::BindingMode::ByRef(ast::Mutability::Not); - let pat = self.ecx.pat_ident_binding_mode(self.macsp, ident, binding_mode); - let arm = self.ecx.arm(self.macsp, pat, body); - self.ecx.expr_match(self.macsp, args_match, vec![arm]) + self.ecx.expr_call_global(self.macsp, path, fn_args) } fn format_arg( diff --git a/compiler/rustc_codegen_cranelift/Cargo.toml b/compiler/rustc_codegen_cranelift/Cargo.toml index 6f40fc0fcb8..61d40702a32 100644 --- a/compiler/rustc_codegen_cranelift/Cargo.toml +++ b/compiler/rustc_codegen_cranelift/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_codegen_cranelift" version = "0.1.0" -edition = "2018" +edition = "2021" [lib] crate-type = ["dylib"] diff --git a/compiler/rustc_codegen_cranelift/src/bin/cg_clif_build_sysroot.rs b/compiler/rustc_codegen_cranelift/src/bin/cg_clif_build_sysroot.rs index e7cd5edbbf6..89e0cb8d90e 100644 --- a/compiler/rustc_codegen_cranelift/src/bin/cg_clif_build_sysroot.rs +++ b/compiler/rustc_codegen_cranelift/src/bin/cg_clif_build_sysroot.rs @@ -8,7 +8,6 @@ #![feature(rustc_private)] -extern crate rustc_data_structures; extern crate rustc_driver; extern crate rustc_interface; extern crate rustc_session; diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index 3c99febbd57..3f024434581 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_codegen_llvm" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] test = false diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 56b93f83466..51c70f0868f 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -305,9 +305,12 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty:: let mut function_features = codegen_fn_attrs .target_features .iter() - .map(|f| { + .flat_map(|f| { let feature = &f.as_str(); - format!("+{}", llvm_util::to_llvm_feature(cx.tcx.sess, feature)) + llvm_util::to_llvm_feature(cx.tcx.sess, feature) + .into_iter() + .map(|f| format!("+{}", f)) + .collect::<Vec<String>>() }) .chain(codegen_fn_attrs.instruction_set.iter().map(|x| match x { InstructionSetAttr::ArmA32 => "-thumb-mode".to_string(), diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index f612785e5a4..99b30264d09 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -325,6 +325,20 @@ fn fat_lto( drop(linker); save_temp_bitcode(&cgcx, &module, "lto.input"); + // Fat LTO also suffers from the invalid DWARF issue similar to Thin LTO. + // Here we rewrite all `DICompileUnit` pointers if there is only one `DICompileUnit`. + // This only works around the problem when codegen-units = 1. + // Refer to the comments in the `optimize_thin_module` function for more details. + let mut cu1 = ptr::null_mut(); + let mut cu2 = ptr::null_mut(); + unsafe { llvm::LLVMRustLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2) }; + if !cu2.is_null() { + let _timer = + cgcx.prof.generic_activity_with_arg("LLVM_fat_lto_patch_debuginfo", &*module.name); + unsafe { llvm::LLVMRustLTOPatchDICompileUnit(llmod, cu1) }; + save_temp_bitcode(cgcx, &module, "fat-lto-after-patch"); + } + // Internalize everything below threshold to help strip out more modules and such. unsafe { let ptr = symbols_below_threshold.as_ptr(); @@ -748,7 +762,7 @@ pub unsafe fn optimize_thin_module( // an error. let mut cu1 = ptr::null_mut(); let mut cu2 = ptr::null_mut(); - llvm::LLVMRustThinLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2); + llvm::LLVMRustLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2); if !cu2.is_null() { let msg = "multiple source DICompileUnits found"; return Err(write::llvm_err(&diag_handler, msg)); @@ -847,7 +861,7 @@ pub unsafe fn optimize_thin_module( let _timer = cgcx .prof .generic_activity_with_arg("LLVM_thin_lto_patch_debuginfo", thin_module.name()); - llvm::LLVMRustThinLTOPatchDICompileUnit(llmod, cu1); + llvm::LLVMRustLTOPatchDICompileUnit(llmod, cu1); save_temp_bitcode(cgcx, &module, "thin-lto-after-patch"); } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 3f2ed02d90d..d8c2a345fb0 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2377,12 +2377,8 @@ extern "C" { len: usize, out_len: &mut usize, ) -> *const u8; - pub fn LLVMRustThinLTOGetDICompileUnit( - M: &Module, - CU1: &mut *mut c_void, - CU2: &mut *mut c_void, - ); - pub fn LLVMRustThinLTOPatchDICompileUnit(M: &Module, CU: *mut c_void); + pub fn LLVMRustLTOGetDICompileUnit(M: &Module, CU1: &mut *mut c_void, CU2: &mut *mut c_void); + pub fn LLVMRustLTOPatchDICompileUnit(M: &Module, CU: *mut c_void); pub fn LLVMRustLinkerNew(M: &'a Module) -> &'a mut Linker<'a>; pub fn LLVMRustLinkerAdd( diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 3b64ec1a991..f9172e43773 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -166,25 +166,32 @@ pub fn time_trace_profiler_finish(file_name: &str) { // Though note that Rust can also be build with an external precompiled version of LLVM // which might lead to failures if the oldest tested / supported LLVM version // doesn't yet support the relevant intrinsics -pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> &'a str { +pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> Vec<&'a str> { let arch = if sess.target.arch == "x86_64" { "x86" } else { &*sess.target.arch }; match (arch, s) { - ("x86", "pclmulqdq") => "pclmul", - ("x86", "rdrand") => "rdrnd", - ("x86", "bmi1") => "bmi", - ("x86", "cmpxchg16b") => "cx16", - ("x86", "avx512vaes") => "vaes", - ("x86", "avx512gfni") => "gfni", - ("x86", "avx512vpclmulqdq") => "vpclmulqdq", - ("aarch64", "fp") => "fp-armv8", - ("aarch64", "fp16") => "fullfp16", - ("aarch64", "fhm") => "fp16fml", - ("aarch64", "rcpc2") => "rcpc-immo", - ("aarch64", "dpb") => "ccpp", - ("aarch64", "dpb2") => "ccdp", - ("aarch64", "frintts") => "fptoint", - ("aarch64", "fcma") => "complxnum", - (_, s) => s, + ("x86", "sse4.2") => { + if get_version() >= (14, 0, 0) { + vec!["sse4.2", "crc32"] + } else { + vec!["sse4.2"] + } + } + ("x86", "pclmulqdq") => vec!["pclmul"], + ("x86", "rdrand") => vec!["rdrnd"], + ("x86", "bmi1") => vec!["bmi"], + ("x86", "cmpxchg16b") => vec!["cx16"], + ("x86", "avx512vaes") => vec!["vaes"], + ("x86", "avx512gfni") => vec!["gfni"], + ("x86", "avx512vpclmulqdq") => vec!["vpclmulqdq"], + ("aarch64", "fp") => vec!["fp-armv8"], + ("aarch64", "fp16") => vec!["fullfp16"], + ("aarch64", "fhm") => vec!["fp16fml"], + ("aarch64", "rcpc2") => vec!["rcpc-immo"], + ("aarch64", "dpb") => vec!["ccpp"], + ("aarch64", "dpb2") => vec!["ccdp"], + ("aarch64", "frintts") => vec!["fptoint"], + ("aarch64", "fcma") => vec!["complxnum"], + (_, s) => vec![s], } } @@ -198,9 +205,13 @@ pub fn target_features(sess: &Session) -> Vec<Symbol> { }, ) .filter(|feature| { - let llvm_feature = to_llvm_feature(sess, feature); - let cstr = CString::new(llvm_feature).unwrap(); - unsafe { llvm::LLVMRustHasFeature(target_machine, cstr.as_ptr()) } + for llvm_feature in to_llvm_feature(sess, feature) { + let cstr = CString::new(llvm_feature).unwrap(); + if unsafe { llvm::LLVMRustHasFeature(target_machine, cstr.as_ptr()) } { + return true; + } + } + false }) .map(|feature| Symbol::intern(feature)) .collect() @@ -253,12 +264,19 @@ fn print_target_features(sess: &Session, tm: &llvm::TargetMachine) { let mut rustc_target_features = supported_target_features(sess) .iter() .filter_map(|(feature, _gate)| { - let llvm_feature = to_llvm_feature(sess, *feature); - // LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these strings. - target_features.binary_search_by_key(&llvm_feature, |(f, _d)| *f).ok().map(|index| { - let (_f, desc) = target_features.remove(index); - (*feature, desc) - }) + for llvm_feature in to_llvm_feature(sess, *feature) { + // LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these strings. + match target_features.binary_search_by_key(&llvm_feature, |(f, _d)| (*f)).ok().map( + |index| { + let (_f, desc) = target_features.remove(index); + (*feature, desc) + }, + ) { + Some(v) => return Some(v), + None => {} + } + } + None }) .collect::<Vec<_>>(); rustc_target_features.extend_from_slice(&[( @@ -373,30 +391,30 @@ pub fn llvm_global_features(sess: &Session) -> Vec<String> { let filter = |s: &str| { if s.is_empty() { - return None; + return vec![]; } let feature = if s.starts_with('+') || s.starts_with('-') { &s[1..] } else { - return Some(s.to_string()); + return vec![s.to_string()]; }; // Rustc-specific feature requests like `+crt-static` or `-crt-static` // are not passed down to LLVM. if RUSTC_SPECIFIC_FEATURES.contains(&feature) { - return None; + return vec![]; } // ... otherwise though we run through `to_llvm_feature` feature when // passing requests down to LLVM. This means that all in-language // features also work on the command line instead of having two // different names when the LLVM name and the Rust name differ. - Some(format!("{}{}", &s[..1], to_llvm_feature(sess, feature))) + to_llvm_feature(sess, feature).iter().map(|f| format!("{}{}", &s[..1], f)).collect() }; // Features implied by an implicit or explicit `--target`. - features.extend(sess.target.features.split(',').filter_map(&filter)); + features.extend(sess.target.features.split(',').flat_map(&filter)); // -Ctarget-features - features.extend(sess.opts.cg.target_feature.split(',').filter_map(&filter)); + features.extend(sess.opts.cg.target_feature.split(',').flat_map(&filter)); features } diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 1446624b881..0713e167c53 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_codegen_ssa" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] test = false diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 4be050fb88c..5aa2a422133 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -777,22 +777,30 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.codegen_argument(&mut bx, op, &mut llargs, &fn_abi.args[i]); } - if let Some(tup) = untuple { + let num_untupled = untuple.map(|tup| { self.codegen_arguments_untupled( &mut bx, tup, &mut llargs, &fn_abi.args[first_args.len()..], ) - } + }); let needs_location = instance.map_or(false, |i| i.def.requires_caller_location(self.cx.tcx())); if needs_location { + let mir_args = if let Some(num_untupled) = num_untupled { + first_args.len() + num_untupled + } else { + args.len() + }; assert_eq!( fn_abi.args.len(), - args.len() + 1, - "#[track_caller] fn's must have 1 more argument in their ABI than in their MIR", + mir_args + 1, + "#[track_caller] fn's must have 1 more argument in their ABI than in their MIR: {:?} {:?} {:?}", + instance, + fn_span, + fn_abi, ); let location = self.get_caller_location(&mut bx, mir::SourceInfo { span: fn_span, ..source_info }); @@ -1122,7 +1130,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { operand: &mir::Operand<'tcx>, llargs: &mut Vec<Bx::Value>, args: &[ArgAbi<'tcx, Ty<'tcx>>], - ) { + ) -> usize { let tuple = self.codegen_operand(bx, operand); // Handle both by-ref and immediate tuples. @@ -1142,6 +1150,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.codegen_argument(bx, op, llargs, &args[i]); } } + tuple.layout.fields.count() } fn get_caller_location( diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index c139f915e6c..c710fcc2c1d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -3,9 +3,11 @@ use rustc_index::vec::IndexVec; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir; use rustc_middle::ty; +use rustc_middle::ty::layout::LayoutOf; use rustc_session::config::DebugInfo; use rustc_span::symbol::{kw, Symbol}; use rustc_span::{BytePos, Span}; +use rustc_target::abi::Abi; use rustc_target::abi::Size; use super::operand::{OperandRef, OperandValue}; @@ -368,21 +370,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { { let arg_index = place.local.index() - 1; if target_is_msvc { - // Rust compiler decomposes every &str or slice argument into two components: - // a pointer to the memory address where the data is stored and a usize representing - // the length of the str (or slice). These components will later be used to reconstruct - // the original argument inside the body of the function that owns it (see the - // definition of debug_introduce_local for more details). - // - // Since the original argument is declared inside a function rather than being passed - // in as an argument, it must be marked as a LocalVariable for MSVC debuggers to visualize - // its data correctly. (See issue #81894 for an in-depth description of the problem). - match *var_ty.kind() { - ty::Ref(_, inner_type, _) => match *inner_type.kind() { - ty::Slice(_) | ty::Str => VariableKind::LocalVariable, - _ => VariableKind::ArgumentVariable(arg_index + 1), - }, - _ => VariableKind::ArgumentVariable(arg_index + 1), + // ScalarPair parameters are spilled to the stack so they need to + // be marked as a `LocalVariable` for MSVC debuggers to visualize + // their data correctly. (See #81894 & #88625) + let var_ty_layout = self.cx.layout_of(var_ty); + if let Abi::ScalarPair(_, _) = var_ty_layout.abi { + VariableKind::LocalVariable + } else { + VariableKind::ArgumentVariable(arg_index + 1) } } else { // FIXME(eddyb) shouldn't `ArgumentVariable` indices be diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 8e3982c72d7..476ddbd9398 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -129,6 +129,7 @@ impl<'a, 'tcx, V: CodegenObject> LocalRef<'tcx, V> { /////////////////////////////////////////////////////////////////////////// +#[instrument(level = "debug", skip(cx))] pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( cx: &'a Bx::CodegenCx, instance: Instance<'tcx>, @@ -257,6 +258,8 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let mut idx = 0; let mut llarg_idx = fx.fn_abi.ret.is_indirect() as usize; + let mut num_untupled = None; + let args = mir .args_iter() .enumerate() @@ -285,6 +288,11 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let pr_field = place.project_field(bx, i); bx.store_fn_arg(arg, &mut llarg_idx, pr_field); } + assert_eq!( + None, + num_untupled.replace(tupled_arg_tys.len()), + "Replaced existing num_tupled" + ); return LocalRef::Place(place); } @@ -361,10 +369,17 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( .collect::<Vec<_>>(); if fx.instance.def.requires_caller_location(bx.tcx()) { + let mir_args = if let Some(num_untupled) = num_untupled { + // Subtract off the tupled argument that gets 'expanded' + args.len() - 1 + num_untupled + } else { + args.len() + }; assert_eq!( fx.fn_abi.args.len(), - args.len() + 1, - "#[track_caller] fn's must have 1 more argument in their ABI than in their MIR", + mir_args + 1, + "#[track_caller] instance {:?} must have 1 more argument in their ABI than in their MIR", + fx.instance ); let arg = fx.fn_abi.args.last().unwrap(); diff --git a/compiler/rustc_const_eval/Cargo.toml b/compiler/rustc_const_eval/Cargo.toml index 1653d5cf6c5..a51273732ae 100644 --- a/compiler/rustc_const_eval/Cargo.toml +++ b/compiler/rustc_const_eval/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_const_eval" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index a6375ad0e02..fc69770bf6a 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -77,7 +77,7 @@ macro_rules! throw_validation_failure { /// macro_rules! try_validation { ($e:expr, $where:expr, - $( $( $p:pat )|+ => { $( $what_fmt:expr ),+ } $( expected { $( $expected_fmt:expr ),+ } )? ),+ $(,)? + $( $( $p:pat_param )|+ => { $( $what_fmt:expr ),+ } $( expected { $( $expected_fmt:expr ),+ } )? ),+ $(,)? ) => {{ match $e { Ok(x) => x, diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index bc13ca26e2e..49962570129 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_data_structures" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index dd6a17b92ae..b1f04bfbf0a 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -18,7 +18,6 @@ #![feature(extend_one)] #![feature(hash_raw_entry)] #![feature(in_band_lifetimes)] -#![feature(iter_map_while)] #![feature(maybe_uninit_uninit_array)] #![feature(min_specialization)] #![feature(never_type)] diff --git a/compiler/rustc_driver/Cargo.toml b/compiler/rustc_driver/Cargo.toml index ba8616cc6ef..6721e00027d 100644 --- a/compiler/rustc_driver/Cargo.toml +++ b/compiler/rustc_driver/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_driver" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] crate-type = ["dylib"] diff --git a/compiler/rustc_error_codes/Cargo.toml b/compiler/rustc_error_codes/Cargo.toml index 270e5301895..7d5f3e4672a 100644 --- a/compiler/rustc_error_codes/Cargo.toml +++ b/compiler/rustc_error_codes/Cargo.toml @@ -1,4 +1,4 @@ [package] name = "rustc_error_codes" version = "0.0.0" -edition = "2018" +edition = "2021" diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index c74fd60e530..4846dc43605 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_errors" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index b1526cf78d2..60a48b5a2d9 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -13,9 +13,11 @@ #[macro_use] extern crate rustc_macros; +#[macro_use] +extern crate tracing; + pub use emitter::ColorConfig; -use tracing::debug; use Level::*; use emitter::{is_case_difference, Emitter, EmitterWriter}; @@ -1028,15 +1030,13 @@ impl HandlerInner { let mut error_codes = self .emitted_diagnostic_codes .iter() - .filter_map(|x| { - match &x { + .filter_map(|x| match &x { DiagnosticId::Error(s) - if let Ok(Some(_explanation)) = registry.try_find_description(s) => + if registry.try_find_description(s).map_or(false, |o| o.is_some()) => { Some(s.clone()) } _ => None, - } }) .collect::<Vec<_>>(); if !error_codes.is_empty() { diff --git a/compiler/rustc_expand/Cargo.toml b/compiler/rustc_expand/Cargo.toml index 1be9321e4fe..45237ab2e9f 100644 --- a/compiler/rustc_expand/Cargo.toml +++ b/compiler/rustc_expand/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_expand" version = "0.0.0" -edition = "2018" +edition = "2021" build = false [lib] diff --git a/compiler/rustc_feature/Cargo.toml b/compiler/rustc_feature/Cargo.toml index ee381e34251..3d8d0db20d1 100644 --- a/compiler/rustc_feature/Cargo.toml +++ b/compiler/rustc_feature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_feature" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index efa93c18636..ecc2de14a79 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -675,6 +675,12 @@ declare_features! ( /// Allows `let...else` statements. (active, let_else, "1.56.0", Some(87335), None), + /// Allows the `#[must_not_suspend]` attribute. + (active, must_not_suspend, "1.57.0", Some(83310), None), + + /// Allows `#[track_caller]` on closures and generators. + (active, closure_track_caller, "1.57.0", Some(87417), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index f74ea0e0c4d..f3eaf2645f5 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -202,6 +202,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ungated!(forbid, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)), ungated!(deny, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)), ungated!(must_use, Normal, template!(Word, NameValueStr: "reason")), + gated!( + must_not_suspend, Normal, template!(Word, NameValueStr: "reason"), must_not_suspend, + experimental!(must_not_suspend) + ), // FIXME(#14407) ungated!( deprecated, Normal, diff --git a/compiler/rustc_fs_util/Cargo.toml b/compiler/rustc_fs_util/Cargo.toml index c417e978b31..34c3fe2a005 100644 --- a/compiler/rustc_fs_util/Cargo.toml +++ b/compiler/rustc_fs_util/Cargo.toml @@ -1,4 +1,4 @@ [package] name = "rustc_fs_util" version = "0.0.0" -edition = "2018" +edition = "2021" diff --git a/compiler/rustc_graphviz/Cargo.toml b/compiler/rustc_graphviz/Cargo.toml index 87c41ae171e..d657fdb1a77 100644 --- a/compiler/rustc_graphviz/Cargo.toml +++ b/compiler/rustc_graphviz/Cargo.toml @@ -1,4 +1,4 @@ [package] name = "rustc_graphviz" version = "0.0.0" -edition = "2018" +edition = "2021" diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml index 61b941fd756..3b6e6db72d1 100644 --- a/compiler/rustc_hir/Cargo.toml +++ b/compiler/rustc_hir/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_hir" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index 3e8b98e9f54..f07e52e04da 100644 --- a/compiler/rustc_hir/src/arena.rs +++ b/compiler/rustc_hir/src/arena.rs @@ -28,9 +28,9 @@ macro_rules! arena_types { [] pat_field: rustc_hir::PatField<$tcx>, [] fn_decl: rustc_hir::FnDecl<$tcx>, [] foreign_item: rustc_hir::ForeignItem<$tcx>, - [few] foreign_item_ref: rustc_hir::ForeignItemRef<$tcx>, + [few] foreign_item_ref: rustc_hir::ForeignItemRef, [] impl_item: rustc_hir::ImplItem<$tcx>, - [] impl_item_ref: rustc_hir::ImplItemRef<$tcx>, + [] impl_item_ref: rustc_hir::ImplItemRef, [] item: rustc_hir::Item<$tcx>, [few] inline_asm: rustc_hir::InlineAsm<$tcx>, [few] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index f5fc693ce25..05b652fd5af 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2745,7 +2745,7 @@ pub enum ItemKind<'hir> { /// A module. Mod(Mod<'hir>), /// An external module, e.g. `extern { .. }`. - ForeignMod { abi: Abi, items: &'hir [ForeignItemRef<'hir>] }, + ForeignMod { abi: Abi, items: &'hir [ForeignItemRef] }, /// Module-level inline assembly (from `global_asm!`). GlobalAsm(&'hir InlineAsm<'hir>), /// A type alias, e.g., `type Foo = Bar<u8>`. @@ -2782,7 +2782,7 @@ pub struct Impl<'hir> { pub of_trait: Option<TraitRef<'hir>>, pub self_ty: &'hir Ty<'hir>, - pub items: &'hir [ImplItemRef<'hir>], + pub items: &'hir [ImplItemRef], } impl ItemKind<'_> { @@ -2846,13 +2846,12 @@ pub struct TraitItemRef { /// passes to find the impl they want without loading the ID (which /// means fewer edges in the incremental compilation graph). #[derive(Debug, HashStable_Generic)] -pub struct ImplItemRef<'hir> { +pub struct ImplItemRef { pub id: ImplItemId, #[stable_hasher(project(name))] pub ident: Ident, pub kind: AssocItemKind, pub span: Span, - pub vis: Visibility<'hir>, pub defaultness: Defaultness, } @@ -2886,12 +2885,11 @@ impl ForeignItemId { /// passes to find the impl they want without loading the ID (which /// means fewer edges in the incremental compilation graph). #[derive(Debug, HashStable_Generic)] -pub struct ForeignItemRef<'hir> { +pub struct ForeignItemRef { pub id: ForeignItemId, #[stable_hasher(project(name))] pub ident: Ident, pub span: Span, - pub vis: Visibility<'hir>, } #[derive(Debug)] diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 137782a6dc7..1ac2625dd47 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -392,10 +392,10 @@ pub trait Visitor<'v>: Sized { fn visit_impl_item(&mut self, ii: &'v ImplItem<'v>) { walk_impl_item(self, ii) } - fn visit_foreign_item_ref(&mut self, ii: &'v ForeignItemRef<'v>) { + fn visit_foreign_item_ref(&mut self, ii: &'v ForeignItemRef) { walk_foreign_item_ref(self, ii) } - fn visit_impl_item_ref(&mut self, ii: &'v ImplItemRef<'v>) { + fn visit_impl_item_ref(&mut self, ii: &'v ImplItemRef) { walk_impl_item_ref(self, ii) } fn visit_trait_ref(&mut self, t: &'v TraitRef<'v>) { @@ -1042,22 +1042,20 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt pub fn walk_foreign_item_ref<'v, V: Visitor<'v>>( visitor: &mut V, - foreign_item_ref: &'v ForeignItemRef<'v>, + foreign_item_ref: &'v ForeignItemRef, ) { // N.B., deliberately force a compilation error if/when new fields are added. - let ForeignItemRef { id, ident, span: _, ref vis } = *foreign_item_ref; + let ForeignItemRef { id, ident, span: _ } = *foreign_item_ref; visitor.visit_nested_foreign_item(id); visitor.visit_ident(ident); - visitor.visit_vis(vis); } -pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &'v ImplItemRef<'v>) { +pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &'v ImplItemRef) { // N.B., deliberately force a compilation error if/when new fields are added. - let ImplItemRef { id, ident, ref kind, span: _, ref vis, ref defaultness } = *impl_item_ref; + let ImplItemRef { id, ident, ref kind, span: _, ref defaultness } = *impl_item_ref; visitor.visit_nested_impl_item(id); visitor.visit_ident(ident); visitor.visit_associated_item_kind(kind); - visitor.visit_vis(vis); visitor.visit_defaultness(defaultness); } diff --git a/compiler/rustc_hir_pretty/Cargo.toml b/compiler/rustc_hir_pretty/Cargo.toml index c7510b7ec14..46a8e7deeed 100644 --- a/compiler/rustc_hir_pretty/Cargo.toml +++ b/compiler/rustc_hir_pretty/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_hir_pretty" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_incremental/Cargo.toml b/compiler/rustc_incremental/Cargo.toml index 9156243a10c..dece752c194 100644 --- a/compiler/rustc_incremental/Cargo.toml +++ b/compiler/rustc_incremental/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_incremental" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_index/Cargo.toml b/compiler/rustc_index/Cargo.toml index e1a2b619763..b984a1321e0 100644 --- a/compiler/rustc_index/Cargo.toml +++ b/compiler/rustc_index/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_index" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index aeb3f9970ab..5b1add4cfc6 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -1072,13 +1072,9 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> { } fn ensure_row(&mut self, row: R) -> &mut HybridBitSet<C> { - // Instantiate any missing rows up to and including row `row` with an - // empty HybridBitSet. - self.rows.ensure_contains_elem(row, || None); - + // Instantiate any missing rows up to and including row `row` with an empty HybridBitSet. // Then replace row `row` with a full HybridBitSet if necessary. - let num_columns = self.num_columns; - self.rows[row].get_or_insert_with(|| HybridBitSet::new_empty(num_columns)) + self.rows.get_or_insert_with(row, || HybridBitSet::new_empty(self.num_columns)) } /// Sets the cell at `(row, column)` to true. Put another way, insert diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 246fa28d986..8535a7c866d 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -720,6 +720,21 @@ impl<I: Idx, T> IndexVec<I, T> { } } +/// `IndexVec` is often used as a map, so it provides some map-like APIs. +impl<I: Idx, T> IndexVec<I, Option<T>> { + #[inline] + pub fn insert(&mut self, index: I, value: T) -> Option<T> { + self.ensure_contains_elem(index, || None); + self[index].replace(value) + } + + #[inline] + pub fn get_or_insert_with(&mut self, index: I, value: impl FnOnce() -> T) -> &mut T { + self.ensure_contains_elem(index, || None); + self[index].get_or_insert_with(value) + } +} + impl<I: Idx, T: Clone> IndexVec<I, T> { #[inline] pub fn resize(&mut self, new_len: usize, value: T) { diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml index 15649bb678e..f87ea43b1a7 100644 --- a/compiler/rustc_infer/Cargo.toml +++ b/compiler/rustc_infer/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_infer" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 354b8e26d53..43d3730c049 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -64,6 +64,7 @@ mod lub; pub mod nll_relate; pub mod opaque_types; pub mod outlives; +mod projection; pub mod region_constraints; pub mod resolve; mod sub; diff --git a/compiler/rustc_infer/src/infer/projection.rs b/compiler/rustc_infer/src/infer/projection.rs new file mode 100644 index 00000000000..9b53ab72b00 --- /dev/null +++ b/compiler/rustc_infer/src/infer/projection.rs @@ -0,0 +1,39 @@ +use rustc_middle::traits::ObligationCause; +use rustc_middle::ty::{self, ToPredicate, Ty}; + +use crate::traits::{Obligation, PredicateObligation}; + +use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use super::InferCtxt; + +impl<'a, 'tcx> InferCtxt<'a, 'tcx> { + /// Instead of normalizing an associated type projection, + /// this function generates an inference variable and registers + /// an obligation that this inference variable must be the result + /// of the given projection. This allows us to proceed with projections + /// while they cannot be resolved yet due to missing information or + /// simply due to the lack of access to the trait resolution machinery. + pub fn infer_projection( + &self, + param_env: ty::ParamEnv<'tcx>, + projection_ty: ty::ProjectionTy<'tcx>, + cause: ObligationCause<'tcx>, + recursion_depth: usize, + obligations: &mut Vec<PredicateObligation<'tcx>>, + ) -> Ty<'tcx> { + let def_id = projection_ty.item_def_id; + let ty_var = self.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::NormalizeProjectionType, + span: self.tcx.def_span(def_id), + }); + let projection = ty::Binder::dummy(ty::ProjectionPredicate { projection_ty, ty: ty_var }); + let obligation = Obligation::with_depth( + cause, + recursion_depth, + param_env, + projection.to_predicate(self.tcx), + ); + obligations.push(obligation); + ty_var + } +} diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index e76fa6d8a1b..07af2201f5f 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_interface" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index a5f0c014778..3d90a6c9345 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -125,6 +125,7 @@ pub fn scoped_thread<F: FnOnce() -> R + Send, R: Send>(cfg: thread::Builder, f: let result_ptr = Ptr(&mut result as *mut _ as *mut ()); let thread = cfg.spawn(move || { + let _ = (&run, &result_ptr); let run = unsafe { (*(run.0 as *mut Option<F>)).take().unwrap() }; let result = unsafe { &mut *(result_ptr.0 as *mut Option<R>) }; *result = Some(run()); diff --git a/compiler/rustc_lexer/Cargo.toml b/compiler/rustc_lexer/Cargo.toml index 7e05fe545ca..60c146f457b 100644 --- a/compiler/rustc_lexer/Cargo.toml +++ b/compiler/rustc_lexer/Cargo.toml @@ -2,7 +2,7 @@ name = "rustc_lexer" version = "0.1.0" license = "MIT OR Apache-2.0" -edition = "2018" +edition = "2021" repository = "https://github.com/rust-lang/rust/" description = """ diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml index 8294d5878fa..414fcbeb9e4 100644 --- a/compiler/rustc_lint/Cargo.toml +++ b/compiler/rustc_lint/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_lint" version = "0.0.0" -edition = "2018" +edition = "2021" [dependencies] if_chain = "1.0" diff --git a/compiler/rustc_lint/src/array_into_iter.rs b/compiler/rustc_lint/src/array_into_iter.rs index 5ac42c50c72..1facd973754 100644 --- a/compiler/rustc_lint/src/array_into_iter.rs +++ b/compiler/rustc_lint/src/array_into_iter.rs @@ -13,7 +13,7 @@ declare_lint! { /// /// ### Example /// - /// ```rust + /// ```rust,edition2018 /// # #![allow(unused)] /// [1, 2, 3].into_iter().for_each(|n| { *n; }); /// ``` diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 2850e7a6b44..e1bcc3aa52b 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1686,7 +1686,7 @@ declare_lint! { /// /// ### Example /// - /// ```rust + /// ```rust,edition2018 /// let x = 123; /// match x { /// 0...100 => {} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index ef4bda666ba..10285272130 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -298,6 +298,7 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) { UNUSED_LABELS, UNUSED_PARENS, UNUSED_BRACES, + MUST_NOT_SUSPEND, REDUNDANT_SEMICOLONS ); diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index 33a6edafa26..ae9c5ce5c3c 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -18,7 +18,7 @@ declare_lint! { /// /// ### Example /// - /// ```rust,no_run + /// ```rust,no_run,edition2018 /// panic!("{}"); /// panic!(123); /// ``` diff --git a/compiler/rustc_lint_defs/Cargo.toml b/compiler/rustc_lint_defs/Cargo.toml index f9ada5cc95f..798d50819e2 100644 --- a/compiler/rustc_lint_defs/Cargo.toml +++ b/compiler/rustc_lint_defs/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_lint_defs" version = "0.0.0" -edition = "2018" +edition = "2021" [dependencies] rustc_ast = { path = "../rustc_ast" } diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index a00561e5213..5830ce26fea 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -315,6 +315,44 @@ declare_lint! { } declare_lint! { + /// The `must_not_suspend` lint guards against values that shouldn't be held across suspend points + /// (`.await`) + /// + /// ### Example + /// + /// ```rust + /// #![feature(must_not_suspend)] + /// + /// #[must_not_suspend] + /// struct SyncThing {} + /// + /// async fn yield_now() {} + /// + /// pub async fn uhoh() { + /// let guard = SyncThing {}; + /// yield_now().await; + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// The `must_not_suspend` lint detects values that are marked with the `#[must_not_suspend]` + /// attribute being held across suspend points. A "suspend" point is usually a `.await` in an async + /// function. + /// + /// This attribute can be used to mark values that are semantically incorrect across suspends + /// (like certain types of timers), values that have async alternatives, and values that + /// regularly cause problems with the `Send`-ness of async fn's returned futures (like + /// `MutexGuard`'s) + /// + pub MUST_NOT_SUSPEND, + Warn, + "use of a `#[must_not_suspend]` value across a yield point", +} + +declare_lint! { /// The `unused_extern_crates` lint guards against `extern crate` items /// that are never used. /// @@ -1584,7 +1622,7 @@ declare_lint! { /// /// ### Example /// - /// ```rust + /// ```rust,edition2018 /// trait Trait { } /// /// fn takes_trait_object(_: Box<Trait>) { @@ -2993,6 +3031,7 @@ declare_lint_pass! { CENUM_IMPL_DROP_CAST, CONST_EVALUATABLE_UNCHECKED, INEFFECTIVE_UNSTABLE_TRAIT_IMPL, + MUST_NOT_SUSPEND, UNINHABITED_STATIC, FUNCTION_ITEM_REFERENCES, USELESS_DEPRECATED, @@ -3313,7 +3352,7 @@ declare_lint! { /// /// ### Example /// - /// ```rust,compile_fail + /// ```rust,edition2018,compile_fail /// #![deny(rust_2021_prefixes_incompatible_syntax)] /// /// macro_rules! m { @@ -3333,6 +3372,8 @@ declare_lint! { /// /// This lint suggests to add whitespace between the `z` and `"hey"` tokens /// to keep them separated in Rust 2021. + // Allow this lint -- rustdoc doesn't yet support threading edition into this lint's parser. + #[allow(rustdoc::invalid_rust_codeblocks)] pub RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX, Allow, "identifiers that will be parsed as a prefix in Rust 2021", diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml index 2f0f3dd9ecb..d8dfcc84e68 100644 --- a/compiler/rustc_llvm/Cargo.toml +++ b/compiler/rustc_llvm/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_llvm" version = "0.0.0" -edition = "2018" +edition = "2021" [features] static-libstdcpp = [] diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 8dbacd71fc1..1a0cfd58885 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -1747,7 +1747,7 @@ LLVMRustGetBitcodeSliceFromObjectData(const char *data, // Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See // the comment in `back/lto.rs` for why this exists. extern "C" void -LLVMRustThinLTOGetDICompileUnit(LLVMModuleRef Mod, +LLVMRustLTOGetDICompileUnit(LLVMModuleRef Mod, DICompileUnit **A, DICompileUnit **B) { Module *M = unwrap(Mod); @@ -1765,7 +1765,7 @@ LLVMRustThinLTOGetDICompileUnit(LLVMModuleRef Mod, // Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See // the comment in `back/lto.rs` for why this exists. extern "C" void -LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) { +LLVMRustLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) { Module *M = unwrap(Mod); // If the original source module didn't have a `DICompileUnit` then try to diff --git a/compiler/rustc_macros/Cargo.toml b/compiler/rustc_macros/Cargo.toml index e4dddbab067..a9192be4d6e 100644 --- a/compiler/rustc_macros/Cargo.toml +++ b/compiler/rustc_macros/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_macros" version = "0.1.0" -edition = "2018" +edition = "2021" [lib] proc-macro = true diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index 6b874aafa10..f71fefd1799 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_metadata" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs index cd368b8c56d..6637dbd1901 100644 --- a/compiler/rustc_metadata/src/dependency_format.rs +++ b/compiler/rustc_metadata/src/dependency_format.rs @@ -11,10 +11,10 @@ //! should be used when linking each output type requested in this session. This //! generally follows this set of rules: //! -//! 1. Each library must appear exactly once in the output. -//! 2. Each rlib contains only one library (it's just an object file) -//! 3. Each dylib can contain more than one library (due to static linking), -//! and can also bring in many dynamic dependencies. +//! 1. Each library must appear exactly once in the output. +//! 2. Each rlib contains only one library (it's just an object file) +//! 3. Each dylib can contain more than one library (due to static linking), +//! and can also bring in many dynamic dependencies. //! //! With these constraints in mind, it's generally a very difficult problem to //! find a solution that's not "all rlibs" or "all dylibs". I have suspicions @@ -22,24 +22,24 @@ //! //! The current selection algorithm below looks mostly similar to: //! -//! 1. If static linking is required, then require all upstream dependencies -//! to be available as rlibs. If not, generate an error. -//! 2. If static linking is requested (generating an executable), then -//! attempt to use all upstream dependencies as rlibs. If any are not -//! found, bail out and continue to step 3. -//! 3. Static linking has failed, at least one library must be dynamically -//! linked. Apply a heuristic by greedily maximizing the number of -//! dynamically linked libraries. -//! 4. Each upstream dependency available as a dynamic library is -//! registered. The dependencies all propagate, adding to a map. It is -//! possible for a dylib to add a static library as a dependency, but it -//! is illegal for two dylibs to add the same static library as a -//! dependency. The same dylib can be added twice. Additionally, it is -//! illegal to add a static dependency when it was previously found as a -//! dylib (and vice versa) -//! 5. After all dynamic dependencies have been traversed, re-traverse the -//! remaining dependencies and add them statically (if they haven't been -//! added already). +//! 1. If static linking is required, then require all upstream dependencies +//! to be available as rlibs. If not, generate an error. +//! 2. If static linking is requested (generating an executable), then +//! attempt to use all upstream dependencies as rlibs. If any are not +//! found, bail out and continue to step 3. +//! 3. Static linking has failed, at least one library must be dynamically +//! linked. Apply a heuristic by greedily maximizing the number of +//! dynamically linked libraries. +//! 4. Each upstream dependency available as a dynamic library is +//! registered. The dependencies all propagate, adding to a map. It is +//! possible for a dylib to add a static library as a dependency, but it +//! is illegal for two dylibs to add the same static library as a +//! dependency. The same dylib can be added twice. Additionally, it is +//! illegal to add a static dependency when it was previously found as a +//! dylib (and vice versa) +//! 5. After all dynamic dependencies have been traversed, re-traverse the +//! remaining dependencies and add them statically (if they haven't been +//! added already). //! //! While not perfect, this algorithm should help support use-cases such as leaf //! dependencies being static while the larger tree of inner dependencies are diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 5f0d8c46f20..5ad55dbf5c8 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -382,7 +382,7 @@ impl Collector<'tcx> { } } - fn i686_arg_list_size(&self, item: &hir::ForeignItemRef<'_>) -> usize { + fn i686_arg_list_size(&self, item: &hir::ForeignItemRef) -> usize { let argument_types: &List<Ty<'_>> = self.tcx.erase_late_bound_regions( self.tcx .type_of(item.id.def_id) @@ -406,7 +406,7 @@ impl Collector<'tcx> { .sum() } - fn build_dll_import(&self, abi: Abi, item: &hir::ForeignItemRef<'_>) -> DllImport { + fn build_dll_import(&self, abi: Abi, item: &hir::ForeignItemRef) -> DllImport { let calling_convention = if self.tcx.sess.target.arch == "x86" { match abi { Abi::C { .. } | Abi::Cdecl => DllCallingConvention::C, diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 68b83fccc85..b1fcc34bee1 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_middle" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_middle/src/hir/map/collector.rs b/compiler/rustc_middle/src/hir/map/collector.rs index 082948eba41..5ecb1c9b0ff 100644 --- a/compiler/rustc_middle/src/hir/map/collector.rs +++ b/compiler/rustc_middle/src/hir/map/collector.rs @@ -413,18 +413,18 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { self.visit_nested_trait_item(id); } - fn visit_impl_item_ref(&mut self, ii: &'hir ImplItemRef<'hir>) { + fn visit_impl_item_ref(&mut self, ii: &'hir ImplItemRef) { // Do not visit the duplicate information in ImplItemRef. We want to // map the actual nodes, not the duplicate ones in the *Ref. - let ImplItemRef { id, ident: _, kind: _, span: _, vis: _, defaultness: _ } = *ii; + let ImplItemRef { id, ident: _, kind: _, span: _, defaultness: _ } = *ii; self.visit_nested_impl_item(id); } - fn visit_foreign_item_ref(&mut self, fi: &'hir ForeignItemRef<'hir>) { + fn visit_foreign_item_ref(&mut self, fi: &'hir ForeignItemRef) { // Do not visit the duplicate information in ForeignItemRef. We want to // map the actual nodes, not the duplicate ones in the *Ref. - let ForeignItemRef { id, ident: _, span: _, vis: _ } = *fi; + let ForeignItemRef { id, ident: _, span: _ } = *fi; self.visit_nested_foreign_item(id); } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 0c2c653e92e..3707fadadac 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -83,12 +83,12 @@ pub struct Map<'hir> { /// An iterator that walks up the ancestor tree of a given `HirId`. /// Constructed using `tcx.hir().parent_iter(hir_id)`. -pub struct ParentHirIterator<'map, 'hir> { +pub struct ParentHirIterator<'hir> { current_id: HirId, - map: &'map Map<'hir>, + map: Map<'hir>, } -impl<'hir> Iterator for ParentHirIterator<'_, 'hir> { +impl<'hir> Iterator for ParentHirIterator<'hir> { type Item = (HirId, Node<'hir>); fn next(&mut self) -> Option<Self::Item> { @@ -115,12 +115,12 @@ impl<'hir> Iterator for ParentHirIterator<'_, 'hir> { /// An iterator that walks up the ancestor tree of a given `HirId`. /// Constructed using `tcx.hir().parent_owner_iter(hir_id)`. -pub struct ParentOwnerIterator<'map, 'hir> { +pub struct ParentOwnerIterator<'hir> { current_id: HirId, - map: &'map Map<'hir>, + map: Map<'hir>, } -impl<'hir> Iterator for ParentOwnerIterator<'_, 'hir> { +impl<'hir> Iterator for ParentOwnerIterator<'hir> { type Item = (HirId, OwnerNode<'hir>); fn next(&mut self) -> Option<Self::Item> { @@ -588,13 +588,13 @@ impl<'hir> Map<'hir> { /// Returns an iterator for the nodes in the ancestor tree of the `current_id` /// until the crate root is reached. Prefer this over your own loop using `get_parent_node`. - pub fn parent_iter(&self, current_id: HirId) -> ParentHirIterator<'_, 'hir> { + pub fn parent_iter(self, current_id: HirId) -> ParentHirIterator<'hir> { ParentHirIterator { current_id, map: self } } /// Returns an iterator for the nodes in the ancestor tree of the `current_id` /// until the crate root is reached. Prefer this over your own loop using `get_parent_node`. - pub fn parent_owner_iter(&self, current_id: HirId) -> ParentOwnerIterator<'_, 'hir> { + pub fn parent_owner_iter(self, current_id: HirId) -> ParentOwnerIterator<'hir> { ParentOwnerIterator { current_id, map: self } } diff --git a/compiler/rustc_middle/src/ich/impls_ty.rs b/compiler/rustc_middle/src/ich/impls_ty.rs index 8e53e4ba948..3b0640eb98d 100644 --- a/compiler/rustc_middle/src/ich/impls_ty.rs +++ b/compiler/rustc_middle/src/ich/impls_ty.rs @@ -90,7 +90,10 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionKind { ty::ReFree(ref free_region) => { free_region.hash_stable(hcx, hasher); } - ty::ReVar(..) | ty::RePlaceholder(..) => { + ty::RePlaceholder(p) => { + p.hash_stable(hcx, hasher); + } + ty::ReVar(..) => { bug!("StableHasher: unexpected region {:?}", *self) } } diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs index bd4e83a42ef..e271f59da87 100644 --- a/compiler/rustc_middle/src/middle/region.rs +++ b/compiler/rustc_middle/src/middle/region.rs @@ -257,7 +257,8 @@ pub struct ScopeTree { /// ``` /// /// With the HIR tree (calls numbered for expository purposes) - /// ``` + /// + /// ```text /// Call#0(foo, [Call#1(f), Yield(y), Call#2(bar, Call#3(g))]) /// ``` /// diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index af7f7796522..13bbb8d1f53 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -348,7 +348,7 @@ macro_rules! make_mir_visitor { ty::InstanceDef::VtableShim(_def_id) | ty::InstanceDef::ReifyShim(_def_id) | ty::InstanceDef::Virtual(_def_id, _) | - ty::InstanceDef::ClosureOnceShim { call_once: _def_id } | + ty::InstanceDef::ClosureOnceShim { call_once: _def_id, track_caller: _ } | ty::InstanceDef::DropGlue(_def_id, None) => {} ty::InstanceDef::FnPtrShim(_def_id, ty) | diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 261a19f862e..9b8247fd028 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -77,7 +77,7 @@ pub enum InstanceDef<'tcx> { /// `<[FnMut closure] as FnOnce>::call_once`. /// /// The `DefId` is the ID of the `call_once` method in `FnOnce`. - ClosureOnceShim { call_once: DefId }, + ClosureOnceShim { call_once: DefId, track_caller: bool }, /// `core::ptr::drop_in_place::<T>`. /// @@ -146,7 +146,7 @@ impl<'tcx> InstanceDef<'tcx> { | InstanceDef::FnPtrShim(def_id, _) | InstanceDef::Virtual(def_id, _) | InstanceDef::Intrinsic(def_id) - | InstanceDef::ClosureOnceShim { call_once: def_id } + | InstanceDef::ClosureOnceShim { call_once: def_id, track_caller: _ } | InstanceDef::DropGlue(def_id, _) | InstanceDef::CloneShim(def_id, _) => def_id, } @@ -161,7 +161,7 @@ impl<'tcx> InstanceDef<'tcx> { | InstanceDef::FnPtrShim(def_id, _) | InstanceDef::Virtual(def_id, _) | InstanceDef::Intrinsic(def_id) - | InstanceDef::ClosureOnceShim { call_once: def_id } + | InstanceDef::ClosureOnceShim { call_once: def_id, track_caller: _ } | InstanceDef::DropGlue(def_id, _) | InstanceDef::CloneShim(def_id, _) => ty::WithOptConstParam::unknown(def_id), } @@ -231,6 +231,7 @@ impl<'tcx> InstanceDef<'tcx> { | InstanceDef::Virtual(def_id, _) => { tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER) } + InstanceDef::ClosureOnceShim { call_once: _, track_caller } => track_caller, _ => false, } } @@ -381,6 +382,8 @@ impl<'tcx> Instance<'tcx> { substs: SubstsRef<'tcx>, ) -> Option<Instance<'tcx>> { debug!("resolve(def_id={:?}, substs={:?})", def_id, substs); + // Use either `resolve_closure` or `resolve_for_vtable` + assert!(!tcx.is_closure(def_id), "Called `resolve_for_fn_ptr` on closure: {:?}", def_id); Instance::resolve(tcx, param_env, def_id, substs).ok().flatten().map(|mut resolved| { match resolved.def { InstanceDef::Item(def) if resolved.def.requires_caller_location(tcx) => { @@ -442,10 +445,20 @@ impl<'tcx> Instance<'tcx> { }) ) { - debug!( - " => vtable fn pointer created for function with #[track_caller]" - ); - resolved.def = InstanceDef::ReifyShim(def.did); + if tcx.is_closure(def.did) { + debug!(" => vtable fn pointer created for closure with #[track_caller]: {:?} for method {:?} {:?}", + def.did, def_id, substs); + + // Create a shim for the `FnOnce/FnMut/Fn` method we are calling + // - unlike functions, invoking a closure always goes through a + // trait. + resolved = Instance { def: InstanceDef::ReifyShim(def_id), substs }; + } else { + debug!( + " => vtable fn pointer created for function with #[track_caller]: {:?}", def.did + ); + resolved.def = InstanceDef::ReifyShim(def.did); + } } } InstanceDef::Virtual(def_id, _) => { @@ -493,7 +506,9 @@ impl<'tcx> Instance<'tcx> { .find(|it| it.kind == ty::AssocKind::Fn) .unwrap() .def_id; - let def = ty::InstanceDef::ClosureOnceShim { call_once }; + let track_caller = + tcx.codegen_fn_attrs(closure_did).flags.contains(CodegenFnAttrFlags::TRACK_CALLER); + let def = ty::InstanceDef::ClosureOnceShim { call_once, track_caller }; let self_ty = tcx.mk_closure(closure_did, substs); diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 9d1be212f5b..2c786538014 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -639,6 +639,15 @@ fn check_const_value_eq<R: TypeRelation<'tcx>>( get_slice_bytes(&tcx, a_val) == get_slice_bytes(&tcx, b_val) } + (ConstValue::ByRef { alloc: alloc_a, .. }, ConstValue::ByRef { alloc: alloc_b, .. }) + if a.ty.is_ref() || b.ty.is_ref() => + { + if a.ty.is_ref() && b.ty.is_ref() { + alloc_a == alloc_b + } else { + false + } + } (ConstValue::ByRef { .. }, ConstValue::ByRef { .. }) => { let a_destructured = tcx.destructure_const(relation.param_env().and(a)); let b_destructured = tcx.destructure_const(relation.param_env().and(b)); diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 89ad99d9f07..8f343ba9fec 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -638,8 +638,8 @@ impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> { Some(ty::InstanceDef::FnPtrShim(def_id, tcx.lift(ty)?)) } ty::InstanceDef::Virtual(def_id, n) => Some(ty::InstanceDef::Virtual(def_id, n)), - ty::InstanceDef::ClosureOnceShim { call_once } => { - Some(ty::InstanceDef::ClosureOnceShim { call_once }) + ty::InstanceDef::ClosureOnceShim { call_once, track_caller } => { + Some(ty::InstanceDef::ClosureOnceShim { call_once, track_caller }) } ty::InstanceDef::DropGlue(def_id, ty) => { Some(ty::InstanceDef::DropGlue(def_id, tcx.lift(ty)?)) @@ -824,8 +824,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { Intrinsic(did) => Intrinsic(did.fold_with(folder)), FnPtrShim(did, ty) => FnPtrShim(did.fold_with(folder), ty.fold_with(folder)), Virtual(did, i) => Virtual(did.fold_with(folder), i), - ClosureOnceShim { call_once } => { - ClosureOnceShim { call_once: call_once.fold_with(folder) } + ClosureOnceShim { call_once, track_caller } => { + ClosureOnceShim { call_once: call_once.fold_with(folder), track_caller } } DropGlue(did, ty) => DropGlue(did.fold_with(folder), ty.fold_with(folder)), CloneShim(did, ty) => CloneShim(did.fold_with(folder), ty.fold_with(folder)), @@ -849,7 +849,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { did.visit_with(visitor)?; ty.visit_with(visitor) } - ClosureOnceShim { call_once } => call_once.visit_with(visitor), + ClosureOnceShim { call_once, track_caller: _ } => call_once.visit_with(visitor), } } } diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml index e9fbc1b186d..998b80a36c2 100644 --- a/compiler/rustc_mir_build/Cargo.toml +++ b/compiler/rustc_mir_build/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_mir_build" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 0ee740a6463..4108ad50470 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -44,15 +44,18 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_ let body_owner_kind = tcx.hir().body_owner_kind(id); let typeck_results = tcx.typeck_opt_const_arg(def); - // Ensure unsafeck is ran before we steal the THIR. + // Ensure unsafeck and abstract const building is ran before we steal the THIR. + // We can't use `ensure()` for `thir_abstract_const` as it doesn't compute the query + // if inputs are green. This can cause ICEs when calling `thir_abstract_const` after + // THIR has been stolen if we haven't computed this query yet. match def { ty::WithOptConstParam { did, const_param_did: Some(const_param_did) } => { tcx.ensure().thir_check_unsafety_for_const_arg((did, const_param_did)); - tcx.ensure().thir_abstract_const_of_const_arg((did, const_param_did)); + drop(tcx.thir_abstract_const_of_const_arg((did, const_param_did))); } ty::WithOptConstParam { did, const_param_did: None } => { tcx.ensure().thir_check_unsafety(did); - tcx.ensure().thir_abstract_const(did); + drop(tcx.thir_abstract_const(did)); } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index bbb5de34d18..847b89f0464 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -322,16 +322,18 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { && !self.saw_const_match_lint.get() { self.saw_const_match_lint.set(true); - let msg = format!( - "to use a constant of type `{}` in a pattern, \ - `{}` must be annotated with `#[derive(PartialEq, Eq)]`", - cv.ty, cv.ty, - ); tcx.struct_span_lint_hir( lint::builtin::INDIRECT_STRUCTURAL_MATCH, id, span, - |lint| lint.build(&msg).emit(), + |lint| { + let msg = format!( + "to use a constant of type `{}` in a pattern, \ + `{}` must be annotated with `#[derive(PartialEq, Eq)]`", + cv.ty, cv.ty, + ); + lint.build(&msg).emit() + }, ); } // Since we are behind a reference, we can just bubble the error up so we get a diff --git a/compiler/rustc_mir_dataflow/Cargo.toml b/compiler/rustc_mir_dataflow/Cargo.toml index 3cd4892402e..ffd7e3cd06b 100644 --- a/compiler/rustc_mir_dataflow/Cargo.toml +++ b/compiler/rustc_mir_dataflow/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_mir_dataflow" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_mir_transform/Cargo.toml b/compiler/rustc_mir_transform/Cargo.toml index 5e1a587b0ec..bde4e215a2a 100644 --- a/compiler/rustc_mir_transform/Cargo.toml +++ b/compiler/rustc_mir_transform/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_mir_transform" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_mir_transform/src/coverage/test_macros/Cargo.toml b/compiler/rustc_mir_transform/src/coverage/test_macros/Cargo.toml index cc93fd482b5..f5e8b65656a 100644 --- a/compiler/rustc_mir_transform/src/coverage/test_macros/Cargo.toml +++ b/compiler/rustc_mir_transform/src/coverage/test_macros/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "coverage_test_macros" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] proc-macro = true diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 4d350fc87cb..f2ea5fedc62 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -53,7 +53,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<' ty::InstanceDef::ReifyShim(def_id) => { build_call_shim(tcx, instance, None, CallKind::Direct(def_id)) } - ty::InstanceDef::ClosureOnceShim { call_once: _ } => { + ty::InstanceDef::ClosureOnceShim { call_once: _, track_caller: _ } => { let fn_mut = tcx.require_lang_item(LangItem::FnMut, None); let call_mut = tcx .associated_items(fn_mut) diff --git a/compiler/rustc_monomorphize/Cargo.toml b/compiler/rustc_monomorphize/Cargo.toml index 350ae088777..f812afe6b62 100644 --- a/compiler/rustc_monomorphize/Cargo.toml +++ b/compiler/rustc_monomorphize/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_monomorphize" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_parse/Cargo.toml b/compiler/rustc_parse/Cargo.toml index 1ca1a92252e..1decaaa955f 100644 --- a/compiler/rustc_parse/Cargo.toml +++ b/compiler/rustc_parse/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_parse" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index aa6b424ce2b..cef5b3a226b 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -3,7 +3,7 @@ use std::iter::once; use std::ops::Range; -use rustc_errors::{Applicability, Handler}; +use rustc_errors::{pluralize, Applicability, Handler}; use rustc_lexer::unescape::{EscapeError, Mode}; use rustc_span::{BytePos, Span}; @@ -49,24 +49,57 @@ pub(crate) fn emit_unescape_error( .emit(); } EscapeError::MoreThanOneChar => { - let (prefix, msg) = if mode.is_bytes() { - ("b", "if you meant to write a byte string literal, use double quotes") - } else { - ("", "if you meant to write a `str` literal, use double quotes") - }; + use unicode_normalization::{char::is_combining_mark, UnicodeNormalization}; - handler - .struct_span_err( - span_with_quotes, - "character literal may only contain one codepoint", - ) - .span_suggestion( + let mut has_help = false; + let mut handler = handler.struct_span_err( + span_with_quotes, + "character literal may only contain one codepoint", + ); + + if lit.chars().skip(1).all(|c| is_combining_mark(c)) { + let escaped_marks = + lit.chars().skip(1).map(|c| c.escape_default().to_string()).collect::<Vec<_>>(); + handler.span_note( + span, + &format!( + "this `{}` is followed by the combining mark{} `{}`", + lit.chars().next().unwrap(), + pluralize!(escaped_marks.len()), + escaped_marks.join(""), + ), + ); + let normalized = lit.nfc().to_string(); + if normalized.chars().count() == 1 { + has_help = true; + handler.span_suggestion( + span, + &format!( + "consider using the normalized form `{}` of this character", + normalized.chars().next().unwrap().escape_default() + ), + normalized, + Applicability::MachineApplicable, + ); + } + } + + if !has_help { + let (prefix, msg) = if mode.is_bytes() { + ("b", "if you meant to write a byte string literal, use double quotes") + } else { + ("", "if you meant to write a `str` literal, use double quotes") + }; + + handler.span_suggestion( span_with_quotes, msg, format!("{}\"{}\"", prefix, lit), Applicability::MachineApplicable, - ) - .emit(); + ); + } + + handler.emit(); } EscapeError::EscapeOnlyChar => { let (c, char_span) = last_char(); diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index af41a99ada4..a40f47f895b 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -6,6 +6,9 @@ #![feature(box_patterns)] #![recursion_limit = "256"] +#[macro_use] +extern crate tracing; + use rustc_ast as ast; use rustc_ast::token::{self, Nonterminal, Token, TokenKind}; use rustc_ast::tokenstream::{self, AttributesData, CanSynthesizeMissingTokens, LazyTokenStream}; diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index c62ea66b693..fe0468c6956 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1084,6 +1084,7 @@ impl<'a> Parser<'a> { /// If we encounter a parser state that looks like the user has written a `struct` literal with /// parentheses instead of braces, recover the parser state and provide suggestions. + #[instrument(skip(self, seq, snapshot), level = "trace")] fn maybe_recover_struct_lit_bad_delims( &mut self, lo: Span, diff --git a/compiler/rustc_parse_format/Cargo.toml b/compiler/rustc_parse_format/Cargo.toml index 7b77560717e..aa1714e820f 100644 --- a/compiler/rustc_parse_format/Cargo.toml +++ b/compiler/rustc_parse_format/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_parse_format" version = "0.0.0" -edition = "2018" +edition = "2021" [dependencies] rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_passes/Cargo.toml b/compiler/rustc_passes/Cargo.toml index bf1e52cd9a8..39e578bce7e 100644 --- a/compiler/rustc_passes/Cargo.toml +++ b/compiler/rustc_passes/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_passes" version = "0.0.0" -edition = "2018" +edition = "2021" [dependencies] tracing = "0.1" diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index fd438bdc900..3e59fc4f551 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -104,6 +104,7 @@ impl CheckAttrVisitor<'tcx> { sym::default_method_body_is_const => { self.check_default_method_body_is_const(attr, span, target) } + sym::must_not_suspend => self.check_must_not_suspend(&attr, span, target), sym::rustc_const_unstable | sym::rustc_const_stable | sym::unstable @@ -1014,6 +1015,21 @@ impl CheckAttrVisitor<'tcx> { is_valid } + /// Checks if `#[must_not_suspend]` is applied to a function. Returns `true` if valid. + fn check_must_not_suspend(&self, attr: &Attribute, span: &Span, target: Target) -> bool { + match target { + Target::Struct | Target::Enum | Target::Union | Target::Trait => true, + _ => { + self.tcx + .sess + .struct_span_err(attr.span, "`must_not_suspend` attribute should be applied to a struct, enum, or trait") + .span_label(*span, "is not a struct, enum, or trait") + .emit(); + false + } + } + } + /// Checks if `#[cold]` is applied to a non-function. Returns `true` if valid. fn check_cold(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) { match target { diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs index eff1096c855..0e60ca9f900 100644 --- a/compiler/rustc_passes/src/hir_id_validator.rs +++ b/compiler/rustc_passes/src/hir_id_validator.rs @@ -163,14 +163,14 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> { self.hir_ids_seen.insert(hir_id.local_id); } - fn visit_impl_item_ref(&mut self, _: &'hir hir::ImplItemRef<'hir>) { + fn visit_impl_item_ref(&mut self, _: &'hir hir::ImplItemRef) { // Explicitly do nothing here. ImplItemRefs contain hir::Visibility // values that actually belong to an ImplItem instead of the ItemKind::Impl // we are currently in. So for those it's correct that they have a // different owner. } - fn visit_foreign_item_ref(&mut self, _: &'hir hir::ForeignItemRef<'hir>) { + fn visit_foreign_item_ref(&mut self, _: &'hir hir::ForeignItemRef) { // Explicitly do nothing here. ForeignItemRefs contain hir::Visibility // values that actually belong to an ForeignItem instead of the ItemKind::ForeignMod // we are currently in. So for those it's correct that they have a diff --git a/compiler/rustc_plugin_impl/Cargo.toml b/compiler/rustc_plugin_impl/Cargo.toml index c8eaca0703c..4e666e7e93d 100644 --- a/compiler/rustc_plugin_impl/Cargo.toml +++ b/compiler/rustc_plugin_impl/Cargo.toml @@ -2,7 +2,7 @@ name = "rustc_plugin_impl" version = "0.0.0" build = false -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_privacy/Cargo.toml b/compiler/rustc_privacy/Cargo.toml index 6ac2915c345..d952e288a64 100644 --- a/compiler/rustc_privacy/Cargo.toml +++ b/compiler/rustc_privacy/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_privacy" version = "0.0.0" -edition = "2018" +edition = "2021" [dependencies] rustc_middle = { path = "../rustc_middle" } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 391e4305423..e14f758ddae 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -743,7 +743,9 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { } hir::ItemKind::Impl(ref impl_) => { for impl_item_ref in impl_.items { - if impl_.of_trait.is_some() || impl_item_ref.vis.node.is_pub() { + if impl_.of_trait.is_some() + || self.tcx.visibility(impl_item_ref.id.def_id) == ty::Visibility::Public + { self.update(impl_item_ref.id.def_id, item_level); } } @@ -768,7 +770,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { } hir::ItemKind::ForeignMod { items, .. } => { for foreign_item in items { - if foreign_item.vis.node.is_pub() { + if self.tcx.visibility(foreign_item.id.def_id) == ty::Visibility::Public { self.update(foreign_item.id.def_id, item_level); } } @@ -1678,7 +1680,10 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { // methods will be visible as `Public::foo`. let mut found_pub_static = false; for impl_item_ref in impl_.items { - if self.item_is_public(impl_item_ref.id.def_id, &impl_item_ref.vis) { + if self.access_levels.is_reachable(impl_item_ref.id.def_id) + || self.tcx.visibility(impl_item_ref.id.def_id) + == ty::Visibility::Public + { let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); match impl_item_ref.kind { AssocItemKind::Const => { diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index 7c8dbe34240..89df3d4674b 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_query_impl" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml index 47fb78be640..11c18a497e5 100644 --- a/compiler/rustc_query_system/Cargo.toml +++ b/compiler/rustc_query_system/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_query_system" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml index 1581b056275..f1d3315d6e6 100644 --- a/compiler/rustc_resolve/Cargo.toml +++ b/compiler/rustc_resolve/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_resolve" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] test = false diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index a158e0e48e8..84e7c68713f 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -522,8 +522,7 @@ fn item_for(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> LocalDefId { _ => {} } let item = { - let hir = tcx.hir(); - let mut parent_iter = hir.parent_iter(hir_id); + let mut parent_iter = tcx.hir().parent_iter(hir_id); loop { let node = parent_iter.next().map(|n| n.1); match node { diff --git a/compiler/rustc_save_analysis/Cargo.toml b/compiler/rustc_save_analysis/Cargo.toml index 535a48bcda1..15a89d82fa6 100644 --- a/compiler/rustc_save_analysis/Cargo.toml +++ b/compiler/rustc_save_analysis/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_save_analysis" version = "0.0.0" -edition = "2018" +edition = "2021" [dependencies] tracing = "0.1" diff --git a/compiler/rustc_serialize/Cargo.toml b/compiler/rustc_serialize/Cargo.toml index 593a7563e36..49778f82253 100644 --- a/compiler/rustc_serialize/Cargo.toml +++ b/compiler/rustc_serialize/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_serialize" version = "0.0.0" -edition = "2018" +edition = "2021" [dependencies] indexmap = "1" diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index 5b617a2997c..4cff21bee3d 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_session" version = "0.0.0" -edition = "2018" +edition = "2021" [dependencies] getopts = "0.2" diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index d6f4a3ae4f1..27215556045 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -902,7 +902,12 @@ impl Session { let mut fuel = self.optimization_fuel.lock(); ret = fuel.remaining != 0; if fuel.remaining == 0 && !fuel.out_of_fuel { - self.warn(&format!("optimization-fuel-exhausted: {}", msg())); + if self.diagnostic().can_emit_warnings() { + // We only call `msg` in case we can actually emit warnings. + // Otherwise, this could cause a `delay_good_path_bug` to + // trigger (issue #79546). + self.warn(&format!("optimization-fuel-exhausted: {}", msg())); + } fuel.out_of_fuel = true; } else if fuel.remaining > 0 { fuel.remaining -= 1; diff --git a/compiler/rustc_span/Cargo.toml b/compiler/rustc_span/Cargo.toml index e475e89d87e..781fb8c1e5d 100644 --- a/compiler/rustc_span/Cargo.toml +++ b/compiler/rustc_span/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_span" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 9c5469f635f..032ae73bbf3 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -25,6 +25,9 @@ #[macro_use] extern crate rustc_macros; +#[macro_use] +extern crate tracing; + use rustc_data_structures::AtomicRef; use rustc_macros::HashStable_Generic; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; @@ -782,13 +785,30 @@ impl Span { /// ^^^^^^^^^^^^^^^^^ /// ``` pub fn until(self, end: Span) -> Span { - let span = self.data(); - let end = end.data(); + // Most of this function's body is copied from `to`. + // We can't just do `self.to(end.shrink_to_lo())`, + // because to also does some magic where it uses min/max so + // it can handle overlapping spans. Some advanced mis-use of + // `until` with different ctxts makes this visible. + let span_data = self.data(); + let end_data = end.data(); + // FIXME(jseyfried): `self.ctxt` should always equal `end.ctxt` here (cf. issue #23480). + // 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::root() { + return end; + } else if end_data.ctxt == SyntaxContext::root() { + return self; + } + // Both spans fall within a macro. + // FIXME(estebank): check if it is the *same* macro. + } Span::new( - span.lo, - end.lo, - if end.ctxt == SyntaxContext::root() { end.ctxt } else { span.ctxt }, - if span.parent == end.parent { span.parent } else { None }, + span_data.lo, + end_data.lo, + if end_data.ctxt == SyntaxContext::root() { end_data.ctxt } else { span_data.ctxt }, + if span_data.parent == end_data.parent { span_data.parent } else { None }, ) } diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 9e403eb3f67..b79f00a8a36 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -474,11 +474,12 @@ impl SourceMap { f.lookup_line(sp.lo()) != f.lookup_line(sp.hi()) } + #[instrument(skip(self), level = "trace")] pub fn is_valid_span(&self, sp: Span) -> Result<(Loc, Loc), SpanLinesError> { let lo = self.lookup_char_pos(sp.lo()); - debug!("span_to_lines: lo={:?}", lo); + trace!(?lo); let hi = self.lookup_char_pos(sp.hi()); - debug!("span_to_lines: hi={:?}", hi); + trace!(?hi); if lo.file.start_pos != hi.file.start_pos { return Err(SpanLinesError::DistinctSources(DistinctSources { begin: (lo.file.name.clone(), lo.file.start_pos), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 322bea3806c..44137290d78 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -253,6 +253,7 @@ symbols! { TyCtxt, TyKind, Unknown, + UnsafeArg, Vec, Yield, _DECLS, @@ -407,6 +408,7 @@ symbols! { clone_from, closure, closure_to_fn_coercion, + closure_track_caller, cmp, cmp_max, cmp_min, @@ -837,6 +839,7 @@ symbols! { mul, mul_assign, mul_with_overflow, + must_not_suspend, must_use, mut_ptr, mut_slice_ptr, diff --git a/compiler/rustc_symbol_mangling/Cargo.toml b/compiler/rustc_symbol_mangling/Cargo.toml index aebf77a1fd8..d5befa10e23 100644 --- a/compiler/rustc_symbol_mangling/Cargo.toml +++ b/compiler/rustc_symbol_mangling/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_symbol_mangling" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_target/Cargo.toml b/compiler/rustc_target/Cargo.toml index e47a84dbc11..925813e6bb4 100644 --- a/compiler/rustc_target/Cargo.toml +++ b/compiler/rustc_target/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_target" version = "0.0.0" -edition = "2018" +edition = "2021" [dependencies] bitflags = "1.2.1" diff --git a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs index bf3ec8f9160..dc91f123096 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs @@ -4,7 +4,9 @@ pub fn target() -> Target { let mut base = super::apple_base::opts("macos"); base.cpu = "apple-a12".to_string(); base.max_atomic_width = Some(128); - base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD; + + // FIXME: The leak sanitizer currently fails the tests, see #88132. + base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-arch".to_string(), "arm64".to_string()]); base.link_env_remove.extend(super::apple_base::macos_link_env_remove()); diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index e2c626d1b22..9a9737362c6 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_trait_selection" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index 8abcdb5e89b..c01faae5d6a 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -1,4 +1,3 @@ -use crate::infer::InferCtxtExt as _; use crate::traits::{self, ObligationCause, PredicateObligation}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; @@ -863,7 +862,6 @@ struct Instantiator<'a, 'tcx> { } impl<'a, 'tcx> Instantiator<'a, 'tcx> { - #[instrument(level = "debug", skip(self))] fn instantiate_opaque_types_in_map<T: TypeFoldable<'tcx>>(&mut self, value: T) -> T { let tcx = self.infcx.tcx; value.fold_with(&mut BottomUpFolder { @@ -954,6 +952,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { }) } + #[instrument(skip(self), level = "debug")] fn fold_opaque_ty( &mut self, ty: Ty<'tcx>, @@ -964,25 +963,18 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { let tcx = infcx.tcx; let OpaqueTypeKey { def_id, substs } = opaque_type_key; - debug!("instantiate_opaque_types: Opaque(def_id={:?}, substs={:?})", def_id, substs); - // Use the same type variable if the exact same opaque type appears more // than once in the return type (e.g., if it's passed to a type alias). if let Some(opaque_defn) = infcx.inner.borrow().opaque_types.get(&opaque_type_key) { - debug!("instantiate_opaque_types: returning concrete ty {:?}", opaque_defn.concrete_ty); + debug!("re-using cached concrete type {:?}", opaque_defn.concrete_ty.kind()); return opaque_defn.concrete_ty; } + let ty_var = infcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span: self.value_span, }); - // Make sure that we are in fact defining the *entire* type - // (e.g., `type Foo<T: Bound> = impl Bar;` needs to be - // defined by a function like `fn foo<T: Bound>() -> Foo<T>`). - debug!("instantiate_opaque_types: param_env={:#?}", self.param_env,); - debug!("instantiate_opaque_types: generics={:#?}", tcx.generics_of(def_id),); - // Ideally, we'd get the span where *this specific `ty` came // from*, but right now we just use the span from the overall // value being folded. In simple cases like `-> impl Foo`, @@ -999,43 +991,40 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { infcx.opaque_types_vars.insert(ty_var, ty); } - debug!("instantiate_opaque_types: ty_var={:?}", ty_var); - self.compute_opaque_type_obligations(opaque_type_key); - - ty_var - } - - fn compute_opaque_type_obligations(&mut self, opaque_type_key: OpaqueTypeKey<'tcx>) { - let infcx = self.infcx; - let tcx = infcx.tcx; - let OpaqueTypeKey { def_id, substs } = opaque_type_key; + debug!("generated new type inference var {:?}", ty_var.kind()); let item_bounds = tcx.explicit_item_bounds(def_id); - debug!("instantiate_opaque_types: bounds={:#?}", item_bounds); - let bounds: Vec<_> = - item_bounds.iter().map(|(bound, _)| bound.subst(tcx, substs)).collect(); - - let param_env = tcx.param_env(def_id); - let InferOk { value: bounds, obligations } = infcx.partially_normalize_associated_types_in( - ObligationCause::misc(self.value_span, self.body_id), - param_env, - bounds, - ); - self.obligations.extend(obligations); - debug!("instantiate_opaque_types: bounds={:?}", bounds); + self.obligations.reserve(item_bounds.len()); + for (predicate, _) in item_bounds { + debug!(?predicate); + let predicate = predicate.subst(tcx, substs); + debug!(?predicate); + + // We can't normalize associated types from `rustc_infer`, but we can eagerly register inference variables for them. + let predicate = predicate.fold_with(&mut BottomUpFolder { + tcx, + ty_op: |ty| match ty.kind() { + ty::Projection(projection_ty) => infcx.infer_projection( + self.param_env, + *projection_ty, + ObligationCause::misc(self.value_span, self.body_id), + 0, + &mut self.obligations, + ), + _ => ty, + }, + lt_op: |lt| lt, + ct_op: |ct| ct, + }); + debug!(?predicate); - for predicate in &bounds { if let ty::PredicateKind::Projection(projection) = predicate.kind().skip_binder() { if projection.ty.references_error() { // No point on adding these obligations since there's a type error involved. - return; + return tcx.ty_error(); } } - } - - self.obligations.reserve(bounds.len()); - for predicate in bounds { // Change the predicate to refer to the type variable, // which will be the concrete type instead of the opaque type. // This also instantiates nested instances of `impl Trait`. @@ -1045,9 +1034,11 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { traits::ObligationCause::new(self.value_span, self.body_id, traits::OpaqueType); // Require that the predicate holds for the concrete type. - debug!("instantiate_opaque_types: predicate={:?}", predicate); + debug!(?predicate); self.obligations.push(traits::Obligation::new(cause, self.param_env, predicate)); } + + ty_var } } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 4f22543950c..58589e556f2 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -810,17 +810,7 @@ pub fn normalize_projection_type<'a, 'b, 'tcx>( // and a deferred predicate to resolve this when more type // information is available. - let tcx = selcx.infcx().tcx; - let def_id = projection_ty.item_def_id; - let ty_var = selcx.infcx().next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::NormalizeProjectionType, - span: tcx.def_span(def_id), - }); - let projection = ty::Binder::dummy(ty::ProjectionPredicate { projection_ty, ty: ty_var }); - let obligation = - Obligation::with_depth(cause, depth + 1, param_env, projection.to_predicate(tcx)); - obligations.push(obligation); - ty_var + selcx.infcx().infer_projection(param_env, projection_ty, cause, depth + 1, obligations) }) } @@ -844,6 +834,10 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>( obligations: &mut Vec<PredicateObligation<'tcx>>, ) -> Result<Option<Ty<'tcx>>, InProgress> { let infcx = selcx.infcx(); + // Don't use the projection cache in intercrate mode - + // the `infcx` may be re-used between intercrate in non-intercrate + // mode, which could lead to using incorrect cache results. + let use_cache = !selcx.is_intercrate(); let projection_ty = infcx.resolve_vars_if_possible(projection_ty); let cache_key = ProjectionCacheKey::new(projection_ty); @@ -856,7 +850,11 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>( // bounds. It might be the case that we want two distinct caches, // or else another kind of cache entry. - let cache_result = infcx.inner.borrow_mut().projection_cache().try_start(cache_key); + let cache_result = if use_cache { + infcx.inner.borrow_mut().projection_cache().try_start(cache_key) + } else { + Ok(()) + }; match cache_result { Ok(()) => debug!("no cache"), Err(ProjectionCacheEntry::Ambiguous) => { @@ -881,7 +879,9 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>( // should ensure that, unless this happens within a snapshot that's // rolled back, fulfillment or evaluation will notice the cycle. - infcx.inner.borrow_mut().projection_cache().recur(cache_key); + if use_cache { + infcx.inner.borrow_mut().projection_cache().recur(cache_key); + } return Err(InProgress); } Err(ProjectionCacheEntry::Recur) => { @@ -963,20 +963,26 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>( .map_or(false, |res| res.must_apply_considering_regions()) }); - infcx.inner.borrow_mut().projection_cache().insert_ty(cache_key, result.clone()); + if use_cache { + infcx.inner.borrow_mut().projection_cache().insert_ty(cache_key, result.clone()); + } obligations.extend(result.obligations); Ok(Some(result.value)) } Ok(ProjectedTy::NoProgress(projected_ty)) => { debug!(?projected_ty, "opt_normalize_projection_type: no progress"); let result = Normalized { value: projected_ty, obligations: vec![] }; - infcx.inner.borrow_mut().projection_cache().insert_ty(cache_key, result.clone()); + if use_cache { + infcx.inner.borrow_mut().projection_cache().insert_ty(cache_key, result.clone()); + } // No need to extend `obligations`. Ok(Some(result.value)) } Err(ProjectionTyError::TooManyCandidates) => { debug!("opt_normalize_projection_type: too many candidates"); - infcx.inner.borrow_mut().projection_cache().ambiguous(cache_key); + if use_cache { + infcx.inner.borrow_mut().projection_cache().ambiguous(cache_key); + } Ok(None) } Err(ProjectionTyError::TraitSelectionError(_)) => { @@ -986,7 +992,9 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>( // Trait`, which when processed will cause the error to be // reported later - infcx.inner.borrow_mut().projection_cache().error(cache_key); + if use_cache { + infcx.inner.borrow_mut().projection_cache().error(cache_key); + } let result = normalize_to_error(selcx, param_env, projection_ty, cause, depth); obligations.extend(result.obligations); Ok(Some(result.value)) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index b966779500b..50d6f82ae18 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -314,6 +314,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.infcx.tcx } + pub fn is_intercrate(&self) -> bool { + self.intercrate + } + /// Returns `true` if the trait predicate is considerd `const` to this selection context. pub fn is_trait_predicate_const(&self, pred: ty::TraitPredicate<'_>) -> bool { match pred.constness { @@ -1197,6 +1201,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { param_env: ty::ParamEnv<'tcx>, cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> Option<SelectionResult<'tcx, SelectionCandidate<'tcx>>> { + // Neither the global nor local cache is aware of intercrate + // mode, so don't do any caching. In particular, we might + // re-use the same `InferCtxt` with both an intercrate + // and non-intercrate `SelectionContext` + if self.intercrate { + return None; + } let tcx = self.tcx(); let pred = &cache_fresh_trait_pred.skip_binder(); let trait_ref = pred.trait_ref; @@ -1233,6 +1244,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &self, result: &SelectionResult<'tcx, SelectionCandidate<'tcx>>, ) -> bool { + // Neither the global nor local cache is aware of intercrate + // mode, so don't do any caching. In particular, we might + // re-use the same `InferCtxt` with both an intercrate + // and non-intercrate `SelectionContext` + if self.intercrate { + return false; + } match result { Ok(Some(SelectionCandidate::ParamCandidate(trait_ref))) => !trait_ref.needs_infer(), _ => true, diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs index 0efc46edb06..ec7dcd4a419 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs @@ -104,19 +104,21 @@ impl ChildrenExt for Children { let self_ty = trait_ref.self_ty(); // FIXME: should postpone string formatting until we decide to actually emit. - with_no_trimmed_paths(|| OverlapError { - with_impl: possible_sibling, - trait_desc: trait_ref.print_only_trait_path().to_string(), - // Only report the `Self` type if it has at least - // some outer concrete shell; otherwise, it's - // not adding much information. - self_desc: if self_ty.has_concrete_skeleton() { - Some(self_ty.to_string()) - } else { - None - }, - intercrate_ambiguity_causes: overlap.intercrate_ambiguity_causes, - involves_placeholder: overlap.involves_placeholder, + with_no_trimmed_paths(|| { + OverlapError { + with_impl: possible_sibling, + trait_desc: trait_ref.print_only_trait_path().to_string(), + // Only report the `Self` type if it has at least + // some outer concrete shell; otherwise, it's + // not adding much information. + self_desc: if self_ty.has_concrete_skeleton() { + Some(self_ty.to_string()) + } else { + None + }, + intercrate_ambiguity_causes: overlap.intercrate_ambiguity_causes, + involves_placeholder: overlap.involves_placeholder, + } }) }; diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 75307f13563..611ff26d652 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -209,7 +209,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>( _ => return, }; let fix_span = - |impl_item_ref: &hir::ImplItemRef<'_>| match tcx.hir().impl_item(impl_item_ref.id).kind { + |impl_item_ref: &hir::ImplItemRef| match tcx.hir().impl_item(impl_item_ref.id).kind { hir::ImplItemKind::Const(ty, _) | hir::ImplItemKind::TyAlias(ty) => ty.span, _ => impl_item_ref.span, }; diff --git a/compiler/rustc_traits/Cargo.toml b/compiler/rustc_traits/Cargo.toml index 219165ff550..2e56a1bf683 100644 --- a/compiler/rustc_traits/Cargo.toml +++ b/compiler/rustc_traits/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_traits" version = "0.0.0" -edition = "2018" +edition = "2021" [dependencies] tracing = "0.1" diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml index 2eb27fb1ad6..78df95e680e 100644 --- a/compiler/rustc_ty_utils/Cargo.toml +++ b/compiler/rustc_ty_utils/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_ty_utils" version = "0.0.0" -edition = "2018" +edition = "2021" [dependencies] tracing = "0.1" diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 27ad7bf4c2d..3d3b2743700 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -100,7 +100,7 @@ fn associated_item_from_trait_item_ref( fn associated_item_from_impl_item_ref( tcx: TyCtxt<'_>, parent_def_id: LocalDefId, - impl_item_ref: &hir::ImplItemRef<'_>, + impl_item_ref: &hir::ImplItemRef, ) -> ty::AssocItem { let def_id = impl_item_ref.id.def_id; let (kind, has_self) = match impl_item_ref.kind { diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 1f6acbe0d81..439e6cdf706 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_type_ir" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] doctest = false diff --git a/compiler/rustc_typeck/Cargo.toml b/compiler/rustc_typeck/Cargo.toml index dd76a5e4b99..7e570e151c5 100644 --- a/compiler/rustc_typeck/Cargo.toml +++ b/compiler/rustc_typeck/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_typeck" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] test = false diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 2f2223ee822..33df541eb2b 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2417,13 +2417,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let substs = InternalSubsts::for_item(tcx, def_id, |param, _| { if let Some(i) = (param.index as usize).checked_sub(generics.parent_count) { // Our own parameters are the resolved lifetimes. - match param.kind { - GenericParamDefKind::Lifetime - if let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] => - { + if let GenericParamDefKind::Lifetime = param.kind { + if let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] { self.ast_region_to_region(lifetime, None).into() + } else { + bug!() } - _ => bug!(), + } else { + bug!() } } else { match param.kind { diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 54e4eb47688..d6c59312c0b 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -906,7 +906,7 @@ pub(super) fn check_impl_items_against_trait<'tcx>( full_impl_span: Span, impl_id: LocalDefId, impl_trait_ref: ty::TraitRef<'tcx>, - impl_item_refs: &[hir::ImplItemRef<'_>], + impl_item_refs: &[hir::ImplItemRef], ) { // If the trait reference itself is erroneous (so the compilation is going // to fail), skip checking the items here -- the `impl_item` table in `tcx` diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index 0acf1d26e25..da8b863e2db 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -484,8 +484,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("suggest_missing_return_type: return type {:?}", ty); debug!("suggest_missing_return_type: expected type {:?}", ty); let bound_vars = self.tcx.late_bound_vars(fn_id); - let ty = self.tcx.erase_late_bound_regions(Binder::bind_with_vars(ty, bound_vars)); + let ty = Binder::bind_with_vars(ty, bound_vars); let ty = self.normalize_associated_types_in(sp, ty); + let ty = self.tcx.erase_late_bound_regions(ty); if self.can_coerce(expected, ty) { err.span_label(sp, format!("expected `{}` because of return type", expected)); return true; diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs index 3da9fd159a7..2910ce6de68 100644 --- a/compiler/rustc_typeck/src/check/generator_interior.rs +++ b/compiler/rustc_typeck/src/check/generator_interior.rs @@ -5,6 +5,7 @@ use super::FnCtxt; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; +use rustc_errors::pluralize; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; @@ -12,9 +13,11 @@ use rustc_hir::hir_id::HirIdSet; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::{Arm, Expr, ExprKind, Guard, HirId, Pat, PatKind}; use rustc_middle::middle::region::{self, YieldData}; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_span::symbol::sym; use rustc_span::Span; use smallvec::SmallVec; +use tracing::debug; struct InteriorVisitor<'a, 'tcx> { fcx: &'a FnCtxt<'a, 'tcx>, @@ -30,12 +33,14 @@ struct InteriorVisitor<'a, 'tcx> { /// that they may succeed the said yield point in the post-order. guard_bindings: SmallVec<[SmallVec<[HirId; 4]>; 1]>, guard_bindings_set: HirIdSet, + linted_values: HirIdSet, } impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> { fn record( &mut self, ty: Ty<'tcx>, + hir_id: HirId, scope: Option<region::Scope>, expr: Option<&'tcx Expr<'tcx>>, source_span: Span, @@ -117,6 +122,23 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> { } else { // Insert the type into the ordered set. let scope_span = scope.map(|s| s.span(self.fcx.tcx, self.region_scope_tree)); + + if !self.linted_values.contains(&hir_id) { + check_must_not_suspend_ty( + self.fcx, + ty, + hir_id, + SuspendCheckData { + expr, + source_span, + yield_span: yield_data.span, + plural_len: 1, + ..Default::default() + }, + ); + self.linted_values.insert(hir_id); + } + self.types.insert(ty::GeneratorInteriorTypeCause { span: source_span, ty: &ty, @@ -163,6 +185,7 @@ pub fn resolve_interior<'a, 'tcx>( prev_unresolved_span: None, guard_bindings: <_>::default(), guard_bindings_set: <_>::default(), + linted_values: <_>::default(), }; intravisit::walk_body(&mut visitor, body); @@ -290,7 +313,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> { if let PatKind::Binding(..) = pat.kind { let scope = self.region_scope_tree.var_scope(pat.hir_id.local_id); let ty = self.fcx.typeck_results.borrow().pat_ty(pat); - self.record(ty, Some(scope), None, pat.span, false); + self.record(ty, pat.hir_id, Some(scope), None, pat.span, false); } } @@ -342,7 +365,14 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> { // If there are adjustments, then record the final type -- // this is the actual value that is being produced. if let Some(adjusted_ty) = self.fcx.typeck_results.borrow().expr_ty_adjusted_opt(expr) { - self.record(adjusted_ty, scope, Some(expr), expr.span, guard_borrowing_from_pattern); + self.record( + adjusted_ty, + expr.hir_id, + scope, + Some(expr), + expr.span, + guard_borrowing_from_pattern, + ); } // Also record the unadjusted type (which is the only type if @@ -380,9 +410,23 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> { tcx.mk_region(ty::RegionKind::ReErased), ty::TypeAndMut { ty, mutbl: hir::Mutability::Not }, ); - self.record(ref_ty, scope, Some(expr), expr.span, guard_borrowing_from_pattern); + self.record( + ref_ty, + expr.hir_id, + scope, + Some(expr), + expr.span, + guard_borrowing_from_pattern, + ); } - self.record(ty, scope, Some(expr), expr.span, guard_borrowing_from_pattern); + self.record( + ty, + expr.hir_id, + scope, + Some(expr), + expr.span, + guard_borrowing_from_pattern, + ); } else { self.fcx.tcx.sess.delay_span_bug(expr.span, "no type for node"); } @@ -409,3 +453,173 @@ impl<'a, 'tcx> Visitor<'tcx> for ArmPatCollector<'a> { } } } + +#[derive(Default)] +pub struct SuspendCheckData<'a, 'tcx> { + expr: Option<&'tcx Expr<'tcx>>, + source_span: Span, + yield_span: Span, + descr_pre: &'a str, + descr_post: &'a str, + plural_len: usize, +} + +// Returns whether it emitted a diagnostic or not +// Note that this fn and the proceding one are based on the code +// for creating must_use diagnostics +// +// Note that this technique was chosen over things like a `Suspend` marker trait +// as it is simpler and has precendent in the compiler +pub fn check_must_not_suspend_ty<'tcx>( + fcx: &FnCtxt<'_, 'tcx>, + ty: Ty<'tcx>, + hir_id: HirId, + data: SuspendCheckData<'_, 'tcx>, +) -> bool { + if ty.is_unit() + // FIXME: should this check `is_ty_uninhabited_from`. This query is not available in this stage + // of typeck (before ReVar and RePlaceholder are removed), but may remove noise, like in + // `must_use` + // || fcx.tcx.is_ty_uninhabited_from(fcx.tcx.parent_module(hir_id).to_def_id(), ty, fcx.param_env) + { + return false; + } + + let plural_suffix = pluralize!(data.plural_len); + + match *ty.kind() { + ty::Adt(..) if ty.is_box() => { + let boxed_ty = ty.boxed_ty(); + let descr_pre = &format!("{}boxed ", data.descr_pre); + check_must_not_suspend_ty(fcx, boxed_ty, hir_id, SuspendCheckData { descr_pre, ..data }) + } + ty::Adt(def, _) => check_must_not_suspend_def(fcx.tcx, def.did, hir_id, data), + // FIXME: support adding the attribute to TAITs + ty::Opaque(def, _) => { + let mut has_emitted = false; + for &(predicate, _) in fcx.tcx.explicit_item_bounds(def) { + // We only look at the `DefId`, so it is safe to skip the binder here. + if let ty::PredicateKind::Trait(ref poly_trait_predicate) = + predicate.kind().skip_binder() + { + let def_id = poly_trait_predicate.trait_ref.def_id; + let descr_pre = &format!("{}implementer{} of ", data.descr_pre, plural_suffix); + if check_must_not_suspend_def( + fcx.tcx, + def_id, + hir_id, + SuspendCheckData { descr_pre, ..data }, + ) { + has_emitted = true; + break; + } + } + } + has_emitted + } + ty::Dynamic(binder, _) => { + let mut has_emitted = false; + for predicate in binder.iter() { + if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() { + let def_id = trait_ref.def_id; + let descr_post = &format!(" trait object{}{}", plural_suffix, data.descr_post); + if check_must_not_suspend_def( + fcx.tcx, + def_id, + hir_id, + SuspendCheckData { descr_post, ..data }, + ) { + has_emitted = true; + break; + } + } + } + has_emitted + } + ty::Tuple(ref tys) => { + let mut has_emitted = false; + let spans = if let Some(hir::ExprKind::Tup(comps)) = data.expr.map(|e| &e.kind) { + debug_assert_eq!(comps.len(), tys.len()); + comps.iter().map(|e| e.span).collect() + } else { + vec![] + }; + for (i, ty) in tys.iter().map(|k| k.expect_ty()).enumerate() { + let descr_post = &format!(" in tuple element {}", i); + let span = *spans.get(i).unwrap_or(&data.source_span); + if check_must_not_suspend_ty( + fcx, + ty, + hir_id, + SuspendCheckData { descr_post, source_span: span, ..data }, + ) { + has_emitted = true; + } + } + has_emitted + } + ty::Array(ty, len) => { + let descr_pre = &format!("{}array{} of ", data.descr_pre, plural_suffix); + check_must_not_suspend_ty( + fcx, + ty, + hir_id, + SuspendCheckData { + descr_pre, + plural_len: len.try_eval_usize(fcx.tcx, fcx.param_env).unwrap_or(0) as usize + + 1, + ..data + }, + ) + } + _ => false, + } +} + +fn check_must_not_suspend_def( + tcx: TyCtxt<'_>, + def_id: DefId, + hir_id: HirId, + data: SuspendCheckData<'_, '_>, +) -> bool { + for attr in tcx.get_attrs(def_id).iter() { + if attr.has_name(sym::must_not_suspend) { + tcx.struct_span_lint_hir( + rustc_session::lint::builtin::MUST_NOT_SUSPEND, + hir_id, + data.source_span, + |lint| { + let msg = format!( + "{}`{}`{} held across a suspend point, but should not be", + data.descr_pre, + tcx.def_path_str(def_id), + data.descr_post, + ); + let mut err = lint.build(&msg); + + // add span pointing to the offending yield/await + err.span_label(data.yield_span, "the value is held across this suspend point"); + + // Add optional reason note + if let Some(note) = attr.value_str() { + // FIXME(guswynn): consider formatting this better + err.span_note(data.source_span, ¬e.as_str()); + } + + // Add some quick suggestions on what to do + // FIXME: can `drop` work as a suggestion here as well? + err.span_help( + data.source_span, + "consider using a block (`{ ... }`) \ + to shrink the value's scope, ending before the suspend point", + ); + + err.emit(); + }, + ); + + return true; + } + } + false +} diff --git a/compiler/rustc_typeck/src/coherence/inherent_impls.rs b/compiler/rustc_typeck/src/coherence/inherent_impls.rs index c7be9e21235..f3fe09ac003 100644 --- a/compiler/rustc_typeck/src/coherence/inherent_impls.rs +++ b/compiler/rustc_typeck/src/coherence/inherent_impls.rs @@ -401,7 +401,7 @@ impl InherentCollect<'tcx> { lang: &str, ty: &str, span: Span, - assoc_items: &[hir::ImplItemRef<'_>], + assoc_items: &[hir::ImplItemRef], ) { match (lang_def_id, lang_def_id2) { (Some(lang_def_id), _) if lang_def_id == impl_def_id.to_def_id() => { diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 1bc7bc3e063..231a8142174 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2778,10 +2778,19 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { } else if attr.has_name(sym::thread_local) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL; } else if attr.has_name(sym::track_caller) { - if tcx.is_closure(id) || tcx.fn_sig(id).abi() != abi::Abi::Rust { + if !tcx.is_closure(id) && tcx.fn_sig(id).abi() != abi::Abi::Rust { struct_span_err!(tcx.sess, attr.span, E0737, "`#[track_caller]` requires Rust ABI") .emit(); } + if tcx.is_closure(id) && !tcx.features().closure_track_caller { + feature_err( + &tcx.sess.parse_sess, + sym::closure_track_caller, + attr.span, + "`#[track_caller]` on closures is currently unstable", + ) + .emit(); + } codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER; } else if attr.has_name(sym::export_name) { if let Some(s) = attr.value_str() { diff --git a/compiler/rustc_typeck/src/impl_wf_check.rs b/compiler/rustc_typeck/src/impl_wf_check.rs index 9b23bf241cc..5d2f8fc4242 100644 --- a/compiler/rustc_typeck/src/impl_wf_check.rs +++ b/compiler/rustc_typeck/src/impl_wf_check.rs @@ -97,7 +97,7 @@ impl ItemLikeVisitor<'tcx> for ImplWfCheck<'tcx> { fn enforce_impl_params_are_constrained( tcx: TyCtxt<'_>, impl_def_id: LocalDefId, - impl_item_refs: &[hir::ImplItemRef<'_>], + impl_item_refs: &[hir::ImplItemRef], ) { // Every lifetime used in an associated type must be constrained. let impl_self_ty = tcx.type_of(impl_def_id); @@ -228,7 +228,7 @@ fn report_unused_parameter(tcx: TyCtxt<'_>, span: Span, kind: &str, name: &str) } /// Enforce that we do not have two items in an impl with the same name. -fn enforce_impl_items_are_distinct(tcx: TyCtxt<'_>, impl_item_refs: &[hir::ImplItemRef<'_>]) { +fn enforce_impl_items_are_distinct(tcx: TyCtxt<'_>, impl_item_refs: &[hir::ImplItemRef]) { let mut seen_type_items = FxHashMap::default(); let mut seen_value_items = FxHashMap::default(); for impl_item_ref in impl_item_refs { diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 72216852376..2b3a18a439f 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1086,6 +1086,7 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Box<T, A> { } } +#[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] impl<T: Default> Default for Box<T> { /// Creates a `Box<T>`, with the `Default` value for T. @@ -1394,6 +1395,7 @@ impl<A: Allocator> From<Box<str, A>> for Box<[u8], A> { } } +#[cfg(not(no_global_oom_handling))] #[stable(feature = "box_from_array", since = "1.45.0")] impl<T, const N: usize> From<[T; N]> for Box<[T]> { /// Converts a `[T; N]` into a `Box<[T]>` diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 87a0d371815..2f6887229e7 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2841,6 +2841,7 @@ impl<T: Clone> From<&mut [T]> for Vec<T> { } } +#[cfg(not(no_global_oom_handling))] #[stable(feature = "vec_from_array", since = "1.44.0")] impl<T, const N: usize> From<[T; N]> for Vec<T> { #[cfg(not(test))] diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 5767108d423..cae4dae708e 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -18,7 +18,6 @@ #![feature(binary_heap_retain)] #![feature(binary_heap_as_slice)] #![feature(inplace_iteration)] -#![feature(iter_map_while)] #![feature(slice_group_by)] #![feature(slice_partition_dedup)] #![feature(vec_spare_capacity)] diff --git a/library/core/src/ascii.rs b/library/core/src/ascii.rs index 4780d8dc788..0a456ee1eb2 100644 --- a/library/core/src/ascii.rs +++ b/library/core/src/ascii.rs @@ -21,7 +21,7 @@ use crate::str::from_utf8_unchecked; #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct EscapeDefault { - range: Range<usize>, + range: Range<u8>, data: [u8; 4], } @@ -114,7 +114,7 @@ pub fn escape_default(c: u8) -> EscapeDefault { impl Iterator for EscapeDefault { type Item = u8; fn next(&mut self) -> Option<u8> { - self.range.next().map(|i| self.data[i]) + self.range.next().map(|i| self.data[i as usize]) } fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() @@ -126,7 +126,7 @@ impl Iterator for EscapeDefault { #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for EscapeDefault { fn next_back(&mut self) -> Option<u8> { - self.range.next_back().map(|i| self.data[i]) + self.range.next_back().map(|i| self.data[i as usize]) } } #[stable(feature = "rust1", since = "1.0.0")] @@ -138,7 +138,9 @@ impl FusedIterator for EscapeDefault {} impl fmt::Display for EscapeDefault { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // SAFETY: ok because `escape_default` created only valid utf-8 data - f.write_str(unsafe { from_utf8_unchecked(&self.data[self.range.clone()]) }) + f.write_str(unsafe { + from_utf8_unchecked(&self.data[(self.range.start as usize)..(self.range.end as usize)]) + }) } } diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 166a8e3f28a..8fa941c42fc 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -265,6 +265,26 @@ pub struct ArgumentV1<'a> { formatter: fn(&Opaque, &mut Formatter<'_>) -> Result, } +/// This struct represents the unsafety of constructing an `Arguments`. +/// It exists, rather than an unsafe function, in order to simplify the expansion +/// of `format_args!(..)` and reduce the scope of the `unsafe` block. +#[allow(missing_debug_implementations)] +#[doc(hidden)] +#[non_exhaustive] +#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] +pub struct UnsafeArg; + +impl UnsafeArg { + /// See documentation where `UnsafeArg` is required to know when it is safe to + /// create and use `UnsafeArg`. + #[doc(hidden)] + #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] + #[inline(always)] + pub unsafe fn new() -> Self { + Self + } +} + // This guarantees a single stable value for the function pointer associated with // indices/counts in the formatting infrastructure. // @@ -337,10 +357,7 @@ impl<'a> Arguments<'a> { #[inline] #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] #[rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none")] - pub const unsafe fn new_v1( - pieces: &'a [&'static str], - args: &'a [ArgumentV1<'a>], - ) -> Arguments<'a> { + pub const fn new_v1(pieces: &'a [&'static str], args: &'a [ArgumentV1<'a>]) -> Arguments<'a> { if pieces.len() < args.len() || pieces.len() > args.len() + 1 { panic!("invalid args"); } @@ -348,11 +365,29 @@ impl<'a> Arguments<'a> { } /// This function is used to specify nonstandard formatting parameters. - /// The `pieces` array must be at least as long as `fmt` to construct - /// a valid Arguments structure. Also, any `Count` within `fmt` that is - /// `CountIsParam` or `CountIsNextParam` has to point to an argument - /// created with `argumentusize`. However, failing to do so doesn't cause - /// unsafety, but will ignore invalid . + /// + /// An `UnsafeArg` is required because the following invariants must be held + /// in order for this function to be safe: + /// 1. The `pieces` slice must be at least as long as `fmt`. + /// 2. Every [`rt::v1::Argument::position`] value within `fmt` must be a + /// valid index of `args`. + /// 3. Every [`Count::Param`] within `fmt` must contain a valid index of + /// `args`. + #[cfg(not(bootstrap))] + #[doc(hidden)] + #[inline] + #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] + #[rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none")] + pub const fn new_v1_formatted( + pieces: &'a [&'static str], + args: &'a [ArgumentV1<'a>], + fmt: &'a [rt::v1::Argument], + _unsafe_arg: UnsafeArg, + ) -> Arguments<'a> { + Arguments { pieces, fmt: Some(fmt), args } + } + + #[cfg(bootstrap)] #[doc(hidden)] #[inline] #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] diff --git a/library/core/src/iter/adapters/map_while.rs b/library/core/src/iter/adapters/map_while.rs index 8f89e158804..793b05fcf95 100644 --- a/library/core/src/iter/adapters/map_while.rs +++ b/library/core/src/iter/adapters/map_while.rs @@ -10,7 +10,7 @@ use crate::ops::{ControlFlow, Try}; /// [`map_while`]: Iterator::map_while /// [`Iterator`]: trait.Iterator.html #[must_use = "iterators are lazy and do nothing unless consumed"] -#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")] +#[stable(feature = "iter_map_while", since = "1.57.0")] #[derive(Clone)] pub struct MapWhile<I, P> { iter: I, @@ -23,14 +23,14 @@ impl<I, P> MapWhile<I, P> { } } -#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")] +#[stable(feature = "iter_map_while", since = "1.57.0")] impl<I: fmt::Debug, P> fmt::Debug for MapWhile<I, P> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("MapWhile").field("iter", &self.iter).finish() } } -#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")] +#[stable(feature = "iter_map_while", since = "1.57.0")] impl<B, I: Iterator, P> Iterator for MapWhile<I, P> where P: FnMut(I::Item) -> Option<B>, diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs index f02d278aff5..48e7dcfa7d9 100644 --- a/library/core/src/iter/adapters/mod.rs +++ b/library/core/src/iter/adapters/mod.rs @@ -45,7 +45,7 @@ pub use self::copied::Copied; #[stable(feature = "iter_intersperse", since = "1.56.0")] pub use self::intersperse::{Intersperse, IntersperseWith}; -#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")] +#[stable(feature = "iter_map_while", since = "1.57.0")] pub use self::map_while::MapWhile; #[unstable(feature = "trusted_random_access", issue = "none")] diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs index cd8a26025ff..d6f9edaa046 100644 --- a/library/core/src/iter/mod.rs +++ b/library/core/src/iter/mod.rs @@ -399,7 +399,7 @@ pub use self::adapters::Cloned; pub use self::adapters::Copied; #[stable(feature = "iterator_flatten", since = "1.29.0")] pub use self::adapters::Flatten; -#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")] +#[stable(feature = "iter_map_while", since = "1.57.0")] pub use self::adapters::MapWhile; #[unstable(feature = "inplace_iteration", issue = "none")] pub use self::adapters::SourceIter; diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index b0a9d9f5ef5..f884340f4e0 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -1116,7 +1116,6 @@ pub trait Iterator { /// Basic usage: /// /// ``` - /// #![feature(iter_map_while)] /// let a = [-1i32, 4, 0, 1]; /// /// let mut iter = a.iter().map_while(|x| 16i32.checked_div(*x)); @@ -1147,7 +1146,6 @@ pub trait Iterator { /// Stopping after an initial [`None`]: /// /// ``` - /// #![feature(iter_map_while)] /// use std::convert::TryFrom; /// /// let a = [0, 1, 2, -3, 4, 5, -6]; @@ -1165,7 +1163,6 @@ pub trait Iterator { /// removed: /// /// ``` - /// #![feature(iter_map_while)] /// use std::convert::TryFrom; /// /// let a = [1, 2, -3, 4]; @@ -1191,7 +1188,7 @@ pub trait Iterator { /// /// [`fuse`]: Iterator::fuse #[inline] - #[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")] + #[stable(feature = "iter_map_while", since = "1.57.0")] fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P> where Self: Sized, diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index a6aa4bf43c8..6d3ec6ae861 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -47,10 +47,7 @@ pub fn panic(expr: &'static str) -> ! { // truncation and padding (even though none is used here). Using // Arguments::new_v1 may allow the compiler to omit Formatter::pad from the // output binary, saving up to a few kilobytes. - panic_fmt( - // SAFETY: Arguments::new_v1 is safe with exactly one str and zero args - unsafe { fmt::Arguments::new_v1(&[expr], &[]) }, - ); + panic_fmt(fmt::Arguments::new_v1(&[expr], &[])); } #[inline] diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 19bcc45108d..cd3aed4cd28 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -50,7 +50,6 @@ #![feature(iter_partition_in_place)] #![feature(iter_is_partitioned)] #![feature(iter_order_by)] -#![feature(iter_map_while)] #![feature(const_mut_refs)] #![feature(const_pin)] #![feature(const_slice_from_raw_parts)] diff --git a/library/std/src/error.rs b/library/std/src/error.rs index 8164ec56985..cc4ea27e57e 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -31,6 +31,7 @@ use crate::num; use crate::str; use crate::string; use crate::sync::Arc; +use crate::time; /// `Error` is a trait representing the basic expectations for error values, /// i.e., values of type `E` in [`Result<T, E>`]. @@ -598,7 +599,7 @@ impl Error for char::ParseCharError { impl Error for alloc::collections::TryReserveError {} #[unstable(feature = "duration_checked_float", issue = "83400")] -impl Error for core::time::FromSecsError {} +impl Error for time::FromSecsError {} // Copied from `any.rs`. impl dyn Error + 'static { diff --git a/library/std/src/os/raw/char.md b/library/std/src/os/raw/char.md index 8256b725acf..375d070516e 100644 --- a/library/std/src/os/raw/char.md +++ b/library/std/src/os/raw/char.md @@ -1,6 +1,6 @@ Equivalent to C's `char` type. -[C's `char` type] is completely unlike [Rust's `char` type]; while Rust's type represents a unicode scalar value, C's `char` type is just an ordinary integer. This type will always be either [`i8`] or [`u8`], as the type is defined as being one byte long. +[C's `char` type] is completely unlike [Rust's `char` type]; while Rust's type represents a unicode scalar value, C's `char` type is just an ordinary integer. On modern architectures this type will always be either [`i8`] or [`u8`], as they use byte-addresses memory with 8-bit bytes. C chars are most commonly used to make C strings. Unlike Rust, where the length of a string is included alongside the string, C strings mark the end of a string with the character `'\0'`. See [`CStr`] for more information. diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index 0c1a50e231c..cc137771bb8 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -357,7 +357,7 @@ impl File { let mut info: c::FILE_BASIC_INFO = mem::zeroed(); let size = mem::size_of_val(&info); cvt(c::GetFileInformationByHandleEx( - self.handle.raw(), + self.handle.as_raw_handle(), c::FileBasicInfo, &mut info as *mut _ as *mut libc::c_void, size as c::DWORD, @@ -385,7 +385,7 @@ impl File { let mut info: c::FILE_STANDARD_INFO = mem::zeroed(); let size = mem::size_of_val(&info); cvt(c::GetFileInformationByHandleEx( - self.handle.raw(), + self.handle.as_raw_handle(), c::FileStandardInfo, &mut info as *mut _ as *mut libc::c_void, size as c::DWORD, diff --git a/library/std/src/sys/windows/stdio_uwp.rs b/library/std/src/sys/windows/stdio_uwp.rs index 872511af862..32550f796ec 100644 --- a/library/std/src/sys/windows/stdio_uwp.rs +++ b/library/std/src/sys/windows/stdio_uwp.rs @@ -2,6 +2,7 @@ use crate::io; use crate::mem::ManuallyDrop; +use crate::os::windows::io::FromRawHandle; use crate::sys::c; use crate::sys::handle::Handle; @@ -25,7 +26,8 @@ pub fn get_handle(handle_id: c::DWORD) -> io::Result<c::HANDLE> { fn write(handle_id: c::DWORD, data: &[u8]) -> io::Result<usize> { let handle = get_handle(handle_id)?; - let handle = Handle::new(handle); + // SAFETY: The handle returned from `get_handle` must be valid and non-null. + let handle = unsafe { Handle::from_raw_handle(handle) }; ManuallyDrop::new(handle).write(data) } @@ -38,7 +40,8 @@ impl Stdin { impl io::Read for Stdin { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { let handle = get_handle(c::STD_INPUT_HANDLE)?; - let handle = Handle::new(handle); + // SAFETY: The handle returned from `get_handle` must be valid and non-null. + let handle = unsafe { Handle::from_raw_handle(handle) }; ManuallyDrop::new(handle).read(buf) } } diff --git a/library/std/src/time.rs b/library/std/src/time.rs index e9207ee3617..bf3eb5b30c7 100644 --- a/library/std/src/time.rs +++ b/library/std/src/time.rs @@ -44,6 +44,9 @@ use crate::sys_common::FromInner; #[stable(feature = "time", since = "1.3.0")] pub use core::time::Duration; +#[unstable(feature = "duration_checked_float", issue = "83400")] +pub use core::time::FromSecsError; + /// A measurement of a monotonically nondecreasing clock. /// Opaque and useful only with [`Duration`]. /// diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 0b76a13e02b..1ce1f0b26db 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "bootstrap" version = "0.0.0" -edition = "2018" +edition = "2021" build = "build.rs" [lib] diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index f5fad4b4136..f66f282bea9 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -262,7 +262,7 @@ impl Step for CodegenBackend { let mut cargo = builder.cargo( compiler, Mode::Codegen, - SourceType::Submodule, + SourceType::InTree, target, cargo_subcommand(builder.kind), ); diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index df9e9bce415..ae234fb1dc7 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -817,8 +817,7 @@ impl Step for CodegenBackend { let out_dir = builder.cargo_out(compiler, Mode::Codegen, target); - let mut cargo = - builder.cargo(compiler, Mode::Codegen, SourceType::Submodule, target, "build"); + let mut cargo = builder.cargo(compiler, Mode::Codegen, SourceType::InTree, target, "build"); cargo .arg("--manifest-path") .arg(builder.src.join(format!("compiler/rustc_codegen_{}/Cargo.toml", backend))); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index a4735d54be0..2d4e1527897 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -1494,8 +1494,13 @@ impl Build { { eprintln!( " -Couldn't find required command: ninja -You should install ninja, or set `ninja=false` in config.toml in the `[llvm]` section. +Couldn't find required command: ninja (or ninja-build) + +You should install ninja as described at +<https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages>, +or set `ninja = false` in the `[llvm]` section of `config.toml`. +Alternatively, set `download-ci-llvm = true` in that `[llvm]` section +to download LLVM rather than building it. " ); std::process::exit(1); diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 386ffb384a8..272b7153111 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -390,7 +390,7 @@ impl Step for Rustfmt { host, "test", "src/tools/rustfmt", - SourceType::Submodule, + SourceType::InTree, &[], ); diff --git a/src/build_helper/Cargo.toml b/src/build_helper/Cargo.toml index 17a9e55b323..d88df0e08fa 100644 --- a/src/build_helper/Cargo.toml +++ b/src/build_helper/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "build_helper" version = "0.1.0" -edition = "2018" +edition = "2021" [lib] path = "lib.rs" diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index b55db452f12..91795997641 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -209,6 +209,22 @@ some consideration for their stability, and names that end in a number). Giving `rustdoc` will disable this sorting and instead make it print the items in the order they appear in the source. +### `--show-type-layout`: add a section to each type's docs describing its memory layout + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs -Z unstable-options --show-type-layout +``` + +When this flag is passed, rustdoc will add a "Layout" section at the bottom of +each type's docs page that includes a summary of the type's memory layout as +computed by rustc. For example, rustdoc will show the size in bytes that a value +of that type will take in memory. + +Note that most layout information is **completely unstable** and may even differ +between compilations. + ### `--resource-suffix`: modifying the name of CSS/JavaScript in crate docs Using this flag looks like this: @@ -333,7 +349,7 @@ Some methodology notes about what rustdoc counts in this metric: Public items that are not documented can be seen with the built-in `missing_docs` lint. Private items that are not documented can be seen with Clippy's `missing_docs_in_private_items` lint. -## `-w`/`--output-format`: output format +### `-w`/`--output-format`: output format When using [`--show-coverage`](https://doc.rust-lang.org/nightly/rustdoc/unstable-features.html#--show-coverage-get-statistics-about-code-documentation-coverage), diff --git a/src/doc/unstable-book/src/language-features/closure-track-caller.md b/src/doc/unstable-book/src/language-features/closure-track-caller.md new file mode 100644 index 00000000000..c948810d3e5 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/closure-track-caller.md @@ -0,0 +1,12 @@ +# `closure_track_caller` + +The tracking issue for this feature is: [#87417] + +[#87417]: https://github.com/rust-lang/rust/issues/87417 + +------------------------ + +Allows using the `#[track_caller]` attribute on closures and generators. +Calls made to the closure or generator will have caller information +available through `std::panic::Location::caller()`, just like using +`#[track_caller]` on a function. diff --git a/src/etc/test-float-parse/Cargo.toml b/src/etc/test-float-parse/Cargo.toml index 8226e815c2c..7ee19a0b6d9 100644 --- a/src/etc/test-float-parse/Cargo.toml +++ b/src/etc/test-float-parse/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "test-float-parse" version = "0.1.0" -edition = "2018" +edition = "2021" publish = false [workspace] diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index e02cef235ae..945b2a8e9a8 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustdoc" version = "0.0.0" -edition = "2018" +edition = "2021" [lib] path = "lib.rs" diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 11adb56490b..c83ca6ba54c 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -114,7 +114,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { attrs: Default::default(), visibility: Inherited, def_id: ItemId::Auto { trait_: trait_def_id, for_: item_def_id }, - kind: Box::new(ImplItem(Impl { + kind: box ImplItem(Impl { span: Span::dummy(), unsafety: hir::Unsafety::Normal, generics: new_generics, @@ -124,7 +124,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { negative_polarity, synthetic: true, blanket_impl: None, - })), + }), cfg: None, }) } diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 15d4563ad74..82939c930c4 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -100,7 +100,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { attrs: Default::default(), visibility: Inherited, def_id: ItemId::Blanket { impl_id: impl_def_id, for_: item_def_id }, - kind: Box::new(ImplItem(Impl { + kind: box ImplItem(Impl { span: Span::new(self.cx.tcx.def_span(impl_def_id)), unsafety: hir::Unsafety::Normal, generics: ( @@ -121,8 +121,8 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { .clean(self.cx), negative_polarity: false, synthetic: false, - blanket_impl: Some(Box::new(trait_ref.self_ty().clean(self.cx))), - })), + blanket_impl: Some(box trait_ref.self_ty().clean(self.cx)), + }), cfg: None, }); } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 29834c82b3d..15d704eb57f 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -124,14 +124,8 @@ crate fn try_inline( let (attrs, cfg) = merge_attrs(cx, Some(parent_module), load_attrs(cx, did), attrs_clone); cx.inlined.insert(did.into()); - let mut item = clean::Item::from_def_id_and_attrs_and_parts( - did, - Some(name), - kind, - Box::new(attrs), - cx, - cfg, - ); + let mut item = + clean::Item::from_def_id_and_attrs_and_parts(did, Some(name), kind, box attrs, cx, cfg); if let Some(import_def_id) = import_def_id { // The visibility needs to reflect the one from the reexport and not from the "source" DefId. item.visibility = cx.tcx.visibility(import_def_id).clean(cx); @@ -464,7 +458,7 @@ crate fn build_impl( synthetic: false, blanket_impl: None, }), - Box::new(merged_attrs), + box merged_attrs, cx, cfg, )); @@ -493,10 +487,10 @@ fn build_module( let prim_ty = clean::PrimitiveType::from(p); items.push(clean::Item { name: None, - attrs: Box::new(clean::Attributes::default()), + attrs: box clean::Attributes::default(), def_id: ItemId::Primitive(prim_ty, did.krate), visibility: clean::Public, - kind: Box::new(clean::ImportItem(clean::Import::new_simple( + kind: box clean::ImportItem(clean::Import::new_simple( item.ident.name, clean::ImportSource { path: clean::Path { @@ -513,7 +507,7 @@ fn build_module( did: None, }, true, - ))), + )), cfg: None, }); } else if let Some(i) = try_inline(cx, did, None, res, item.ident.name, None, visited) { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e281bbc59c2..3ec979c5ae9 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -392,8 +392,8 @@ impl<'tcx> Clean<Type> for ty::ProjectionTy<'tcx> { Type::QPath { name: cx.tcx.associated_item(self.item_def_id).ident.name, self_def_id: self_type.def_id(), - self_type: Box::new(self_type), - trait_: Box::new(trait_), + self_type: box self_type, + trait_: box trait_, } } } @@ -1284,8 +1284,8 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type { Type::QPath { name: p.segments.last().expect("segments were empty").ident.name, self_def_id: Some(DefId::local(qself.hir_id.owner.local_def_index)), - self_type: Box::new(qself.clean(cx)), - trait_: Box::new(resolve_type(cx, trait_path)), + self_type: box qself.clean(cx), + trait_: box resolve_type(cx, trait_path), } } hir::QPath::TypeRelative(ref qself, ref segment) => { @@ -1300,8 +1300,8 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type { Type::QPath { name: segment.ident.name, self_def_id: res.opt_def_id(), - self_type: Box::new(qself.clean(cx)), - trait_: Box::new(resolve_type(cx, trait_path)), + self_type: box qself.clean(cx), + trait_: box resolve_type(cx, trait_path), } } hir::QPath::LangItem(..) => bug!("clean: requiring documentation of lang item"), @@ -1314,7 +1314,7 @@ impl Clean<Type> for hir::Ty<'_> { match self.kind { TyKind::Never => Never, - TyKind::Ptr(ref m) => RawPointer(m.mutbl, Box::new(m.ty.clean(cx))), + TyKind::Ptr(ref m) => RawPointer(m.mutbl, box m.ty.clean(cx)), TyKind::Rptr(ref l, ref m) => { // There are two times a `Fresh` lifetime can be created: // 1. For `&'_ x`, written by the user. This corresponds to `lower_lifetime` in `rustc_ast_lowering`. @@ -1326,9 +1326,9 @@ impl Clean<Type> for hir::Ty<'_> { let elided = l.is_elided() || matches!(l.name, LifetimeName::Param(ParamName::Fresh(_))); let lifetime = if elided { None } else { Some(l.clean(cx)) }; - BorrowedRef { lifetime, mutability: m.mutbl, type_: Box::new(m.ty.clean(cx)) } + BorrowedRef { lifetime, mutability: m.mutbl, type_: box m.ty.clean(cx) } } - TyKind::Slice(ref ty) => Slice(Box::new(ty.clean(cx))), + TyKind::Slice(ref ty) => Slice(box ty.clean(cx)), TyKind::Array(ref ty, ref length) => { let def_id = cx.tcx.hir().local_def_id(length.hir_id); // NOTE(min_const_generics): We can't use `const_eval_poly` for constants @@ -1341,7 +1341,7 @@ impl Clean<Type> for hir::Ty<'_> { let ct = ty::Const::from_anon_const(cx.tcx, def_id); let param_env = cx.tcx.param_env(def_id); let length = print_const(cx, ct.eval(cx.tcx, param_env)); - Array(Box::new(ty.clean(cx)), length) + Array(box ty.clean(cx), length) } TyKind::Tup(ref tys) => Tuple(tys.clean(cx)), TyKind::OpaqueDef(item_id, _) => { @@ -1358,7 +1358,7 @@ impl Clean<Type> for hir::Ty<'_> { let lifetime = if !lifetime.is_elided() { Some(lifetime.clean(cx)) } else { None }; DynTrait(bounds, lifetime) } - TyKind::BareFn(ref barefn) => BareFunction(Box::new(barefn.clean(cx))), + TyKind::BareFn(ref barefn) => BareFunction(box barefn.clean(cx)), // Rustdoc handles `TyKind::Err`s by turning them into `Type::Infer`s. TyKind::Infer | TyKind::Err => Infer, TyKind::Typeof(..) => panic!("unimplemented type {:?}", self.kind), @@ -1409,29 +1409,27 @@ impl<'tcx> Clean<Type> for Ty<'tcx> { ty::Uint(uint_ty) => Primitive(uint_ty.into()), ty::Float(float_ty) => Primitive(float_ty.into()), ty::Str => Primitive(PrimitiveType::Str), - ty::Slice(ty) => Slice(Box::new(ty.clean(cx))), + ty::Slice(ty) => Slice(box ty.clean(cx)), ty::Array(ty, n) => { let mut n = cx.tcx.lift(n).expect("array lift failed"); n = n.eval(cx.tcx, ty::ParamEnv::reveal_all()); let n = print_const(cx, n); - Array(Box::new(ty.clean(cx)), n) + Array(box ty.clean(cx), n) + } + ty::RawPtr(mt) => RawPointer(mt.mutbl, box mt.ty.clean(cx)), + ty::Ref(r, ty, mutbl) => { + BorrowedRef { lifetime: r.clean(cx), mutability: mutbl, type_: box ty.clean(cx) } } - ty::RawPtr(mt) => RawPointer(mt.mutbl, Box::new(mt.ty.clean(cx))), - ty::Ref(r, ty, mutbl) => BorrowedRef { - lifetime: r.clean(cx), - mutability: mutbl, - type_: Box::new(ty.clean(cx)), - }, ty::FnDef(..) | ty::FnPtr(_) => { let ty = cx.tcx.lift(*self).expect("FnPtr lift failed"); let sig = ty.fn_sig(cx.tcx); let def_id = DefId::local(CRATE_DEF_INDEX); - BareFunction(Box::new(BareFunctionDecl { + BareFunction(box BareFunctionDecl { unsafety: sig.unsafety(), generic_params: Vec::new(), decl: (def_id, sig).clean(cx), abi: sig.abi(), - })) + }) } ty::Adt(def, substs) => { let did = def.did; @@ -1974,10 +1972,10 @@ fn clean_extern_crate( // FIXME: using `from_def_id_and_kind` breaks `rustdoc/masked` for some reason vec![Item { name: Some(name), - attrs: Box::new(attrs.clean(cx)), + attrs: box attrs.clean(cx), def_id: crate_def_id.into(), visibility: krate.vis.clean(cx), - kind: Box::new(ExternCrateItem { src: orig_name }), + kind: box ExternCrateItem { src: orig_name }, cfg: attrs.cfg(cx.sess()), }] } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index b3c320555f9..d23941d77ba 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -421,7 +421,7 @@ impl Item { def_id, name, kind, - Box::new(ast_attrs.clean(cx)), + box ast_attrs.clean(cx), cx, ast_attrs.cfg(cx.sess()), ) @@ -439,7 +439,7 @@ impl Item { Item { def_id: def_id.into(), - kind: Box::new(kind), + kind: box kind, name, attrs, visibility: cx.tcx.visibility(def_id).clean(cx), diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 765c77d5646..ddbe68762ee 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -263,7 +263,7 @@ crate fn create_config( stderr: None, lint_caps, parse_sess_created: None, - register_lints: Some(Box::new(crate::lint::register_lints)), + register_lints: Some(box crate::lint::register_lints), override_queries: Some(|_sess, providers, _external_providers| { // Most lints will require typechecking, so just don't run them. providers.lint_mod = |_, _| {}; diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index dbeea9cddf3..ac760fad103 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -99,7 +99,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> { stderr: None, lint_caps, parse_sess_created: None, - register_lints: Some(Box::new(crate::lint::register_lints)), + register_lints: Some(box crate::lint::register_lints), override_queries: None, make_codegen_backend: None, registry: rustc_driver::diagnostics_registry(), @@ -550,10 +550,10 @@ crate fn make_test( .supports_color(); let emitter = - EmitterWriter::new(Box::new(io::sink()), None, false, false, false, None, false); + EmitterWriter::new(box io::sink(), None, false, false, false, None, false); // FIXME(misdreavus): pass `-Z treat-err-as-bug` to the doctest parser - let handler = Handler::with_emitter(false, None, Box::new(emitter)); + let handler = Handler::with_emitter(false, None, box emitter); let sess = ParseSess::with_span_handler(handler, sm); let mut found_main = false; @@ -963,7 +963,7 @@ impl Tester for Collector { no_run, test_type: test::TestType::DocTest, }, - testfn: test::DynTestFn(Box::new(move || { + testfn: test::DynTestFn(box move || { let report_unused_externs = |uext| { unused_externs.lock().unwrap().push(uext); }; @@ -1043,9 +1043,9 @@ impl Tester for Collector { } } - panic::resume_unwind(Box::new(())); + panic::resume_unwind(box ()); } - })), + }), }); } diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index b4859e4c9c7..f84850c0fe1 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -2,7 +2,7 @@ use crate::clean::*; crate fn strip_item(mut item: Item) -> Item { if !matches!(*item.kind, StrippedItem(..)) { - item.kind = Box::new(StrippedItem(item.kind)); + item.kind = box StrippedItem(item.kind); } item } @@ -69,10 +69,10 @@ crate trait DocFolder: Sized { /// don't override! fn fold_item_recur(&mut self, mut item: Item) -> Item { - item.kind = Box::new(match *item.kind { - StrippedItem(box i) => StrippedItem(Box::new(self.fold_inner_recur(i))), + item.kind = box match *item.kind { + StrippedItem(box i) => StrippedItem(box self.fold_inner_recur(i)), _ => self.fold_inner_recur(*item.kind), - }); + }; item } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 52505f2d634..3104cb3a3dd 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1663,7 +1663,7 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) { writeln!( w, "<div class=\"warning\"><p><strong>Note:</strong> Most layout information is \ - completely unstable and may be different between compiler versions and platforms. \ + <strong>completely unstable</strong> and may even differ between compilations. \ The only exception is types with certain <code>repr(...)</code> attributes. \ Please see the Rust Reference’s \ <a href=\"https://doc.rust-lang.org/reference/type-layout.html\">“Type Layout”</a> \ diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index f170561300c..5cfd21046f5 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -7,6 +7,7 @@ #![feature(assert_matches)] #![feature(box_patterns)] #![feature(control_flow_enum)] +#![feature(box_syntax)] #![feature(in_band_lifetimes)] #![feature(nll)] #![feature(test)] diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index c0c37ee0611..3edd96a3364 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -64,7 +64,7 @@ enum ErrorKind<'a> { impl<'a> From<ResolutionFailure<'a>> for ErrorKind<'a> { fn from(err: ResolutionFailure<'a>) -> Self { - ErrorKind::Resolve(Box::new(err)) + ErrorKind::Resolve(box err) } } diff --git a/src/rustdoc-json-types/Cargo.toml b/src/rustdoc-json-types/Cargo.toml index a692f6f896d..d60699efd36 100644 --- a/src/rustdoc-json-types/Cargo.toml +++ b/src/rustdoc-json-types/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustdoc-json-types" version = "0.1.0" -edition = "2018" +edition = "2021" [lib] path = "lib.rs" diff --git a/src/test/assembly/x86_64-sse_crc.rs b/src/test/assembly/x86_64-sse_crc.rs new file mode 100644 index 00000000000..cdbf057b80b --- /dev/null +++ b/src/test/assembly/x86_64-sse_crc.rs @@ -0,0 +1,12 @@ +// only-x86_64 +// assembly-output: emit-asm +// compile-flags: --crate-type staticlib -Ctarget-feature=+sse4.2 + +// CHECK-LABEL: banana +// CHECK: crc32 +#[no_mangle] +pub unsafe fn banana(v: u8) -> u32 { + use std::arch::x86_64::*; + let out = !0u32; + _mm_crc32_u8(out, v) +} diff --git a/src/test/codegen/sse42-implies-crc32.rs b/src/test/codegen/sse42-implies-crc32.rs new file mode 100644 index 00000000000..47b1a899340 --- /dev/null +++ b/src/test/codegen/sse42-implies-crc32.rs @@ -0,0 +1,16 @@ +// only-x86_64 +// min-llvm-version: 14.0 +// compile-flags: -Copt-level=3 + +#![crate_type = "lib"] + +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "sse4.2")] +#[no_mangle] +pub unsafe fn crc32sse(v: u8) -> u32 { + use std::arch::x86_64::*; + let out = !0u32; + _mm_crc32_u8(out, v) +} + +// CHECK: attributes #0 {{.*"target-features"="\+sse4.2,\+crc32"}} diff --git a/src/test/debuginfo/msvc-scalarpair-params.rs b/src/test/debuginfo/msvc-scalarpair-params.rs new file mode 100644 index 00000000000..3846fb42f81 --- /dev/null +++ b/src/test/debuginfo/msvc-scalarpair-params.rs @@ -0,0 +1,101 @@ +// only-cdb +// compile-flags: -g + +// cdb-command: g + +// cdb-command: dx r1 +// cdb-check:r1 : (0xa..0xc) [Type: core::ops::range::Range<u32>] +// cdb-command: dx r2 +// cdb-check:r2 : (0x14..0x1e) [Type: core::ops::range::Range<u64>] + +// cdb-command: g + +// cdb-command: dx r1 +// cdb-check:r1 : (0x9..0x64) [Type: core::ops::range::Range<u32>] +// cdb-command: dx r2 +// cdb-check:r2 : (0xc..0x5a) [Type: core::ops::range::Range<u64>] + +// cdb-command: g + +// cdb-command: dx o1 +// cdb-check:o1 : Some [Type: enum$<core::option::Option<u32> >] +// cdb-check: [variant] : Some +// cdb-check: [+0x004] __0 : 0x4d2 [Type: [...]] +// cdb-command: dx o2 +// cdb-check:o2 : Some [Type: enum$<core::option::Option<u64> >] +// cdb-check: [variant] : Some +// cdb-check: [+0x008] __0 : 0x162e [Type: unsigned __int64] + +// cdb-command: g + +// cdb-command: dx t1 +// cdb-check:t1 : (0xa, 0x14) [Type: tuple$<u32,u32>] +// cdb-check: [0] : 0xa [Type: unsigned int] +// cdb-check: [1] : 0x14 [Type: unsigned int] +// cdb-command: dx t2 +// cdb-check:t2 : (0x1e, 0x28) [Type: tuple$<u64,u64>] +// cdb-check: [0] : 0x1e [Type: unsigned __int64] +// cdb-check: [1] : 0x28 [Type: unsigned __int64] + +// cdb-command: g + +// cdb-command: dx s +// cdb-check:s : "this is a static str" [Type: str] +// cdb-check: [len] : 0x14 [Type: unsigned [...]] +// cdb-check: [chars] + +// cdb-command: g + +// cdb-command: dx s +// cdb-check:s : { len=0x5 } [Type: slice$<u8>] +// cdb-check: [len] : 0x5 [Type: unsigned [...]] +// cdb-check: [0] : 0x1 [Type: unsigned char] +// cdb-check: [1] : 0x2 [Type: unsigned char] +// cdb-check: [2] : 0x3 [Type: unsigned char] +// cdb-check: [3] : 0x4 [Type: unsigned char] +// cdb-check: [4] : 0x5 [Type: unsigned char] + +use std::ops::Range; + +fn range(r1: Range<u32>, r2: Range<u64>) { + zzz(); // #break +} + +fn range_mut(mut r1: Range<u32>, mut r2: Range<u64>) { + if r1.start == 9 { + r1.end = 100; + } + + if r2.start == 12 { + r2.end = 90; + } + + zzz(); // #break +} + +fn option(o1: Option<u32>, o2: Option<u64>) { + zzz(); // #break +} + +fn tuple(t1: (u32, u32), t2: (u64, u64)) { + zzz(); // #break +} + +fn str(s: &str) { + zzz(); // #break +} + +fn slice(s: &[u8]) { + zzz(); // #break +} + +fn zzz() { } + +fn main() { + range(10..12, 20..30); + range_mut(9..20, 12..80); + option(Some(1234), Some(5678)); + tuple((10, 20), (30, 40)); + str("this is a static str"); + slice(&[1, 2, 3, 4, 5]); +} diff --git a/src/test/debuginfo/mutex.rs b/src/test/debuginfo/mutex.rs index 4a529541bae..00dccf5f906 100644 --- a/src/test/debuginfo/mutex.rs +++ b/src/test/debuginfo/mutex.rs @@ -3,8 +3,6 @@ // cdb-only // min-cdb-version: 10.0.21287.1005 // compile-flags:-g -// FIXME: Failed on update to 10.0.22000.1 -// ignore-windows // === CDB TESTS ================================================================================== // @@ -14,17 +12,17 @@ // cdb-check:m,d [Type: std::sync::mutex::Mutex<i32>] // cdb-check: [...] inner [Type: std::sys_common::mutex::MovableMutex] // cdb-check: [...] poison [Type: std::sync::poison::Flag] -// cdb-check: [...] data [Type: core::cell::UnsafeCell<i32>] +// cdb-check: [...] data : 0 [Type: core::cell::UnsafeCell<i32>] // // cdb-command:dx m.data,d -// cdb-check:m.data,d [Type: core::cell::UnsafeCell<i32>] -// cdb-check: [...] value : 0 [Type: int] +// cdb-check:m.data,d : 0 [Type: core::cell::UnsafeCell<i32>] +// cdb-check: [<Raw View>] [Type: core::cell::UnsafeCell<i32>] // // cdb-command:dx lock,d -// cdb-check:lock,d : Ok [Type: enum$<core::result::Result<std::sync::mutex::MutexGuard<i32>, enum$<std::sync::poison::TryLockError<std::sync::mutex::MutexGuard<i32> >, 0, 1, Poisoned> > >] -// cdb-check: [...] variant$ : Ok (0) [Type: core::result::Result] +// cdb-check:lock,d : Ok [Type: enum$<core::result::Result<std::sync::mutex::MutexGuard<i32>,enum$<std::sync::poison::TryLockError<std::sync::mutex::MutexGuard<i32> >, 0, 1, Poisoned> > >] +// cdb-check: [variant] : Ok // cdb-check: [...] __0 [Type: std::sync::mutex::MutexGuard<i32>] use std::sync::Mutex; diff --git a/src/test/incremental/hashes/extern_mods.rs b/src/test/incremental/hashes/extern_mods.rs index 783407a9e04..4bc98fd7cd0 100644 --- a/src/test/incremental/hashes/extern_mods.rs +++ b/src/test/incremental/hashes/extern_mods.rs @@ -143,13 +143,13 @@ extern "rust-call" { // Make function public -------------------------------------------------------- #[cfg(any(cfail1,cfail4))] extern "C" { - fn make_function_public(c: i32); + fn make_function_public(c: i32); } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg = "cfail2", except = "hir_owner")] +#[rustc_clean(cfg = "cfail2")] #[rustc_clean(cfg = "cfail3")] -#[rustc_clean(cfg = "cfail5", except = "hir_owner")] +#[rustc_clean(cfg = "cfail5")] #[rustc_clean(cfg = "cfail6")] extern "C" { pub fn make_function_public(c: i32); diff --git a/src/test/incremental/hashes/inherent_impls.rs b/src/test/incremental/hashes/inherent_impls.rs index d711cc20dd7..3a59377e819 100644 --- a/src/test/incremental/hashes/inherent_impls.rs +++ b/src/test/incremental/hashes/inherent_impls.rs @@ -116,20 +116,24 @@ impl Foo { // Change Method Privacy ------------------------------------------------------- #[cfg(any(cfail1,cfail4))] impl Foo { + //------------------------------------------------------------------------------ + //-------------------------- + //------------------------------------------------------------------------------ + //-------------------------- pub fn method_privacy() { } } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner")] +#[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="hir_owner")] +#[rustc_clean(cfg="cfail5")] #[rustc_clean(cfg="cfail6")] impl Foo { #[rustc_clean(cfg="cfail2", except="associated_item,hir_owner,hir_owner_nodes")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(cfg="cfail5", except="associated_item,hir_owner,hir_owner_nodes,optimized_mir")] + #[rustc_clean(cfg="cfail5", except="associated_item,hir_owner,hir_owner_nodes")] #[rustc_clean(cfg="cfail6")] - fn method_privacy() { } + fn method_privacy() { } } // Change Method Selfness ----------------------------------------------------------- diff --git a/src/test/pretty/dollar-crate.pp b/src/test/pretty/dollar-crate.pp index 4eccba06b13..f4be3c1c63a 100644 --- a/src/test/pretty/dollar-crate.pp +++ b/src/test/pretty/dollar-crate.pp @@ -10,11 +10,9 @@ extern crate std; fn main() { { - ::std::io::_print(match match () { () => [], } { - ref args => unsafe { - ::core::fmt::Arguments::new_v1(&["rust\n"], - args) - } - }); + ::std::io::_print(::core::fmt::Arguments::new_v1(&["rust\n"], + &match () { + () => [], + })); }; } diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp index a21ea520121..199aee05622 100644 --- a/src/test/pretty/issue-4264.pp +++ b/src/test/pretty/issue-4264.pp @@ -32,39 +32,29 @@ pub fn bar() ({ ({ let res = ((::alloc::fmt::format as - for<'r> fn(Arguments<'r>) -> String {format})((match (match (() - as - ()) - { - () - => - ([] - as - [ArgumentV1; 0]), - } - as - [ArgumentV1; 0]) - { - ref args - => - unsafe - { - ((::core::fmt::Arguments::new_v1 - as - unsafe fn(&[&'static str], &[ArgumentV1]) -> Arguments {Arguments::new_v1})((&([("test" - as - &str)] - as - [&str; 1]) - as - &[&str; 1]), - (args - as - &[ArgumentV1; 0])) - as - Arguments) - } - } + for<'r> fn(Arguments<'r>) -> String {format})(((::core::fmt::Arguments::new_v1 + as + fn(&[&'static str], &[ArgumentV1]) -> Arguments {Arguments::new_v1})((&([("test" + as + &str)] + as + [&str; 1]) + as + &[&str; 1]), + (&(match (() + as + ()) + { + () + => + ([] + as + [ArgumentV1; 0]), + } + as + [ArgumentV1; 0]) + as + &[ArgumentV1; 0])) as Arguments)) as String); diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-84561.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-84561.txt index b35f3f54de9..f24f7c69404 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-84561.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-84561.txt @@ -31,15 +31,15 @@ 24| 1| println!("{:?}", Foo(1)); 25| 1| 26| 1| assert_ne!(Foo(0), Foo(5), "{}", if is_true { "true message" } else { "false message" }); - ^0 ^0 ^0 ^0 + ^0 ^0 ^0 27| 1| assert_ne!( 28| | Foo(0) 29| | , 30| | Foo(5) 31| | , 32| 0| "{}" - 33| | , - 34| | if + 33| 0| , + 34| 0| if 35| 0| is_true 36| | { 37| 0| "true message" diff --git a/src/test/ui/async-await/issues/issue-65159.rs b/src/test/ui/async-await/issues/issue-65159.rs index 1dbf5db6c32..df2ca025705 100644 --- a/src/test/ui/async-await/issues/issue-65159.rs +++ b/src/test/ui/async-await/issues/issue-65159.rs @@ -6,7 +6,6 @@ async fn copy() -> Result<()> //~^ ERROR this enum takes 2 generic arguments { Ok(()) - //~^ ERROR type annotations needed } fn main() { } diff --git a/src/test/ui/async-await/issues/issue-65159.stderr b/src/test/ui/async-await/issues/issue-65159.stderr index ff46bcb8983..45f5ec40cd7 100644 --- a/src/test/ui/async-await/issues/issue-65159.stderr +++ b/src/test/ui/async-await/issues/issue-65159.stderr @@ -16,13 +16,6 @@ help: add missing generic argument LL | async fn copy() -> Result<(), E> | +++ -error[E0282]: type annotations needed - --> $DIR/issue-65159.rs:8:5 - | -LL | Ok(()) - | ^^ cannot infer type for type parameter `E` declared on the enum `Result` - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0107, E0282. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/attributes/key-value-expansion.stderr b/src/test/ui/attributes/key-value-expansion.stderr index 03ca515265c..31e93ef54f2 100644 --- a/src/test/ui/attributes/key-value-expansion.stderr +++ b/src/test/ui/attributes/key-value-expansion.stderr @@ -17,16 +17,12 @@ LL | bug!(); error: unexpected token: `{ let res = - ::alloc::fmt::format(match match (&"u8",) { - (arg0,) => - [::core::fmt::ArgumentV1::new(arg0, - ::core::fmt::Display::fmt)], - } { - ref args => unsafe { - ::core::fmt::Arguments::new_v1(&[""], - args) - } - }); + ::alloc::fmt::format(::core::fmt::Arguments::new_v1(&[""], + &match (&"u8",) { + (arg0,) => + [::core::fmt::ArgumentV1::new(arg0, + ::core::fmt::Display::fmt)], + })); res }.as_str()` --> $DIR/key-value-expansion.rs:48:23 diff --git a/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs b/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs index 569769b8213..dd0320bc53b 100644 --- a/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs +++ b/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs @@ -17,7 +17,6 @@ async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_> { //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument was supplied //~^^ ERROR this struct takes 1 generic argument but 0 generic arguments were supplied LockedMarket(generator.lock().unwrap().buy()) - //~^ ERROR cannot return value referencing temporary value } struct LockedMarket<T>(T); diff --git a/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr b/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr index 4bd06673043..d2b927fb664 100644 --- a/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr +++ b/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr @@ -7,7 +7,7 @@ LL | async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_> | expected 0 lifetime arguments | note: struct defined here, with 0 lifetime parameters - --> $DIR/issue-82126-mismatched-subst-and-hir.rs:23:8 + --> $DIR/issue-82126-mismatched-subst-and-hir.rs:22:8 | LL | struct LockedMarket<T>(T); | ^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_> | ^^^^^^^^^^^^ expected 1 generic argument | note: struct defined here, with 1 generic parameter: `T` - --> $DIR/issue-82126-mismatched-subst-and-hir.rs:23:8 + --> $DIR/issue-82126-mismatched-subst-and-hir.rs:22:8 | LL | struct LockedMarket<T>(T); | ^^^^^^^^^^^^ - @@ -28,16 +28,6 @@ help: add missing generic argument LL | async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_, T> { | +++ -error[E0515]: cannot return value referencing temporary value - --> $DIR/issue-82126-mismatched-subst-and-hir.rs:19:5 - | -LL | LockedMarket(generator.lock().unwrap().buy()) - | ^^^^^^^^^^^^^-------------------------^^^^^^^ - | | | - | | temporary value created here - | returns a value referencing data owned by the current function - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0107, E0515. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/coherence/coherence-projection-conflict-orphan.stderr b/src/test/ui/coherence/coherence-projection-conflict-orphan.stderr index 51f6faab3c7..9efb5dc75f4 100644 --- a/src/test/ui/coherence/coherence-projection-conflict-orphan.stderr +++ b/src/test/ui/coherence/coherence-projection-conflict-orphan.stderr @@ -8,6 +8,7 @@ LL | impl<A:Iterator> Foo<A::Item> for A { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32` | = note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `i32` in future versions + = note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `i32` in future versions error: aborting due to previous error diff --git a/src/test/ui/consts/issue-89088.rs b/src/test/ui/consts/issue-89088.rs new file mode 100644 index 00000000000..40cc665fb61 --- /dev/null +++ b/src/test/ui/consts/issue-89088.rs @@ -0,0 +1,22 @@ +// Regression test for the ICE described in #89088. + +// check-pass + +#![allow(indirect_structural_match)] +use std::borrow::Cow; + +const FOO: &A = &A::Field(Cow::Borrowed("foo")); + +#[derive(PartialEq, Eq)] +enum A { + Field(Cow<'static, str>) +} + +fn main() { + let var = A::Field(Cow::Borrowed("bar")); + + match &var { + FOO => todo!(), + _ => todo!() + } +} diff --git a/src/test/ui/consts/refs_check_const_eq-issue-88384.rs b/src/test/ui/consts/refs_check_const_eq-issue-88384.rs new file mode 100644 index 00000000000..204d18ea25d --- /dev/null +++ b/src/test/ui/consts/refs_check_const_eq-issue-88384.rs @@ -0,0 +1,25 @@ +// check-pass + +#![feature(fn_traits)] +#![feature(adt_const_params)] +//~^ WARNING the feature `adt_const_params` is incomplete + +#[derive(PartialEq, Eq)] +struct CompileTimeSettings{ + hooks: &'static[fn()], +} + +struct Foo<const T: CompileTimeSettings>; + +impl<const T: CompileTimeSettings> Foo<T> { + fn call_hooks(){ + } +} + +fn main(){ + const SETTINGS: CompileTimeSettings = CompileTimeSettings{ + hooks: &[], + }; + + Foo::<SETTINGS>::call_hooks(); +} diff --git a/src/test/ui/consts/refs_check_const_eq-issue-88384.stderr b/src/test/ui/consts/refs_check_const_eq-issue-88384.stderr new file mode 100644 index 00000000000..55928b495b2 --- /dev/null +++ b/src/test/ui/consts/refs_check_const_eq-issue-88384.stderr @@ -0,0 +1,11 @@ +warning: the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/refs_check_const_eq-issue-88384.rs:4:12 + | +LL | #![feature(adt_const_params)] + | ^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/consts/refs_check_const_value_eq-issue-88876.rs b/src/test/ui/consts/refs_check_const_value_eq-issue-88876.rs new file mode 100644 index 00000000000..6ce9da43668 --- /dev/null +++ b/src/test/ui/consts/refs_check_const_value_eq-issue-88876.rs @@ -0,0 +1,12 @@ +// check-pass + +#![allow(incomplete_features)] +#![feature(adt_const_params)] + +struct FooConst<const ARRAY: &'static [&'static str]> {} + +const FOO_ARR: &[&'static str; 2] = &["Hello", "Friend"]; + +fn main() { + let _ = FooConst::<FOO_ARR> {}; +} diff --git a/src/test/ui/feature-gates/feature-gate-closure_track_caller.rs b/src/test/ui/feature-gates/feature-gate-closure_track_caller.rs new file mode 100644 index 00000000000..a8d63a8145a --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-closure_track_caller.rs @@ -0,0 +1,7 @@ +#![feature(stmt_expr_attributes)] +#![feature(generators)] + +fn main() { + let _closure = #[track_caller] || {}; //~ `#[track_caller]` on closures + let _generator = #[track_caller] || { yield; }; //~ `#[track_caller]` on closures +} diff --git a/src/test/ui/feature-gates/feature-gate-closure_track_caller.stderr b/src/test/ui/feature-gates/feature-gate-closure_track_caller.stderr new file mode 100644 index 00000000000..ed63d74fe4d --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-closure_track_caller.stderr @@ -0,0 +1,21 @@ +error[E0658]: `#[track_caller]` on closures is currently unstable + --> $DIR/feature-gate-closure_track_caller.rs:5:20 + | +LL | let _closure = #[track_caller] || {}; + | ^^^^^^^^^^^^^^^ + | + = note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information + = help: add `#![feature(closure_track_caller)]` to the crate attributes to enable + +error[E0658]: `#[track_caller]` on closures is currently unstable + --> $DIR/feature-gate-closure_track_caller.rs:6:22 + | +LL | let _generator = #[track_caller] || { yield; }; + | ^^^^^^^^^^^^^^^ + | + = note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information + = help: add `#![feature(closure_track_caller)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/generic-associated-types/issue-88360.rs b/src/test/ui/generic-associated-types/issue-88360.rs new file mode 100644 index 00000000000..06af3f5ec96 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-88360.rs @@ -0,0 +1,19 @@ +#![feature(generic_associated_types)] + +trait GatTrait { + type Gat<'a>; + + fn test(&self) -> Self::Gat<'_>; +} + +trait SuperTrait<T> +where + for<'a> Self: GatTrait<Gat<'a> = &'a T>, +{ + fn copy(&self) -> Self::Gat<'_> where T: Copy { + *self.test() + //~^ mismatched types + } +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-88360.stderr b/src/test/ui/generic-associated-types/issue-88360.stderr new file mode 100644 index 00000000000..cfbf3aaa4e6 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-88360.stderr @@ -0,0 +1,20 @@ +error[E0308]: mismatched types + --> $DIR/issue-88360.rs:14:9 + | +LL | trait SuperTrait<T> + | - this type parameter +... +LL | fn copy(&self) -> Self::Gat<'_> where T: Copy { + | ------------- expected `&T` because of return type +LL | *self.test() + | ^^^^^^^^^^^^ + | | + | expected `&T`, found type parameter `T` + | help: consider borrowing here: `&*self.test()` + | + = note: expected reference `&T` + found type parameter `T` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/lint/issue-79546-fuel-ice.rs b/src/test/ui/lint/issue-79546-fuel-ice.rs new file mode 100644 index 00000000000..0e9f54088b8 --- /dev/null +++ b/src/test/ui/lint/issue-79546-fuel-ice.rs @@ -0,0 +1,8 @@ +// Regression test for the ICE described in #79546. + +// compile-flags: --cap-lints=allow -Zfuel=issue79546=0 +// check-pass +#![crate_name="issue79546"] + +struct S; +fn main() {} diff --git a/src/test/ui/lint/must_not_suspend/boxed.rs b/src/test/ui/lint/must_not_suspend/boxed.rs new file mode 100644 index 00000000000..1f823fc559d --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/boxed.rs @@ -0,0 +1,25 @@ +// edition:2018 +#![feature(must_not_suspend)] +#![deny(must_not_suspend)] + +#[must_not_suspend = "You gotta use Umm's, ya know?"] +struct Umm { + i: i64 +} + + +fn bar() -> Box<Umm> { + Box::new(Umm { + i: 1 + }) +} + +async fn other() {} + +pub async fn uhoh() { + let _guard = bar(); //~ ERROR boxed `Umm` held across + other().await; +} + +fn main() { +} diff --git a/src/test/ui/lint/must_not_suspend/boxed.stderr b/src/test/ui/lint/must_not_suspend/boxed.stderr new file mode 100644 index 00000000000..edc62b6d687 --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/boxed.stderr @@ -0,0 +1,26 @@ +error: boxed `Umm` held across a suspend point, but should not be + --> $DIR/boxed.rs:20:9 + | +LL | let _guard = bar(); + | ^^^^^^ +LL | other().await; + | ------------- the value is held across this suspend point + | +note: the lint level is defined here + --> $DIR/boxed.rs:3:9 + | +LL | #![deny(must_not_suspend)] + | ^^^^^^^^^^^^^^^^ +note: You gotta use Umm's, ya know? + --> $DIR/boxed.rs:20:9 + | +LL | let _guard = bar(); + | ^^^^^^ +help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point + --> $DIR/boxed.rs:20:9 + | +LL | let _guard = bar(); + | ^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/lint/must_not_suspend/dedup.rs b/src/test/ui/lint/must_not_suspend/dedup.rs new file mode 100644 index 00000000000..040fff5a5a5 --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/dedup.rs @@ -0,0 +1,20 @@ +// edition:2018 +#![feature(must_not_suspend)] +#![deny(must_not_suspend)] + +#[must_not_suspend] +struct No {} + +async fn shushspend() {} + +async fn wheeee<T>(t: T) { + shushspend().await; + drop(t); +} + +async fn yes() { + wheeee(No {}).await; //~ ERROR `No` held across +} + +fn main() { +} diff --git a/src/test/ui/lint/must_not_suspend/dedup.stderr b/src/test/ui/lint/must_not_suspend/dedup.stderr new file mode 100644 index 00000000000..542b7a3bc7e --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/dedup.stderr @@ -0,0 +1,19 @@ +error: `No` held across a suspend point, but should not be + --> $DIR/dedup.rs:16:12 + | +LL | wheeee(No {}).await; + | -------^^^^^------- the value is held across this suspend point + | +note: the lint level is defined here + --> $DIR/dedup.rs:3:9 + | +LL | #![deny(must_not_suspend)] + | ^^^^^^^^^^^^^^^^ +help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point + --> $DIR/dedup.rs:16:12 + | +LL | wheeee(No {}).await; + | ^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/lint/must_not_suspend/feature-gate-must_not_suspend.rs b/src/test/ui/lint/must_not_suspend/feature-gate-must_not_suspend.rs new file mode 100644 index 00000000000..1554408c174 --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/feature-gate-must_not_suspend.rs @@ -0,0 +1,9 @@ +// edition:2018 + +#[must_not_suspend = "You gotta use Umm's, ya know?"] //~ ERROR the `#[must_not_suspend]` +struct Umm { + _i: i64 +} + +fn main() { +} diff --git a/src/test/ui/lint/must_not_suspend/feature-gate-must_not_suspend.stderr b/src/test/ui/lint/must_not_suspend/feature-gate-must_not_suspend.stderr new file mode 100644 index 00000000000..ab20a8be874 --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/feature-gate-must_not_suspend.stderr @@ -0,0 +1,12 @@ +error[E0658]: the `#[must_not_suspend]` attribute is an experimental feature + --> $DIR/feature-gate-must_not_suspend.rs:3:1 + | +LL | #[must_not_suspend = "You gotta use Umm's, ya know?"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #83310 <https://github.com/rust-lang/rust/issues/83310> for more information + = help: add `#![feature(must_not_suspend)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/lint/must_not_suspend/generic.rs b/src/test/ui/lint/must_not_suspend/generic.rs new file mode 100644 index 00000000000..b3effa020c4 --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/generic.rs @@ -0,0 +1,20 @@ +// edition:2018 +// run-pass +// +// this test shows a case where the lint doesn't fire in generic code +#![feature(must_not_suspend)] +#![deny(must_not_suspend)] + +#[must_not_suspend] +struct No {} + +async fn shushspend() {} + +async fn wheeee<T>(t: T) { + shushspend().await; + drop(t); +} + +fn main() { + let _fut = wheeee(No {}); +} diff --git a/src/test/ui/lint/must_not_suspend/handled.rs b/src/test/ui/lint/must_not_suspend/handled.rs new file mode 100644 index 00000000000..8714be6449f --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/handled.rs @@ -0,0 +1,28 @@ +// edition:2018 +// run-pass +#![feature(must_not_suspend)] +#![deny(must_not_suspend)] + +#[must_not_suspend = "You gotta use Umm's, ya know?"] +struct Umm { + _i: i64 +} + + +fn bar() -> Umm { + Umm { + _i: 1 + } +} + +async fn other() {} + +pub async fn uhoh() { + { + let _guard = bar(); + } + other().await; +} + +fn main() { +} diff --git a/src/test/ui/lint/must_not_suspend/other_items.rs b/src/test/ui/lint/must_not_suspend/other_items.rs new file mode 100644 index 00000000000..5aa1abb14d3 --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/other_items.rs @@ -0,0 +1,8 @@ +// edition:2018 +#![feature(must_not_suspend)] +#![deny(must_not_suspend)] + +#[must_not_suspend] //~ ERROR attribute should be +mod inner {} + +fn main() {} diff --git a/src/test/ui/lint/must_not_suspend/other_items.stderr b/src/test/ui/lint/must_not_suspend/other_items.stderr new file mode 100644 index 00000000000..41c8896921b --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/other_items.stderr @@ -0,0 +1,10 @@ +error: `must_not_suspend` attribute should be applied to a struct, enum, or trait + --> $DIR/other_items.rs:5:1 + | +LL | #[must_not_suspend] + | ^^^^^^^^^^^^^^^^^^^ +LL | mod inner {} + | ------------ is not a struct, enum, or trait + +error: aborting due to previous error + diff --git a/src/test/ui/lint/must_not_suspend/ref.rs b/src/test/ui/lint/must_not_suspend/ref.rs new file mode 100644 index 00000000000..738dd9e0465 --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/ref.rs @@ -0,0 +1,29 @@ +// edition:2018 +#![feature(must_not_suspend)] +#![deny(must_not_suspend)] + +#[must_not_suspend = "You gotta use Umm's, ya know?"] +struct Umm { + i: i64 +} + +struct Bar { + u: Umm, +} + +async fn other() {} + +impl Bar { + async fn uhoh(&mut self) { + let guard = &mut self.u; //~ ERROR `Umm` held across + + other().await; + + *guard = Umm { + i: 2 + } + } +} + +fn main() { +} diff --git a/src/test/ui/lint/must_not_suspend/ref.stderr b/src/test/ui/lint/must_not_suspend/ref.stderr new file mode 100644 index 00000000000..78b44b00625 --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/ref.stderr @@ -0,0 +1,27 @@ +error: `Umm` held across a suspend point, but should not be + --> $DIR/ref.rs:18:26 + | +LL | let guard = &mut self.u; + | ^^^^^^ +LL | +LL | other().await; + | ------------- the value is held across this suspend point + | +note: the lint level is defined here + --> $DIR/ref.rs:3:9 + | +LL | #![deny(must_not_suspend)] + | ^^^^^^^^^^^^^^^^ +note: You gotta use Umm's, ya know? + --> $DIR/ref.rs:18:26 + | +LL | let guard = &mut self.u; + | ^^^^^^ +help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point + --> $DIR/ref.rs:18:26 + | +LL | let guard = &mut self.u; + | ^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/lint/must_not_suspend/return.rs b/src/test/ui/lint/must_not_suspend/return.rs new file mode 100644 index 00000000000..5b1fa5e2721 --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/return.rs @@ -0,0 +1,9 @@ +// edition:2018 +#![feature(must_not_suspend)] +#![deny(must_not_suspend)] + +#[must_not_suspend] //~ ERROR attribute should be +fn foo() -> i32 { + 0 +} +fn main() {} diff --git a/src/test/ui/lint/must_not_suspend/return.stderr b/src/test/ui/lint/must_not_suspend/return.stderr new file mode 100644 index 00000000000..fdada85eb4d --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/return.stderr @@ -0,0 +1,12 @@ +error: `must_not_suspend` attribute should be applied to a struct, enum, or trait + --> $DIR/return.rs:5:1 + | +LL | #[must_not_suspend] + | ^^^^^^^^^^^^^^^^^^^ +LL | / fn foo() -> i32 { +LL | | 0 +LL | | } + | |_- is not a struct, enum, or trait + +error: aborting due to previous error + diff --git a/src/test/ui/lint/must_not_suspend/trait.rs b/src/test/ui/lint/must_not_suspend/trait.rs new file mode 100644 index 00000000000..6c911cb4b0f --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/trait.rs @@ -0,0 +1,28 @@ +// edition:2018 +#![feature(must_not_suspend)] +#![deny(must_not_suspend)] + +#[must_not_suspend] +trait Wow {} + +impl Wow for i32 {} + +fn r#impl() -> impl Wow { + 1 +} + +fn r#dyn() -> Box<dyn Wow> { + Box::new(1) +} + +async fn other() {} + +pub async fn uhoh() { + let _guard1 = r#impl(); //~ ERROR implementer of `Wow` held across + let _guard2 = r#dyn(); //~ ERROR boxed `Wow` trait object held across + + other().await; +} + +fn main() { +} diff --git a/src/test/ui/lint/must_not_suspend/trait.stderr b/src/test/ui/lint/must_not_suspend/trait.stderr new file mode 100644 index 00000000000..d19ffddd482 --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/trait.stderr @@ -0,0 +1,37 @@ +error: implementer of `Wow` held across a suspend point, but should not be + --> $DIR/trait.rs:21:9 + | +LL | let _guard1 = r#impl(); + | ^^^^^^^ +... +LL | other().await; + | ------------- the value is held across this suspend point + | +note: the lint level is defined here + --> $DIR/trait.rs:3:9 + | +LL | #![deny(must_not_suspend)] + | ^^^^^^^^^^^^^^^^ +help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point + --> $DIR/trait.rs:21:9 + | +LL | let _guard1 = r#impl(); + | ^^^^^^^ + +error: boxed `Wow` trait object held across a suspend point, but should not be + --> $DIR/trait.rs:22:9 + | +LL | let _guard2 = r#dyn(); + | ^^^^^^^ +LL | +LL | other().await; + | ------------- the value is held across this suspend point + | +help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point + --> $DIR/trait.rs:22:9 + | +LL | let _guard2 = r#dyn(); + | ^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/lint/must_not_suspend/unit.rs b/src/test/ui/lint/must_not_suspend/unit.rs new file mode 100644 index 00000000000..d3a19f70432 --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/unit.rs @@ -0,0 +1,25 @@ +// edition:2018 +#![feature(must_not_suspend)] +#![deny(must_not_suspend)] + +#[must_not_suspend = "You gotta use Umm's, ya know?"] +struct Umm { + i: i64 +} + + +fn bar() -> Umm { + Umm { + i: 1 + } +} + +async fn other() {} + +pub async fn uhoh() { + let _guard = bar(); //~ ERROR `Umm` held across + other().await; +} + +fn main() { +} diff --git a/src/test/ui/lint/must_not_suspend/unit.stderr b/src/test/ui/lint/must_not_suspend/unit.stderr new file mode 100644 index 00000000000..425c076823d --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/unit.stderr @@ -0,0 +1,26 @@ +error: `Umm` held across a suspend point, but should not be + --> $DIR/unit.rs:20:9 + | +LL | let _guard = bar(); + | ^^^^^^ +LL | other().await; + | ------------- the value is held across this suspend point + | +note: the lint level is defined here + --> $DIR/unit.rs:3:9 + | +LL | #![deny(must_not_suspend)] + | ^^^^^^^^^^^^^^^^ +note: You gotta use Umm's, ya know? + --> $DIR/unit.rs:20:9 + | +LL | let _guard = bar(); + | ^^^^^^ +help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point + --> $DIR/unit.rs:20:9 + | +LL | let _guard = bar(); + | ^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/lint/must_not_suspend/warn.rs b/src/test/ui/lint/must_not_suspend/warn.rs new file mode 100644 index 00000000000..50a696ba523 --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/warn.rs @@ -0,0 +1,25 @@ +// edition:2018 +// run-pass +#![feature(must_not_suspend)] + +#[must_not_suspend = "You gotta use Umm's, ya know?"] +struct Umm { + _i: i64 +} + + +fn bar() -> Umm { + Umm { + _i: 1 + } +} + +async fn other() {} + +pub async fn uhoh() { + let _guard = bar(); //~ WARNING `Umm` held across + other().await; +} + +fn main() { +} diff --git a/src/test/ui/lint/must_not_suspend/warn.stderr b/src/test/ui/lint/must_not_suspend/warn.stderr new file mode 100644 index 00000000000..24f52275b43 --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/warn.stderr @@ -0,0 +1,22 @@ +warning: `Umm` held across a suspend point, but should not be + --> $DIR/warn.rs:20:9 + | +LL | let _guard = bar(); + | ^^^^^^ +LL | other().await; + | ------------- the value is held across this suspend point + | + = note: `#[warn(must_not_suspend)]` on by default +note: You gotta use Umm's, ya know? + --> $DIR/warn.rs:20:9 + | +LL | let _guard = bar(); + | ^^^^^^ +help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point + --> $DIR/warn.rs:20:9 + | +LL | let _guard = bar(); + | ^^^^^^ + +warning: 1 warning emitted + diff --git a/src/test/ui/parser/issue-44406.stderr b/src/test/ui/parser/issue-44406.stderr index 862026408ef..a37a806a157 100644 --- a/src/test/ui/parser/issue-44406.stderr +++ b/src/test/ui/parser/issue-44406.stderr @@ -26,7 +26,7 @@ LL | bar { } help: if `bar` is a function, use the arguments directly | LL - bar(baz: $rest) -LL + bar(true); +LL + bar(: $rest) | error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/unicode-character-literal.fixed b/src/test/ui/parser/unicode-character-literal.fixed new file mode 100644 index 00000000000..26ef5ffa11a --- /dev/null +++ b/src/test/ui/parser/unicode-character-literal.fixed @@ -0,0 +1,21 @@ +// Regression test for #88684: Improve diagnostics for combining marks +// in character literals. + +// run-rustfix + +fn main() { + let _spade = "♠️"; + //~^ ERROR: character literal may only contain one codepoint + //~| NOTE: this `♠` is followed by the combining mark `\u{fe0f}` + //~| HELP: if you meant to write a `str` literal, use double quotes + + let _s = "ṩ̂̊"; + //~^ ERROR: character literal may only contain one codepoint + //~| NOTE: this `s` is followed by the combining marks `\u{323}\u{307}\u{302}\u{30a}` + //~| HELP: if you meant to write a `str` literal, use double quotes + + let _a = 'Å'; + //~^ ERROR: character literal may only contain one codepoint + //~| NOTE: this `A` is followed by the combining mark `\u{30a}` + //~| HELP: consider using the normalized form `\u{c5}` of this character +} diff --git a/src/test/ui/parser/unicode-character-literal.rs b/src/test/ui/parser/unicode-character-literal.rs new file mode 100644 index 00000000000..d331522c04c --- /dev/null +++ b/src/test/ui/parser/unicode-character-literal.rs @@ -0,0 +1,21 @@ +// Regression test for #88684: Improve diagnostics for combining marks +// in character literals. + +// run-rustfix + +fn main() { + let _spade = '♠️'; + //~^ ERROR: character literal may only contain one codepoint + //~| NOTE: this `♠` is followed by the combining mark `\u{fe0f}` + //~| HELP: if you meant to write a `str` literal, use double quotes + + let _s = 'ṩ̂̊'; + //~^ ERROR: character literal may only contain one codepoint + //~| NOTE: this `s` is followed by the combining marks `\u{323}\u{307}\u{302}\u{30a}` + //~| HELP: if you meant to write a `str` literal, use double quotes + + let _a = 'Å'; + //~^ ERROR: character literal may only contain one codepoint + //~| NOTE: this `A` is followed by the combining mark `\u{30a}` + //~| HELP: consider using the normalized form `\u{c5}` of this character +} diff --git a/src/test/ui/parser/unicode-character-literal.stderr b/src/test/ui/parser/unicode-character-literal.stderr new file mode 100644 index 00000000000..5cd3bd0fe69 --- /dev/null +++ b/src/test/ui/parser/unicode-character-literal.stderr @@ -0,0 +1,48 @@ +error: character literal may only contain one codepoint + --> $DIR/unicode-character-literal.rs:7:18 + | +LL | let _spade = '♠️'; + | ^^^ + | +note: this `♠` is followed by the combining mark `\u{fe0f}` + --> $DIR/unicode-character-literal.rs:7:19 + | +LL | let _spade = '♠️'; + | ^ +help: if you meant to write a `str` literal, use double quotes + | +LL | let _spade = "♠️"; + | ~~~ + +error: character literal may only contain one codepoint + --> $DIR/unicode-character-literal.rs:12:14 + | +LL | let _s = 'ṩ̂̊'; + | ^^^ + | +note: this `s` is followed by the combining marks `\u{323}\u{307}\u{302}\u{30a}` + --> $DIR/unicode-character-literal.rs:12:15 + | +LL | let _s = 'ṩ̂̊'; + | ^ +help: if you meant to write a `str` literal, use double quotes + | +LL | let _s = "ṩ̂̊"; + | ~~~ + +error: character literal may only contain one codepoint + --> $DIR/unicode-character-literal.rs:17:14 + | +LL | let _a = 'Å'; + | ^-^ + | | + | help: consider using the normalized form `\u{c5}` of this character: `Å` + | +note: this `A` is followed by the combining mark `\u{30a}` + --> $DIR/unicode-character-literal.rs:17:15 + | +LL | let _a = 'Å'; + | ^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/rfc-2091-track-caller/tracked-closure.rs b/src/test/ui/rfc-2091-track-caller/tracked-closure.rs new file mode 100644 index 00000000000..670c423a7e0 --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/tracked-closure.rs @@ -0,0 +1,154 @@ +// run-pass + +#![feature(stmt_expr_attributes)] +#![feature(closure_track_caller)] +#![feature(generator_trait)] +#![feature(generators)] + +use std::ops::{Generator, GeneratorState}; +use std::pin::Pin; +use std::panic::Location; + +type Loc = &'static Location<'static>; + +#[track_caller] +fn mono_invoke_fn<F: Fn(&'static str, bool) -> (&'static str, bool, Loc)>( + val: &F +) -> (&'static str, bool, Loc) { + val("from_mono", false) +} + +#[track_caller] +fn mono_invoke_fn_once<F: FnOnce(&'static str, bool) -> (&'static str, bool, Loc)>( + val: F +) -> (&'static str, bool, Loc) { + val("from_mono", false) +} + +#[track_caller] +fn dyn_invoke_fn_mut( + val: &mut dyn FnMut(&'static str, bool) -> (&'static str, bool, Loc) +) -> (&'static str, bool, Loc) { + val("from_dyn", false) +} + +#[track_caller] +fn dyn_invoke_fn_once( + val: Box<dyn FnOnce(&'static str, bool) -> (&'static str, bool, Loc)> +) -> (&'static str, bool, Loc) { + val("from_dyn", false) +} + + +fn test_closure() { + let mut track_closure = #[track_caller] |first: &'static str, second: bool| { + (first, second, Location::caller()) + }; + let (first_arg, first_bool, first_loc) = track_closure("first_arg", true); + let first_line = line!() - 1; + assert_eq!(first_arg, "first_arg"); + assert_eq!(first_bool, true); + assert_eq!(first_loc.file(), file!()); + assert_eq!(first_loc.line(), first_line); + assert_eq!(first_loc.column(), 46); + + let (dyn_arg, dyn_bool, dyn_loc) = dyn_invoke_fn_mut(&mut track_closure); + assert_eq!(dyn_arg, "from_dyn"); + assert_eq!(dyn_bool, false); + // `FnMut::call_mut` does not have `#[track_caller]`, + // so this will not match + assert_ne!(dyn_loc.file(), file!()); + + let (dyn_arg, dyn_bool, dyn_loc) = dyn_invoke_fn_once(Box::new(track_closure)); + assert_eq!(dyn_arg, "from_dyn"); + assert_eq!(dyn_bool, false); + // `FnOnce::call_once` does not have `#[track_caller]` + // so this will not match + assert_ne!(dyn_loc.file(), file!()); + + + let (mono_arg, mono_bool, mono_loc) = mono_invoke_fn(&track_closure); + let mono_line = line!() - 1; + assert_eq!(mono_arg, "from_mono"); + assert_eq!(mono_bool, false); + assert_eq!(mono_loc.file(), file!()); + assert_eq!(mono_loc.line(), mono_line); + assert_eq!(mono_loc.column(), 43); + + let (mono_arg, mono_bool, mono_loc) = mono_invoke_fn_once(track_closure); + let mono_line = line!() - 1; + assert_eq!(mono_arg, "from_mono"); + assert_eq!(mono_bool, false); + assert_eq!(mono_loc.file(), file!()); + assert_eq!(mono_loc.line(), mono_line); + assert_eq!(mono_loc.column(), 43); + + let non_tracked_caller = || Location::caller(); + let non_tracked_line = line!() - 1; // This is the line of the closure, not its caller + let non_tracked_loc = non_tracked_caller(); + assert_eq!(non_tracked_loc.file(), file!()); + assert_eq!(non_tracked_loc.line(), non_tracked_line); + assert_eq!(non_tracked_loc.column(), 33); +} + + +#[track_caller] +fn mono_generator<F: Generator<String, Yield = (&'static str, String, Loc), Return = ()>>( + val: Pin<&mut F> +) -> (&'static str, String, Loc) { + match val.resume("Mono".to_string()) { + GeneratorState::Yielded(val) => val, + _ => unreachable!() + } +} + +#[track_caller] +fn dyn_generator( + val: Pin<&mut dyn Generator<String, Yield = (&'static str, String, Loc), Return = ()>> +) -> (&'static str, String, Loc) { + match val.resume("Dyn".to_string()) { + GeneratorState::Yielded(val) => val, + _ => unreachable!() + } +} + +fn test_generator() { + let generator = #[track_caller] |arg: String| { + yield ("first", arg.clone(), Location::caller()); + yield ("second", arg.clone(), Location::caller()); + }; + + let mut pinned = Box::pin(generator); + let (dyn_ret, dyn_arg, dyn_loc) = dyn_generator(pinned.as_mut()); + assert_eq!(dyn_ret, "first"); + assert_eq!(dyn_arg, "Dyn".to_string()); + // The `Generator` trait does not have `#[track_caller]` on `resume`, so + // this will not match. + assert_ne!(dyn_loc.file(), file!()); + + + let (mono_ret, mono_arg, mono_loc) = mono_generator(pinned.as_mut()); + let mono_line = line!() - 1; + assert_eq!(mono_ret, "second"); + // The generator ignores the argument to the second `resume` call + assert_eq!(mono_arg, "Dyn".to_string()); + assert_eq!(mono_loc.file(), file!()); + assert_eq!(mono_loc.line(), mono_line); + assert_eq!(mono_loc.column(), 42); + + let non_tracked_generator = || { yield Location::caller(); }; + let non_tracked_line = line!() - 1; // This is the line of the generator, not its caller + let non_tracked_loc = match Box::pin(non_tracked_generator).as_mut().resume(()) { + GeneratorState::Yielded(val) => val, + _ => unreachable!() + }; + assert_eq!(non_tracked_loc.file(), file!()); + assert_eq!(non_tracked_loc.line(), non_tracked_line); + assert_eq!(non_tracked_loc.column(), 44); + +} + +fn main() { + test_closure(); + test_generator(); +} diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml index 334407c2b2e..340acff34f2 100644 --- a/src/tools/build-manifest/Cargo.toml +++ b/src/tools/build-manifest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "build-manifest" version = "0.1.0" -edition = "2018" +edition = "2021" [dependencies] toml = "0.5" diff --git a/src/tools/bump-stage0/Cargo.toml b/src/tools/bump-stage0/Cargo.toml index 7d64e20a3d3..cf8840ff6ee 100644 --- a/src/tools/bump-stage0/Cargo.toml +++ b/src/tools/bump-stage0/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "bump-stage0" version = "0.1.0" -edition = "2018" +edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 9a28ac83c9eb73e42ffafac552c0a55f00dbf40 +Subproject 0121d66aa2ef5ffa9735f86c2b56f5fdc5a837a diff --git a/src/tools/cargotest/Cargo.toml b/src/tools/cargotest/Cargo.toml index a88272d2344..bfd894e2bd2 100644 --- a/src/tools/cargotest/Cargo.toml +++ b/src/tools/cargotest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cargotest2" version = "0.1.0" -edition = "2018" +edition = "2021" [[bin]] name = "cargotest" diff --git a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs index 7e4d1b3ef9f..f22f52b949e 100644 --- a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs +++ b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs @@ -65,7 +65,7 @@ impl<'tcx> LateLintPass<'tcx> for FallibleImplFrom { } } -fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_items: &[hir::ImplItemRef<'_>]) { +fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_items: &[hir::ImplItemRef]) { use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::{Expr, ExprKind, ImplItemKind, QPath}; diff --git a/src/tools/clippy/clippy_utils/src/higher.rs b/src/tools/clippy/clippy_utils/src/higher.rs index 05a4a014319..e6c06224999 100644 --- a/src/tools/clippy/clippy_utils/src/higher.rs +++ b/src/tools/clippy/clippy_utils/src/higher.rs @@ -105,8 +105,7 @@ impl<'hir> IfLet<'hir> { if_else, ) = expr.kind { - let hir = cx.tcx.hir(); - let mut iter = hir.parent_iter(expr.hir_id); + let mut iter = cx.tcx.hir().parent_iter(expr.hir_id); if let Some((_, Node::Block(Block { stmts: [], .. }))) = iter.next() { if let Some(( _, @@ -524,28 +523,12 @@ impl FormatArgsExpn<'tcx> { if let ExpnKind::Macro(_, name) = expr.span.ctxt().outer_expn_data().kind; let name = name.as_str(); if name.ends_with("format_args") || name.ends_with("format_args_nl"); - - if let ExprKind::Match(inner_match, [arm], _) = expr.kind; - - // `match match`, if you will - if let ExprKind::Match(args, [inner_arm], _) = inner_match.kind; - if let ExprKind::Tup(value_args) = args.kind; - if let Some(value_args) = value_args - .iter() - .map(|e| match e.kind { - ExprKind::AddrOf(_, _, e) => Some(e), - _ => None, - }) - .collect(); - if let ExprKind::Array(args) = inner_arm.body.kind; - - if let ExprKind::Block(Block { stmts: [], expr: Some(expr), .. }, _) = arm.body.kind; - if let ExprKind::Call(_, call_args) = expr.kind; - if let Some((strs_ref, fmt_expr)) = match call_args { + if let ExprKind::Call(_, args) = expr.kind; + if let Some((strs_ref, args, fmt_expr)) = match args { // Arguments::new_v1 - [strs_ref, _] => Some((strs_ref, None)), + [strs_ref, args] => Some((strs_ref, args, None)), // Arguments::new_v1_formatted - [strs_ref, _, fmt_expr] => Some((strs_ref, Some(fmt_expr))), + [strs_ref, args, fmt_expr, _unsafe_arg] => Some((strs_ref, args, Some(fmt_expr))), _ => None, }; if let ExprKind::AddrOf(BorrowKind::Ref, _, strs_arr) = strs_ref.kind; @@ -561,6 +544,17 @@ impl FormatArgsExpn<'tcx> { None }) .collect(); + if let ExprKind::AddrOf(BorrowKind::Ref, _, args) = args.kind; + if let ExprKind::Match(args, [arm], _) = args.kind; + if let ExprKind::Tup(value_args) = args.kind; + if let Some(value_args) = value_args + .iter() + .map(|e| match e.kind { + ExprKind::AddrOf(_, _, e) => Some(e), + _ => None, + }) + .collect(); + if let ExprKind::Array(args) = arm.body.kind; then { Some(FormatArgsExpn { format_string_span: strs_ref.span, diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 3a94f472983..7f5a1bf9c07 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -833,12 +833,11 @@ pub fn capture_local_usage(cx: &LateContext<'tcx>, e: &Expr<'_>) -> CaptureKind ExprKind::Path(QPath::Resolved(None, Path { res: Res::Local(_), .. })) )); - let map = cx.tcx.hir(); let mut child_id = e.hir_id; let mut capture = CaptureKind::Value; let mut capture_expr_ty = e; - for (parent_id, parent) in map.parent_iter(e.hir_id) { + for (parent_id, parent) in cx.tcx.hir().parent_iter(e.hir_id) { if let [Adjustment { kind: Adjust::Deref(_) | Adjust::Borrow(AutoBorrow::Ref(..)), target, @@ -1224,8 +1223,7 @@ pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Optio /// Gets the loop or closure enclosing the given expression, if any. pub fn get_enclosing_loop_or_closure(tcx: TyCtxt<'tcx>, expr: &Expr<'_>) -> Option<&'tcx Expr<'tcx>> { - let map = tcx.hir(); - for (_, node) in map.parent_iter(expr.hir_id) { + for (_, node) in tcx.hir().parent_iter(expr.hir_id) { match node { Node::Expr( e @@ -1244,8 +1242,7 @@ pub fn get_enclosing_loop_or_closure(tcx: TyCtxt<'tcx>, expr: &Expr<'_>) -> Opti /// Gets the parent node if it's an impl block. pub fn get_parent_as_impl(tcx: TyCtxt<'_>, id: HirId) -> Option<&Impl<'_>> { - let map = tcx.hir(); - match map.parent_iter(id).next() { + match tcx.hir().parent_iter(id).next() { Some(( _, Node::Item(Item { @@ -1259,8 +1256,7 @@ pub fn get_parent_as_impl(tcx: TyCtxt<'_>, id: HirId) -> Option<&Impl<'_>> { /// Checks if the given expression is the else clause of either an `if` or `if let` expression. pub fn is_else_clause(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool { - let map = tcx.hir(); - let mut iter = map.parent_iter(expr.hir_id); + let mut iter = tcx.hir().parent_iter(expr.hir_id); match iter.next() { Some(( _, @@ -1794,9 +1790,8 @@ pub fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool /// Gets the node where an expression is either used, or it's type is unified with another branch. pub fn get_expr_use_or_unification_node(tcx: TyCtxt<'tcx>, expr: &Expr<'_>) -> Option<Node<'tcx>> { - let map = tcx.hir(); let mut child_id = expr.hir_id; - let mut iter = map.parent_iter(child_id); + let mut iter = tcx.hir().parent_iter(child_id); loop { match iter.next() { None => break None, diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml index d6aa3fd2631..e9426a2d9f5 100644 --- a/src/tools/compiletest/Cargo.toml +++ b/src/tools/compiletest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "compiletest" version = "0.0.0" -edition = "2018" +edition = "2021" [dependencies] colored = "2" diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 75d392951ec..d03c21dc508 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -96,7 +96,8 @@ pub const ASAN_SUPPORTED_TARGETS: &[&str] = &[ ]; pub const LSAN_SUPPORTED_TARGETS: &[&str] = &[ - "aarch64-apple-darwin", + // FIXME: currently broken, see #88132 + // "aarch64-apple-darwin", "aarch64-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-unknown-linux-gnu", diff --git a/src/tools/error_index_generator/Cargo.toml b/src/tools/error_index_generator/Cargo.toml index 2e4b7beb376..c84b79e11e9 100644 --- a/src/tools/error_index_generator/Cargo.toml +++ b/src/tools/error_index_generator/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "error_index_generator" version = "0.0.0" -edition = "2018" +edition = "2021" [dependencies] rustdoc = { path = "../../librustdoc" } diff --git a/src/tools/expand-yaml-anchors/Cargo.toml b/src/tools/expand-yaml-anchors/Cargo.toml index 358dff06532..9a25b6c1f1c 100644 --- a/src/tools/expand-yaml-anchors/Cargo.toml +++ b/src/tools/expand-yaml-anchors/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "expand-yaml-anchors" version = "0.1.0" -edition = "2018" +edition = "2021" [dependencies] yaml-rust = "0.4.3" diff --git a/src/tools/html-checker/Cargo.toml b/src/tools/html-checker/Cargo.toml index e88d2f0d928..34d3954db28 100644 --- a/src/tools/html-checker/Cargo.toml +++ b/src/tools/html-checker/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "html-checker" version = "0.1.0" -edition = "2018" +edition = "2021" [[bin]] name = "html-checker" diff --git a/src/tools/jsondocck/Cargo.toml b/src/tools/jsondocck/Cargo.toml index a65deb12541..ccabe6483d7 100644 --- a/src/tools/jsondocck/Cargo.toml +++ b/src/tools/jsondocck/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "jsondocck" version = "0.1.0" -edition = "2018" +edition = "2021" [dependencies] jsonpath_lib = "0.2" diff --git a/src/tools/linkchecker/Cargo.toml b/src/tools/linkchecker/Cargo.toml index 21ba2269556..1d8f2f91882 100644 --- a/src/tools/linkchecker/Cargo.toml +++ b/src/tools/linkchecker/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "linkchecker" version = "0.1.0" -edition = "2018" +edition = "2021" [[bin]] name = "linkchecker" diff --git a/src/tools/lint-docs/Cargo.toml b/src/tools/lint-docs/Cargo.toml index 6792887fa5d..3578bda8276 100644 --- a/src/tools/lint-docs/Cargo.toml +++ b/src/tools/lint-docs/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "lint-docs" version = "0.1.0" -edition = "2018" +edition = "2021" description = "A script to extract the lint documentation for the rustc book." # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs index e5c7f125712..fdc89a184da 100644 --- a/src/tools/lint-docs/src/lib.rs +++ b/src/tools/lint-docs/src/lib.rs @@ -149,6 +149,10 @@ impl<'a> LintExtractor<'a> { } else if line.starts_with("// ") { // Ignore comments. continue; + } else if line.starts_with("#[allow") { + // Ignore allow of lints (useful for + // invalid_rust_codeblocks). + continue; } else { let name = lint_name(line).map_err(|e| { format!( diff --git a/src/tools/remote-test-client/Cargo.toml b/src/tools/remote-test-client/Cargo.toml index 7b20ba83546..d59cd6b3d8e 100644 --- a/src/tools/remote-test-client/Cargo.toml +++ b/src/tools/remote-test-client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "remote-test-client" version = "0.1.0" -edition = "2018" +edition = "2021" [dependencies] diff --git a/src/tools/remote-test-server/Cargo.toml b/src/tools/remote-test-server/Cargo.toml index 01309aec9a3..e6be8530cf6 100644 --- a/src/tools/remote-test-server/Cargo.toml +++ b/src/tools/remote-test-server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "remote-test-server" version = "0.1.0" -edition = "2018" +edition = "2021" [dependencies] diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer -Subproject b73b321478d3b2a98d380eb79de717e01620c4e +Subproject f1d7f98ed07b9934286b9c4809dd4d7a4753787 diff --git a/src/tools/rust-demangler/Cargo.toml b/src/tools/rust-demangler/Cargo.toml index 157409bc847..2bb73b3262d 100644 --- a/src/tools/rust-demangler/Cargo.toml +++ b/src/tools/rust-demangler/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rust-demangler" version = "0.0.1" -edition = "2018" +edition = "2021" [dependencies] regex = "1.0" diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml index da36ce0e690..de1327d74ff 100644 --- a/src/tools/rustbook/Cargo.toml +++ b/src/tools/rustbook/Cargo.toml @@ -2,7 +2,7 @@ name = "rustbook" version = "0.1.0" license = "MIT OR Apache-2.0" -edition = "2018" +edition = "2021" [dependencies] clap = "2.25.0" diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml index 38b9fefbaf5..a28cf28841e 100644 --- a/src/tools/rustc-workspace-hack/Cargo.toml +++ b/src/tools/rustc-workspace-hack/Cargo.toml @@ -5,7 +5,7 @@ license = 'MIT OR Apache-2.0' description = """ Hack for the compiler's own build system """ -edition = "2018" +edition = "2021" [lib] path = "lib.rs" diff --git a/src/tools/rustdoc-themes/Cargo.toml b/src/tools/rustdoc-themes/Cargo.toml index 4b2ad982a84..3d8c77d36d7 100644 --- a/src/tools/rustdoc-themes/Cargo.toml +++ b/src/tools/rustdoc-themes/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustdoc-themes" version = "0.1.0" -edition = "2018" +edition = "2021" [[bin]] name = "rustdoc-themes" diff --git a/src/tools/rustdoc/Cargo.toml b/src/tools/rustdoc/Cargo.toml index 5625707b25a..c4101f72cc2 100644 --- a/src/tools/rustdoc/Cargo.toml +++ b/src/tools/rustdoc/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustdoc-tool" version = "0.0.0" -edition = "2018" +edition = "2021" # Cargo adds a number of paths to the dylib search path on windows, which results in # the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool" diff --git a/src/tools/rustfmt/Cargo.toml b/src/tools/rustfmt/Cargo.toml index 81e3e26e8b0..7b4667c17c8 100644 --- a/src/tools/rustfmt/Cargo.toml +++ b/src/tools/rustfmt/Cargo.toml @@ -8,7 +8,7 @@ readme = "README.md" license = "Apache-2.0/MIT" build = "build.rs" categories = ["development-tools"] -edition = "2018" +edition = "2021" [[bin]] name = "rustfmt" diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml index 57fe5a62e9a..69c8063f42e 100644 --- a/src/tools/tidy/Cargo.toml +++ b/src/tools/tidy/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "tidy" version = "0.1.0" -edition = "2018" +edition = "2021" autobins = false [dependencies] diff --git a/src/tools/tidy/src/edition.rs b/src/tools/tidy/src/edition.rs index 283c43e325c..b5e9ceddbaf 100644 --- a/src/tools/tidy/src/edition.rs +++ b/src/tools/tidy/src/edition.rs @@ -1,10 +1,15 @@ -//! Tidy check to ensure that crate `edition` is '2018' +//! Tidy check to ensure that crate `edition` is '2018' or '2021'. use std::path::Path; fn is_edition_2018(mut line: &str) -> bool { line = line.trim(); - line == "edition = \"2018\"" || line == "edition = \'2018\'" + line == "edition = \"2018\"" +} + +fn is_edition_2021(mut line: &str) -> bool { + line = line.trim(); + line == "edition = \"2021\"" } pub fn check(path: &Path, bad: &mut bool) { @@ -13,17 +18,38 @@ pub fn check(path: &Path, bad: &mut bool) { &mut |path| super::filter_dirs(path) || path.ends_with("src/test"), &mut |entry, contents| { let file = entry.path(); + let filestr = file.to_string_lossy().replace("\\", "/"); let filename = file.file_name().unwrap(); if filename != "Cargo.toml" { return; } - let has_edition = contents.lines().any(is_edition_2018); - if !has_edition { - tidy_error!( - bad, - "{} doesn't have `edition = \"2018\"` on a separate line", - file.display() - ); + + // Library crates are not yet ready to migrate to 2021. + // + // The reference and rustc-dev-guide are submodules, so are left at + // 2018 for now. They should be removed from this exception list + // when bumped. + if path.components().any(|c| c.as_os_str() == "library") + || filestr.contains("src/doc/reference/style-check/Cargo.toml") + || filestr.contains("src/doc/rustc-dev-guide/ci/date-check/Cargo.toml") + { + let has = contents.lines().any(is_edition_2018); + if !has { + tidy_error!( + bad, + "{} doesn't have `edition = \"2018\"` on a separate line", + file.display() + ); + } + } else { + let is_2021 = contents.lines().any(is_edition_2021); + if !is_2021 { + tidy_error!( + bad, + "{} doesn't have `edition = \"2021\"` on a separate line", + file.display() + ); + } } }, ); diff --git a/src/tools/tier-check/Cargo.toml b/src/tools/tier-check/Cargo.toml index d6119cac5f3..3f08165a3fc 100644 --- a/src/tools/tier-check/Cargo.toml +++ b/src/tools/tier-check/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "tier-check" version = "0.1.0" -edition = "2018" +edition = "2021" license = "MIT OR Apache-2.0" [dependencies] diff --git a/src/tools/unicode-table-generator/Cargo.toml b/src/tools/unicode-table-generator/Cargo.toml index 948773f7810..ef01877c0b9 100644 --- a/src/tools/unicode-table-generator/Cargo.toml +++ b/src/tools/unicode-table-generator/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "unicode-bdd" version = "0.1.0" -edition = "2018" +edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/tools/unstable-book-gen/Cargo.toml b/src/tools/unstable-book-gen/Cargo.toml index febeaa446b3..73e5a91bec7 100644 --- a/src/tools/unstable-book-gen/Cargo.toml +++ b/src/tools/unstable-book-gen/Cargo.toml @@ -2,7 +2,7 @@ name = "unstable-book-gen" version = "0.1.0" license = "MIT OR Apache-2.0" -edition = "2018" +edition = "2021" [dependencies] tidy = { path = "../tidy" } diff --git a/src/tools/x/Cargo.toml b/src/tools/x/Cargo.toml index 264a741159a..31502727962 100644 --- a/src/tools/x/Cargo.toml +++ b/src/tools/x/Cargo.toml @@ -2,5 +2,5 @@ name = "x" version = "0.1.0" description = "Run x.py slightly more conveniently" -edition = "2018" +edition = "2021" publish = false |
