diff --git a/CHANGELOG.md b/CHANGELOG.md index 5966ec3965c..79a045644e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Fix regression in 0.14.0 rejecting usage of `#[doc(hidden)]` on structs and functions annotated with PyO3 macros. [#1722](https://github.com/PyO3/pyo3/pull/1722) - Fix regression in 0.14.0 leading to incorrect code coverage being computed for `#[pyfunction]`s. [#1726](https://github.com/PyO3/pyo3/pull/1726) - Fix incorrect FFI definition of `Py_Buffer` on PyPy. [#1737](https://github.com/PyO3/pyo3/pull/1737) +- Fix incorrect calculation of `dictoffset` on 32-bit Windows. [#1475](https://github.com/PyO3/pyo3/pull/1475) ## [0.14.1] - 2021-07-04 diff --git a/Cargo.toml b/Cargo.toml index bc573e6a8d6..0ee2d5a16da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,8 @@ serde = {version = "1.0", optional = true} [dev-dependencies] assert_approx_eq = "1.1.0" -criterion = "0.3" +# O.3.5 uses the matches! macro, which isn't compatible with Rust 1.41 +criterion = "=0.3.4" trybuild = "1.0.23" rustversion = "1.0" proptest = { version = "0.10.1", default-features = false, features = ["std"] } diff --git a/benches/bench_call.rs b/benches/bench_call.rs index 86f502701a3..08b194967e1 100644 --- a/benches/bench_call.rs +++ b/benches/bench_call.rs @@ -18,11 +18,11 @@ fn bench_call_0(b: &mut Bencher) { "# ); - let foo = module.getattr("foo").unwrap(); + let foo_module = module.getattr("foo").unwrap(); b.iter(|| { for _ in 0..1000 { - foo.call0().unwrap(); + foo_module.call0().unwrap(); } }); }) @@ -38,11 +38,11 @@ fn bench_call_method_0(b: &mut Bencher) { "# ); - let foo = module.getattr("Foo").unwrap().call0().unwrap(); + let foo_module = module.getattr("Foo").unwrap().call0().unwrap(); b.iter(|| { for _ in 0..1000 { - foo.call_method0("foo").unwrap(); + foo_module.call_method0("foo").unwrap(); } }); }) diff --git a/build.rs b/build.rs index 3f562c50669..282949cf0c2 100644 --- a/build.rs +++ b/build.rs @@ -108,7 +108,7 @@ fn emit_cargo_configuration(interpreter_config: &InterpreterConfig) -> Result<() match (is_extension_module, target_os.as_str()) { (_, "windows") => { // always link on windows, even with extension module - println!("{}", get_rustc_link_lib(&interpreter_config)?); + println!("{}", get_rustc_link_lib(interpreter_config)?); // Set during cross-compiling. if let Some(libdir) = &interpreter_config.libdir { println!("cargo:rustc-link-search=native={}", libdir); @@ -126,7 +126,7 @@ fn emit_cargo_configuration(interpreter_config: &InterpreterConfig) -> Result<() (false, _) | (_, "android") => { // other systems, only link libs if not extension module // android always link. - println!("{}", get_rustc_link_lib(&interpreter_config)?); + println!("{}", get_rustc_link_lib(interpreter_config)?); if let Some(libdir) = &interpreter_config.libdir { println!("cargo:rustc-link-search=native={}", libdir); } @@ -192,11 +192,18 @@ fn configure_pyo3() -> Result<()> { )?; interpreter_config.emit_pyo3_cfgs(); + let rustc_minor_version = rustc_minor_version().unwrap_or(0); + // Enable use of const generics on Rust 1.51 and greater - if rustc_minor_version().unwrap_or(0) >= 51 { + if rustc_minor_version >= 51 { println!("cargo:rustc-cfg=min_const_generics"); } + // Enable use of std::ptr::addr_of! on Rust 1.51 and greater + if rustc_minor_version >= 51 { + println!("cargo:rustc-cfg=addr_of"); + } + Ok(()) } diff --git a/pyo3-build-config/src/impl_.rs b/pyo3-build-config/src/impl_.rs index 239194411d5..ef0860dbcc1 100644 --- a/pyo3-build-config/src/impl_.rs +++ b/pyo3-build-config/src/impl_.rs @@ -431,7 +431,7 @@ impl BuildFlags { script.push_str(&format!("print(config.get('{}', '0'))\n", k)); } - let stdout = run_python_script(&interpreter, &script)?; + let stdout = run_python_script(interpreter, &script)?; let split_stdout: Vec<&str> = stdout.trim_end().lines().collect(); ensure!( split_stdout.len() == BuildFlags::ALL.len(), @@ -573,7 +573,7 @@ fn ends_with(entry: &DirEntry, pat: &str) -> bool { /// /// [1]: https://github.com/python/cpython/blob/3.5/Lib/sysconfig.py#L389 fn find_sysconfigdata(cross: &CrossCompileConfig) -> Result { - let sysconfig_paths = search_lib_dir(&cross.lib_dir, &cross); + let sysconfig_paths = search_lib_dir(&cross.lib_dir, cross); let sysconfig_name = env_var("_PYTHON_SYSCONFIGDATA_NAME"); let mut sysconfig_paths = sysconfig_paths .iter() diff --git a/pyo3-macros-backend/src/from_pyobject.rs b/pyo3-macros-backend/src/from_pyobject.rs index e28b10d4a74..e50a217f56a 100644 --- a/pyo3-macros-backend/src/from_pyobject.rs +++ b/pyo3-macros-backend/src/from_pyobject.rs @@ -186,7 +186,7 @@ impl<'a> Container<'a> { /// Build derivation body for a struct. fn build(&self) -> TokenStream { match &self.ty { - ContainerType::StructNewtype(ident) => self.build_newtype_struct(Some(&ident)), + ContainerType::StructNewtype(ident) => self.build_newtype_struct(Some(ident)), ContainerType::TupleNewtype => self.build_newtype_struct(None), ContainerType::Tuple(len) => self.build_tuple_struct(*len), ContainerType::Struct(tups) => self.build_struct(tups), diff --git a/pyo3-macros-backend/src/method.rs b/pyo3-macros-backend/src/method.rs index 78da63cb305..09fad20596b 100644 --- a/pyo3-macros-backend/src/method.rs +++ b/pyo3-macros-backend/src/method.rs @@ -266,7 +266,7 @@ impl<'a> FnSpec<'a> { let python_name = python_name.as_ref().unwrap_or(name).unraw(); let doc = utils::get_doc( - &meth_attrs, + meth_attrs, options .text_signature .as_ref() @@ -413,7 +413,7 @@ impl<'a> FnSpec<'a> { Argument::Arg(path, opt) | Argument::Kwarg(path, opt) => { if path.is_ident(name) { if let Some(val) = opt { - let i: syn::Expr = syn::parse_str(&val).unwrap(); + let i: syn::Expr = syn::parse_str(val).unwrap(); return Some(i.into_token_stream()); } } diff --git a/pyo3-macros-backend/src/params.rs b/pyo3-macros-backend/src/params.rs index e283749bbcd..fbc3f00014d 100644 --- a/pyo3-macros-backend/src/params.rs +++ b/pyo3-macros-backend/src/params.rs @@ -29,7 +29,7 @@ pub fn accept_args_kwargs(attrs: &[Argument]) -> (bool, bool) { /// Return true if the argument list is simply (*args, **kwds). pub fn is_forwarded_args(args: &[FnArg<'_>], attrs: &[Argument]) -> bool { - args.len() == 2 && is_args(attrs, &args[0].name) && is_kwargs(attrs, &args[1].name) + args.len() == 2 && is_args(attrs, args[0].name) && is_kwargs(attrs, args[1].name) } fn is_args(attrs: &[Argument], name: &syn::Ident) -> bool { @@ -68,15 +68,7 @@ pub fn impl_arg_params( // is (*args, **kwds). let mut arg_convert = vec![]; for (i, arg) in spec.args.iter().enumerate() { - arg_convert.push(impl_arg_param( - arg, - &spec, - i, - None, - &mut 0, - py, - &args_array, - )?); + arg_convert.push(impl_arg_param(arg, spec, i, None, &mut 0, py, &args_array)?); } return Ok(quote! {{ let _args = Some(_args); @@ -90,12 +82,12 @@ pub fn impl_arg_params( let mut keyword_only_parameters = Vec::new(); for arg in spec.args.iter() { - if arg.py || is_args(&spec.attrs, &arg.name) || is_kwargs(&spec.attrs, &arg.name) { + if arg.py || is_args(&spec.attrs, arg.name) || is_kwargs(&spec.attrs, arg.name) { continue; } let name = arg.name.unraw().to_string(); - let kwonly = spec.is_kw_only(&arg.name); - let required = !(arg.optional.is_some() || spec.default_value(&arg.name).is_some()); + let kwonly = spec.is_kw_only(arg.name); + let required = !(arg.optional.is_some() || spec.default_value(arg.name).is_some()); if kwonly { keyword_only_parameters.push(quote! { @@ -118,8 +110,8 @@ pub fn impl_arg_params( let mut option_pos = 0; for (idx, arg) in spec.args.iter().enumerate() { param_conversion.push(impl_arg_param( - &arg, - &spec, + arg, + spec, idx, self_, &mut option_pos, @@ -212,7 +204,7 @@ fn impl_arg_param( |e| pyo3::derive_utils::argument_extraction_error(#py, stringify!(#name), e) }; - if is_args(&spec.attrs, &name) { + if is_args(&spec.attrs, name) { ensure_spanned!( arg.optional.is_none(), arg.name.span() => "args cannot be optional" @@ -220,7 +212,7 @@ fn impl_arg_param( return Ok(quote_arg_span! { let #arg_name = _args.unwrap().extract().map_err(#transform_error)?; }); - } else if is_kwargs(&spec.attrs, &name) { + } else if is_kwargs(&spec.attrs, name) { ensure_spanned!( arg.optional.is_some(), arg.name.span() => "kwargs must be Option<_>" @@ -259,7 +251,7 @@ fn impl_arg_param( } }; - return if let syn::Type::Reference(tref) = unwrap_ty_group(arg.optional.unwrap_or(&ty)) { + return if let syn::Type::Reference(tref) = unwrap_ty_group(arg.optional.unwrap_or(ty)) { let (tref, mut_) = preprocess_tref(tref, self_); let (target_ty, borrow_tmp) = if arg.optional.is_some() { // Get Option<&T> from Option> diff --git a/pyo3-macros-backend/src/pyclass.rs b/pyo3-macros-backend/src/pyclass.rs index 71ba5899bbd..470e7909760 100644 --- a/pyo3-macros-backend/src/pyclass.rs +++ b/pyo3-macros-backend/src/pyclass.rs @@ -262,7 +262,7 @@ pub fn build_py_class( impl_class( &class.ident, - &args, + args, doc, field_options, methods_type, @@ -452,7 +452,7 @@ fn impl_class( let (impl_inventory, for_each_py_method) = match methods_type { PyClassMethodsType::Specialization => (None, quote! { visitor(collector.py_methods()); }), PyClassMethodsType::Inventory => ( - Some(impl_methods_inventory(&cls)), + Some(impl_methods_inventory(cls)), quote! { for inventory in pyo3::inventory::iter::<::Methods>() { visitor(pyo3::class::impl_::PyMethodsInventory::get(inventory)); diff --git a/pyo3-macros-backend/src/pymethod.rs b/pyo3-macros-backend/src/pymethod.rs index e3cd603f0cc..e31d5fc093e 100644 --- a/pyo3-macros-backend/src/pymethod.rs +++ b/pyo3-macros-backend/src/pymethod.rs @@ -303,7 +303,7 @@ pub fn impl_py_getter_def(cls: &syn::Type, property_type: PropertyType) -> Resul fn split_off_python_arg<'a>(args: &'a [FnArg<'a>]) -> (Option<&FnArg>, &[FnArg]) { if args .get(0) - .map(|py| utils::is_python(&py.ty)) + .map(|py| utils::is_python(py.ty)) .unwrap_or(false) { (Some(&args[0]), &args[1..]) diff --git a/src/buffer.rs b/src/buffer.rs index 69771e4d50a..fbded572133 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -666,7 +666,7 @@ mod tests { let gil = Python::acquire_gil(); let py = gil.python(); let bytes = py.eval("b'abcde'", None, None).unwrap(); - let buffer = PyBuffer::get(&bytes).unwrap(); + let buffer = PyBuffer::get(bytes).unwrap(); assert_eq!(buffer.dimensions(), 1); assert_eq!(buffer.item_count(), 5); assert_eq!(buffer.format().to_str().unwrap(), "B"); diff --git a/src/conversions/osstr.rs b/src/conversions/osstr.rs index 7efe4a51558..72fa1d55bdf 100644 --- a/src/conversions/osstr.rs +++ b/src/conversions/osstr.rs @@ -121,7 +121,7 @@ impl IntoPy for &'_ OsStr { impl ToPyObject for Cow<'_, OsStr> { #[inline] fn to_object(&self, py: Python) -> PyObject { - (&self as &OsStr).to_object(py) + (self as &OsStr).to_object(py) } } @@ -135,7 +135,7 @@ impl IntoPy for Cow<'_, OsStr> { impl ToPyObject for OsString { #[inline] fn to_object(&self, py: Python) -> PyObject { - (&self as &OsStr).to_object(py) + (self as &OsStr).to_object(py) } } diff --git a/src/exceptions.rs b/src/exceptions.rs index a33fe9fed1a..c1cb583246c 100644 --- a/src/exceptions.rs +++ b/src/exceptions.rs @@ -402,7 +402,7 @@ mod tests { let error_type = py.get_type::(); let ctx = [("CustomError", error_type)].into_py_dict(py); let type_description: String = py - .eval("str(CustomError)", None, Some(&ctx)) + .eval("str(CustomError)", None, Some(ctx)) .unwrap() .extract() .unwrap(); @@ -410,7 +410,7 @@ mod tests { py.run( "assert CustomError('oops').args == ('oops',)", None, - Some(&ctx), + Some(ctx), ) .unwrap(); } diff --git a/src/pycell.rs b/src/pycell.rs index 6eea718ab9a..a7f8c267ca0 100644 --- a/src/pycell.rs +++ b/src/pycell.rs @@ -104,8 +104,6 @@ pub struct PyCell { pub(crate) struct PyCellContents { pub(crate) value: ManuallyDrop>, pub(crate) thread_checker: T::ThreadChecker, - // DO NOT CHANGE THE ORDER OF THESE FIELDS WITHOUT CHANGING PyCell::dict_offset() - // AND PyCell::weakref_offset() pub(crate) dict: T::Dict, pub(crate) weakref: T::WeakRef, } @@ -113,25 +111,77 @@ pub(crate) struct PyCellContents { impl PyCell { /// Get the offset of the dictionary from the start of the struct in bytes. #[cfg(not(all(Py_LIMITED_API, not(Py_3_9))))] - pub(crate) fn dict_offset() -> Option { + pub(crate) fn dict_offset() -> Option { + use std::convert::TryInto; if T::Dict::IS_DUMMY { None } else { - Some( - std::mem::size_of::() - - std::mem::size_of::() - - std::mem::size_of::(), - ) + #[cfg(addr_of)] + let offset = { + // With std::ptr::addr_of - can measure offset using uninit memory without UB. + let cell = std::mem::MaybeUninit::::uninit(); + let base_ptr = cell.as_ptr(); + let dict_ptr = unsafe { std::ptr::addr_of!((*base_ptr).contents.dict) }; + unsafe { (dict_ptr as *const u8).offset_from(base_ptr as *const u8) } + }; + #[cfg(not(addr_of))] + let offset = { + // No std::ptr::addr_of - need to take references to PyCell to measure offsets; + // make a zero-initialised "fake" one so that referencing it is not UB. + let mut cell = std::mem::MaybeUninit::::uninit(); + unsafe { + std::ptr::write_bytes(cell.as_mut_ptr(), 0, 1); + } + let cell = unsafe { cell.assume_init() }; + let dict_ptr = &cell.contents.dict; + // offset_from wasn't stabilised until 1.47, so we also have to work around + // that... + let offset = (dict_ptr as *const _ as usize) - (&cell as *const _ as usize); + // This isn't a valid cell, so ensure no Drop code runs etc. + std::mem::forget(cell); + offset + }; + // Py_ssize_t may not be equal to isize on all platforms + #[allow(clippy::useless_conversion)] + Some(offset.try_into().expect("offset should fit in Py_ssize_t")) } } /// Get the offset of the weakref list from the start of the struct in bytes. #[cfg(not(all(Py_LIMITED_API, not(Py_3_9))))] - pub(crate) fn weakref_offset() -> Option { + pub(crate) fn weakref_offset() -> Option { + use std::convert::TryInto; if T::WeakRef::IS_DUMMY { None } else { - Some(std::mem::size_of::() - std::mem::size_of::()) + #[cfg(addr_of)] + let offset = { + // With std::ptr::addr_of - can measure offset using uninit memory without UB. + let cell = std::mem::MaybeUninit::::uninit(); + let base_ptr = cell.as_ptr(); + let weaklist_ptr = unsafe { std::ptr::addr_of!((*base_ptr).contents.weakref) }; + unsafe { (weaklist_ptr as *const u8).offset_from(base_ptr as *const u8) } + }; + #[cfg(not(addr_of))] + let offset = { + // No std::ptr::addr_of - need to take references to PyCell to measure offsets; + // make a zero-initialised "fake" one so that referencing it is not UB. + let mut cell = std::mem::MaybeUninit::::uninit(); + unsafe { + std::ptr::write_bytes(cell.as_mut_ptr(), 0, 1); + } + let cell = unsafe { cell.assume_init() }; + let weaklist_ptr = &cell.contents.weakref; + // offset_from wasn't stabilised until 1.47, so we also have to work around + // that... + let offset = (weaklist_ptr as *const _ as usize) - (&cell as *const _ as usize); + // This isn't a valid cell, so ensure no Drop code runs etc. + std::mem::forget(cell); + offset + }; + // Py_ssize_t may not be equal to isize on all platforms + #[allow(clippy::useless_conversion)] + Some(offset.try_into().expect("offset should fit in Py_ssize_t")) } } } diff --git a/src/pyclass.rs b/src/pyclass.rs index 987b6050333..83a1d963d58 100644 --- a/src/pyclass.rs +++ b/src/pyclass.rs @@ -174,13 +174,13 @@ fn tp_init_additional(type_object: *mut ffi::PyTypeObject) { // __dict__ support if let Some(dict_offset) = PyCell::::dict_offset() { unsafe { - (*type_object).tp_dictoffset = dict_offset as ffi::Py_ssize_t; + (*type_object).tp_dictoffset = dict_offset; } } // weakref support if let Some(weakref_offset) = PyCell::::weakref_offset() { unsafe { - (*type_object).tp_weaklistoffset = weakref_offset as ffi::Py_ssize_t; + (*type_object).tp_weaklistoffset = weakref_offset; } } } @@ -233,11 +233,11 @@ fn py_class_method_defs( #[cfg(Py_3_9)] fn py_class_members() -> Vec { #[inline(always)] - fn offset_def(name: &'static str, offset: usize) -> ffi::structmember::PyMemberDef { + fn offset_def(name: &'static str, offset: ffi::Py_ssize_t) -> ffi::structmember::PyMemberDef { ffi::structmember::PyMemberDef { name: name.as_ptr() as _, type_code: ffi::structmember::T_PYSSIZET, - offset: offset as _, + offset, flags: ffi::structmember::READONLY, doc: std::ptr::null_mut(), } diff --git a/src/types/dict.rs b/src/types/dict.rs index f5a11a9e1ee..82e92540130 100644 --- a/src/types/dict.rs +++ b/src/types/dict.rs @@ -724,7 +724,7 @@ mod tests { assert_eq!(iter.size_hint(), (v.len() - 1, Some(v.len() - 1))); // Exhust iterator. - while let Some(_) = iter.next() {} + for _ in &mut iter {} assert_eq!(iter.size_hint(), (0, Some(0))); } diff --git a/src/types/list.rs b/src/types/list.rs index ace26b0a138..535f676f82f 100644 --- a/src/types/list.rs +++ b/src/types/list.rs @@ -366,7 +366,7 @@ mod tests { assert_eq!(iter.size_hint(), (v.len() - 1, Some(v.len() - 1))); // Exhust iterator. - while let Some(_) = iter.next() {} + for _ in &mut iter {} assert_eq!(iter.size_hint(), (0, Some(0))); } diff --git a/src/types/sequence.rs b/src/types/sequence.rs index a625e376866..c9a931883aa 100644 --- a/src/types/sequence.rs +++ b/src/types/sequence.rs @@ -541,7 +541,7 @@ mod tests { let v: Vec = vec![1, 2, 3]; let ob = v.to_object(py); let seq = ob.cast_as::(py).unwrap(); - let concat_seq = seq.concat(&seq).unwrap(); + let concat_seq = seq.concat(seq).unwrap(); assert_eq!(6, concat_seq.len().unwrap()); let concat_v: Vec = vec![1, 2, 3, 1, 2, 3]; for (el, cc) in concat_seq.iter().unwrap().zip(concat_v) { @@ -556,7 +556,7 @@ mod tests { let v = "string"; let ob = v.to_object(py); let seq = ob.cast_as::(py).unwrap(); - let concat_seq = seq.concat(&seq).unwrap(); + let concat_seq = seq.concat(seq).unwrap(); assert_eq!(12, concat_seq.len().unwrap()); /*let concat_v = "stringstring".to_owned(); for (el, cc) in seq.iter(py).unwrap().zip(concat_v.chars()) { diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index 18bf31c892d..e5d405dfcdf 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -12,17 +12,9 @@ fn test_compile_errors() { t.compile_fail("tests/ui/invalid_argument_attributes.rs"); t.compile_fail("tests/ui/reject_generics.rs"); - tests_rust_1_45(&t); tests_rust_1_48(&t); tests_rust_1_49(&t); - tests_rust_1_52(&t); - - #[rustversion::since(1.45)] - fn tests_rust_1_45(t: &trybuild::TestCases) { - t.compile_fail("tests/ui/static_ref.rs"); - } - #[rustversion::before(1.45)] - fn tests_rust_1_45(_t: &trybuild::TestCases) {} + tests_rust_1_54(&t); #[rustversion::since(1.48)] fn tests_rust_1_48(t: &trybuild::TestCases) { @@ -35,20 +27,21 @@ fn test_compile_errors() { #[rustversion::since(1.49)] fn tests_rust_1_49(t: &trybuild::TestCases) { t.compile_fail("tests/ui/deprecations.rs"); - t.compile_fail("tests/ui/invalid_frompy_derive.rs"); t.compile_fail("tests/ui/invalid_pymethod_receiver.rs"); - t.compile_fail("tests/ui/pyclass_send.rs"); - - #[cfg(Py_LIMITED_API)] - t.compile_fail("tests/ui/abi3_nativetype_inheritance.rs"); } #[rustversion::before(1.49)] fn tests_rust_1_49(_t: &trybuild::TestCases) {} - #[rustversion::since(1.52)] - fn tests_rust_1_52(t: &trybuild::TestCases) { + #[rustversion::since(1.54)] + fn tests_rust_1_54(t: &trybuild::TestCases) { + t.compile_fail("tests/ui/invalid_frompy_derive.rs"); t.compile_fail("tests/ui/invalid_result_conversion.rs"); + t.compile_fail("tests/ui/pyclass_send.rs"); + t.compile_fail("tests/ui/static_ref.rs"); + + #[cfg(Py_LIMITED_API)] + t.compile_fail("tests/ui/abi3_nativetype_inheritance.rs"); } - #[rustversion::before(1.52)] - fn tests_rust_1_52(_t: &trybuild::TestCases) {} + #[rustversion::before(1.54)] + fn tests_rust_1_54(_t: &trybuild::TestCases) {} } diff --git a/tests/test_datetime.rs b/tests/test_datetime.rs index 0fbc4df04db..c6d62cd1aab 100644 --- a/tests/test_datetime.rs +++ b/tests/test_datetime.rs @@ -17,17 +17,17 @@ fn _get_subclasses<'p>( let make_sub_subclass_py = "class SubSubklass(Subklass):\n pass"; - py.run(&make_subclass_py, None, Some(&locals))?; - py.run(&make_sub_subclass_py, None, Some(&locals))?; + py.run(&make_subclass_py, None, Some(locals))?; + py.run(make_sub_subclass_py, None, Some(locals))?; // Construct an instance of the base class - let obj = py.eval(&format!("{}({})", py_type, args), None, Some(&locals))?; + let obj = py.eval(&format!("{}({})", py_type, args), None, Some(locals))?; // Construct an instance of the subclass - let sub_obj = py.eval(&format!("Subklass({})", args), None, Some(&locals))?; + let sub_obj = py.eval(&format!("Subklass({})", args), None, Some(locals))?; // Construct an instance of the sub-subclass - let sub_sub_obj = py.eval(&format!("SubSubklass({})", args), None, Some(&locals))?; + let sub_sub_obj = py.eval(&format!("SubSubklass({})", args), None, Some(locals))?; Ok((obj, sub_obj, sub_sub_obj)) } diff --git a/tests/ui/abi3_nativetype_inheritance.stderr b/tests/ui/abi3_nativetype_inheritance.stderr index c4f21ac4a4e..b0756c69b94 100644 --- a/tests/ui/abi3_nativetype_inheritance.stderr +++ b/tests/ui/abi3_nativetype_inheritance.stderr @@ -5,7 +5,7 @@ error[E0277]: the trait bound `PyDict: PyClass` is not satisfied | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `PyClass` is not implemented for `PyDict` | = note: required because of the requirements on the impl of `PyClassBaseType` for `PyDict` - = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `PyDict: PyClass` is not satisfied --> $DIR/abi3_nativetype_inheritance.rs:5:1 @@ -19,4 +19,4 @@ error[E0277]: the trait bound `PyDict: PyClass` is not satisfied | --------------- required by this bound in `ThreadCheckerInherited` | = note: required because of the requirements on the impl of `PyClassBaseType` for `PyDict` - = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/invalid_frompy_derive.stderr b/tests/ui/invalid_frompy_derive.stderr index 3a0b128fbed..007c9eea823 100644 --- a/tests/ui/invalid_frompy_derive.stderr +++ b/tests/ui/invalid_frompy_derive.stderr @@ -168,7 +168,7 @@ error: cannot derive FromPyObject for empty structs and variants 151 | #[derive(FromPyObject)] | ^^^^^^^^^^^^ | - = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the derive macro `FromPyObject` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected `=` --> $DIR/invalid_frompy_derive.rs:158:11 diff --git a/tests/ui/invalid_result_conversion.stderr b/tests/ui/invalid_result_conversion.stderr index c422e27d9cd..8c8bdc318fa 100644 --- a/tests/ui/invalid_result_conversion.stderr +++ b/tests/ui/invalid_result_conversion.stderr @@ -11,4 +11,4 @@ error[E0277]: the trait bound `Result<(), MyError>: IntoPyCallbackOutput<_>` is | = help: the following implementations were found: as IntoPyCallbackOutput> - = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the attribute macro `pyfunction` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/pyclass_send.stderr b/tests/ui/pyclass_send.stderr index 42cd481ecc0..67b5a7e23a8 100644 --- a/tests/ui/pyclass_send.stderr +++ b/tests/ui/pyclass_send.stderr @@ -15,4 +15,4 @@ note: required because it appears within the type `NotThreadSafe` | 5 | struct NotThreadSafe { | ^^^^^^^^^^^^^ - = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/static_ref.stderr b/tests/ui/static_ref.stderr index b4f452e245a..b88d8016c37 100644 --- a/tests/ui/static_ref.stderr +++ b/tests/ui/static_ref.stderr @@ -22,4 +22,4 @@ note: ...so that reference does not outlive borrowed content | 4 | #[pyfunction] | ^^^^^^^^^^^^^ - = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the attribute macro `pyfunction` (in Nightly builds, run with -Z macro-backtrace for more info)