diff --git a/app/buildSrc/src/main/java/Setup.kt b/app/buildSrc/src/main/java/Setup.kt index c7bb190cd..d8c2d6047 100644 --- a/app/buildSrc/src/main/java/Setup.kt +++ b/app/buildSrc/src/main/java/Setup.kt @@ -55,7 +55,7 @@ fun Project.setupCommon() { compileSdkVersion(36) buildToolsVersion = "36.0.0" ndkPath = "$sdkDirectory/ndk/magisk" - ndkVersion = "28.1.13356709" + ndkVersion = "29.0.13846066" defaultConfig { minSdk = 23 diff --git a/build.py b/build.py index 16a026652..152110038 100755 --- a/build.py +++ b/build.py @@ -11,7 +11,6 @@ import stat import subprocess import sys import tarfile -import textwrap import urllib.request from pathlib import Path from zipfile import ZipFile @@ -71,7 +70,7 @@ default_archs = {"armeabi-v7a", "x86", "arm64-v8a", "x86_64"} default_targets = {"magisk", "magiskinit", "magiskboot", "magiskpolicy"} support_targets = default_targets | {"resetprop"} rust_targets = {"magisk", "magiskinit", "magiskboot", "magiskpolicy"} -ondk_version = "r28.5" +ondk_version = "r29.2" # Global vars config = {} diff --git a/native/src/Cargo.lock b/native/src/Cargo.lock index c9db8f848..0513af703 100644 --- a/native/src/Cargo.lock +++ b/native/src/Cargo.lock @@ -200,10 +200,11 @@ checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "codespan-reporting" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" dependencies = [ + "serde", "termcolor", "unicode-width", ] @@ -313,7 +314,7 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.137" +version = "1.0.170" dependencies = [ "cc", "cxxbridge-cmd", @@ -324,9 +325,10 @@ dependencies = [ [[package]] name = "cxx-gen" -version = "0.7.137" +version = "0.7.170" dependencies = [ "codespan-reporting", + "indexmap", "proc-macro2", "quote", "syn", @@ -334,10 +336,11 @@ dependencies = [ [[package]] name = "cxxbridge-cmd" -version = "1.0.137" +version = "1.0.170" dependencies = [ "clap", "codespan-reporting", + "indexmap", "proc-macro2", "quote", "syn", @@ -345,12 +348,13 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.137" +version = "1.0.170" [[package]] name = "cxxbridge-macro" -version = "1.0.137" +version = "1.0.170" dependencies = [ + "indexmap", "proc-macro2", "quote", "rustversion", @@ -447,6 +451,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + [[package]] name = "fdt" version = "0.1.5" @@ -482,9 +492,9 @@ dependencies = [ [[package]] name = "foldhash" -version = "0.1.5" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "generic-array" @@ -519,6 +529,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" + [[package]] name = "hmac" version = "0.13.0-rc.0" @@ -538,6 +554,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "indexmap" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "libbz2-rs-sys" version = "0.2.1" diff --git a/native/src/base/Android.mk b/native/src/base/Android.mk index 2a9ebdc1e..fce9a9015 100644 --- a/native/src/base/Android.mk +++ b/native/src/base/Android.mk @@ -12,7 +12,6 @@ LOCAL_C_INCLUDES := \ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES) LOCAL_EXPORT_STATIC_LIBRARIES := libcxx LOCAL_STATIC_LIBRARIES := libcxx -LOCAL_CFLAGS := -DRUST_CXX_NO_EXCEPTIONS LOCAL_SRC_FILES := \ base.cpp \ base-rs.cpp \ diff --git a/native/src/base/cstr.rs b/native/src/base/cstr.rs index aaaaf725e..5152d18f4 100644 --- a/native/src/base/cstr.rs +++ b/native/src/base/cstr.rs @@ -56,7 +56,7 @@ pub mod buf { } #[inline(always)] - pub fn wrap(buf: &mut [u8]) -> Utf8CStrBufRef { + pub fn wrap(buf: &mut [u8]) -> Utf8CStrBufRef<'_> { Utf8CStrBufRef::from(buf) } diff --git a/native/src/base/cxx_extern.rs b/native/src/base/cxx_extern.rs index 24e1fa2d3..695c0f82b 100644 --- a/native/src/base/cxx_extern.rs +++ b/native/src/base/cxx_extern.rs @@ -110,11 +110,10 @@ pub(crate) unsafe fn readlinkat( #[unsafe(export_name = "cp_afc")] unsafe extern "C" fn cp_afc_for_cxx(src: *const c_char, dest: *const c_char) -> bool { unsafe { - if let Ok(src) = Utf8CStr::from_ptr(src) { - if let Ok(dest) = Utf8CStr::from_ptr(dest) { + if let Ok(src) = Utf8CStr::from_ptr(src) + && let Ok(dest) = Utf8CStr::from_ptr(dest) { return src.copy_to(dest).log_cxx().is_ok(); } - } false } } @@ -122,11 +121,10 @@ unsafe extern "C" fn cp_afc_for_cxx(src: *const c_char, dest: *const c_char) -> #[unsafe(export_name = "mv_path")] unsafe extern "C" fn mv_path_for_cxx(src: *const c_char, dest: *const c_char) -> bool { unsafe { - if let Ok(src) = Utf8CStr::from_ptr(src) { - if let Ok(dest) = Utf8CStr::from_ptr(dest) { + if let Ok(src) = Utf8CStr::from_ptr(src) + && let Ok(dest) = Utf8CStr::from_ptr(dest) { return src.move_to(dest).log_cxx().is_ok(); } - } false } } @@ -134,11 +132,10 @@ unsafe extern "C" fn mv_path_for_cxx(src: *const c_char, dest: *const c_char) -> #[unsafe(export_name = "link_path")] unsafe extern "C" fn link_path_for_cxx(src: *const c_char, dest: *const c_char) -> bool { unsafe { - if let Ok(src) = Utf8CStr::from_ptr(src) { - if let Ok(dest) = Utf8CStr::from_ptr(dest) { + if let Ok(src) = Utf8CStr::from_ptr(src) + && let Ok(dest) = Utf8CStr::from_ptr(dest) { return src.link_to(dest).log_cxx().is_ok(); } - } false } } @@ -146,11 +143,10 @@ unsafe extern "C" fn link_path_for_cxx(src: *const c_char, dest: *const c_char) #[unsafe(export_name = "clone_attr")] unsafe extern "C" fn clone_attr_for_cxx(src: *const c_char, dest: *const c_char) -> bool { unsafe { - if let Ok(src) = Utf8CStr::from_ptr(src) { - if let Ok(dest) = Utf8CStr::from_ptr(dest) { + if let Ok(src) = Utf8CStr::from_ptr(src) + && let Ok(dest) = Utf8CStr::from_ptr(dest) { return clone_attr(src, dest).log_cxx().is_ok(); } - } false } } diff --git a/native/src/base/dir.rs b/native/src/base/dir.rs index 1c4cb72db..395f41fcd 100644 --- a/native/src/base/dir.rs +++ b/native/src/base/dir.rs @@ -63,16 +63,16 @@ impl DirEntry<'_> { self.d_type == libc::DT_SOCK } - pub fn unlink(&self) -> OsResult<()> { + pub fn unlink(&self) -> OsResult<'_, ()> { let flag = if self.is_dir() { libc::AT_REMOVEDIR } else { 0 }; self.dir.unlink_at(self.name(), flag) } - pub fn read_link(&self, buf: &mut dyn Utf8CStrBuf) -> OsResult<()> { + pub fn read_link(&self, buf: &mut dyn Utf8CStrBuf) -> OsResult<'_, ()> { self.dir.read_link_at(self.name(), buf) } - pub fn open_as_dir(&self) -> OsResult { + pub fn open_as_dir(&self) -> OsResult<'_, Directory> { if !self.is_dir() { return Err(OsError::with_os_error( libc::ENOTDIR, @@ -84,7 +84,7 @@ impl DirEntry<'_> { self.dir.open_as_dir_at(self.name()) } - pub fn open_as_file(&self, flags: i32) -> OsResult { + pub fn open_as_file(&self, flags: i32) -> OsResult<'_, File> { if self.is_dir() { return Err(OsError::with_os_error( libc::EISDIR, @@ -141,7 +141,7 @@ pub enum WalkResult { } impl Directory { - fn borrow(&self) -> BorrowedDirectory { + fn borrow(&self) -> BorrowedDirectory<'_> { BorrowedDirectory { inner: self.inner, phantom: PhantomData, @@ -164,13 +164,13 @@ impl Directory { } impl Directory { - pub fn open(path: &Utf8CStr) -> OsResult { + pub fn open(path: &Utf8CStr) -> OsResult<'_, Directory> { let dirp = unsafe { libc::opendir(path.as_ptr()) }; let dirp = dirp.as_os_result("opendir", Some(path), None)?; Ok(Directory { inner: dirp }) } - pub fn read(&mut self) -> OsResult<'static, Option> { + pub fn read(&mut self) -> OsResult<'static, Option>> { *errno() = 0; let e = unsafe { libc::readdir(self.inner.as_ptr()) }; if e.is_null() { @@ -481,7 +481,7 @@ impl AsRawFd for Directory { } impl AsFd for Directory { - fn as_fd(&self) -> BorrowedFd { + fn as_fd(&self) -> BorrowedFd<'_> { unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) } } } diff --git a/native/src/base/files.rs b/native/src/base/files.rs index 1f88b45d9..3af9c6cd3 100644 --- a/native/src/base/files.rs +++ b/native/src/base/files.rs @@ -139,7 +139,7 @@ impl FileOrStd { } } -fn open_fd(path: &Utf8CStr, flags: i32, mode: mode_t) -> OsResult { +fn open_fd(path: &Utf8CStr, flags: i32, mode: mode_t) -> OsResult<'_, OwnedFd> { unsafe { let fd = libc::open(path.as_ptr(), flags, mode as c_uint).as_os_result( "open", @@ -224,11 +224,11 @@ impl Utf8CStr { unsafe { mem::transmute(self) } } - pub fn open(&self, flags: i32) -> OsResult { + pub fn open(&self, flags: i32) -> OsResult<'_, File> { Ok(File::from(open_fd(self, flags, 0)?)) } - pub fn create(&self, flags: i32, mode: mode_t) -> OsResult { + pub fn create(&self, flags: i32, mode: mode_t) -> OsResult<'_, File> { Ok(File::from(open_fd(self, O_CREAT | flags, mode)?)) } @@ -249,7 +249,7 @@ impl Utf8CStr { } } - pub fn remove(&self) -> OsResult<()> { + pub fn remove(&self) -> OsResult<'_, ()> { unsafe { libc::remove(self.as_ptr()).check_os_err("remove", Some(self), None) } } @@ -263,7 +263,7 @@ impl Utf8CStr { } #[allow(clippy::unnecessary_cast)] - pub fn read_link(&self, buf: &mut dyn Utf8CStrBuf) -> OsResult<()> { + pub fn read_link(&self, buf: &mut dyn Utf8CStrBuf) -> OsResult<'_, ()> { buf.clear(); unsafe { let r = libc::readlink(self.as_ptr(), buf.as_mut_ptr(), buf.capacity() - 1) @@ -274,7 +274,7 @@ impl Utf8CStr { Ok(()) } - pub fn mkdir(&self, mode: mode_t) -> OsResult<()> { + pub fn mkdir(&self, mode: mode_t) -> OsResult<'_, ()> { unsafe { if libc::mkdir(self.as_ptr(), mode) < 0 { if *errno() == EEXIST { @@ -317,7 +317,7 @@ impl Utf8CStr { } // Inspired by https://android.googlesource.com/platform/bionic/+/master/libc/bionic/realpath.cpp - pub fn realpath(&self, buf: &mut dyn Utf8CStrBuf) -> OsResult<()> { + pub fn realpath(&self, buf: &mut dyn Utf8CStrBuf) -> OsResult<'_, ()> { let fd = self.open(O_PATH | O_CLOEXEC)?; let mut st1: libc::stat; let mut st2: libc::stat; @@ -341,7 +341,7 @@ impl Utf8CStr { Ok(()) } - pub fn get_attr(&self) -> OsResult { + pub fn get_attr(&self) -> OsResult<'_, FileAttr> { let mut attr = FileAttr::new(); unsafe { libc::lstat(self.as_ptr(), &mut attr.st).check_os_err("lstat", Some(self), None)?; @@ -375,7 +375,7 @@ impl Utf8CStr { Ok(()) } - pub fn get_secontext(&self, con: &mut dyn Utf8CStrBuf) -> OsResult<()> { + pub fn get_secontext(&self, con: &mut dyn Utf8CStrBuf) -> OsResult<'_, ()> { unsafe { let sz = libc::lgetxattr( self.as_ptr(), @@ -500,7 +500,7 @@ impl Utf8CStr { } } - pub fn mkfifo(&self, mode: mode_t) -> OsResult<()> { + pub fn mkfifo(&self, mode: mode_t) -> OsResult<'_, ()> { unsafe { libc::mkfifo(self.as_ptr(), mode).check_os_err("mkfifo", Some(self), None) } } } @@ -510,7 +510,7 @@ impl FsPathFollow { unsafe { libc::access(self.as_ptr(), F_OK) == 0 } } - pub fn get_attr(&self) -> OsResult { + pub fn get_attr(&self) -> OsResult<'_, FileAttr> { let mut attr = FileAttr::new(); unsafe { libc::stat(self.as_ptr(), &mut attr.st).check_os_err("stat", Some(self), None)?; @@ -542,7 +542,7 @@ impl FsPathFollow { Ok(()) } - pub fn get_secontext(&self, con: &mut dyn Utf8CStrBuf) -> OsResult<()> { + pub fn get_secontext(&self, con: &mut dyn Utf8CStrBuf) -> OsResult<'_, ()> { unsafe { let sz = libc::getxattr( self.as_ptr(), @@ -640,7 +640,7 @@ pub fn fd_get_attr(fd: RawFd) -> OsResult<'static, FileAttr> { Ok(attr) } -pub fn fd_set_attr(fd: RawFd, attr: &FileAttr) -> OsResult<()> { +pub fn fd_set_attr(fd: RawFd, attr: &FileAttr) -> OsResult<'_, ()> { unsafe { libc::fchmod(fd, (attr.st.st_mode & 0o777).as_()).check_os_err("fchmod", None, None)?; libc::fchown(fd, attr.st.st_uid, attr.st.st_gid).check_os_err("fchown", None, None)?; @@ -672,7 +672,7 @@ pub fn fd_get_secontext(fd: RawFd, con: &mut dyn Utf8CStrBuf) -> OsResult<'stati Ok(()) } -pub fn fd_set_secontext(fd: RawFd, con: &Utf8CStr) -> OsResult<()> { +pub fn fd_set_secontext(fd: RawFd, con: &Utf8CStr) -> OsResult<'_, ()> { unsafe { libc::fsetxattr( fd, @@ -698,11 +698,11 @@ pub fn fclone_attr(a: RawFd, b: RawFd) -> OsResult<'static, ()> { pub struct MappedFile(&'static mut [u8]); impl MappedFile { - pub fn open(path: &Utf8CStr) -> OsResult { + pub fn open(path: &Utf8CStr) -> OsResult<'_, MappedFile> { Ok(MappedFile(map_file(path, false)?)) } - pub fn open_rw(path: &Utf8CStr) -> OsResult { + pub fn open_rw(path: &Utf8CStr) -> OsResult<'_, MappedFile> { Ok(MappedFile(map_file(path, true)?)) } @@ -745,7 +745,7 @@ unsafe extern "C" { } // We mark the returned slice static because it is valid until explicitly unmapped -pub(crate) fn map_file(path: &Utf8CStr, rw: bool) -> OsResult<&'static mut [u8]> { +pub(crate) fn map_file(path: &Utf8CStr, rw: bool) -> OsResult<'_, &'static mut [u8]> { unsafe { map_file_at(BorrowedFd::borrow_raw(libc::AT_FDCWD), path, rw) } } diff --git a/native/src/base/mount.rs b/native/src/base/mount.rs index aa1b0234d..b72f66110 100644 --- a/native/src/base/mount.rs +++ b/native/src/base/mount.rs @@ -17,7 +17,7 @@ impl Utf8CStr { } } - pub fn remount_mount_point_flags(&self, flags: c_ulong) -> OsResult<()> { + pub fn remount_mount_point_flags(&self, flags: c_ulong) -> OsResult<'_, ()> { unsafe { libc::mount( ptr::null(), @@ -30,7 +30,7 @@ impl Utf8CStr { } } - pub fn remount_mount_flags(&self, flags: c_ulong) -> OsResult<()> { + pub fn remount_mount_flags(&self, flags: c_ulong) -> OsResult<'_, ()> { unsafe { libc::mount( ptr::null(), @@ -43,7 +43,7 @@ impl Utf8CStr { } } - pub fn remount_with_data(&self, data: &Utf8CStr) -> OsResult<()> { + pub fn remount_with_data(&self, data: &Utf8CStr) -> OsResult<'_, ()> { unsafe { libc::mount( ptr::null(), @@ -69,13 +69,13 @@ impl Utf8CStr { } } - pub fn unmount(&self) -> OsResult<()> { + pub fn unmount(&self) -> OsResult<'_, ()> { unsafe { libc::umount2(self.as_ptr(), libc::MNT_DETACH).check_os_err("unmount", Some(self), None) } } - pub fn set_mount_private(&self, recursive: bool) -> OsResult<()> { + pub fn set_mount_private(&self, recursive: bool) -> OsResult<'_, ()> { let flag = if recursive { libc::MS_REC } else { 0 }; unsafe { libc::mount( diff --git a/native/src/boot/cpio.rs b/native/src/boot/cpio.rs index aab1bb0e5..f4949bf63 100644 --- a/native/src/boot/cpio.rs +++ b/native/src/boot/cpio.rs @@ -560,7 +560,7 @@ impl Cpio { let mut backups = HashMap::>::new(); let mut rm_list = String::new(); self.entries - .extract_if(|name, _| name.starts_with(".backup/")) + .extract_if(.., |name, _| name.starts_with(".backup/")) .for_each(|(name, mut entry)| { if name == ".backup/.rmlist" { if let Ok(data) = str::from_utf8(&entry.data) { diff --git a/native/src/boot/dtb.rs b/native/src/boot/dtb.rs index 4ad2aa7be..d438c38dc 100644 --- a/native/src/boot/dtb.rs +++ b/native/src/boot/dtb.rs @@ -210,12 +210,11 @@ fn dtb_test(file: &Utf8CStr) -> LoggedResult { if child.name != "system" { continue; } - if let Some(mount_point) = child.property("mnt_point") { - if mount_point.value == b"/system_root\0" { + if let Some(mount_point) = child.property("mnt_point") + && mount_point.value == b"/system_root\0" { ret = false; break; } - } } } Ok(()) diff --git a/native/src/core/module.rs b/native/src/core/module.rs index da8a11e31..06bbfd7ec 100644 --- a/native/src/core/module.rs +++ b/native/src/core/module.rs @@ -70,7 +70,7 @@ impl PathTracker<'_> { PathTracker { path, len } } - fn append(&mut self, name: &str) -> PathTracker { + fn append(&mut self, name: &str) -> PathTracker<'_> { let len = self.path.len(); self.path.append_path(name); PathTracker { @@ -79,7 +79,7 @@ impl PathTracker<'_> { } } - fn reborrow(&mut self) -> PathTracker { + fn reborrow(&mut self) -> PathTracker<'_> { Self::from(self.path) } } @@ -99,7 +99,7 @@ struct FilePaths<'a> { } impl FilePaths<'_> { - fn append(&mut self, name: &str) -> FilePaths { + fn append(&mut self, name: &str) -> FilePaths<'_> { FilePaths { real: self.real.append(name), worker: self.worker.append(name), @@ -108,7 +108,7 @@ impl FilePaths<'_> { } } - fn reborrow(&mut self) -> FilePaths { + fn reborrow(&mut self) -> FilePaths<'_> { FilePaths { real: self.real.reborrow(), worker: self.worker.reborrow(), diff --git a/native/src/core/socket.rs b/native/src/core/socket.rs index 8ed4f4ea8..6df6c79c1 100644 --- a/native/src/core/socket.rs +++ b/native/src/core/socket.rs @@ -7,6 +7,7 @@ use std::os::fd::{FromRawFd, IntoRawFd, OwnedFd, RawFd}; use std::os::unix::net::{AncillaryData, SocketAncillary, UnixStream}; pub trait Encodable { + #[allow(dead_code)] fn encoded_len(&self) -> usize; fn encode(&self, w: &mut impl Write) -> io::Result<()>; } diff --git a/native/src/external/cxx-rs b/native/src/external/cxx-rs index 0ea6d507c..667377297 160000 --- a/native/src/external/cxx-rs +++ b/native/src/external/cxx-rs @@ -1 +1 @@ -Subproject commit 0ea6d507cee40da9581b71bd531a4e3ac0a37164 +Subproject commit 667377297a1cc0e1ab3dfc82fa56da83e59d0378 diff --git a/native/src/init/mount.rs b/native/src/init/mount.rs index be422986c..3daba8149 100644 --- a/native/src/init/mount.rs +++ b/native/src/init/mount.rs @@ -29,11 +29,9 @@ pub(crate) fn switch_root(path: &Utf8CStr) { if let Some(last_mount) = mounts .range::((Unbounded, Excluded(&info.target))) .last() - { - if info.target.starts_with(&format!("{}/", *last_mount)) { + && info.target.starts_with(&format!("{}/", *last_mount)) { continue; } - } let mut target = info.target.clone(); let target = Utf8CStr::from_string(&mut target); diff --git a/native/src/sepolicy/cli.rs b/native/src/sepolicy/cli.rs index 872f879a8..ca5542837 100644 --- a/native/src/sepolicy/cli.rs +++ b/native/src/sepolicy/cli.rs @@ -127,11 +127,10 @@ pub unsafe extern "C" fn main( log_err!("Cannot apply policy")?; } - if let Some(file) = cli.save { - if !sepol.to_file(&file) { + if let Some(file) = cli.save + && !sepol.to_file(&file) { log_err!("Cannot dump policy to {}", file)?; } - } }; if res.is_ok() { 0 } else { 1 } } diff --git a/native/src/sepolicy/statement.rs b/native/src/sepolicy/statement.rs index 8db9b2fee..d3f25f17b 100644 --- a/native/src/sepolicy/statement.rs +++ b/native/src/sepolicy/statement.rs @@ -202,10 +202,10 @@ fn parse_xperms<'a>(tokens: &mut Tokens<'a>) -> ParseResult<'a, Vec> { } fn match_string<'a>(tokens: &mut Tokens<'a>, pattern: &str) -> ParseResult<'a, ()> { - if let Some(Token::ID(s)) = tokens.next() { - if s == pattern { - return Ok(()); - } + if let Some(Token::ID(s)) = tokens.next() + && s == pattern + { + return Ok(()); } Err(ParseError::General) } @@ -263,7 +263,7 @@ fn extract_token<'a>(s: &'a str, tokens: &mut Vec>) { } } -fn tokenize_statement(statement: &str) -> Vec { +fn tokenize_statement(statement: &str) -> Vec> { let mut tokens = Vec::new(); for s in statement.split_whitespace() { extract_token(s, &mut tokens);