Skip to content

Commit f217411

Browse files
committed
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
2 parents 2d0aa57 + 3b059e0 commit f217411

File tree

12 files changed

+167
-131
lines changed

12 files changed

+167
-131
lines changed

compiler/rustc_hir_typeck/src/demand.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -370,13 +370,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
370370
// Fudge the receiver, so we can do new inference on it.
371371
let possible_rcvr_ty = possible_rcvr_ty.fold_with(&mut fudger);
372372
let method = self
373-
.lookup_method(
373+
.lookup_method_for_diagnostic(
374374
possible_rcvr_ty,
375375
segment,
376376
DUMMY_SP,
377377
call_expr,
378378
binding,
379-
args,
380379
)
381380
.ok()?;
382381
// Unify the method signature with our incompatible arg, to
@@ -435,14 +434,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
435434
let Some(rcvr_ty) = self.node_ty_opt(rcvr.hir_id) else { continue; };
436435
let rcvr_ty = rcvr_ty.fold_with(&mut fudger);
437436
let Ok(method) =
438-
self.lookup_method(rcvr_ty, segment, DUMMY_SP, parent_expr, rcvr, args)
437+
self.lookup_method_for_diagnostic(rcvr_ty, segment, DUMMY_SP, parent_expr, rcvr)
439438
else {
440439
continue;
441440
};
442441

443442
let ideal_rcvr_ty = rcvr_ty.fold_with(&mut fudger);
444443
let ideal_method = self
445-
.lookup_method(ideal_rcvr_ty, segment, DUMMY_SP, parent_expr, rcvr, args)
444+
.lookup_method_for_diagnostic(ideal_rcvr_ty, segment, DUMMY_SP, parent_expr, rcvr)
446445
.ok()
447446
.and_then(|method| {
448447
let _ = self.at(&ObligationCause::dummy(), self.param_env)

compiler/rustc_hir_typeck/src/method/confirm.rs

+23-3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ struct ConfirmContext<'a, 'tcx> {
2626
span: Span,
2727
self_expr: &'tcx hir::Expr<'tcx>,
2828
call_expr: &'tcx hir::Expr<'tcx>,
29+
skip_record_for_diagnostics: bool,
2930
}
3031

3132
impl<'a, 'tcx> Deref for ConfirmContext<'a, 'tcx> {
@@ -59,6 +60,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
5960
let mut confirm_cx = ConfirmContext::new(self, span, self_expr, call_expr);
6061
confirm_cx.confirm(unadjusted_self_ty, pick, segment)
6162
}
63+
64+
pub fn confirm_method_for_diagnostic(
65+
&self,
66+
span: Span,
67+
self_expr: &'tcx hir::Expr<'tcx>,
68+
call_expr: &'tcx hir::Expr<'tcx>,
69+
unadjusted_self_ty: Ty<'tcx>,
70+
pick: &probe::Pick<'tcx>,
71+
segment: &hir::PathSegment<'_>,
72+
) -> ConfirmResult<'tcx> {
73+
let mut confirm_cx = ConfirmContext::new(self, span, self_expr, call_expr);
74+
confirm_cx.skip_record_for_diagnostics = true;
75+
confirm_cx.confirm(unadjusted_self_ty, pick, segment)
76+
}
6277
}
6378

6479
impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
@@ -68,7 +83,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
6883
self_expr: &'tcx hir::Expr<'tcx>,
6984
call_expr: &'tcx hir::Expr<'tcx>,
7085
) -> ConfirmContext<'a, 'tcx> {
71-
ConfirmContext { fcx, span, self_expr, call_expr }
86+
ConfirmContext { fcx, span, self_expr, call_expr, skip_record_for_diagnostics: false }
7287
}
7388

7489
fn confirm(
@@ -219,7 +234,9 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
219234
self.register_predicates(autoderef.into_obligations());
220235

221236
// Write out the final adjustments.
222-
self.apply_adjustments(self.self_expr, adjustments);
237+
if !self.skip_record_for_diagnostics {
238+
self.apply_adjustments(self.self_expr, adjustments);
239+
}
223240

224241
target
225242
}
@@ -453,7 +470,10 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
453470
});
454471

455472
debug!("instantiate_method_substs: user_type_annotation={:?}", user_type_annotation);
456-
self.fcx.write_user_type_annotation(self.call_expr.hir_id, user_type_annotation);
473+
474+
if !self.skip_record_for_diagnostics {
475+
self.fcx.write_user_type_annotation(self.call_expr.hir_id, user_type_annotation);
476+
}
457477
}
458478

459479
self.normalize(self.span, substs)

compiler/rustc_hir_typeck/src/method/mod.rs

+21
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
254254
Ok(result.callee)
255255
}
256256

257+
pub fn lookup_method_for_diagnostic(
258+
&self,
259+
self_ty: Ty<'tcx>,
260+
segment: &hir::PathSegment<'_>,
261+
span: Span,
262+
call_expr: &'tcx hir::Expr<'tcx>,
263+
self_expr: &'tcx hir::Expr<'tcx>,
264+
) -> Result<MethodCallee<'tcx>, MethodError<'tcx>> {
265+
let pick = self.lookup_probe_for_diagnostic(
266+
segment.ident,
267+
self_ty,
268+
call_expr,
269+
ProbeScope::TraitsInScope,
270+
None,
271+
)?;
272+
273+
Ok(self
274+
.confirm_method_for_diagnostic(span, self_expr, call_expr, self_ty, &pick, segment)
275+
.callee)
276+
}
277+
257278
#[instrument(level = "debug", skip(self, call_expr))]
258279
pub fn lookup_probe(
259280
&self,

compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs

+26-59
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,15 @@ impl<'tcx> ConstToPat<'tcx> {
359359
def.non_enum_variant().fields.iter().map(|field| field.ty(self.tcx(), substs)),
360360
))?,
361361
},
362+
ty::Slice(elem_ty) => PatKind::Slice {
363+
prefix: cv
364+
.unwrap_branch()
365+
.iter()
366+
.map(|val| self.recur(*val, *elem_ty, false))
367+
.collect::<Result<_, _>>()?,
368+
slice: None,
369+
suffix: Box::new([]),
370+
},
362371
ty::Array(elem_ty, _) => PatKind::Array {
363372
prefix: cv
364373
.unwrap_branch()
@@ -372,70 +381,16 @@ impl<'tcx> ConstToPat<'tcx> {
372381
// `&str` is represented as a valtree, let's keep using this
373382
// optimization for now.
374383
ty::Str => PatKind::Constant { value: mir::ConstantKind::Ty(tcx.mk_const(cv, ty)) },
375-
// `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when
376-
// matching against references, you can only use byte string literals.
377-
// The typechecker has a special case for byte string literals, by treating them
378-
// as slices. This means we turn `&[T; N]` constants into slice patterns, which
379-
// has no negative effects on pattern matching, even if we're actually matching on
380-
// arrays.
381-
ty::Array(elem_ty, _) if !self.treat_byte_string_as_slice => {
382-
let old = self.behind_reference.replace(true);
383-
// References have the same valtree representation as their pointee.
384-
let array = cv;
385-
let val = PatKind::Deref {
386-
subpattern: Box::new(Pat {
387-
kind: PatKind::Array {
388-
prefix: array.unwrap_branch()
389-
.iter()
390-
.map(|val| self.recur(*val, elem_ty, false))
391-
.collect::<Result<_, _>>()?,
392-
slice: None,
393-
suffix: Box::new([]),
394-
},
395-
span,
396-
ty: tcx.mk_slice(elem_ty),
397-
}),
398-
};
399-
self.behind_reference.set(old);
400-
val
401-
}
402-
ty::Array(elem_ty, _) |
403-
// Cannot merge this with the catch all branch below, because the `const_deref`
404-
// changes the type from slice to array, we need to keep the original type in the
405-
// pattern.
406-
ty::Slice(elem_ty) => {
407-
let old = self.behind_reference.replace(true);
408-
// References have the same valtree representation as their pointee.
409-
let array = cv;
410-
let val = PatKind::Deref {
411-
subpattern: Box::new(Pat {
412-
kind: PatKind::Slice {
413-
prefix: array.unwrap_branch()
414-
.iter()
415-
.map(|val| self.recur(*val, elem_ty, false))
416-
.collect::<Result<_, _>>()?,
417-
slice: None,
418-
suffix: Box::new([]),
419-
},
420-
span,
421-
ty: tcx.mk_slice(elem_ty),
422-
}),
423-
};
424-
self.behind_reference.set(old);
425-
val
426-
}
427384
// Backwards compatibility hack: support references to non-structural types,
428385
// but hard error if we aren't behind a double reference. We could just use
429386
// the fallback code path below, but that would allow *more* of this fishy
430387
// code to compile, as then it only goes through the future incompat lint
431388
// instead of a hard error.
432389
ty::Adt(_, _) if !self.type_marked_structural(*pointee_ty) => {
433390
if self.behind_reference.get() {
434-
if !self.saw_const_match_error.get()
435-
&& !self.saw_const_match_lint.get()
436-
{
437-
self.saw_const_match_lint.set(true);
438-
tcx.emit_spanned_lint(
391+
if !self.saw_const_match_error.get() && !self.saw_const_match_lint.get() {
392+
self.saw_const_match_lint.set(true);
393+
tcx.emit_spanned_lint(
439394
lint::builtin::INDIRECT_STRUCTURAL_MATCH,
440395
self.id,
441396
span,
@@ -456,16 +411,28 @@ impl<'tcx> ConstToPat<'tcx> {
456411
// convert the dereferenced constant to a pattern that is the sub-pattern of the
457412
// deref pattern.
458413
_ => {
459-
if !pointee_ty.is_sized(tcx, param_env) {
414+
if !pointee_ty.is_sized(tcx, param_env) && !pointee_ty.is_slice() {
460415
let err = UnsizedPattern { span, non_sm_ty: *pointee_ty };
461416
tcx.sess.emit_err(err);
462417

463418
// FIXME: introduce PatKind::Error to silence follow up diagnostics due to unreachable patterns.
464419
PatKind::Wild
465420
} else {
466421
let old = self.behind_reference.replace(true);
422+
// `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when
423+
// matching against references, you can only use byte string literals.
424+
// The typechecker has a special case for byte string literals, by treating them
425+
// as slices. This means we turn `&[T; N]` constants into slice patterns, which
426+
// has no negative effects on pattern matching, even if we're actually matching on
427+
// arrays.
428+
let pointee_ty = match *pointee_ty.kind() {
429+
ty::Array(elem_ty, _) if self.treat_byte_string_as_slice => {
430+
tcx.mk_slice(elem_ty)
431+
}
432+
_ => *pointee_ty,
433+
};
467434
// References have the same valtree representation as their pointee.
468-
let subpattern = self.recur(cv, *pointee_ty, false)?;
435+
let subpattern = self.recur(cv, pointee_ty, false)?;
469436
self.behind_reference.set(old);
470437
PatKind::Deref { subpattern }
471438
}

compiler/rustc_resolve/src/imports.rs

+40-53
Original file line numberDiff line numberDiff line change
@@ -304,21 +304,23 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
304304
let res = binding.res();
305305
self.check_reserved_macro_name(key.ident, res);
306306
self.set_binding_parent_module(binding, module);
307-
self.update_resolution(module, key, |this, resolution| {
308-
if let Some(old_binding) = resolution.binding {
309-
if res == Res::Err && old_binding.res() != Res::Err {
310-
// Do not override real bindings with `Res::Err`s from error recovery.
311-
return Ok(());
312-
}
307+
308+
let mut resolution = self.resolution(module, key).borrow_mut();
309+
let old_binding = resolution.binding();
310+
let mut t = Ok(());
311+
if let Some(old_binding) = resolution.binding {
312+
if res == Res::Err && old_binding.res() != Res::Err {
313+
// Do not override real bindings with `Res::Err`s from error recovery.
314+
} else {
313315
match (old_binding.is_glob_import(), binding.is_glob_import()) {
314316
(true, true) => {
315317
if res != old_binding.res() {
316-
resolution.binding = Some(this.ambiguity(
318+
resolution.binding = Some(self.ambiguity(
317319
AmbiguityKind::GlobVsGlob,
318320
old_binding,
319321
binding,
320322
));
321-
} else if !old_binding.vis.is_at_least(binding.vis, this.tcx) {
323+
} else if !old_binding.vis.is_at_least(binding.vis, self.tcx) {
322324
// We are glob-importing the same item but with greater visibility.
323325
resolution.binding = Some(binding);
324326
}
@@ -330,7 +332,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
330332
&& key.ns == MacroNS
331333
&& nonglob_binding.expansion != LocalExpnId::ROOT
332334
{
333-
resolution.binding = Some(this.ambiguity(
335+
resolution.binding = Some(self.ambiguity(
334336
AmbiguityKind::GlobVsExpanded,
335337
nonglob_binding,
336338
glob_binding,
@@ -342,66 +344,40 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
342344
if let Some(old_binding) = resolution.shadowed_glob {
343345
assert!(old_binding.is_glob_import());
344346
if glob_binding.res() != old_binding.res() {
345-
resolution.shadowed_glob = Some(this.ambiguity(
347+
resolution.shadowed_glob = Some(self.ambiguity(
346348
AmbiguityKind::GlobVsGlob,
347349
old_binding,
348350
glob_binding,
349351
));
350-
} else if !old_binding.vis.is_at_least(binding.vis, this.tcx) {
352+
} else if !old_binding.vis.is_at_least(binding.vis, self.tcx) {
351353
resolution.shadowed_glob = Some(glob_binding);
352354
}
353355
} else {
354356
resolution.shadowed_glob = Some(glob_binding);
355357
}
356358
}
357359
(false, false) => {
358-
return Err(old_binding);
360+
t = Err(old_binding);
359361
}
360362
}
361-
} else {
362-
resolution.binding = Some(binding);
363363
}
364+
} else {
365+
resolution.binding = Some(binding);
366+
};
364367

365-
Ok(())
366-
})
367-
}
368-
369-
fn ambiguity(
370-
&self,
371-
kind: AmbiguityKind,
372-
primary_binding: &'a NameBinding<'a>,
373-
secondary_binding: &'a NameBinding<'a>,
374-
) -> &'a NameBinding<'a> {
375-
self.arenas.alloc_name_binding(NameBinding {
376-
ambiguity: Some((secondary_binding, kind)),
377-
..primary_binding.clone()
378-
})
379-
}
380-
381-
// Use `f` to mutate the resolution of the name in the module.
382-
// If the resolution becomes a success, define it in the module's glob importers.
383-
fn update_resolution<T, F>(&mut self, module: Module<'a>, key: BindingKey, f: F) -> T
384-
where
385-
F: FnOnce(&mut Resolver<'a, 'tcx>, &mut NameResolution<'a>) -> T,
386-
{
387368
// Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
388369
// during which the resolution might end up getting re-defined via a glob cycle.
389-
let (binding, t) = {
390-
let resolution = &mut *self.resolution(module, key).borrow_mut();
391-
let old_binding = resolution.binding();
392-
393-
let t = f(self, resolution);
394-
395-
match resolution.binding() {
396-
_ if old_binding.is_some() => return t,
397-
None => return t,
398-
Some(binding) => match old_binding {
399-
Some(old_binding) if ptr::eq(old_binding, binding) => return t,
400-
_ => (binding, t),
401-
},
402-
}
370+
let (binding, t) = match resolution.binding() {
371+
_ if old_binding.is_some() => return t,
372+
None => return t,
373+
Some(binding) => match old_binding {
374+
Some(old_binding) if ptr::eq(old_binding, binding) => return t,
375+
_ => (binding, t),
376+
},
403377
};
404378

379+
drop(resolution);
380+
405381
// Define `binding` in `module`s glob importers.
406382
for import in module.glob_importers.borrow_mut().iter() {
407383
let mut ident = key.ident;
@@ -420,6 +396,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
420396
t
421397
}
422398

399+
fn ambiguity(
400+
&self,
401+
kind: AmbiguityKind,
402+
primary_binding: &'a NameBinding<'a>,
403+
secondary_binding: &'a NameBinding<'a>,
404+
) -> &'a NameBinding<'a> {
405+
self.arenas.alloc_name_binding(NameBinding {
406+
ambiguity: Some((secondary_binding, kind)),
407+
..primary_binding.clone()
408+
})
409+
}
410+
423411
// Define a dummy resolution containing a `Res::Err` as a placeholder for a failed
424412
// or indeterminate resolution, also mark such failed imports as used to avoid duplicate diagnostics.
425413
fn import_dummy_binding(&mut self, import: &'a Import<'a>, is_indeterminate: bool) {
@@ -769,9 +757,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
769757
.emit();
770758
}
771759
let key = BindingKey::new(target, ns);
772-
this.update_resolution(parent, key, |_, resolution| {
773-
resolution.single_imports.remove(&Interned::new_unchecked(import));
774-
});
760+
let mut resolution = this.resolution(parent, key).borrow_mut();
761+
resolution.single_imports.remove(&Interned::new_unchecked(import));
775762
}
776763
}
777764
}

0 commit comments

Comments
 (0)