From b75351e98ee0a33dbd4dfe2b40e54e191d16dde5 Mon Sep 17 00:00:00 2001 From: danflapjax <12000932+danflapjax@users.noreply.github.com> Date: Thu, 10 Aug 2023 22:38:30 -0700 Subject: [PATCH 1/8] Optimized implementations of max, min, and clamp for bool --- library/core/src/cmp.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index faf48ae570fdd..3c127efb390ae 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1406,6 +1406,22 @@ mod impls { _ => unsafe { unreachable_unchecked() }, } } + + #[inline] + fn min(self, other: bool) -> bool { + self & other + } + + #[inline] + fn max(self, other: bool) -> bool { + self | other + } + + #[inline] + fn clamp(self, min: bool, max: bool) -> bool { + assert!(min <= max); + self.max(min).min(max) + } } ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } From e4cf708d2fff1ebc8aa7a21a1be152b5247206a1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 11 Aug 2023 21:27:52 +0000 Subject: [PATCH 2/8] Don't add associated type bound for non-types --- compiler/rustc_hir_analysis/messages.ftl | 3 ++ .../rustc_hir_analysis/src/astconv/bounds.rs | 29 ++++++++++++------- compiler/rustc_hir_analysis/src/errors.rs | 9 ++++++ tests/ui/associated-type-bounds/consts.rs | 10 +++++++ tests/ui/associated-type-bounds/consts.stderr | 10 +++++++ 5 files changed, 51 insertions(+), 10 deletions(-) create mode 100644 tests/ui/associated-type-bounds/consts.rs create mode 100644 tests/ui/associated-type-bounds/consts.stderr diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 166760166c108..597cae6ff33ca 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -1,6 +1,9 @@ hir_analysis_ambiguous_lifetime_bound = ambiguous lifetime bound, explicit lifetime bound required +hir_analysis_assoc_bound_on_const = expected associated type, found {$descr} + .note = trait bounds not allowed on {$descr} + hir_analysis_assoc_type_binding_not_allowed = associated type bindings are not allowed here .label = associated type not allowed here diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs index 30145b1a185ac..ba152cd48dea4 100644 --- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs +++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs @@ -13,7 +13,7 @@ use crate::astconv::{ AstConv, ConvertedBinding, ConvertedBindingKind, OnlySelfBounds, PredicateFilter, }; use crate::bounds::Bounds; -use crate::errors::{MultipleRelaxedDefaultBounds, ValueOfAssociatedStructAlreadySpecified}; +use crate::errors; impl<'tcx> dyn AstConv<'tcx> + '_ { /// Sets `implicitly_sized` to true on `Bounds` if necessary @@ -35,7 +35,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { if unbound.is_none() { unbound = Some(&ptr.trait_ref); } else { - tcx.sess.emit_err(MultipleRelaxedDefaultBounds { span }); + tcx.sess.emit_err(errors::MultipleRelaxedDefaultBounds { span }); } } } @@ -326,7 +326,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { dup_bindings .entry(assoc_item.def_id) .and_modify(|prev_span| { - tcx.sess.emit_err(ValueOfAssociatedStructAlreadySpecified { + tcx.sess.emit_err(errors::ValueOfAssociatedStructAlreadySpecified { span: binding.span, prev_span: *prev_span, item_name: binding.item_name, @@ -488,6 +488,8 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { } } + let assoc_item_def_id = projection_ty.skip_binder().def_id; + let def_kind = tcx.def_kind(assoc_item_def_id); match binding.kind { ConvertedBindingKind::Equality(..) if return_type_notation => { return Err(self.tcx().sess.emit_err( @@ -499,11 +501,9 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { // the "projection predicate" for: // // `::Item = u32` - let assoc_item_def_id = projection_ty.skip_binder().def_id; - let def_kind = tcx.def_kind(assoc_item_def_id); match (def_kind, term.unpack()) { - (hir::def::DefKind::AssocTy, ty::TermKind::Ty(_)) - | (hir::def::DefKind::AssocConst, ty::TermKind::Const(_)) => (), + (DefKind::AssocTy, ty::TermKind::Ty(_)) + | (DefKind::AssocConst, ty::TermKind::Const(_)) => (), (_, _) => { let got = if let Some(_) = term.ty() { "type" } else { "constant" }; let expected = tcx.def_descr(assoc_item_def_id); @@ -516,7 +516,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { format!("{expected} defined here"), ); - if let hir::def::DefKind::AssocConst = def_kind + if let DefKind::AssocConst = def_kind && let Some(t) = term.ty() && (t.is_enum() || t.references_error()) && tcx.features().associated_const_equality { err.span_suggestion( @@ -528,8 +528,8 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { } let reported = err.emit(); term = match def_kind { - hir::def::DefKind::AssocTy => Ty::new_error(tcx, reported).into(), - hir::def::DefKind::AssocConst => ty::Const::new_error( + DefKind::AssocTy => Ty::new_error(tcx, reported).into(), + DefKind::AssocConst => ty::Const::new_error( tcx, reported, tcx.type_of(assoc_item_def_id) @@ -548,6 +548,15 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { ); } ConvertedBindingKind::Constraint(ast_bounds) => { + match def_kind { + DefKind::AssocTy => {} + _ => { + return Err(tcx.sess.emit_err(errors::AssocBoundOnConst { + span: assoc_ident.span, + descr: tcx.def_descr(assoc_item_def_id), + })); + } + } // "Desugar" a constraint like `T: Iterator` to // // `::Item: Debug` diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 0babdf7e5b3e7..9471ad9ca9063 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -918,3 +918,12 @@ pub struct UnusedAssociatedTypeBounds { #[suggestion(code = "")] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(hir_analysis_assoc_bound_on_const)] +#[note] +pub struct AssocBoundOnConst { + #[primary_span] + pub span: Span, + pub descr: &'static str, +} diff --git a/tests/ui/associated-type-bounds/consts.rs b/tests/ui/associated-type-bounds/consts.rs new file mode 100644 index 0000000000000..9b95b1b52c05a --- /dev/null +++ b/tests/ui/associated-type-bounds/consts.rs @@ -0,0 +1,10 @@ +#![feature(associated_type_bounds)] + +pub fn accept(_: impl Trait) {} +//~^ ERROR expected associated type, found associated constant + +pub trait Trait { + const K: i32; +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/consts.stderr b/tests/ui/associated-type-bounds/consts.stderr new file mode 100644 index 0000000000000..ddfb6612b081f --- /dev/null +++ b/tests/ui/associated-type-bounds/consts.stderr @@ -0,0 +1,10 @@ +error: expected associated type, found associated constant + --> $DIR/consts.rs:3:29 + | +LL | pub fn accept(_: impl Trait) {} + | ^ + | + = note: trait bounds not allowed on associated constant + +error: aborting due to previous error + From b1ddd57b5c0d306c02d06fbf8c3750f1c5a16d3c Mon Sep 17 00:00:00 2001 From: Mu001999 Date: Sun, 13 Aug 2023 20:34:36 +0800 Subject: [PATCH 3/8] Add check before suggest removing parens --- compiler/rustc_hir_typeck/src/callee.rs | 1 + tests/ui/suggestions/issue-114701.rs | 15 ++++++++ tests/ui/suggestions/issue-114701.stderr | 48 ++++++++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 tests/ui/suggestions/issue-114701.rs create mode 100644 tests/ui/suggestions/issue-114701.stderr diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index dd79d1afc62fe..02371f85ac3b6 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -599,6 +599,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { = self.typeck_results.borrow().qpath_res(qpath, callee_expr.hir_id) // Only suggest removing parens if there are no arguments && arg_exprs.is_empty() + && call_expr.span.contains(callee_expr.span) { let descr = match kind { def::CtorOf::Struct => "struct", diff --git a/tests/ui/suggestions/issue-114701.rs b/tests/ui/suggestions/issue-114701.rs new file mode 100644 index 0000000000000..09d573f054bdc --- /dev/null +++ b/tests/ui/suggestions/issue-114701.rs @@ -0,0 +1,15 @@ +enum Enum { , SVariant { v: T }, UVariant } //~ ERROR expected identifier, found `,` + +macro_rules! is_variant { + (TSVariant, ) => (!); + (SVariant, ) => (!); + (UVariant, $expr:expr) => (is_variant!(@check UVariant, {}, $expr)); + (@check $variant:ident, $matcher:tt, $expr:expr) => ( + assert!(if let Enum::$variant::<()> $matcher = $expr () else { false }, //~ ERROR this `if` expression + ); + ); +} + +fn main() { + is_variant!(UVariant, Enum::<()>::UVariant); //~ ERROR expected function +} diff --git a/tests/ui/suggestions/issue-114701.stderr b/tests/ui/suggestions/issue-114701.stderr new file mode 100644 index 0000000000000..bccc98e060883 --- /dev/null +++ b/tests/ui/suggestions/issue-114701.stderr @@ -0,0 +1,48 @@ +error: expected identifier, found `,` + --> $DIR/issue-114701.rs:1:16 + | +LL | enum Enum { , SVariant { v: T }, UVariant } + | ^ + | | + | expected identifier + | help: remove this comma + +error: this `if` expression is missing a block after the condition + --> $DIR/issue-114701.rs:8:17 + | +LL | assert!(if let Enum::$variant::<()> $matcher = $expr () else { false }, + | ^^ +... +LL | is_variant!(UVariant, Enum::<()>::UVariant); + | ------------------------------------------- in this macro invocation + | +help: add a block here + --> $DIR/issue-114701.rs:8:64 + | +LL | assert!(if let Enum::$variant::<()> $matcher = $expr () else { false }, + | ^ +... +LL | is_variant!(UVariant, Enum::<()>::UVariant); + | ------------------------------------------- in this macro invocation + = note: this error originates in the macro `is_variant` (in Nightly builds, run with -Z macro-backtrace for more info) +help: remove the `if` if you meant to write a `let...else` statement + | +LL - assert!(if let Enum::$variant::<()> $matcher = $expr () else { false }, +LL + assert!(let Enum::$variant::<()> $matcher = $expr () else { false }, + | + +error[E0618]: expected function, found `Enum<()>` + --> $DIR/issue-114701.rs:14:27 + | +LL | enum Enum { , SVariant { v: T }, UVariant } + | -------- `Enum::UVariant` defined here +... +LL | assert!(if let Enum::$variant::<()> $matcher = $expr () else { false }, + | -------- call expression requires function +... +LL | is_variant!(UVariant, Enum::<()>::UVariant); + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0618`. From 860fc246088c349bd95ce2da3e8637bb0c590105 Mon Sep 17 00:00:00 2001 From: r0cky Date: Tue, 15 Aug 2023 10:58:33 +0000 Subject: [PATCH 4/8] Remove extra errors --- tests/ui/suggestions/issue-114701.rs | 4 +-- tests/ui/suggestions/issue-114701.stderr | 41 +++--------------------- 2 files changed, 6 insertions(+), 39 deletions(-) diff --git a/tests/ui/suggestions/issue-114701.rs b/tests/ui/suggestions/issue-114701.rs index 09d573f054bdc..81d7803ec8ce0 100644 --- a/tests/ui/suggestions/issue-114701.rs +++ b/tests/ui/suggestions/issue-114701.rs @@ -1,11 +1,11 @@ -enum Enum { , SVariant { v: T }, UVariant } //~ ERROR expected identifier, found `,` +enum Enum { SVariant { v: T }, UVariant } macro_rules! is_variant { (TSVariant, ) => (!); (SVariant, ) => (!); (UVariant, $expr:expr) => (is_variant!(@check UVariant, {}, $expr)); (@check $variant:ident, $matcher:tt, $expr:expr) => ( - assert!(if let Enum::$variant::<()> $matcher = $expr () else { false }, //~ ERROR this `if` expression + assert!(if let Enum::$variant::<()> $matcher = $expr () { true } else { false }, ); ); } diff --git a/tests/ui/suggestions/issue-114701.stderr b/tests/ui/suggestions/issue-114701.stderr index bccc98e060883..67462a09c78da 100644 --- a/tests/ui/suggestions/issue-114701.stderr +++ b/tests/ui/suggestions/issue-114701.stderr @@ -1,48 +1,15 @@ -error: expected identifier, found `,` - --> $DIR/issue-114701.rs:1:16 - | -LL | enum Enum { , SVariant { v: T }, UVariant } - | ^ - | | - | expected identifier - | help: remove this comma - -error: this `if` expression is missing a block after the condition - --> $DIR/issue-114701.rs:8:17 - | -LL | assert!(if let Enum::$variant::<()> $matcher = $expr () else { false }, - | ^^ -... -LL | is_variant!(UVariant, Enum::<()>::UVariant); - | ------------------------------------------- in this macro invocation - | -help: add a block here - --> $DIR/issue-114701.rs:8:64 - | -LL | assert!(if let Enum::$variant::<()> $matcher = $expr () else { false }, - | ^ -... -LL | is_variant!(UVariant, Enum::<()>::UVariant); - | ------------------------------------------- in this macro invocation - = note: this error originates in the macro `is_variant` (in Nightly builds, run with -Z macro-backtrace for more info) -help: remove the `if` if you meant to write a `let...else` statement - | -LL - assert!(if let Enum::$variant::<()> $matcher = $expr () else { false }, -LL + assert!(let Enum::$variant::<()> $matcher = $expr () else { false }, - | - error[E0618]: expected function, found `Enum<()>` --> $DIR/issue-114701.rs:14:27 | -LL | enum Enum { , SVariant { v: T }, UVariant } - | -------- `Enum::UVariant` defined here +LL | enum Enum { SVariant { v: T }, UVariant } + | -------- `Enum::UVariant` defined here ... -LL | assert!(if let Enum::$variant::<()> $matcher = $expr () else { false }, +LL | assert!(if let Enum::$variant::<()> $matcher = $expr () { true } else { false }, | -------- call expression requires function ... LL | is_variant!(UVariant, Enum::<()>::UVariant); | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0618`. From 826471e93bda7a2cbf2213d1cf8f76a2cd77ec2c Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 15 Aug 2023 13:37:47 -0300 Subject: [PATCH 5/8] Add trait related queries to SMIR's rustc_internal --- compiler/rustc_smir/src/stable_mir/mod.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs index a74975cefc2cd..19061742b64be 100644 --- a/compiler/rustc_smir/src/stable_mir/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/mod.rs @@ -85,6 +85,22 @@ pub fn all_local_items() -> CrateItems { with(|cx| cx.all_local_items()) } +pub fn all_trait_decls() -> TraitDecls { + with(|cx| cx.all_trait_decls()) +} + +pub fn trait_decl(trait_def: &TraitDef) -> TraitDecl { + with(|cx| cx.trait_decl(trait_def)) +} + +pub fn all_trait_impls() -> ImplTraitDecls { + with(|cx| cx.all_trait_impls()) +} + +pub fn trait_impl(trait_impl: &ImplDef) -> ImplTrait { + with(|cx| cx.trait_impl(trait_impl)) +} + pub trait Context { fn entry_fn(&mut self) -> Option; /// Retrieve all items of the local crate that have a MIR associated with them. From e1e6c002d826117806f55247c239fe7f40324c1c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 15 Aug 2023 19:30:09 +0200 Subject: [PATCH 6/8] fix typo: affect -> effect --- library/alloc/src/lib.rs | 2 +- library/core/src/lib.rs | 2 +- library/std/src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index cb8691aac138f..41aac02eaa97a 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -58,7 +58,7 @@ // To run alloc tests without x.py without ending up with two copies of alloc, Miri needs to be // able to "empty" this crate. See . -// rustc itself never sets the feature, so this line has no affect there. +// rustc itself never sets the feature, so this line has no effect there. #![cfg(any(not(feature = "miri-test-libstd"), test, doctest))] // #![allow(unused_attributes)] diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index ded799160bf89..48c3c1f212344 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -51,7 +51,7 @@ #![cfg(not(test))] // To run core tests without x.py without ending up with two copies of core, Miri needs to be // able to "empty" this crate. See . -// rustc itself never sets the feature, so this line has no affect there. +// rustc itself never sets the feature, so this line has no effect there. #![cfg(any(not(feature = "miri-test-libstd"), test, doctest))] #![stable(feature = "core", since = "1.6.0")] #![doc( diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index c07aa5cd91fee..ac4ce222fbaac 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -190,7 +190,7 @@ // To run std tests without x.py without ending up with two copies of std, Miri needs to be // able to "empty" this crate. See . -// rustc itself never sets the feature, so this line has no affect there. +// rustc itself never sets the feature, so this line has no effect there. #![cfg(any(not(feature = "miri-test-libstd"), test, doctest))] // miri-test-libstd also prefers to make std use the sysroot versions of the dependencies. #![cfg_attr(feature = "miri-test-libstd", feature(rustc_private))] From 785ebd9b21b15ab1b90b7e8765b9a5072a08a7e4 Mon Sep 17 00:00:00 2001 From: Taras Tsugrii Date: Tue, 15 Aug 2023 14:26:14 -0500 Subject: [PATCH 7/8] [nit] Fix a comment typo. --- library/alloc/src/str.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index 921ce850d1eb1..38f9f39fbf89a 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -612,7 +612,7 @@ pub unsafe fn from_boxed_utf8_unchecked(v: Box<[u8]>) -> Box { } /// Converts the bytes while the bytes are still ascii. -/// For better average performance, this is happens in chunks of `2*size_of::()`. +/// For better average performance, this happens in chunks of `2*size_of::()`. /// Returns a vec with the converted bytes. #[inline] #[cfg(not(test))] From e6ab5f72a2fa62158e29df30b0e9c6b3ec0c2b9b Mon Sep 17 00:00:00 2001 From: Tim Kurdov Date: Tue, 15 Aug 2023 22:37:48 +0100 Subject: [PATCH 8/8] Update the link in the docs of `std::intrinsics` The previous link in that place, https://github.com/rust-lang/miri/blob/master/src/shims/intrinsics.rs, no longer points to an existing file. --- library/core/src/intrinsics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 9ef2c7cde02eb..676d4f2f38ca3 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -9,7 +9,7 @@ //! This includes changes in the stability of the constness. //! //! In order to make an intrinsic usable at compile-time, one needs to copy the implementation -//! from to +//! from to //! and add a //! `#[rustc_const_unstable(feature = "const_such_and_such", issue = "01234")]` to the intrinsic declaration. //!