about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-06-18 22:30:48 +0000
committerbors <bors@rust-lang.org>2023-06-18 22:30:48 +0000
commitf217411bacbe943ead9dfca93a91dff0753c2a96 (patch)
treec3256c4d063cdeef5ab9dbaee43903634a32cf10 /compiler
parent2d0aa57684e10f7b3d3fe740ee18d431181583ad (diff)
parent3b059e0fdbf0257ac4921552781d070e8288233a (diff)
downloadrust-f217411bacbe943ead9dfca93a91dff0753c2a96.tar.gz
rust-f217411bacbe943ead9dfca93a91dff0753c2a96.zip
Auto merge of #112774 - compiler-errors:rollup-z8oof6r, r=compiler-errors
Rollup of 6 pull requests

Successful merges:

 - #112537 (Don't record adjustments twice in `note_source_of_type_mismatch_constraint`)
 - #112663 (cleanup azure leftovers)
 - #112668 (Test `x.ps1` in `msvc` CI job)
 - #112710 (Re-use the deref-pattern recursion instead of duplicating the logic)
 - #112753 (Don't try to auto-bless 32-bit `mir-opt` tests on ARM Mac hosts)
 - #112758 (refactor(resolve): delete update_resolution function)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs7
-rw-r--r--compiler/rustc_hir_typeck/src/method/confirm.rs26
-rw-r--r--compiler/rustc_hir_typeck/src/method/mod.rs21
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs85
-rw-r--r--compiler/rustc_resolve/src/imports.rs93
5 files changed, 113 insertions, 119 deletions
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index b62f689ec6b..9ce03060e0f 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -370,13 +370,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // Fudge the receiver, so we can do new inference on it.
                     let possible_rcvr_ty = possible_rcvr_ty.fold_with(&mut fudger);
                     let method = self
-                        .lookup_method(
+                        .lookup_method_for_diagnostic(
                             possible_rcvr_ty,
                             segment,
                             DUMMY_SP,
                             call_expr,
                             binding,
-                            args,
                         )
                         .ok()?;
                     // Unify the method signature with our incompatible arg, to
@@ -435,14 +434,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let Some(rcvr_ty) = self.node_ty_opt(rcvr.hir_id) else { continue; };
                 let rcvr_ty = rcvr_ty.fold_with(&mut fudger);
                 let Ok(method) =
-                    self.lookup_method(rcvr_ty, segment, DUMMY_SP, parent_expr, rcvr, args)
+                    self.lookup_method_for_diagnostic(rcvr_ty, segment, DUMMY_SP, parent_expr, rcvr)
                 else {
                     continue;
                 };
 
                 let ideal_rcvr_ty = rcvr_ty.fold_with(&mut fudger);
                 let ideal_method = self
-                    .lookup_method(ideal_rcvr_ty, segment, DUMMY_SP, parent_expr, rcvr, args)
+                    .lookup_method_for_diagnostic(ideal_rcvr_ty, segment, DUMMY_SP, parent_expr, rcvr)
                     .ok()
                     .and_then(|method| {
                         let _ = self.at(&ObligationCause::dummy(), self.param_env)
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs
index 98529b66602..6cd7bd5d196 100644
--- a/compiler/rustc_hir_typeck/src/method/confirm.rs
+++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -26,6 +26,7 @@ struct ConfirmContext<'a, 'tcx> {
     span: Span,
     self_expr: &'tcx hir::Expr<'tcx>,
     call_expr: &'tcx hir::Expr<'tcx>,
+    skip_record_for_diagnostics: bool,
 }
 
 impl<'a, 'tcx> Deref for ConfirmContext<'a, 'tcx> {
@@ -59,6 +60,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let mut confirm_cx = ConfirmContext::new(self, span, self_expr, call_expr);
         confirm_cx.confirm(unadjusted_self_ty, pick, segment)
     }
+
+    pub fn confirm_method_for_diagnostic(
+        &self,
+        span: Span,
+        self_expr: &'tcx hir::Expr<'tcx>,
+        call_expr: &'tcx hir::Expr<'tcx>,
+        unadjusted_self_ty: Ty<'tcx>,
+        pick: &probe::Pick<'tcx>,
+        segment: &hir::PathSegment<'_>,
+    ) -> ConfirmResult<'tcx> {
+        let mut confirm_cx = ConfirmContext::new(self, span, self_expr, call_expr);
+        confirm_cx.skip_record_for_diagnostics = true;
+        confirm_cx.confirm(unadjusted_self_ty, pick, segment)
+    }
 }
 
 impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
@@ -68,7 +83,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
         self_expr: &'tcx hir::Expr<'tcx>,
         call_expr: &'tcx hir::Expr<'tcx>,
     ) -> ConfirmContext<'a, 'tcx> {
-        ConfirmContext { fcx, span, self_expr, call_expr }
+        ConfirmContext { fcx, span, self_expr, call_expr, skip_record_for_diagnostics: false }
     }
 
     fn confirm(
@@ -219,7 +234,9 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
         self.register_predicates(autoderef.into_obligations());
 
         // Write out the final adjustments.
-        self.apply_adjustments(self.self_expr, adjustments);
+        if !self.skip_record_for_diagnostics {
+            self.apply_adjustments(self.self_expr, adjustments);
+        }
 
         target
     }
@@ -453,7 +470,10 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
             });
 
             debug!("instantiate_method_substs: user_type_annotation={:?}", user_type_annotation);
-            self.fcx.write_user_type_annotation(self.call_expr.hir_id, user_type_annotation);
+
+            if !self.skip_record_for_diagnostics {
+                self.fcx.write_user_type_annotation(self.call_expr.hir_id, user_type_annotation);
+            }
         }
 
         self.normalize(self.span, substs)
diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs
index cca97d10517..59736b42cf7 100644
--- a/compiler/rustc_hir_typeck/src/method/mod.rs
+++ b/compiler/rustc_hir_typeck/src/method/mod.rs
@@ -254,6 +254,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         Ok(result.callee)
     }
 
+    pub fn lookup_method_for_diagnostic(
+        &self,
+        self_ty: Ty<'tcx>,
+        segment: &hir::PathSegment<'_>,
+        span: Span,
+        call_expr: &'tcx hir::Expr<'tcx>,
+        self_expr: &'tcx hir::Expr<'tcx>,
+    ) -> Result<MethodCallee<'tcx>, MethodError<'tcx>> {
+        let pick = self.lookup_probe_for_diagnostic(
+            segment.ident,
+            self_ty,
+            call_expr,
+            ProbeScope::TraitsInScope,
+            None,
+        )?;
+
+        Ok(self
+            .confirm_method_for_diagnostic(span, self_expr, call_expr, self_ty, &pick, segment)
+            .callee)
+    }
+
     #[instrument(level = "debug", skip(self, call_expr))]
     pub fn lookup_probe(
         &self,
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 7976b148f75..a2e00d3bfc5 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
@@ -359,6 +359,15 @@ impl<'tcx> ConstToPat<'tcx> {
                     def.non_enum_variant().fields.iter().map(|field| field.ty(self.tcx(), substs)),
                 ))?,
             },
+            ty::Slice(elem_ty) => PatKind::Slice {
+                prefix: cv
+                    .unwrap_branch()
+                    .iter()
+                    .map(|val| self.recur(*val, *elem_ty, false))
+                    .collect::<Result<_, _>>()?,
+                slice: None,
+                suffix: Box::new([]),
+            },
             ty::Array(elem_ty, _) => PatKind::Array {
                 prefix: cv
                     .unwrap_branch()
@@ -372,58 +381,6 @@ impl<'tcx> ConstToPat<'tcx> {
                 // `&str` is represented as a valtree, let's keep using this
                 // optimization for now.
                 ty::Str => PatKind::Constant { value: mir::ConstantKind::Ty(tcx.mk_const(cv, ty)) },
-                // `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when
-                // matching against references, you can only use byte string literals.
-                // The typechecker has a special case for byte string literals, by treating them
-                // as slices. This means we turn `&[T; N]` constants into slice patterns, which
-                // has no negative effects on pattern matching, even if we're actually matching on
-                // arrays.
-                ty::Array(elem_ty, _) if !self.treat_byte_string_as_slice => {
-                    let old = self.behind_reference.replace(true);
-                    // References have the same valtree representation as their pointee.
-                    let array = cv;
-                    let val = PatKind::Deref {
-                        subpattern: Box::new(Pat {
-                            kind: PatKind::Array {
-                                prefix: array.unwrap_branch()
-                                    .iter()
-                                    .map(|val| self.recur(*val, elem_ty, false))
-                                    .collect::<Result<_, _>>()?,
-                                slice: None,
-                                suffix: Box::new([]),
-                            },
-                            span,
-                            ty: tcx.mk_slice(elem_ty),
-                        }),
-                    };
-                    self.behind_reference.set(old);
-                    val
-                }
-                ty::Array(elem_ty, _) |
-                // Cannot merge this with the catch all branch below, because the `const_deref`
-                // changes the type from slice to array, we need to keep the original type in the
-                // pattern.
-                ty::Slice(elem_ty) => {
-                    let old = self.behind_reference.replace(true);
-                    // References have the same valtree representation as their pointee.
-                    let array = cv;
-                    let val = PatKind::Deref {
-                        subpattern: Box::new(Pat {
-                            kind: PatKind::Slice {
-                                prefix: array.unwrap_branch()
-                                    .iter()
-                                    .map(|val| self.recur(*val, elem_ty, false))
-                                    .collect::<Result<_, _>>()?,
-                                slice: None,
-                                suffix: Box::new([]),
-                            },
-                            span,
-                            ty: tcx.mk_slice(elem_ty),
-                        }),
-                    };
-                    self.behind_reference.set(old);
-                    val
-                }
                 // Backwards compatibility hack: support references to non-structural types,
                 // but hard error if we aren't behind a double reference. We could just use
                 // the fallback code path below, but that would allow *more* of this fishy
@@ -431,11 +388,9 @@ impl<'tcx> ConstToPat<'tcx> {
                 // instead of a hard error.
                 ty::Adt(_, _) if !self.type_marked_structural(*pointee_ty) => {
                     if self.behind_reference.get() {
-                        if !self.saw_const_match_error.get()
-                            && !self.saw_const_match_lint.get()
-                        {
-                           self.saw_const_match_lint.set(true);
-                           tcx.emit_spanned_lint(
+                        if !self.saw_const_match_error.get() && !self.saw_const_match_lint.get() {
+                            self.saw_const_match_lint.set(true);
+                            tcx.emit_spanned_lint(
                                 lint::builtin::INDIRECT_STRUCTURAL_MATCH,
                                 self.id,
                                 span,
@@ -456,7 +411,7 @@ impl<'tcx> ConstToPat<'tcx> {
                 // convert the dereferenced constant to a pattern that is the sub-pattern of the
                 // deref pattern.
                 _ => {
-                    if !pointee_ty.is_sized(tcx, param_env) {
+                    if !pointee_ty.is_sized(tcx, param_env) && !pointee_ty.is_slice() {
                         let err = UnsizedPattern { span, non_sm_ty: *pointee_ty };
                         tcx.sess.emit_err(err);
 
@@ -464,8 +419,20 @@ impl<'tcx> ConstToPat<'tcx> {
                         PatKind::Wild
                     } else {
                         let old = self.behind_reference.replace(true);
+                        // `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when
+                        // matching against references, you can only use byte string literals.
+                        // The typechecker has a special case for byte string literals, by treating them
+                        // as slices. This means we turn `&[T; N]` constants into slice patterns, which
+                        // has no negative effects on pattern matching, even if we're actually matching on
+                        // arrays.
+                        let pointee_ty = match *pointee_ty.kind() {
+                            ty::Array(elem_ty, _) if self.treat_byte_string_as_slice => {
+                                tcx.mk_slice(elem_ty)
+                            }
+                            _ => *pointee_ty,
+                        };
                         // References have the same valtree representation as their pointee.
-                        let subpattern = self.recur(cv, *pointee_ty, false)?;
+                        let subpattern = self.recur(cv, pointee_ty, false)?;
                         self.behind_reference.set(old);
                         PatKind::Deref { subpattern }
                     }
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 47d8e5993fd..23ef9bf53a1 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -304,21 +304,23 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let res = binding.res();
         self.check_reserved_macro_name(key.ident, res);
         self.set_binding_parent_module(binding, module);
-        self.update_resolution(module, key, |this, resolution| {
-            if let Some(old_binding) = resolution.binding {
-                if res == Res::Err && old_binding.res() != Res::Err {
-                    // Do not override real bindings with `Res::Err`s from error recovery.
-                    return Ok(());
-                }
+
+        let mut resolution = self.resolution(module, key).borrow_mut();
+        let old_binding = resolution.binding();
+        let mut t = Ok(());
+        if let Some(old_binding) = resolution.binding {
+            if res == Res::Err && old_binding.res() != Res::Err {
+                // Do not override real bindings with `Res::Err`s from error recovery.
+            } else {
                 match (old_binding.is_glob_import(), binding.is_glob_import()) {
                     (true, true) => {
                         if res != old_binding.res() {
-                            resolution.binding = Some(this.ambiguity(
+                            resolution.binding = Some(self.ambiguity(
                                 AmbiguityKind::GlobVsGlob,
                                 old_binding,
                                 binding,
                             ));
-                        } else if !old_binding.vis.is_at_least(binding.vis, this.tcx) {
+                        } else if !old_binding.vis.is_at_least(binding.vis, self.tcx) {
                             // We are glob-importing the same item but with greater visibility.
                             resolution.binding = Some(binding);
                         }
@@ -330,7 +332,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             && key.ns == MacroNS
                             && nonglob_binding.expansion != LocalExpnId::ROOT
                         {
-                            resolution.binding = Some(this.ambiguity(
+                            resolution.binding = Some(self.ambiguity(
                                 AmbiguityKind::GlobVsExpanded,
                                 nonglob_binding,
                                 glob_binding,
@@ -342,12 +344,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         if let Some(old_binding) = resolution.shadowed_glob {
                             assert!(old_binding.is_glob_import());
                             if glob_binding.res() != old_binding.res() {
-                                resolution.shadowed_glob = Some(this.ambiguity(
+                                resolution.shadowed_glob = Some(self.ambiguity(
                                     AmbiguityKind::GlobVsGlob,
                                     old_binding,
                                     glob_binding,
                                 ));
-                            } else if !old_binding.vis.is_at_least(binding.vis, this.tcx) {
+                            } else if !old_binding.vis.is_at_least(binding.vis, self.tcx) {
                                 resolution.shadowed_glob = Some(glob_binding);
                             }
                         } else {
@@ -355,53 +357,27 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         }
                     }
                     (false, false) => {
-                        return Err(old_binding);
+                        t = Err(old_binding);
                     }
                 }
-            } else {
-                resolution.binding = Some(binding);
             }
+        } else {
+            resolution.binding = Some(binding);
+        };
 
-            Ok(())
-        })
-    }
-
-    fn ambiguity(
-        &self,
-        kind: AmbiguityKind,
-        primary_binding: &'a NameBinding<'a>,
-        secondary_binding: &'a NameBinding<'a>,
-    ) -> &'a NameBinding<'a> {
-        self.arenas.alloc_name_binding(NameBinding {
-            ambiguity: Some((secondary_binding, kind)),
-            ..primary_binding.clone()
-        })
-    }
-
-    // Use `f` to mutate the resolution of the name in the module.
-    // If the resolution becomes a success, define it in the module's glob importers.
-    fn update_resolution<T, F>(&mut self, module: Module<'a>, key: BindingKey, f: F) -> T
-    where
-        F: FnOnce(&mut Resolver<'a, 'tcx>, &mut NameResolution<'a>) -> T,
-    {
         // Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
         // during which the resolution might end up getting re-defined via a glob cycle.
-        let (binding, t) = {
-            let resolution = &mut *self.resolution(module, key).borrow_mut();
-            let old_binding = resolution.binding();
-
-            let t = f(self, resolution);
-
-            match resolution.binding() {
-                _ if old_binding.is_some() => return t,
-                None => return t,
-                Some(binding) => match old_binding {
-                    Some(old_binding) if ptr::eq(old_binding, binding) => return t,
-                    _ => (binding, t),
-                },
-            }
+        let (binding, t) = match resolution.binding() {
+            _ if old_binding.is_some() => return t,
+            None => return t,
+            Some(binding) => match old_binding {
+                Some(old_binding) if ptr::eq(old_binding, binding) => return t,
+                _ => (binding, t),
+            },
         };
 
+        drop(resolution);
+
         // Define `binding` in `module`s glob importers.
         for import in module.glob_importers.borrow_mut().iter() {
             let mut ident = key.ident;
@@ -420,6 +396,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         t
     }
 
+    fn ambiguity(
+        &self,
+        kind: AmbiguityKind,
+        primary_binding: &'a NameBinding<'a>,
+        secondary_binding: &'a NameBinding<'a>,
+    ) -> &'a NameBinding<'a> {
+        self.arenas.alloc_name_binding(NameBinding {
+            ambiguity: Some((secondary_binding, kind)),
+            ..primary_binding.clone()
+        })
+    }
+
     // Define a dummy resolution containing a `Res::Err` as a placeholder for a failed
     // or indeterminate resolution, also mark such failed imports as used to avoid duplicate diagnostics.
     fn import_dummy_binding(&mut self, import: &'a Import<'a>, is_indeterminate: bool) {
@@ -769,9 +757,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 .emit();
                         }
                         let key = BindingKey::new(target, ns);
-                        this.update_resolution(parent, key, |_, resolution| {
-                            resolution.single_imports.remove(&Interned::new_unchecked(import));
-                        });
+                        let mut resolution = this.resolution(parent, key).borrow_mut();
+                        resolution.single_imports.remove(&Interned::new_unchecked(import));
                     }
                 }
             }