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
This commit is contained in:
bors 2023-06-18 22:30:48 +00:00
commit f217411bac
12 changed files with 167 additions and 131 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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,

View File

@ -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 }
}

View File

@ -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));
}
}
}

View File

@ -60,8 +60,11 @@ prepare:
## MSVC native builders
# this intentionally doesn't use `$(BOOTSTRAP)` so we can test the shebang on Windows
ci-msvc:
$(Q)$(CFG_SRC_DIR)/x.py test --stage 2
ci-msvc-py:
$(Q)$(CFG_SRC_DIR)/x.py test --stage 2 tidy
ci-msvc-ps1:
$(Q)$(CFG_SRC_DIR)/x.ps1 test --stage 2 --exclude tidy
ci-msvc: ci-msvc-py ci-msvc-ps1
## MingW native builders

View File

@ -44,7 +44,8 @@ const MIR_OPT_BLESS_TARGET_MAPPING: &[(&str, &str)] = &[
("i686-pc-windows-msvc", "x86_64-pc-windows-msvc"),
("i686-pc-windows-gnu", "x86_64-pc-windows-gnu"),
("i686-apple-darwin", "x86_64-apple-darwin"),
("i686-apple-darwin", "aarch64-apple-darwin"),
// ARM Macs don't have a corresponding 32-bit target that they can (easily)
// build for, so there is no entry for "aarch64-apple-darwin" here.
];
fn try_run(builder: &Builder<'_>, cmd: &mut Command) -> bool {

View File

@ -159,8 +159,6 @@ pub fn symlink_dir(config: &Config, original: &Path, link: &Path) -> io::Result<
pub enum CiEnv {
/// Not a CI environment.
None,
/// The Azure Pipelines environment, for Linux (including Docker), Windows, and macOS builds.
AzurePipelines,
/// The GitHub Actions environment, for Linux (including Docker), Windows and macOS builds.
GitHubActions,
}

View File

@ -254,8 +254,6 @@ docker \
--env DEPLOY \
--env DEPLOY_ALT \
--env CI \
--env TF_BUILD \
--env BUILD_SOURCEBRANCHNAME \
--env GITHUB_ACTIONS \
--env GITHUB_REF \
--env TOOLSTATE_REPO_ACCESS_TOKEN \

View File

@ -4,8 +4,6 @@ use std::process::Command;
pub enum CiEnv {
/// Not a CI environment.
None,
/// The Azure Pipelines environment, for Linux (including Docker), Windows, and macOS builds.
AzurePipelines,
/// The GitHub Actions environment, for Linux (including Docker), Windows and macOS builds.
GitHubActions,
}
@ -13,9 +11,7 @@ pub enum CiEnv {
impl CiEnv {
/// Obtains the current CI environment.
pub fn current() -> CiEnv {
if std::env::var("TF_BUILD").map_or(false, |e| e == "True") {
CiEnv::AzurePipelines
} else if std::env::var("GITHUB_ACTIONS").map_or(false, |e| e == "true") {
if std::env::var("GITHUB_ACTIONS").map_or(false, |e| e == "true") {
CiEnv::GitHubActions
} else {
CiEnv::None

View File

@ -0,0 +1,29 @@
pub trait NSWindow: Sized {
fn frame(self) -> () {
unimplemented!()
}
fn setFrame_display_(self, display: ()) {}
}
impl NSWindow for () {}
pub struct NSRect {}
use std::ops::Deref;
struct MainThreadSafe<T = ()>(T);
impl<T> Deref for MainThreadSafe<T> {
type Target = T;
fn deref(&self) -> &T {
unimplemented!()
}
}
fn main() {
|| {
let ns_window = MainThreadSafe(());
// Don't record adjustments twice for `*ns_window`
(*ns_window).frame();
ns_window.setFrame_display_(0);
//~^ ERROR mismatched types
};
}

View File

@ -0,0 +1,17 @@
error[E0308]: mismatched types
--> $DIR/dont-record-adjustments-when-pointing-at-arg.rs:26:37
|
LL | ns_window.setFrame_display_(0);
| ----------------- ^ expected `()`, found integer
| |
| arguments to this method are incorrect
|
note: method defined here
--> $DIR/dont-record-adjustments-when-pointing-at-arg.rs:5:8
|
LL | fn setFrame_display_(self, display: ()) {}
| ^^^^^^^^^^^^^^^^^ -----------
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.