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:
commit
f217411bac
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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 }
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
}
|
@ -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`.
|
Loading…
x
Reference in New Issue
Block a user