about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_errors/src/diagnostic_impls.rs47
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs28
-rw-r--r--compiler/rustc_middle/src/middle/region.rs8
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs19
-rw-r--r--library/core/src/net/ip_addr.rs1
-rw-r--r--tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.rs9
-rw-r--r--tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.stderr27
-rw-r--r--tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.fixed29
-rw-r--r--tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.rs29
-rw-r--r--tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.stderr60
-rw-r--r--triagebot.toml3
11 files changed, 213 insertions, 47 deletions
diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs
index f6679ae9bb3..d58d05095cd 100644
--- a/compiler/rustc_errors/src/diagnostic_impls.rs
+++ b/compiler/rustc_errors/src/diagnostic_impls.rs
@@ -58,16 +58,29 @@ macro_rules! into_diagnostic_arg_using_display {
     }
 }
 
+macro_rules! into_diagnostic_arg_for_number {
+    ($( $ty:ty ),+ $(,)?) => {
+        $(
+            impl IntoDiagnosticArg for $ty {
+                fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+                    // HACK: `FluentNumber` the underline backing struct represent
+                    // numbers using a f64 which can't represent all the i128 numbers
+                    // So in order to be able to use fluent selectors and still
+                    // have all the numbers representable we only convert numbers
+                    // below a certain threshold.
+                    if let Ok(n) = TryInto::<i128>::try_into(self) && n >= -100 && n <= 100 {
+                        DiagnosticArgValue::Number(n)
+                    } else {
+                        self.to_string().into_diagnostic_arg()
+                    }
+                }
+            }
+        )+
+    }
+}
+
 into_diagnostic_arg_using_display!(
     ast::ParamKindOrd,
-    i8,
-    u8,
-    i16,
-    u16,
-    u32,
-    i64,
-    i128,
-    u128,
     std::io::Error,
     Box<dyn std::error::Error>,
     std::num::NonZeroU32,
@@ -82,17 +95,7 @@ into_diagnostic_arg_using_display!(
     ExitStatus,
 );
 
-impl IntoDiagnosticArg for i32 {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
-        DiagnosticArgValue::Number(self.into())
-    }
-}
-
-impl IntoDiagnosticArg for u64 {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
-        DiagnosticArgValue::Number(self.into())
-    }
-}
+into_diagnostic_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize);
 
 impl IntoDiagnosticArg for bool {
     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
@@ -154,12 +157,6 @@ impl IntoDiagnosticArg for PathBuf {
     }
 }
 
-impl IntoDiagnosticArg for usize {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
-        DiagnosticArgValue::Number(self as i128)
-    }
-}
-
 impl IntoDiagnosticArg for PanicStrategy {
     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
         DiagnosticArgValue::Str(Cow::Owned(self.desc().to_string()))
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 0b8a25eedaf..47f6e3f934e 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -1601,23 +1601,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.ty_to_value_string(rcvr_ty.peel_refs())
         };
         if let SelfSource::MethodCall(_) = source {
-            let first_arg = if let Some(CandidateSource::Impl(impl_did)) = static_candidates.get(0)
-                && let Some(assoc) = self.associated_value(*impl_did, item_name)
-                && assoc.kind == ty::AssocKind::Fn
-            {
+            let first_arg = static_candidates.get(0).and_then(|candidate_source| {
+                let (assoc_did, self_ty) = match candidate_source {
+                    CandidateSource::Impl(impl_did) => {
+                        (*impl_did, self.tcx.type_of(*impl_did).instantiate_identity())
+                    }
+                    CandidateSource::Trait(trait_did) => (*trait_did, rcvr_ty),
+                };
+
+                let assoc = self.associated_value(assoc_did, item_name)?;
+                if assoc.kind != ty::AssocKind::Fn {
+                    return None;
+                }
+
+                // for CandidateSource::Impl, `Self` will be instantiated to a concrete type
+                // but for CandidateSource::Trait, `Self` is still `Self`
                 let sig = self.tcx.fn_sig(assoc.def_id).instantiate_identity();
                 sig.inputs().skip_binder().get(0).and_then(|first| {
-                    let impl_ty = self.tcx.type_of(*impl_did).instantiate_identity();
                     // if the type of first arg is the same as the current impl type, we should take the first arg into assoc function
-                    if first.peel_refs() == impl_ty {
+                    let first_ty = first.peel_refs();
+                    if first_ty == self_ty || first_ty == self.tcx.types.self_param {
                         Some(first.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str()))
                     } else {
                         None
                     }
                 })
-            } else {
-                None
-            };
+            });
+
             let mut applicability = Applicability::MachineApplicable;
             let args = if let SelfSource::MethodCall(receiver) = source
                 && let Some(args) = args
diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs
index 5d6a7f75df8..b9914f6cb7a 100644
--- a/compiler/rustc_middle/src/middle/region.rs
+++ b/compiler/rustc_middle/src/middle/region.rs
@@ -221,9 +221,6 @@ pub struct ScopeTree {
     /// variable is declared.
     var_map: FxIndexMap<hir::ItemLocalId, Scope>,
 
-    /// Maps from a `NodeId` to the associated destruction scope (if any).
-    destruction_scopes: FxIndexMap<hir::ItemLocalId, Scope>,
-
     /// Identifies expressions which, if captured into a temporary, ought to
     /// have a temporary whose lifetime extends to the end of the enclosing *block*,
     /// and not the enclosing *statement*. Expressions that are not present in this
@@ -336,11 +333,6 @@ impl ScopeTree {
             let prev = self.parent_map.insert(child, p);
             assert!(prev.is_none());
         }
-
-        // Record the destruction scopes for later so we can query them.
-        if let ScopeData::Destruction = child.data {
-            self.destruction_scopes.insert(child.item_local_id(), child);
-        }
     }
 
     pub fn record_var_scope(&mut self, var: hir::ItemLocalId, lifetime: Scope) {
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index dd9157564db..7a24b819b5f 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -791,13 +791,28 @@ impl<'a> Parser<'a> {
                 && let [segment] = &attr_kind.item.path.segments[..]
                 && segment.ident.name == sym::cfg
                 && let Some(args_span) = attr_kind.item.args.span()
-                && let Ok(next_attr) = snapshot.parse_attribute(InnerAttrPolicy::Forbidden(None))
+                && let next_attr = match snapshot.parse_attribute(InnerAttrPolicy::Forbidden(None))
+                {
+                    Ok(next_attr) => next_attr,
+                    Err(inner_err) => {
+                        err.cancel();
+                        inner_err.cancel();
+                        return;
+                    }
+                }
                 && let ast::AttrKind::Normal(next_attr_kind) = next_attr.kind
                 && let Some(next_attr_args_span) = next_attr_kind.item.args.span()
                 && let [next_segment] = &next_attr_kind.item.path.segments[..]
                 && segment.ident.name == sym::cfg
-                && let Ok(next_expr) = snapshot.parse_expr()
             {
+                let next_expr = match snapshot.parse_expr() {
+                    Ok(next_expr) => next_expr,
+                    Err(inner_err) => {
+                        err.cancel();
+                        inner_err.cancel();
+                        return;
+                    }
+                };
                 // We have for sure
                 // #[cfg(..)]
                 // expr
diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs
index 408002d18ca..959c3289aff 100644
--- a/library/core/src/net/ip_addr.rs
+++ b/library/core/src/net/ip_addr.rs
@@ -1893,7 +1893,6 @@ impl Ipv6Addr {
     /// # Examples
     ///
     /// ```
-    /// #![feature(ip)]
     /// use std::net::Ipv6Addr;
     ///
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1).is_loopback(), false);
diff --git a/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.rs b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.rs
new file mode 100644
index 00000000000..a7412f51782
--- /dev/null
+++ b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.rs
@@ -0,0 +1,9 @@
+// Issue #118164: recovery path leaving unemitted error behind
+fn bar() -> String {
+    #[cfg(feature = )]
+    [1, 2, 3].iter().map().collect::<String>() //~ ERROR expected `;`, found `#`
+    #[attr] //~ ERROR expected statement after outer attribute
+}
+fn main() {
+    let _ = bar();
+}
diff --git a/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.stderr b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.stderr
new file mode 100644
index 00000000000..dd0081cc2df
--- /dev/null
+++ b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.stderr
@@ -0,0 +1,27 @@
+error: expected `;`, found `#`
+  --> $DIR/properly-recover-from-trailing-outer-attribute-in-body.rs:4:47
+   |
+LL |     #[cfg(feature = )]
+   |     ------------------ only `;` terminated statements or tail expressions are allowed after this attribute
+LL |     [1, 2, 3].iter().map().collect::<String>()
+   |                                               ^ expected `;` here
+LL |     #[attr]
+   |     - unexpected token
+   |
+help: add `;` here
+   |
+LL |     [1, 2, 3].iter().map().collect::<String>();
+   |                                               +
+help: alternatively, consider surrounding the expression with a block
+   |
+LL |     { [1, 2, 3].iter().map().collect::<String>() }
+   |     +                                            +
+
+error: expected statement after outer attribute
+  --> $DIR/properly-recover-from-trailing-outer-attribute-in-body.rs:5:5
+   |
+LL |     #[attr]
+   |     ^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.fixed b/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.fixed
new file mode 100644
index 00000000000..86ac07a93a3
--- /dev/null
+++ b/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.fixed
@@ -0,0 +1,29 @@
+// run-rustfix
+
+struct A {
+
+}
+
+trait M {
+    fn foo(_a: Self);
+    fn bar(_a: Self);
+    fn baz(_a: i32);
+}
+
+impl M for A {
+    fn foo(_a: Self) {}
+    fn bar(_a: A) {}
+    fn baz(_a: i32) {}
+}
+
+fn main() {
+    let _a = A {};
+    A::foo(_a);
+    //~^ ERROR no method named `foo` found
+    A::baz(0);
+    //~^ ERROR no method named `baz` found
+
+    let _b = A {};
+    A::bar(_b);
+    //~^ ERROR no method named `bar` found
+}
diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.rs b/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.rs
new file mode 100644
index 00000000000..9a57ffb7740
--- /dev/null
+++ b/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.rs
@@ -0,0 +1,29 @@
+// run-rustfix
+
+struct A {
+
+}
+
+trait M {
+    fn foo(_a: Self);
+    fn bar(_a: Self);
+    fn baz(_a: i32);
+}
+
+impl M for A {
+    fn foo(_a: Self) {}
+    fn bar(_a: A) {}
+    fn baz(_a: i32) {}
+}
+
+fn main() {
+    let _a = A {};
+    _a.foo();
+    //~^ ERROR no method named `foo` found
+    _a.baz(0);
+    //~^ ERROR no method named `baz` found
+
+    let _b = A {};
+    _b.bar();
+    //~^ ERROR no method named `bar` found
+}
diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.stderr b/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.stderr
new file mode 100644
index 00000000000..0df2b08d3be
--- /dev/null
+++ b/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.stderr
@@ -0,0 +1,60 @@
+error[E0599]: no method named `foo` found for struct `A` in the current scope
+  --> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:21:8
+   |
+LL | struct A {
+   | -------- method `foo` not found for this struct
+...
+LL |     _a.foo();
+   |     ---^^^--
+   |     |  |
+   |     |  this is an associated function, not a method
+   |     help: use associated function syntax instead: `A::foo(_a)`
+   |
+   = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: the candidate is defined in the trait `M`
+  --> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:8:5
+   |
+LL |     fn foo(_a: Self);
+   |     ^^^^^^^^^^^^^^^^^
+
+error[E0599]: no method named `baz` found for struct `A` in the current scope
+  --> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:23:8
+   |
+LL | struct A {
+   | -------- method `baz` not found for this struct
+...
+LL |     _a.baz(0);
+   |     ---^^^---
+   |     |  |
+   |     |  this is an associated function, not a method
+   |     help: use associated function syntax instead: `A::baz(0)`
+   |
+   = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: the candidate is defined in the trait `M`
+  --> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:10:5
+   |
+LL |     fn baz(_a: i32);
+   |     ^^^^^^^^^^^^^^^^
+
+error[E0599]: no method named `bar` found for struct `A` in the current scope
+  --> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:27:8
+   |
+LL | struct A {
+   | -------- method `bar` not found for this struct
+...
+LL |     _b.bar();
+   |     ---^^^--
+   |     |  |
+   |     |  this is an associated function, not a method
+   |     help: use associated function syntax instead: `A::bar(_b)`
+   |
+   = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: the candidate is defined in the trait `M`
+  --> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:9:5
+   |
+LL |     fn bar(_a: Self);
+   |     ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/triagebot.toml b/triagebot.toml
index 07af53106f1..c46f9c90030 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -663,7 +663,6 @@ libs = [
     "@joshtriplett",
     "@Mark-Simulacrum",
     "@m-ou-se",
-    "@thomcc",
 ]
 bootstrap = [
     "@Mark-Simulacrum",
@@ -803,7 +802,7 @@ project-stable-mir = [
 "/library/panic_unwind" =                                ["libs"]
 "/library/proc_macro" =                                  ["@petrochenkov"]
 "/library/std" =                                         ["libs"]
-"/library/std/src/sys/pal/windows" =                     ["@ChrisDenton", "@thomcc"]
+"/library/std/src/sys/pal/windows" =                     ["@ChrisDenton"]
 "/library/stdarch" =                                     ["libs"]
 "/library/test" =                                        ["libs"]
 "/src/bootstrap" =                                       ["bootstrap"]