about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl3
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/bounds.rs29
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs9
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs1
-rw-r--r--compiler/rustc_smir/src/stable_mir/mod.rs16
-rw-r--r--library/alloc/src/lib.rs2
-rw-r--r--library/alloc/src/str.rs2
-rw-r--r--library/core/src/cmp.rs16
-rw-r--r--library/core/src/intrinsics.rs2
-rw-r--r--library/core/src/lib.rs2
-rw-r--r--library/std/src/lib.rs2
-rw-r--r--tests/ui/associated-type-bounds/consts.rs10
-rw-r--r--tests/ui/associated-type-bounds/consts.stderr10
-rw-r--r--tests/ui/suggestions/issue-114701.rs15
-rw-r--r--tests/ui/suggestions/issue-114701.stderr15
15 files changed, 119 insertions, 15 deletions
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 166760166c1..597cae6ff33 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 30145b1a185..ba152cd48de 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:
                 //
                 // `<T as Iterator>::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<Item: Debug>` to
                 //
                 // `<T as Iterator>::Item: Debug`
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 0babdf7e5b3..9471ad9ca90 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/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index dd79d1afc62..02371f85ac3 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/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs
index a74975cefc2..19061742b64 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<CrateItem>;
     /// Retrieve all items of the local crate that have a MIR associated with them.
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index cb8691aac13..41aac02eaa9 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 <https://github.com/rust-lang/miri-test-libstd/issues/4>.
-// 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/alloc/src/str.rs b/library/alloc/src/str.rs
index 921ce850d1e..38f9f39fbf8 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<str> {
 }
 
 /// Converts the bytes while the bytes are still ascii.
-/// For better average performance, this is happens in chunks of `2*size_of::<usize>()`.
+/// For better average performance, this happens in chunks of `2*size_of::<usize>()`.
 /// Returns a vec with the converted bytes.
 #[inline]
 #[cfg(not(test))]
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index faf48ae570f..3c127efb390 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 }
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 9ef2c7cde02..676d4f2f38c 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 <https://github.com/rust-lang/miri/blob/master/src/shims/intrinsics.rs> to
+//! from <https://github.com/rust-lang/miri/blob/master/src/shims/intrinsics> to
 //! <https://github.com/rust-lang/rust/blob/master/compiler/rustc_const_eval/src/interpret/intrinsics.rs> and add a
 //! `#[rustc_const_unstable(feature = "const_such_and_such", issue = "01234")]` to the intrinsic declaration.
 //!
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index ded799160bf..48c3c1f2123 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 <https://github.com/rust-lang/miri-test-libstd/issues/4>.
-// 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 c07aa5cd91f..ac4ce222fba 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 <https://github.com/rust-lang/miri-test-libstd/issues/4>.
-// 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))]
diff --git a/tests/ui/associated-type-bounds/consts.rs b/tests/ui/associated-type-bounds/consts.rs
new file mode 100644
index 00000000000..9b95b1b52c0
--- /dev/null
+++ b/tests/ui/associated-type-bounds/consts.rs
@@ -0,0 +1,10 @@
+#![feature(associated_type_bounds)]
+
+pub fn accept(_: impl Trait<K: Copy>) {}
+//~^ 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 00000000000..ddfb6612b08
--- /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<K: Copy>) {}
+   |                             ^
+   |
+   = note: trait bounds not allowed on associated constant
+
+error: aborting due to previous error
+
diff --git a/tests/ui/suggestions/issue-114701.rs b/tests/ui/suggestions/issue-114701.rs
new file mode 100644
index 00000000000..81d7803ec8c
--- /dev/null
+++ b/tests/ui/suggestions/issue-114701.rs
@@ -0,0 +1,15 @@
+enum Enum<T> { 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 () { true } else { false },
+                );
+    );
+}
+
+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 00000000000..67462a09c78
--- /dev/null
+++ b/tests/ui/suggestions/issue-114701.stderr
@@ -0,0 +1,15 @@
+error[E0618]: expected function, found `Enum<()>`
+  --> $DIR/issue-114701.rs:14:27
+   |
+LL | enum Enum<T> { SVariant { v: T }, UVariant }
+   |                                   -------- `Enum::UVariant` defined here
+...
+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 previous error
+
+For more information about this error, try `rustc --explain E0618`.