diff --git a/lib/Filesystem.hs b/lib/Filesystem.hs
--- a/lib/Filesystem.hs
+++ b/lib/Filesystem.hs
@@ -198,6 +198,7 @@
 -- Since: 0.1.1
 canonicalizePath :: FilePath -> IO FilePath
 canonicalizePath path =
+	fmap (preserveFinalSlash path) $
 	let path' = encodeString path in
 #ifdef CABAL_OS_WINDOWS
 	fmap decodeString $
@@ -215,6 +216,11 @@
 		c_free cOut
 		return (R.decode R.posix bytes)
 #endif
+
+preserveFinalSlash :: FilePath -> FilePath -> FilePath
+preserveFinalSlash orig out = if Path.null (Path.filename orig)
+	then Path.append out Path.empty
+	else out
 
 #ifdef CABAL_OS_WINDOWS
 #if MIN_VERSION_Win32(2,2,1)
diff --git a/system-fileio.cabal b/system-fileio.cabal
--- a/system-fileio.cabal
+++ b/system-fileio.cabal
@@ -1,5 +1,5 @@
 name: system-fileio
-version: 0.3.7
+version: 0.3.8
 license: MIT
 license-file: license.txt
 author: John Millikin <jmillikin@gmail.com>
@@ -42,7 +42,7 @@
 source-repository this
   type: bazaar
   location: https://john-millikin.com/branches/system-fileio/0.3/
-  tag: system-fileio_0.3.7
+  tag: system-fileio_0.3.8
 
 library
   ghc-options: -Wall -O2
diff --git a/tests/FilesystemTests/Posix.hs b/tests/FilesystemTests/Posix.hs
--- a/tests/FilesystemTests/Posix.hs
+++ b/tests/FilesystemTests/Posix.hs
@@ -83,6 +83,7 @@
 #else
 			(decode "\xA1\xA2\xA3-b.txt")
 #endif
+		, test_CanonicalizePath_TrailingSlash
 		]
 	, suite "createDirectory"
 		[ test_CreateDirectory "ascii"
@@ -322,6 +323,24 @@
 	
 	canonicalized <- liftIO $ Filesystem.canonicalizePath src_path
 	$expect $ equal canonicalized dst_path
+
+test_CanonicalizePath_TrailingSlash :: Suite
+test_CanonicalizePath_TrailingSlash = assertionsWithTemp "trailing-slash" $ \tmp -> do
+	let src_path = tmp </> "src"
+	let subdir = tmp </> "subdir"
+	
+	-- canonicalize the directory first, to avoid false negatives if
+	-- it gets placed in a symlinked location.
+	mkdir_ffi subdir
+	canon_subdir <- liftIO (Filesystem.canonicalizePath (tmp </> "subdir"))
+	
+	let dst_path = canon_subdir </> "dst"
+	
+	mkdir_ffi dst_path
+	symlink_ffi dst_path src_path
+	
+	canonicalized <- liftIO (Filesystem.canonicalizePath (src_path </> empty))
+	$expect (equal canonicalized (dst_path </> empty))
 
 test_CreateDirectory :: Text -> FilePath -> Suite
 test_CreateDirectory test_name dir_name = assertionsWithTemp test_name $ \tmp -> do
